Lines Matching +full:rst +full:- +full:syscon

1 // SPDX-License-Identifier: GPL-2.0
3 // Copyright (C) 2017-2018 Socionext Inc.
10 #include <linux/dma-mapping.h>
11 #include <linux/mfd/syscon.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) */
71 struct reset_control *rst; member
84 return container_of(host->pdata, struct uniphier_sd_priv, tmio_data); in uniphier_sd_priv()
99 dma_async_issue_pending(priv->chan); in uniphier_sd_external_dma_issue()
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()
124 host->data->error = -ETIMEDOUT; in uniphier_sd_external_dma_callback()
128 spin_unlock_irqrestore(&host->lock, flags); in uniphier_sd_external_dma_callback()
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()
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()
209 if (priv->chan) in uniphier_sd_external_dma_release()
210 dma_release_channel(priv->chan); in uniphier_sd_external_dma_release()
219 if (priv->chan) in uniphier_sd_external_dma_abort()
220 dmaengine_terminate_sync(priv->chan); in uniphier_sd_external_dma_abort()
244 spin_lock_irqsave(&host->lock, flags); in uniphier_sd_internal_dma_issue()
246 spin_unlock_irqrestore(&host->lock, flags); 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()
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()
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()
326 host->chan_rx = NULL; in uniphier_sd_internal_dma_release()
327 host->chan_tx = NULL; in uniphier_sd_internal_dma_release()
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()
349 dma_unmap_sg(mmc_dev(host->mmc), host->sg_ptr, 1, priv->dma_dir); in uniphier_sd_internal_dma_dataend()
366 struct mmc_host *mmc = host->mmc; in uniphier_sd_clk_enable()
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()
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()
424 reset_control_assert(priv->rst_hw); in uniphier_sd_hw_reset()
427 reset_control_deassert(priv->rst_hw); in uniphier_sd_hw_reset()
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()
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()
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()
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()
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()
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()
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()
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()
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()
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 ret = PTR_ERR(priv->rst_hw); in uniphier_sd_probe()
669 host->ops.card_hw_reset = uniphier_sd_hw_reset; in uniphier_sd_probe()
672 if (host->mmc->caps & MMC_CAP_UHS) { in uniphier_sd_probe()
678 host->mmc->caps &= ~MMC_CAP_UHS; in uniphier_sd_probe()
680 host->ops.start_signal_voltage_switch = in uniphier_sd_probe()
685 if (priv->caps & UNIPHIER_SD_CAP_EXTENDED_IP) in uniphier_sd_probe()
686 host->dma_ops = &uniphier_sd_internal_dma_ops; in uniphier_sd_probe()
688 host->dma_ops = &uniphier_sd_external_dma_ops; in uniphier_sd_probe()
690 host->bus_shift = 1; in uniphier_sd_probe()
691 host->clk_enable = uniphier_sd_clk_enable; in uniphier_sd_probe()
692 host->clk_disable = uniphier_sd_clk_disable; in uniphier_sd_probe()
693 host->set_clock = uniphier_sd_set_clock; in uniphier_sd_probe()
701 tmio_data->ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34; in uniphier_sd_probe()
702 if (host->mmc->caps & MMC_CAP_UHS) in uniphier_sd_probe()
703 tmio_data->ocr_mask |= MMC_VDD_165_195; in uniphier_sd_probe()
705 tmio_data->max_segs = 1; in uniphier_sd_probe()
706 tmio_data->max_blk_count = U16_MAX; in uniphier_sd_probe()
740 .compatible = "socionext,uniphier-sd-v2.91",
743 .compatible = "socionext,uniphier-sd-v3.1",
748 .compatible = "socionext,uniphier-sd-v3.1.1",
759 .name = "uniphier-sd",