Lines Matching +full:pxa +full:- +full:mmc
2 * linux/drivers/mmc/host/pxa.c - PXA MMCI driver
11 * - No way to clear interrupts.
12 * - Have to turn off the clock whenever we touch the device.
13 * - Doesn't tell you how many data blocks were transferred.
26 #include <linux/dma-mapping.h>
29 #include <linux/mmc/host.h>
30 #include <linux/mmc/slot-gpio.h>
42 #include <linux/platform_data/mmc-pxamci.h>
46 #define DRIVER_NAME "pxa2xx-mci"
55 struct mmc_host *mmc; member
81 struct mmc_host *mmc = host->mmc; in pxamci_init_ocr() local
84 ret = mmc_regulator_get_supply(mmc); in pxamci_init_ocr()
88 if (IS_ERR(mmc->supply.vmmc)) { in pxamci_init_ocr()
89 /* fall-back to platform data */ in pxamci_init_ocr()
90 mmc->ocr_avail = host->pdata ? in pxamci_init_ocr()
91 host->pdata->ocr_mask : in pxamci_init_ocr()
102 struct mmc_host *mmc = host->mmc; in pxamci_set_power() local
103 struct regulator *supply = mmc->supply.vmmc; in pxamci_set_power()
107 return mmc_regulator_set_ocr(mmc, supply, vdd); in pxamci_set_power()
109 if (host->pdata && in pxamci_set_power()
110 gpio_is_valid(host->pdata->gpio_power)) { in pxamci_set_power()
111 on = ((1 << vdd) & host->pdata->ocr_mask); in pxamci_set_power()
112 gpio_set_value(host->pdata->gpio_power, in pxamci_set_power()
113 !!on ^ host->pdata->gpio_power_invert); in pxamci_set_power()
116 if (host->pdata && host->pdata->setpower) in pxamci_set_power()
117 return host->pdata->setpower(mmc_dev(host->mmc), vdd); in pxamci_set_power()
124 if (readl(host->base + MMC_STAT) & STAT_CLK_EN) { in pxamci_stop_clock()
128 writel(STOP_CLOCK, host->base + MMC_STRPCL); in pxamci_stop_clock()
131 v = readl(host->base + MMC_STAT); in pxamci_stop_clock()
135 } while (timeout--); in pxamci_stop_clock()
138 dev_err(mmc_dev(host->mmc), "unable to stop clock\n"); in pxamci_stop_clock()
146 spin_lock_irqsave(&host->lock, flags); in pxamci_enable_irq()
147 host->imask &= ~mask; in pxamci_enable_irq()
148 writel(host->imask, host->base + MMC_I_MASK); in pxamci_enable_irq()
149 spin_unlock_irqrestore(&host->lock, flags); in pxamci_enable_irq()
156 spin_lock_irqsave(&host->lock, flags); in pxamci_disable_irq()
157 host->imask |= mask; in pxamci_disable_irq()
158 writel(host->imask, host->base + MMC_I_MASK); in pxamci_disable_irq()
159 spin_unlock_irqrestore(&host->lock, flags); in pxamci_disable_irq()
170 unsigned int nob = data->blocks; in pxamci_setup_data()
175 host->data = data; in pxamci_setup_data()
177 writel(nob, host->base + MMC_NOB); in pxamci_setup_data()
178 writel(data->blksz, host->base + MMC_BLKLEN); in pxamci_setup_data()
180 clks = (unsigned long long)data->timeout_ns * host->clkrate; in pxamci_setup_data()
182 timeout = (unsigned int)clks + (data->timeout_clks << host->clkrt); in pxamci_setup_data()
183 writel((timeout + 255) / 256, host->base + MMC_RDTO); in pxamci_setup_data()
188 config.src_addr = host->res->start + MMC_RXFIFO; in pxamci_setup_data()
189 config.dst_addr = host->res->start + MMC_TXFIFO; in pxamci_setup_data()
193 if (data->flags & MMC_DATA_READ) { in pxamci_setup_data()
194 host->dma_dir = DMA_FROM_DEVICE; in pxamci_setup_data()
196 chan = host->dma_chan_rx; in pxamci_setup_data()
198 host->dma_dir = DMA_TO_DEVICE; in pxamci_setup_data()
200 chan = host->dma_chan_tx; in pxamci_setup_data()
207 dev_err(mmc_dev(host->mmc), "dma slave config failed\n"); in pxamci_setup_data()
211 host->dma_len = dma_map_sg(chan->device->dev, data->sg, data->sg_len, in pxamci_setup_data()
212 host->dma_dir); in pxamci_setup_data()
214 tx = dmaengine_prep_slave_sg(chan, data->sg, host->dma_len, direction, in pxamci_setup_data()
217 dev_err(mmc_dev(host->mmc), "prep_slave_sg() failed\n"); in pxamci_setup_data()
221 if (!(data->flags & MMC_DATA_READ)) { in pxamci_setup_data()
222 tx->callback = pxamci_dma_irq; in pxamci_setup_data()
223 tx->callback_param = host; in pxamci_setup_data()
226 host->dma_cookie = dmaengine_submit(tx); in pxamci_setup_data()
234 if (!cpu_is_pxa27x() || data->flags & MMC_DATA_READ) in pxamci_setup_data()
240 WARN_ON(host->cmd != NULL); in pxamci_start_cmd()
241 host->cmd = cmd; in pxamci_start_cmd()
243 if (cmd->flags & MMC_RSP_BUSY) in pxamci_start_cmd()
261 writel(cmd->opcode, host->base + MMC_CMD); in pxamci_start_cmd()
262 writel(cmd->arg >> 16, host->base + MMC_ARGH); in pxamci_start_cmd()
263 writel(cmd->arg & 0xffff, host->base + MMC_ARGL); in pxamci_start_cmd()
264 writel(cmdat, host->base + MMC_CMDAT); in pxamci_start_cmd()
265 writel(host->clkrt, host->base + MMC_CLKRT); in pxamci_start_cmd()
267 writel(START_CLOCK, host->base + MMC_STRPCL); in pxamci_start_cmd()
274 host->mrq = NULL; in pxamci_finish_request()
275 host->cmd = NULL; in pxamci_finish_request()
276 host->data = NULL; in pxamci_finish_request()
277 mmc_request_done(host->mmc, mrq); in pxamci_finish_request()
282 struct mmc_command *cmd = host->cmd; in pxamci_cmd_done()
289 host->cmd = NULL; in pxamci_cmd_done()
293 * discard the upper 8 bits of the first 16-bit word. in pxamci_cmd_done()
295 v = readl(host->base + MMC_RES) & 0xffff; in pxamci_cmd_done()
297 u32 w1 = readl(host->base + MMC_RES) & 0xffff; in pxamci_cmd_done()
298 u32 w2 = readl(host->base + MMC_RES) & 0xffff; in pxamci_cmd_done()
299 cmd->resp[i] = v << 24 | w1 << 8 | w2 >> 8; in pxamci_cmd_done()
304 cmd->error = -ETIMEDOUT; in pxamci_cmd_done()
305 } else if (stat & STAT_RES_CRC_ERR && cmd->flags & MMC_RSP_CRC) { in pxamci_cmd_done()
313 (cmd->flags & MMC_RSP_136 && cmd->resp[0] & 0x80000000)) in pxamci_cmd_done()
314 pr_debug("ignoring CRC from command %d - *risky*\n", cmd->opcode); in pxamci_cmd_done()
316 cmd->error = -EILSEQ; in pxamci_cmd_done()
320 if (host->data && !cmd->error) { in pxamci_cmd_done()
326 if (cpu_is_pxa27x() && host->data->flags & MMC_DATA_WRITE) in pxamci_cmd_done()
327 dma_async_issue_pending(host->dma_chan_tx); in pxamci_cmd_done()
329 pxamci_finish_request(host, host->mrq); in pxamci_cmd_done()
337 struct mmc_data *data = host->data; in pxamci_data_done()
343 if (data->flags & MMC_DATA_READ) in pxamci_data_done()
344 chan = host->dma_chan_rx; in pxamci_data_done()
346 chan = host->dma_chan_tx; in pxamci_data_done()
347 dma_unmap_sg(chan->device->dev, in pxamci_data_done()
348 data->sg, data->sg_len, host->dma_dir); in pxamci_data_done()
351 data->error = -ETIMEDOUT; in pxamci_data_done()
353 data->error = -EILSEQ; in pxamci_data_done()
361 if (!data->error) in pxamci_data_done()
362 data->bytes_xfered = data->blocks * data->blksz; in pxamci_data_done()
364 data->bytes_xfered = 0; in pxamci_data_done()
368 host->data = NULL; in pxamci_data_done()
369 if (host->mrq->stop) { in pxamci_data_done()
371 pxamci_start_cmd(host, host->mrq->stop, host->cmdat); in pxamci_data_done()
373 pxamci_finish_request(host, host->mrq); in pxamci_data_done()
385 ireg = readl(host->base + MMC_I_REG) & ~readl(host->base + MMC_I_MASK); in pxamci_irq()
388 unsigned stat = readl(host->base + MMC_STAT); in pxamci_irq()
397 mmc_signal_sdio_irq(host->mmc); in pxamci_irq()
405 static void pxamci_request(struct mmc_host *mmc, struct mmc_request *mrq) in pxamci_request() argument
407 struct pxamci_host *host = mmc_priv(mmc); in pxamci_request()
410 WARN_ON(host->mrq != NULL); in pxamci_request()
412 host->mrq = mrq; in pxamci_request()
416 cmdat = host->cmdat; in pxamci_request()
417 host->cmdat &= ~CMDAT_INIT; in pxamci_request()
419 if (mrq->data) { in pxamci_request()
420 pxamci_setup_data(host, mrq->data); in pxamci_request()
424 if (mrq->data->flags & MMC_DATA_WRITE) in pxamci_request()
428 pxamci_start_cmd(host, mrq->cmd, cmdat); in pxamci_request()
431 static int pxamci_get_ro(struct mmc_host *mmc) in pxamci_get_ro() argument
433 struct pxamci_host *host = mmc_priv(mmc); in pxamci_get_ro()
435 if (host->pdata && gpio_is_valid(host->pdata->gpio_card_ro)) in pxamci_get_ro()
436 return mmc_gpio_get_ro(mmc); in pxamci_get_ro()
437 if (host->pdata && host->pdata->get_ro) in pxamci_get_ro()
438 return !!host->pdata->get_ro(mmc_dev(mmc)); in pxamci_get_ro()
440 * Board doesn't support read only detection; let the mmc core in pxamci_get_ro()
443 return -ENOSYS; in pxamci_get_ro()
446 static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) in pxamci_set_ios() argument
448 struct pxamci_host *host = mmc_priv(mmc); in pxamci_set_ios()
450 if (ios->clock) { in pxamci_set_ios()
451 unsigned long rate = host->clkrate; in pxamci_set_ios()
452 unsigned int clk = rate / ios->clock; in pxamci_set_ios()
454 if (host->clkrt == CLKRT_OFF) in pxamci_set_ios()
455 clk_prepare_enable(host->clk); in pxamci_set_ios()
457 if (ios->clock == 26000000) { in pxamci_set_ios()
459 host->clkrt = 7; in pxamci_set_ios()
470 if (rate / clk > ios->clock) in pxamci_set_ios()
472 host->clkrt = fls(clk) - 1; in pxamci_set_ios()
480 if (host->clkrt != CLKRT_OFF) { in pxamci_set_ios()
481 host->clkrt = CLKRT_OFF; in pxamci_set_ios()
482 clk_disable_unprepare(host->clk); in pxamci_set_ios()
486 if (host->power_mode != ios->power_mode) { in pxamci_set_ios()
489 host->power_mode = ios->power_mode; in pxamci_set_ios()
491 ret = pxamci_set_power(host, ios->power_mode, ios->vdd); in pxamci_set_ios()
493 dev_err(mmc_dev(mmc), "unable to set power\n"); in pxamci_set_ios()
503 if (ios->power_mode == MMC_POWER_ON) in pxamci_set_ios()
504 host->cmdat |= CMDAT_INIT; in pxamci_set_ios()
507 if (ios->bus_width == MMC_BUS_WIDTH_4) in pxamci_set_ios()
508 host->cmdat |= CMDAT_SD_4DAT; in pxamci_set_ios()
510 host->cmdat &= ~CMDAT_SD_4DAT; in pxamci_set_ios()
512 dev_dbg(mmc_dev(mmc), "PXAMCI: clkrt = %x cmdat = %x\n", in pxamci_set_ios()
513 host->clkrt, host->cmdat); in pxamci_set_ios()
542 spin_lock_irqsave(&host->lock, flags); in pxamci_dma_irq()
544 if (!host->data) in pxamci_dma_irq()
547 if (host->data->flags & MMC_DATA_READ) in pxamci_dma_irq()
548 chan = host->dma_chan_rx; in pxamci_dma_irq()
550 chan = host->dma_chan_tx; in pxamci_dma_irq()
552 status = dmaengine_tx_status(chan, host->dma_cookie, &state); in pxamci_dma_irq()
555 writel(BUF_PART_FULL, host->base + MMC_PRTBUF); in pxamci_dma_irq()
557 pr_err("%s: DMA error on %s channel\n", mmc_hostname(host->mmc), in pxamci_dma_irq()
558 host->data->flags & MMC_DATA_READ ? "rx" : "tx"); in pxamci_dma_irq()
559 host->data->error = -EIO; in pxamci_dma_irq()
564 spin_unlock_irqrestore(&host->lock, flags); in pxamci_dma_irq()
571 mmc_detect_change(devid, msecs_to_jiffies(host->detect_delay_ms)); in pxamci_detect_irq()
577 { .compatible = "marvell,pxa-mmc" },
584 struct mmc_host *mmc) in pxamci_of_init() argument
586 struct device_node *np = pdev->dev.of_node; in pxamci_of_init()
587 struct pxamci_host *host = mmc_priv(mmc); in pxamci_of_init()
594 /* pxa-mmc specific */ in pxamci_of_init()
595 if (of_property_read_u32(np, "pxa-mmc,detect-delay-ms", &tmp) == 0) in pxamci_of_init()
596 host->detect_delay_ms = tmp; in pxamci_of_init()
598 ret = mmc_of_parse(mmc); in pxamci_of_init()
606 struct mmc_host *mmc) in pxamci_of_init() argument
614 struct mmc_host *mmc; in pxamci_probe() local
616 struct device *dev = &pdev->dev; in pxamci_probe()
625 mmc = mmc_alloc_host(sizeof(struct pxamci_host), dev); in pxamci_probe()
626 if (!mmc) { in pxamci_probe()
627 ret = -ENOMEM; in pxamci_probe()
631 mmc->ops = &pxamci_ops; in pxamci_probe()
634 * We can do SG-DMA, but we don't because we never know how much in pxamci_probe()
637 mmc->max_segs = NR_SG; in pxamci_probe()
642 mmc->max_seg_size = PAGE_SIZE; in pxamci_probe()
647 mmc->max_blk_size = cpu_is_pxa25x() ? 1023 : 2048; in pxamci_probe()
652 mmc->max_blk_count = 65535; in pxamci_probe()
654 ret = pxamci_of_init(pdev, mmc); in pxamci_probe()
658 host = mmc_priv(mmc); in pxamci_probe()
659 host->mmc = mmc; in pxamci_probe()
660 host->pdata = pdev->dev.platform_data; in pxamci_probe()
661 host->clkrt = CLKRT_OFF; in pxamci_probe()
663 host->clk = devm_clk_get(dev, NULL); in pxamci_probe()
664 if (IS_ERR(host->clk)) { in pxamci_probe()
665 ret = PTR_ERR(host->clk); in pxamci_probe()
666 host->clk = NULL; in pxamci_probe()
670 host->clkrate = clk_get_rate(host->clk); in pxamci_probe()
675 mmc->f_min = (host->clkrate + 63) / 64; in pxamci_probe()
676 mmc->f_max = (mmc_has_26MHz()) ? 26000000 : host->clkrate; in pxamci_probe()
682 mmc->caps = 0; in pxamci_probe()
683 host->cmdat = 0; in pxamci_probe()
685 mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; in pxamci_probe()
686 host->cmdat |= CMDAT_SDIO_INT_EN; in pxamci_probe()
688 mmc->caps |= MMC_CAP_MMC_HIGHSPEED | in pxamci_probe()
692 spin_lock_init(&host->lock); in pxamci_probe()
693 host->res = r; in pxamci_probe()
694 host->imask = MMC_I_MASK_ALL; in pxamci_probe()
696 host->base = devm_ioremap_resource(dev, r); in pxamci_probe()
697 if (IS_ERR(host->base)) { in pxamci_probe()
698 ret = PTR_ERR(host->base); in pxamci_probe()
707 writel(0, host->base + MMC_SPI); in pxamci_probe()
708 writel(64, host->base + MMC_RESTO); in pxamci_probe()
709 writel(host->imask, host->base + MMC_I_MASK); in pxamci_probe()
716 platform_set_drvdata(pdev, mmc); in pxamci_probe()
718 host->dma_chan_rx = dma_request_slave_channel(dev, "rx"); in pxamci_probe()
719 if (host->dma_chan_rx == NULL) { in pxamci_probe()
721 ret = -ENODEV; in pxamci_probe()
725 host->dma_chan_tx = dma_request_slave_channel(dev, "tx"); in pxamci_probe()
726 if (host->dma_chan_tx == NULL) { in pxamci_probe()
728 ret = -ENODEV; in pxamci_probe()
732 if (host->pdata) { in pxamci_probe()
733 int gpio_cd = host->pdata->gpio_card_detect; in pxamci_probe()
734 int gpio_ro = host->pdata->gpio_card_ro; in pxamci_probe()
735 int gpio_power = host->pdata->gpio_power; in pxamci_probe()
737 host->detect_delay_ms = host->pdata->detect_delay_ms; in pxamci_probe()
741 "mmc card power"); in pxamci_probe()
749 host->pdata->gpio_power_invert); in pxamci_probe()
753 ret = mmc_gpio_request_ro(mmc, gpio_ro); in pxamci_probe()
760 mmc->caps2 |= host->pdata->gpio_card_ro_invert ? in pxamci_probe()
766 ret = mmc_gpio_request_cd(mmc, gpio_cd, 0); in pxamci_probe()
773 if (host->pdata->init) in pxamci_probe()
774 host->pdata->init(dev, pxamci_detect_irq, mmc); in pxamci_probe()
776 if (gpio_is_valid(gpio_power) && host->pdata->setpower) in pxamci_probe()
778 if (gpio_is_valid(gpio_ro) && host->pdata->get_ro) in pxamci_probe()
782 mmc_add_host(mmc); in pxamci_probe()
788 if (host->dma_chan_rx) in pxamci_probe()
789 dma_release_channel(host->dma_chan_rx); in pxamci_probe()
790 if (host->dma_chan_tx) in pxamci_probe()
791 dma_release_channel(host->dma_chan_tx); in pxamci_probe()
793 if (mmc) in pxamci_probe()
794 mmc_free_host(mmc); in pxamci_probe()
800 struct mmc_host *mmc = platform_get_drvdata(pdev); in pxamci_remove() local
802 if (mmc) { in pxamci_remove()
803 struct pxamci_host *host = mmc_priv(mmc); in pxamci_remove()
805 mmc_remove_host(mmc); in pxamci_remove()
807 if (host->pdata && host->pdata->exit) in pxamci_remove()
808 host->pdata->exit(&pdev->dev, mmc); in pxamci_remove()
813 host->base + MMC_I_MASK); in pxamci_remove()
815 dmaengine_terminate_all(host->dma_chan_rx); in pxamci_remove()
816 dmaengine_terminate_all(host->dma_chan_tx); in pxamci_remove()
817 dma_release_channel(host->dma_chan_rx); in pxamci_remove()
818 dma_release_channel(host->dma_chan_tx); in pxamci_remove()
820 mmc_free_host(mmc); in pxamci_remove()
837 MODULE_DESCRIPTION("PXA Multimedia Card Interface Driver");
839 MODULE_ALIAS("platform:pxa2xx-mci");