/* * Wait for an interrupt if we have an interrupt and either there is * data to be transferred, or if the card can report busy via DAT0.
*/ if (host->irq > 0 &&
(transfer != SD_CTL_DATA_XFER_NONE ||
response_len == SD_CTL_RESP_SHORT_BUSY)) {
reinit_completion(&host->cmd_done);
litex_write32(host->sdirq + LITEX_IRQ_ENABLE,
SDIRQ_CMD_DONE | SDIRQ_CARD_DETECT);
wait_for_completion(&host->cmd_done);
}
ret = litex_mmc_sdcard_wait_done(host->sdcore + LITEX_CORE_CMDEVT, dev); if (ret) {
dev_err(dev, "Command (cmd %d) error, status %d\n", cmd, ret); return ret;
}
if (response_len != SD_CTL_RESP_NONE) { /* * NOTE: this matches the semantics of litex_read32() * regardless of underlying arch endianness!
*/
memcpy_fromio(host->resp,
host->sdcore + LITEX_CORE_CMDRSP, 0x10);
}
/* Check for card change interrupt */ if (pending & SDIRQ_CARD_DETECT) {
litex_write32(host->sdirq + LITEX_IRQ_PENDING,
SDIRQ_CARD_DETECT);
mmc_detect_change(mmc, msecs_to_jiffies(10));
ret = IRQ_HANDLED;
}
/* Check for command completed */ if (pending & SDIRQ_CMD_DONE) { /* Disable it so it doesn't keep interrupting */
litex_write32(host->sdirq + LITEX_IRQ_ENABLE,
SDIRQ_CARD_DETECT);
complete(&host->cmd_done);
ret = IRQ_HANDLED;
}
return ret;
}
static u32 litex_mmc_response_len(struct mmc_command *cmd)
{ if (cmd->flags & MMC_RSP_136) return SD_CTL_RESP_LONG; if (!(cmd->flags & MMC_RSP_PRESENT)) return SD_CTL_RESP_NONE; if (cmd->flags & MMC_RSP_BUSY) return SD_CTL_RESP_SHORT_BUSY; return SD_CTL_RESP_SHORT;
}
/* * Try to DMA directly to/from the data buffer. * We can do that if the buffer can be mapped for DMA * in one contiguous chunk.
*/
dma = host->dma;
*len = data->blksz * data->blocks;
sg_count = dma_map_sg(dev, data->sg, data->sg_len,
mmc_get_dma_dir(data)); if (sg_count == 1) {
dma = sg_dma_address(data->sg);
*len = sg_dma_len(data->sg);
*direct = true;
} elseif (*len > host->buf_size)
*len = host->buf_size;
/* First check that the card is still there */ if (!litex_mmc_get_cd(mmc)) {
cmd->error = -ENOMEDIUM;
mmc_request_done(mmc, mrq); return;
}
/* Send set-block-count command if needed */ if (sbc) {
sbc->error = litex_mmc_send_cmd(host, sbc->opcode, sbc->arg,
litex_mmc_response_len(sbc),
SD_CTL_DATA_XFER_NONE); if (sbc->error) {
host->is_bus_width_set = false;
mmc_request_done(mmc, mrq); return;
}
}
if (data) { /* * LiteSDCard only supports 4-bit bus width; therefore, we MUST * inject a SET_BUS_WIDTH (acmd6) before the very first data * transfer, earlier than when the mmc subsystem would normally * get around to it!
*/
cmd->error = litex_mmc_set_bus_width(host); if (cmd->error) {
dev_err(dev, "Can't set bus width!\n");
mmc_request_done(mmc, mrq); return;
}
/* * NOTE: Ignore any ios->bus_width updates; they occur right after * the mmc core sends its own acmd6 bus-width change notification, * which is redundant since we snoop on the command flow and inject * an early acmd6 before the first data transfer command is sent!
*/
ret = platform_get_irq_optional(pdev, 0); if (ret < 0 && ret != -ENXIO) return ret; if (ret > 0)
host->irq = ret; else {
dev_warn(dev, "Failed to get IRQ, using polling\n"); goto use_polling;
}
host->sdirq = devm_platform_ioremap_resource_byname(pdev, "irq"); if (IS_ERR(host->sdirq)) return PTR_ERR(host->sdirq);
ret = devm_request_irq(dev, host->irq, litex_mmc_interrupt, 0, "litex-mmc", host->mmc); if (ret < 0) {
dev_warn(dev, "IRQ request error %d, using polling\n", ret); goto use_polling;
}
/* * NOTE: defaults to max_[req,seg]_size=PAGE_SIZE, max_blk_size=512, * and max_blk_count accordingly set to 8; * If for some reason we need to modify max_blk_count, we must also * re-calculate `max_[req,seg]_size = max_blk_size * max_blk_count;`
*/
mmc = devm_mmc_alloc_host(dev, sizeof(*host)); if (!mmc) return -ENOMEM;
/* * LiteSDCard only supports 4-bit bus width; therefore, we MUST inject * a SET_BUS_WIDTH (acmd6) before the very first data transfer, earlier * than when the mmc subsystem would normally get around to it!
*/
host->is_bus_width_set = false;
host->app_cmd = false;
/* LiteSDCard can support 64-bit DMA addressing */
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); if (ret) return ret;
host->sdphy = devm_platform_ioremap_resource_byname(pdev, "phy"); if (IS_ERR(host->sdphy)) return PTR_ERR(host->sdphy);
host->sdcore = devm_platform_ioremap_resource_byname(pdev, "core"); if (IS_ERR(host->sdcore)) return PTR_ERR(host->sdcore);
host->sdreader = devm_platform_ioremap_resource_byname(pdev, "reader"); if (IS_ERR(host->sdreader)) return PTR_ERR(host->sdreader);
host->sdwriter = devm_platform_ioremap_resource_byname(pdev, "writer"); if (IS_ERR(host->sdwriter)) return PTR_ERR(host->sdwriter);
/* Ensure DMA bus masters are disabled */
litex_write8(host->sdreader + LITEX_BLK2MEM_ENA, 0);
litex_write8(host->sdwriter + LITEX_MEM2BLK_ENA, 0);
init_completion(&host->cmd_done);
ret = litex_mmc_irq_init(pdev, host); if (ret) return ret;
mmc->ops = &litex_mmc_ops;
ret = mmc_regulator_get_supply(mmc); if (ret || mmc->ocr_avail == 0) {
dev_warn(dev, "can't get voltage, defaulting to 3.3V\n");
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
}
/* * Set default sd_clk frequency range based on empirical observations * of LiteSDCard gateware behavior on typical SDCard media
*/
mmc->f_min = 12.5e6;
mmc->f_max = 50e6;
ret = mmc_of_parse(mmc); if (ret) return ret;
/* Force 4-bit bus_width (only width supported by hardware) */
mmc->caps &= ~MMC_CAP_8_BIT_DATA;
mmc->caps |= MMC_CAP_4_BIT_DATA;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.