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

1 // SPDX-License-Identifier: GPL-2.0
3 // Copyright (C) 2017-2018 Socionext Inc.
10 #include <linux/dma-mapping.h>
12 #include <linux/mmc/host.h>
59 * IP is extended to support various features: built-in DMA engine,
63 /* RX channel of the built-in DMA controller is broken (Pro5) */
82 static void *uniphier_sd_priv(struct tmio_mmc_host *host) in uniphier_sd_priv() argument
84 return container_of(host->pdata, struct uniphier_sd_priv, tmio_data); in uniphier_sd_priv()
87 static void uniphier_sd_dma_endisable(struct tmio_mmc_host *host, int enable) in uniphier_sd_dma_endisable() argument
89 sd_ctrl_write16(host, CTL_DMA_ENABLE, enable ? DMA_ENABLE_DMASDRW : 0); in uniphier_sd_dma_endisable()
95 struct tmio_mmc_host *host = from_work(host, t, dma_issue); in uniphier_sd_external_dma_issue() local
96 struct uniphier_sd_priv *priv = uniphier_sd_priv(host); in uniphier_sd_external_dma_issue()
98 uniphier_sd_dma_endisable(host, 1); in uniphier_sd_external_dma_issue()
99 dma_async_issue_pending(priv->chan); in uniphier_sd_external_dma_issue()
105 struct tmio_mmc_host *host = param; in uniphier_sd_external_dma_callback() local
106 struct uniphier_sd_priv *priv = uniphier_sd_priv(host); in uniphier_sd_external_dma_callback()
109 dma_unmap_sg(mmc_dev(host->mmc), host->sg_ptr, host->sg_len, in uniphier_sd_external_dma_callback()
110 priv->dma_dir); in uniphier_sd_external_dma_callback()
112 spin_lock_irqsave(&host->lock, flags); in uniphier_sd_external_dma_callback()
114 if (result->result == DMA_TRANS_NOERROR) { in uniphier_sd_external_dma_callback()
122 tmio_mmc_enable_mmc_irqs(host, TMIO_STAT_DATAEND); in uniphier_sd_external_dma_callback()
124 host->data->error = -ETIMEDOUT; in uniphier_sd_external_dma_callback()
125 tmio_mmc_do_data_irq(host); in uniphier_sd_external_dma_callback()
128 spin_unlock_irqrestore(&host->lock, flags); in uniphier_sd_external_dma_callback()
131 static void uniphier_sd_external_dma_start(struct tmio_mmc_host *host, in uniphier_sd_external_dma_start() argument
134 struct uniphier_sd_priv *priv = uniphier_sd_priv(host); in uniphier_sd_external_dma_start()
140 if (!priv->chan) in uniphier_sd_external_dma_start()
143 if (data->flags & MMC_DATA_READ) { in uniphier_sd_external_dma_start()
144 priv->dma_dir = DMA_FROM_DEVICE; in uniphier_sd_external_dma_start()
147 priv->dma_dir = DMA_TO_DEVICE; in uniphier_sd_external_dma_start()
151 sg_len = dma_map_sg(mmc_dev(host->mmc), host->sg_ptr, host->sg_len, in uniphier_sd_external_dma_start()
152 priv->dma_dir); in uniphier_sd_external_dma_start()
156 desc = dmaengine_prep_slave_sg(priv->chan, host->sg_ptr, sg_len, in uniphier_sd_external_dma_start()
161 desc->callback_result = uniphier_sd_external_dma_callback; in uniphier_sd_external_dma_start()
162 desc->callback_param = host; in uniphier_sd_external_dma_start()
168 host->dma_on = true; in uniphier_sd_external_dma_start()
173 dma_unmap_sg(mmc_dev(host->mmc), host->sg_ptr, host->sg_len, in uniphier_sd_external_dma_start()
174 priv->dma_dir); in uniphier_sd_external_dma_start()
176 uniphier_sd_dma_endisable(host, 0); in uniphier_sd_external_dma_start()
179 static void uniphier_sd_external_dma_enable(struct tmio_mmc_host *host, in uniphier_sd_external_dma_enable() argument
184 static void uniphier_sd_external_dma_request(struct tmio_mmc_host *host, in uniphier_sd_external_dma_request() argument
187 struct uniphier_sd_priv *priv = uniphier_sd_priv(host); in uniphier_sd_external_dma_request()
190 chan = dma_request_chan(mmc_dev(host->mmc), "rx-tx"); in uniphier_sd_external_dma_request()
192 dev_warn(mmc_dev(host->mmc), in uniphier_sd_external_dma_request()
194 return; /* just use PIO even for -EPROBE_DEFER */ in uniphier_sd_external_dma_request()
198 priv->chan = chan; in uniphier_sd_external_dma_request()
199 host->chan_rx = chan; in uniphier_sd_external_dma_request()
200 host->chan_tx = chan; in uniphier_sd_external_dma_request()
202 INIT_WORK(&host->dma_issue, uniphier_sd_external_dma_issue); in uniphier_sd_external_dma_request()
205 static void uniphier_sd_external_dma_release(struct tmio_mmc_host *host) in uniphier_sd_external_dma_release() argument
207 struct uniphier_sd_priv *priv = uniphier_sd_priv(host); in uniphier_sd_external_dma_release()
209 if (priv->chan) in uniphier_sd_external_dma_release()
210 dma_release_channel(priv->chan); in uniphier_sd_external_dma_release()
213 static void uniphier_sd_external_dma_abort(struct tmio_mmc_host *host) in uniphier_sd_external_dma_abort() argument
215 struct uniphier_sd_priv *priv = uniphier_sd_priv(host); in uniphier_sd_external_dma_abort()
217 uniphier_sd_dma_endisable(host, 0); in uniphier_sd_external_dma_abort()
219 if (priv->chan) in uniphier_sd_external_dma_abort()
220 dmaengine_terminate_sync(priv->chan); in uniphier_sd_external_dma_abort()
223 static void uniphier_sd_external_dma_dataend(struct tmio_mmc_host *host) in uniphier_sd_external_dma_dataend() argument
225 uniphier_sd_dma_endisable(host, 0); in uniphier_sd_external_dma_dataend()
227 tmio_mmc_do_data_irq(host); in uniphier_sd_external_dma_dataend()
241 struct tmio_mmc_host *host = from_work(host, t, dma_issue); in uniphier_sd_internal_dma_issue() local
244 spin_lock_irqsave(&host->lock, flags); in uniphier_sd_internal_dma_issue()
245 tmio_mmc_enable_mmc_irqs(host, TMIO_STAT_DATAEND); in uniphier_sd_internal_dma_issue()
246 spin_unlock_irqrestore(&host->lock, flags); in uniphier_sd_internal_dma_issue()
248 uniphier_sd_dma_endisable(host, 1); in uniphier_sd_internal_dma_issue()
249 writel(UNIPHIER_SD_DMA_CTL_START, host->ctl + UNIPHIER_SD_DMA_CTL); in uniphier_sd_internal_dma_issue()
252 static void uniphier_sd_internal_dma_start(struct tmio_mmc_host *host, in uniphier_sd_internal_dma_start() argument
255 struct uniphier_sd_priv *priv = uniphier_sd_priv(host); in uniphier_sd_internal_dma_start()
256 struct scatterlist *sg = host->sg_ptr; in uniphier_sd_internal_dma_start()
262 if ((data->flags & MMC_DATA_READ) && !host->chan_rx) in uniphier_sd_internal_dma_start()
265 if (WARN_ON(host->sg_len != 1)) in uniphier_sd_internal_dma_start()
268 if (!IS_ALIGNED(sg->offset, 8)) in uniphier_sd_internal_dma_start()
271 if (data->flags & MMC_DATA_READ) { in uniphier_sd_internal_dma_start()
272 priv->dma_dir = DMA_FROM_DEVICE; in uniphier_sd_internal_dma_start()
275 priv->dma_dir = DMA_TO_DEVICE; in uniphier_sd_internal_dma_start()
279 sg_len = dma_map_sg(mmc_dev(host->mmc), sg, 1, priv->dma_dir); in uniphier_sd_internal_dma_start()
288 writel(dma_mode, host->ctl + UNIPHIER_SD_DMA_MODE); in uniphier_sd_internal_dma_start()
290 dma_addr = sg_dma_address(data->sg); in uniphier_sd_internal_dma_start()
291 writel(lower_32_bits(dma_addr), host->ctl + UNIPHIER_SD_DMA_ADDR_L); in uniphier_sd_internal_dma_start()
292 writel(upper_32_bits(dma_addr), host->ctl + UNIPHIER_SD_DMA_ADDR_H); in uniphier_sd_internal_dma_start()
294 host->dma_on = true; in uniphier_sd_internal_dma_start()
298 uniphier_sd_dma_endisable(host, 0); in uniphier_sd_internal_dma_start()
301 static void uniphier_sd_internal_dma_enable(struct tmio_mmc_host *host, in uniphier_sd_internal_dma_enable() argument
306 static void uniphier_sd_internal_dma_request(struct tmio_mmc_host *host, in uniphier_sd_internal_dma_request() argument
309 struct uniphier_sd_priv *priv = uniphier_sd_priv(host); in uniphier_sd_internal_dma_request()
315 if (!(priv->caps & UNIPHIER_SD_CAP_BROKEN_DMA_RX)) in uniphier_sd_internal_dma_request()
316 host->chan_rx = (void *)0xdeadbeaf; in uniphier_sd_internal_dma_request()
318 host->chan_tx = (void *)0xdeadbeaf; in uniphier_sd_internal_dma_request()
320 INIT_WORK(&host->dma_issue, uniphier_sd_internal_dma_issue); in uniphier_sd_internal_dma_request()
323 static void uniphier_sd_internal_dma_release(struct tmio_mmc_host *host) in uniphier_sd_internal_dma_release() argument
326 host->chan_rx = NULL; in uniphier_sd_internal_dma_release()
327 host->chan_tx = NULL; in uniphier_sd_internal_dma_release()
330 static void uniphier_sd_internal_dma_abort(struct tmio_mmc_host *host) in uniphier_sd_internal_dma_abort() argument
334 uniphier_sd_dma_endisable(host, 0); in uniphier_sd_internal_dma_abort()
336 tmp = readl(host->ctl + UNIPHIER_SD_DMA_RST); in uniphier_sd_internal_dma_abort()
338 writel(tmp, host->ctl + UNIPHIER_SD_DMA_RST); in uniphier_sd_internal_dma_abort()
341 writel(tmp, host->ctl + UNIPHIER_SD_DMA_RST); in uniphier_sd_internal_dma_abort()
344 static void uniphier_sd_internal_dma_dataend(struct tmio_mmc_host *host) in uniphier_sd_internal_dma_dataend() argument
346 struct uniphier_sd_priv *priv = uniphier_sd_priv(host); in uniphier_sd_internal_dma_dataend()
348 uniphier_sd_dma_endisable(host, 0); in uniphier_sd_internal_dma_dataend()
349 dma_unmap_sg(mmc_dev(host->mmc), host->sg_ptr, 1, priv->dma_dir); in uniphier_sd_internal_dma_dataend()
351 tmio_mmc_do_data_irq(host); in uniphier_sd_internal_dma_dataend()
363 static int uniphier_sd_clk_enable(struct tmio_mmc_host *host) in uniphier_sd_clk_enable() argument
365 struct uniphier_sd_priv *priv = uniphier_sd_priv(host); in uniphier_sd_clk_enable()
366 struct mmc_host *mmc = host->mmc; in uniphier_sd_clk_enable() local
369 ret = clk_prepare_enable(priv->clk); in uniphier_sd_clk_enable()
373 ret = clk_set_rate(priv->clk, ULONG_MAX); in uniphier_sd_clk_enable()
377 priv->clk_rate = clk_get_rate(priv->clk); in uniphier_sd_clk_enable()
379 /* If max-frequency property is set, use it. */ in uniphier_sd_clk_enable()
380 if (!mmc->f_max) in uniphier_sd_clk_enable()
381 mmc->f_max = priv->clk_rate; in uniphier_sd_clk_enable()
385 * also supports 1/1024 divisor. (UniPhier-specific extension) in uniphier_sd_clk_enable()
387 if (priv->caps & UNIPHIER_SD_CAP_EXTENDED_IP) in uniphier_sd_clk_enable()
388 mmc->f_min = priv->clk_rate / 1024; in uniphier_sd_clk_enable()
390 mmc->f_min = priv->clk_rate / 512; in uniphier_sd_clk_enable()
392 ret = reset_control_deassert(priv->rst); in uniphier_sd_clk_enable()
396 ret = reset_control_deassert(priv->rst_br); in uniphier_sd_clk_enable()
403 reset_control_assert(priv->rst); in uniphier_sd_clk_enable()
405 clk_disable_unprepare(priv->clk); in uniphier_sd_clk_enable()
410 static void uniphier_sd_clk_disable(struct tmio_mmc_host *host) in uniphier_sd_clk_disable() argument
412 struct uniphier_sd_priv *priv = uniphier_sd_priv(host); in uniphier_sd_clk_disable()
414 reset_control_assert(priv->rst_br); in uniphier_sd_clk_disable()
415 reset_control_assert(priv->rst); in uniphier_sd_clk_disable()
416 clk_disable_unprepare(priv->clk); in uniphier_sd_clk_disable()
419 static void uniphier_sd_hw_reset(struct mmc_host *mmc) in uniphier_sd_hw_reset() argument
421 struct tmio_mmc_host *host = mmc_priv(mmc); in uniphier_sd_hw_reset() local
422 struct uniphier_sd_priv *priv = uniphier_sd_priv(host); in uniphier_sd_hw_reset()
424 reset_control_assert(priv->rst_hw); in uniphier_sd_hw_reset()
427 reset_control_deassert(priv->rst_hw); in uniphier_sd_hw_reset()
432 static void uniphier_sd_speed_switch(struct tmio_mmc_host *host) in uniphier_sd_speed_switch() argument
434 struct uniphier_sd_priv *priv = uniphier_sd_priv(host); in uniphier_sd_speed_switch()
438 if (!(host->mmc->caps & MMC_CAP_UHS)) in uniphier_sd_speed_switch()
441 if (host->mmc->ios.timing == MMC_TIMING_UHS_SDR50 || in uniphier_sd_speed_switch()
442 host->mmc->ios.timing == MMC_TIMING_UHS_SDR104) in uniphier_sd_speed_switch()
445 offset = UNIPHIER_SDCTRL_CHOFFSET * priv->sdctrl_ch in uniphier_sd_speed_switch()
447 regmap_write_bits(priv->sdctrl_regmap, offset, in uniphier_sd_speed_switch()
451 static void uniphier_sd_uhs_enable(struct tmio_mmc_host *host, bool uhs_en) in uniphier_sd_uhs_enable() argument
453 struct uniphier_sd_priv *priv = uniphier_sd_priv(host); in uniphier_sd_uhs_enable()
457 if (!(host->mmc->caps & MMC_CAP_UHS)) in uniphier_sd_uhs_enable()
462 offset = UNIPHIER_SDCTRL_CHOFFSET * priv->sdctrl_ch in uniphier_sd_uhs_enable()
464 regmap_write_bits(priv->sdctrl_regmap, offset, in uniphier_sd_uhs_enable()
468 static void uniphier_sd_set_clock(struct tmio_mmc_host *host, in uniphier_sd_set_clock() argument
471 struct uniphier_sd_priv *priv = uniphier_sd_priv(host); in uniphier_sd_set_clock()
475 tmp = readl(host->ctl + (CTL_SD_CARD_CLK_CTL << 1)); in uniphier_sd_set_clock()
479 writel(tmp, host->ctl + (CTL_SD_CARD_CLK_CTL << 1)); in uniphier_sd_set_clock()
481 uniphier_sd_speed_switch(host); in uniphier_sd_set_clock()
490 divisor = priv->clk_rate / clock; in uniphier_sd_set_clock()
502 else if (priv->caps & UNIPHIER_SD_CAP_EXTENDED_IP && divisor > 512) in uniphier_sd_set_clock()
507 writel(tmp, host->ctl + (CTL_SD_CARD_CLK_CTL << 1)); in uniphier_sd_set_clock()
510 writel(tmp, host->ctl + (CTL_SD_CARD_CLK_CTL << 1)); in uniphier_sd_set_clock()
513 static void uniphier_sd_host_init(struct tmio_mmc_host *host) in uniphier_sd_host_init() argument
515 struct uniphier_sd_priv *priv = uniphier_sd_priv(host); in uniphier_sd_host_init()
520 * This register holds settings for SoC-specific internal bus in uniphier_sd_host_init()
525 if (priv->caps & UNIPHIER_SD_CAP_EXTENDED_IP) in uniphier_sd_host_init()
530 writel(val, host->ctl + UNIPHIER_SD_HOST_MODE); in uniphier_sd_host_init()
537 if (priv->caps & UNIPHIER_SD_CAP_EXTENDED_IP) in uniphier_sd_host_init()
540 writel(val, host->ctl + (CTL_SD_CARD_CLK_CTL << 1)); in uniphier_sd_host_init()
543 static int uniphier_sd_start_signal_voltage_switch(struct mmc_host *mmc, in uniphier_sd_start_signal_voltage_switch() argument
546 struct tmio_mmc_host *host = mmc_priv(mmc); in uniphier_sd_start_signal_voltage_switch() local
547 struct uniphier_sd_priv *priv = uniphier_sd_priv(host); in uniphier_sd_start_signal_voltage_switch()
552 switch (ios->signal_voltage) { in uniphier_sd_start_signal_voltage_switch()
559 pinstate = priv->pinstate_uhs; in uniphier_sd_start_signal_voltage_switch()
563 return -ENOTSUPP; in uniphier_sd_start_signal_voltage_switch()
566 tmp = readl(host->ctl + UNIPHIER_SD_VOLT); in uniphier_sd_start_signal_voltage_switch()
569 writel(tmp, host->ctl + UNIPHIER_SD_VOLT); in uniphier_sd_start_signal_voltage_switch()
572 pinctrl_select_state(priv->pinctrl, pinstate); in uniphier_sd_start_signal_voltage_switch()
574 pinctrl_select_default_state(mmc_dev(mmc)); in uniphier_sd_start_signal_voltage_switch()
576 uniphier_sd_uhs_enable(host, uhs_en); in uniphier_sd_start_signal_voltage_switch()
581 static int uniphier_sd_uhs_init(struct tmio_mmc_host *host) in uniphier_sd_uhs_init() argument
583 struct uniphier_sd_priv *priv = uniphier_sd_priv(host); in uniphier_sd_uhs_init()
584 struct device *dev = &host->pdev->dev; in uniphier_sd_uhs_init()
585 struct device_node *np = dev->of_node; in uniphier_sd_uhs_init()
589 priv->pinctrl = devm_pinctrl_get(mmc_dev(host->mmc)); in uniphier_sd_uhs_init()
590 if (IS_ERR(priv->pinctrl)) in uniphier_sd_uhs_init()
591 return PTR_ERR(priv->pinctrl); in uniphier_sd_uhs_init()
593 priv->pinstate_uhs = pinctrl_lookup_state(priv->pinctrl, "uhs"); in uniphier_sd_uhs_init()
594 if (IS_ERR(priv->pinstate_uhs)) in uniphier_sd_uhs_init()
595 return PTR_ERR(priv->pinstate_uhs); in uniphier_sd_uhs_init()
598 "socionext,syscon-uhs-mode", in uniphier_sd_uhs_init()
601 dev_err(dev, "Can't get syscon-uhs-mode property\n"); in uniphier_sd_uhs_init()
604 priv->sdctrl_regmap = syscon_node_to_regmap(args.np); in uniphier_sd_uhs_init()
606 if (IS_ERR(priv->sdctrl_regmap)) { in uniphier_sd_uhs_init()
607 dev_err(dev, "Can't map syscon-uhs-mode\n"); in uniphier_sd_uhs_init()
608 return PTR_ERR(priv->sdctrl_regmap); in uniphier_sd_uhs_init()
610 priv->sdctrl_ch = args.args[0]; in uniphier_sd_uhs_init()
617 struct device *dev = &pdev->dev; in uniphier_sd_probe()
620 struct tmio_mmc_host *host; in uniphier_sd_probe() local
629 return -ENOMEM; in uniphier_sd_probe()
631 priv->caps = (unsigned long)of_device_get_match_data(dev); in uniphier_sd_probe()
633 priv->clk = devm_clk_get(dev, NULL); in uniphier_sd_probe()
634 if (IS_ERR(priv->clk)) { in uniphier_sd_probe()
636 return PTR_ERR(priv->clk); in uniphier_sd_probe()
639 priv->rst = devm_reset_control_get_shared(dev, "host"); in uniphier_sd_probe()
640 if (IS_ERR(priv->rst)) { in uniphier_sd_probe()
641 dev_err(dev, "failed to get host reset\n"); in uniphier_sd_probe()
642 return PTR_ERR(priv->rst); in uniphier_sd_probe()
646 if (!(priv->caps & UNIPHIER_SD_CAP_EXTENDED_IP)) { in uniphier_sd_probe()
647 priv->rst_br = devm_reset_control_get_shared(dev, "bridge"); in uniphier_sd_probe()
648 if (IS_ERR(priv->rst_br)) { in uniphier_sd_probe()
650 return PTR_ERR(priv->rst_br); in uniphier_sd_probe()
654 tmio_data = &priv->tmio_data; in uniphier_sd_probe()
655 tmio_data->flags |= TMIO_MMC_32BIT_DATA_PORT; in uniphier_sd_probe()
656 tmio_data->flags |= TMIO_MMC_USE_BUSY_TIMEOUT; in uniphier_sd_probe()
658 host = tmio_mmc_host_alloc(pdev, tmio_data); in uniphier_sd_probe()
659 if (IS_ERR(host)) in uniphier_sd_probe()
660 return PTR_ERR(host); in uniphier_sd_probe()
662 if (host->mmc->caps & MMC_CAP_HW_RESET) { in uniphier_sd_probe()
663 priv->rst_hw = devm_reset_control_get_exclusive(dev, "hw"); in uniphier_sd_probe()
664 if (IS_ERR(priv->rst_hw)) { in uniphier_sd_probe()
666 return PTR_ERR(priv->rst_hw); in uniphier_sd_probe()
668 host->ops.card_hw_reset = uniphier_sd_hw_reset; in uniphier_sd_probe()
671 if (host->mmc->caps & MMC_CAP_UHS) { in uniphier_sd_probe()
672 ret = uniphier_sd_uhs_init(host); in uniphier_sd_probe()
677 host->mmc->caps &= ~MMC_CAP_UHS; in uniphier_sd_probe()
679 host->ops.start_signal_voltage_switch = in uniphier_sd_probe()
684 if (priv->caps & UNIPHIER_SD_CAP_EXTENDED_IP) in uniphier_sd_probe()
685 host->dma_ops = &uniphier_sd_internal_dma_ops; in uniphier_sd_probe()
687 host->dma_ops = &uniphier_sd_external_dma_ops; in uniphier_sd_probe()
689 host->bus_shift = 1; in uniphier_sd_probe()
690 host->clk_enable = uniphier_sd_clk_enable; in uniphier_sd_probe()
691 host->clk_disable = uniphier_sd_clk_disable; in uniphier_sd_probe()
692 host->set_clock = uniphier_sd_set_clock; in uniphier_sd_probe()
694 ret = uniphier_sd_clk_enable(host); in uniphier_sd_probe()
698 uniphier_sd_host_init(host); in uniphier_sd_probe()
700 tmio_data->ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34; in uniphier_sd_probe()
701 if (host->mmc->caps & MMC_CAP_UHS) in uniphier_sd_probe()
702 tmio_data->ocr_mask |= MMC_VDD_165_195; in uniphier_sd_probe()
704 tmio_data->max_segs = 1; in uniphier_sd_probe()
705 tmio_data->max_blk_count = U16_MAX; in uniphier_sd_probe()
707 sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK, TMIO_MASK_ALL); in uniphier_sd_probe()
710 dev_name(dev), host); in uniphier_sd_probe()
714 ret = tmio_mmc_host_probe(host); in uniphier_sd_probe()
721 uniphier_sd_clk_disable(host); in uniphier_sd_probe()
728 struct tmio_mmc_host *host = platform_get_drvdata(pdev); in uniphier_sd_remove() local
730 tmio_mmc_host_remove(host); in uniphier_sd_remove()
731 uniphier_sd_clk_disable(host); in uniphier_sd_remove()
736 .compatible = "socionext,uniphier-sd-v2.91",
739 .compatible = "socionext,uniphier-sd-v3.1",
744 .compatible = "socionext,uniphier-sd-v3.1.1",
755 .name = "uniphier-sd",
763 MODULE_DESCRIPTION("UniPhier SD/eMMC host controller driver");