Lines Matching +full:mmc +full:- +full:host

1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2019-2020 Antmicro <contact@antmicro.com>
6 * Copyright (C) 2019-2020 Kamil Rakoczy <krakoczy@antmicro.com>
7 * Copyright (C) 2019-2020 Maciej Dudek <mdudek@internships.antmicro.com>
9 * Copyright (C) 2020-2022 Gabriel Somlo <gsomlo@gmail.com>
15 #include <linux/dma-mapping.h>
23 #include <linux/mmc/host.h>
24 #include <linux/mmc/mmc.h>
25 #include <linux/mmc/sd.h>
77 struct mmc_host *mmc; member
114 return -EIO; in litex_mmc_sdcard_wait_done()
116 return -ETIMEDOUT; in litex_mmc_sdcard_wait_done()
118 return -EILSEQ; in litex_mmc_sdcard_wait_done()
120 return -EINVAL; in litex_mmc_sdcard_wait_done()
123 static int litex_mmc_send_cmd(struct litex_mmc_host *host, in litex_mmc_send_cmd() argument
126 struct device *dev = mmc_dev(host->mmc); in litex_mmc_send_cmd()
131 litex_write32(host->sdcore + LITEX_CORE_CMDARG, arg); in litex_mmc_send_cmd()
132 litex_write32(host->sdcore + LITEX_CORE_CMDCMD, in litex_mmc_send_cmd()
134 litex_write8(host->sdcore + LITEX_CORE_CMDSND, 1); in litex_mmc_send_cmd()
140 if (host->irq > 0 && in litex_mmc_send_cmd()
143 reinit_completion(&host->cmd_done); in litex_mmc_send_cmd()
144 litex_write32(host->sdirq + LITEX_IRQ_ENABLE, in litex_mmc_send_cmd()
146 wait_for_completion(&host->cmd_done); in litex_mmc_send_cmd()
149 ret = litex_mmc_sdcard_wait_done(host->sdcore + LITEX_CORE_CMDEVT, dev); in litex_mmc_send_cmd()
160 memcpy_fromio(host->resp, in litex_mmc_send_cmd()
161 host->sdcore + LITEX_CORE_CMDRSP, 0x10); in litex_mmc_send_cmd()
164 if (!host->app_cmd && cmd == SD_SEND_RELATIVE_ADDR) in litex_mmc_send_cmd()
165 host->rca = (host->resp[3] >> 16); in litex_mmc_send_cmd()
167 host->app_cmd = (cmd == MMC_APP_CMD); in litex_mmc_send_cmd()
172 ret = litex_mmc_sdcard_wait_done(host->sdcore + LITEX_CORE_DATEVT, dev); in litex_mmc_send_cmd()
180 host->sdreader + LITEX_BLK2MEM_DONE : in litex_mmc_send_cmd()
181 host->sdwriter + LITEX_MEM2BLK_DONE; in litex_mmc_send_cmd()
190 static int litex_mmc_send_app_cmd(struct litex_mmc_host *host) in litex_mmc_send_app_cmd() argument
192 return litex_mmc_send_cmd(host, MMC_APP_CMD, host->rca << 16, in litex_mmc_send_app_cmd()
196 static int litex_mmc_send_set_bus_w_cmd(struct litex_mmc_host *host, u32 width) in litex_mmc_send_set_bus_w_cmd() argument
198 return litex_mmc_send_cmd(host, SD_APP_SET_BUS_WIDTH, width, in litex_mmc_send_set_bus_w_cmd()
202 static int litex_mmc_set_bus_width(struct litex_mmc_host *host) in litex_mmc_set_bus_width() argument
207 if (host->is_bus_width_set) in litex_mmc_set_bus_width()
211 app_cmd_sent = host->app_cmd; /* was preceding command app_cmd? */ in litex_mmc_set_bus_width()
213 ret = litex_mmc_send_app_cmd(host); in litex_mmc_set_bus_width()
218 /* LiteSDCard only supports 4-bit bus width */ in litex_mmc_set_bus_width()
219 ret = litex_mmc_send_set_bus_w_cmd(host, MMC_BUS_WIDTH_4); in litex_mmc_set_bus_width()
223 /* Re-send 'app_cmd' if necessary */ in litex_mmc_set_bus_width()
225 ret = litex_mmc_send_app_cmd(host); in litex_mmc_set_bus_width()
230 host->is_bus_width_set = true; in litex_mmc_set_bus_width()
235 static int litex_mmc_get_cd(struct mmc_host *mmc) in litex_mmc_get_cd() argument
237 struct litex_mmc_host *host = mmc_priv(mmc); in litex_mmc_get_cd() local
240 if (!mmc_card_is_removable(mmc)) in litex_mmc_get_cd()
243 ret = !litex_read8(host->sdphy + LITEX_PHY_CARDDETECT); in litex_mmc_get_cd()
248 host->is_bus_width_set = false; in litex_mmc_get_cd()
255 struct mmc_host *mmc = arg; in litex_mmc_interrupt() local
256 struct litex_mmc_host *host = mmc_priv(mmc); in litex_mmc_interrupt() local
257 u32 pending = litex_read32(host->sdirq + LITEX_IRQ_PENDING); in litex_mmc_interrupt()
262 litex_write32(host->sdirq + LITEX_IRQ_PENDING, in litex_mmc_interrupt()
264 mmc_detect_change(mmc, msecs_to_jiffies(10)); in litex_mmc_interrupt()
271 litex_write32(host->sdirq + LITEX_IRQ_ENABLE, in litex_mmc_interrupt()
273 complete(&host->cmd_done); in litex_mmc_interrupt()
282 if (cmd->flags & MMC_RSP_136) in litex_mmc_response_len()
284 if (!(cmd->flags & MMC_RSP_PRESENT)) in litex_mmc_response_len()
286 if (cmd->flags & MMC_RSP_BUSY) in litex_mmc_response_len()
291 static void litex_mmc_do_dma(struct litex_mmc_host *host, struct mmc_data *data, in litex_mmc_do_dma() argument
294 struct device *dev = mmc_dev(host->mmc); in litex_mmc_do_dma()
303 dma = host->dma; in litex_mmc_do_dma()
304 *len = data->blksz * data->blocks; in litex_mmc_do_dma()
305 sg_count = dma_map_sg(dev, data->sg, data->sg_len, in litex_mmc_do_dma()
308 dma = sg_dma_address(data->sg); in litex_mmc_do_dma()
309 *len = sg_dma_len(data->sg); in litex_mmc_do_dma()
311 } else if (*len > host->buf_size) in litex_mmc_do_dma()
312 *len = host->buf_size; in litex_mmc_do_dma()
314 if (data->flags & MMC_DATA_READ) { in litex_mmc_do_dma()
315 litex_write8(host->sdreader + LITEX_BLK2MEM_ENA, 0); in litex_mmc_do_dma()
316 litex_write64(host->sdreader + LITEX_BLK2MEM_BASE, dma); in litex_mmc_do_dma()
317 litex_write32(host->sdreader + LITEX_BLK2MEM_LEN, *len); in litex_mmc_do_dma()
318 litex_write8(host->sdreader + LITEX_BLK2MEM_ENA, 1); in litex_mmc_do_dma()
320 } else if (data->flags & MMC_DATA_WRITE) { in litex_mmc_do_dma()
322 sg_copy_to_buffer(data->sg, data->sg_len, in litex_mmc_do_dma()
323 host->buffer, *len); in litex_mmc_do_dma()
324 litex_write8(host->sdwriter + LITEX_MEM2BLK_ENA, 0); in litex_mmc_do_dma()
325 litex_write64(host->sdwriter + LITEX_MEM2BLK_BASE, dma); in litex_mmc_do_dma()
326 litex_write32(host->sdwriter + LITEX_MEM2BLK_LEN, *len); in litex_mmc_do_dma()
327 litex_write8(host->sdwriter + LITEX_MEM2BLK_ENA, 1); in litex_mmc_do_dma()
334 litex_write16(host->sdcore + LITEX_CORE_BLKLEN, data->blksz); in litex_mmc_do_dma()
335 litex_write32(host->sdcore + LITEX_CORE_BLKCNT, data->blocks); in litex_mmc_do_dma()
338 static void litex_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) in litex_mmc_request() argument
340 struct litex_mmc_host *host = mmc_priv(mmc); in litex_mmc_request() local
341 struct device *dev = mmc_dev(mmc); in litex_mmc_request()
342 struct mmc_command *cmd = mrq->cmd; in litex_mmc_request()
343 struct mmc_command *sbc = mrq->sbc; in litex_mmc_request()
344 struct mmc_data *data = mrq->data; in litex_mmc_request()
345 struct mmc_command *stop = mrq->stop; in litex_mmc_request()
346 unsigned int retries = cmd->retries; in litex_mmc_request()
353 if (!litex_mmc_get_cd(mmc)) { in litex_mmc_request()
354 cmd->error = -ENOMEDIUM; in litex_mmc_request()
355 mmc_request_done(mmc, mrq); in litex_mmc_request()
359 /* Send set-block-count command if needed */ in litex_mmc_request()
361 sbc->error = litex_mmc_send_cmd(host, sbc->opcode, sbc->arg, in litex_mmc_request()
364 if (sbc->error) { in litex_mmc_request()
365 host->is_bus_width_set = false; in litex_mmc_request()
366 mmc_request_done(mmc, mrq); in litex_mmc_request()
373 * LiteSDCard only supports 4-bit bus width; therefore, we MUST in litex_mmc_request()
375 * transfer, earlier than when the mmc subsystem would normally in litex_mmc_request()
378 cmd->error = litex_mmc_set_bus_width(host); in litex_mmc_request()
379 if (cmd->error) { in litex_mmc_request()
381 mmc_request_done(mmc, mrq); in litex_mmc_request()
385 litex_mmc_do_dma(host, data, &len, &direct, &transfer); in litex_mmc_request()
389 cmd->error = litex_mmc_send_cmd(host, cmd->opcode, cmd->arg, in litex_mmc_request()
391 } while (cmd->error && retries-- > 0); in litex_mmc_request()
393 if (cmd->error) { in litex_mmc_request()
395 host->is_bus_width_set = false; in litex_mmc_request()
399 /* Pull short response fields from appropriate host registers */ in litex_mmc_request()
400 cmd->resp[0] = host->resp[3]; in litex_mmc_request()
401 cmd->resp[1] = host->resp[2] & 0xFF; in litex_mmc_request()
403 cmd->resp[0] = host->resp[0]; in litex_mmc_request()
404 cmd->resp[1] = host->resp[1]; in litex_mmc_request()
405 cmd->resp[2] = host->resp[2]; in litex_mmc_request()
406 cmd->resp[3] = host->resp[3]; in litex_mmc_request()
409 /* Send stop-transmission command if required */ in litex_mmc_request()
410 if (stop && (cmd->error || !sbc)) { in litex_mmc_request()
411 stop->error = litex_mmc_send_cmd(host, stop->opcode, stop->arg, in litex_mmc_request()
414 if (stop->error) in litex_mmc_request()
415 host->is_bus_width_set = false; in litex_mmc_request()
419 dma_unmap_sg(dev, data->sg, data->sg_len, in litex_mmc_request()
423 if (!cmd->error && transfer != SD_CTL_DATA_XFER_NONE) { in litex_mmc_request()
424 data->bytes_xfered = min(len, mmc->max_req_size); in litex_mmc_request()
426 sg_copy_from_buffer(data->sg, sg_nents(data->sg), in litex_mmc_request()
427 host->buffer, data->bytes_xfered); in litex_mmc_request()
431 mmc_request_done(mmc, mrq); in litex_mmc_request()
434 static void litex_mmc_setclk(struct litex_mmc_host *host, unsigned int freq) in litex_mmc_setclk() argument
436 struct device *dev = mmc_dev(host->mmc); in litex_mmc_setclk()
439 div = freq ? host->ref_clk / freq : 256U; in litex_mmc_setclk()
443 freq, host->ref_clk / div, div); in litex_mmc_setclk()
444 litex_write16(host->sdphy + LITEX_PHY_CLOCKERDIV, div); in litex_mmc_setclk()
445 host->sd_clk = freq; in litex_mmc_setclk()
448 static void litex_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) in litex_mmc_set_ios() argument
450 struct litex_mmc_host *host = mmc_priv(mmc); in litex_mmc_set_ios() local
453 * NOTE: Ignore any ios->bus_width updates; they occur right after in litex_mmc_set_ios()
454 * the mmc core sends its own acmd6 bus-width change notification, in litex_mmc_set_ios()
460 if (ios->clock != host->sd_clk) in litex_mmc_set_ios()
461 litex_mmc_setclk(host, ios->clock); in litex_mmc_set_ios()
471 struct litex_mmc_host *host) in litex_mmc_irq_init() argument
473 struct device *dev = mmc_dev(host->mmc); in litex_mmc_irq_init()
477 if (ret < 0 && ret != -ENXIO) in litex_mmc_irq_init()
480 host->irq = ret; in litex_mmc_irq_init()
486 host->sdirq = devm_platform_ioremap_resource_byname(pdev, "irq"); in litex_mmc_irq_init()
487 if (IS_ERR(host->sdirq)) in litex_mmc_irq_init()
488 return PTR_ERR(host->sdirq); in litex_mmc_irq_init()
490 ret = devm_request_irq(dev, host->irq, litex_mmc_interrupt, 0, in litex_mmc_irq_init()
491 "litex-mmc", host->mmc); in litex_mmc_irq_init()
497 /* Clear & enable card-change interrupts */ in litex_mmc_irq_init()
498 litex_write32(host->sdirq + LITEX_IRQ_PENDING, SDIRQ_CARD_DETECT); in litex_mmc_irq_init()
499 litex_write32(host->sdirq + LITEX_IRQ_ENABLE, SDIRQ_CARD_DETECT); in litex_mmc_irq_init()
504 host->mmc->caps |= MMC_CAP_NEEDS_POLL; in litex_mmc_irq_init()
505 host->irq = 0; in litex_mmc_irq_init()
509 static void litex_mmc_free_host_wrapper(void *mmc) in litex_mmc_free_host_wrapper() argument
511 mmc_free_host(mmc); in litex_mmc_free_host_wrapper()
516 struct device *dev = &pdev->dev; in litex_mmc_probe()
517 struct litex_mmc_host *host; in litex_mmc_probe() local
518 struct mmc_host *mmc; in litex_mmc_probe() local
526 * re-calculate `max_[req,seg]_size = max_blk_size * max_blk_count;` in litex_mmc_probe()
528 mmc = mmc_alloc_host(sizeof(struct litex_mmc_host), dev); in litex_mmc_probe()
529 if (!mmc) in litex_mmc_probe()
530 return -ENOMEM; in litex_mmc_probe()
532 ret = devm_add_action_or_reset(dev, litex_mmc_free_host_wrapper, mmc); in litex_mmc_probe()
537 host = mmc_priv(mmc); in litex_mmc_probe()
538 host->mmc = mmc; in litex_mmc_probe()
544 host->ref_clk = clk_get_rate(clk); in litex_mmc_probe()
545 host->sd_clk = 0; in litex_mmc_probe()
548 * LiteSDCard only supports 4-bit bus width; therefore, we MUST inject in litex_mmc_probe()
550 * than when the mmc subsystem would normally get around to it! in litex_mmc_probe()
552 host->is_bus_width_set = false; in litex_mmc_probe()
553 host->app_cmd = false; in litex_mmc_probe()
555 /* LiteSDCard can support 64-bit DMA addressing */ in litex_mmc_probe()
560 host->buf_size = mmc->max_req_size * 2; in litex_mmc_probe()
561 host->buffer = dmam_alloc_coherent(dev, host->buf_size, in litex_mmc_probe()
562 &host->dma, GFP_KERNEL); in litex_mmc_probe()
563 if (host->buffer == NULL) in litex_mmc_probe()
564 return -ENOMEM; in litex_mmc_probe()
566 host->sdphy = devm_platform_ioremap_resource_byname(pdev, "phy"); in litex_mmc_probe()
567 if (IS_ERR(host->sdphy)) in litex_mmc_probe()
568 return PTR_ERR(host->sdphy); in litex_mmc_probe()
570 host->sdcore = devm_platform_ioremap_resource_byname(pdev, "core"); in litex_mmc_probe()
571 if (IS_ERR(host->sdcore)) in litex_mmc_probe()
572 return PTR_ERR(host->sdcore); in litex_mmc_probe()
574 host->sdreader = devm_platform_ioremap_resource_byname(pdev, "reader"); in litex_mmc_probe()
575 if (IS_ERR(host->sdreader)) in litex_mmc_probe()
576 return PTR_ERR(host->sdreader); in litex_mmc_probe()
578 host->sdwriter = devm_platform_ioremap_resource_byname(pdev, "writer"); in litex_mmc_probe()
579 if (IS_ERR(host->sdwriter)) in litex_mmc_probe()
580 return PTR_ERR(host->sdwriter); in litex_mmc_probe()
583 litex_write8(host->sdreader + LITEX_BLK2MEM_ENA, 0); in litex_mmc_probe()
584 litex_write8(host->sdwriter + LITEX_MEM2BLK_ENA, 0); in litex_mmc_probe()
586 init_completion(&host->cmd_done); in litex_mmc_probe()
587 ret = litex_mmc_irq_init(pdev, host); in litex_mmc_probe()
591 mmc->ops = &litex_mmc_ops; in litex_mmc_probe()
593 ret = mmc_regulator_get_supply(mmc); in litex_mmc_probe()
594 if (ret || mmc->ocr_avail == 0) { in litex_mmc_probe()
596 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; in litex_mmc_probe()
603 mmc->f_min = 12.5e6; in litex_mmc_probe()
604 mmc->f_max = 50e6; in litex_mmc_probe()
606 ret = mmc_of_parse(mmc); in litex_mmc_probe()
610 /* Force 4-bit bus_width (only width supported by hardware) */ in litex_mmc_probe()
611 mmc->caps &= ~MMC_CAP_8_BIT_DATA; in litex_mmc_probe()
612 mmc->caps |= MMC_CAP_4_BIT_DATA; in litex_mmc_probe()
615 mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | in litex_mmc_probe()
618 mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT | in litex_mmc_probe()
622 platform_set_drvdata(pdev, host); in litex_mmc_probe()
624 ret = mmc_add_host(mmc); in litex_mmc_probe()
628 dev_info(dev, "LiteX MMC controller initialized.\n"); in litex_mmc_probe()
634 struct litex_mmc_host *host = platform_get_drvdata(pdev); in litex_mmc_remove() local
636 mmc_remove_host(host->mmc); in litex_mmc_remove()
640 { .compatible = "litex,mmc" },
649 .name = "litex-mmc",