Lines Matching +full:hs400 +full:- +full:cmd +full:- +full:int +full:- +full:delay

1 // SPDX-License-Identifier: GPL-2.0
12 #include <linux/dma-mapping.h>
22 #include "sdhci-pltfm.h"
76 ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1)))
93 int vendor_specific_area1; /* P_VENDOR_SPECIFIC_AREA reg */
102 dma_addr_t addr, int len, unsigned int cmd) in dwcmshc_adma_write_desc() argument
104 int tmplen, offset; in dwcmshc_adma_write_desc()
107 sdhci_adma_write_desc(host, desc, addr, len, cmd); in dwcmshc_adma_write_desc()
111 offset = addr & (SZ_128M - 1); in dwcmshc_adma_write_desc()
112 tmplen = SZ_128M - offset; in dwcmshc_adma_write_desc()
113 sdhci_adma_write_desc(host, desc, addr, tmplen, cmd); in dwcmshc_adma_write_desc()
116 len -= tmplen; in dwcmshc_adma_write_desc()
117 sdhci_adma_write_desc(host, desc, addr, len, cmd); in dwcmshc_adma_write_desc()
120 static unsigned int dwcmshc_get_max_clock(struct sdhci_host *host) in dwcmshc_get_max_clock()
124 if (pltfm_host->clk) in dwcmshc_get_max_clock()
127 return pltfm_host->clock; in dwcmshc_get_max_clock()
130 static unsigned int rk35xx_get_max_clock(struct sdhci_host *host) in rk35xx_get_max_clock()
134 return clk_round_rate(pltfm_host->clk, ULONG_MAX); in rk35xx_get_max_clock()
143 * No matter V4 is enabled or not, ARGUMENT2 register is 32-bit in dwcmshc_check_auto_cmd23()
147 if (mrq->sbc && (mrq->sbc->arg & SDHCI_DWCMSHC_ARG2_STUFF)) in dwcmshc_check_auto_cmd23()
148 host->flags &= ~SDHCI_AUTO_CMD23; in dwcmshc_check_auto_cmd23()
150 host->flags |= SDHCI_AUTO_CMD23; in dwcmshc_check_auto_cmd23()
161 unsigned int timing) in dwcmshc_set_uhs_signaling()
184 /* set CARD_IS_EMMC bit to enable Data Strobe for HS400 */ in dwcmshc_set_uhs_signaling()
185 ctrl = sdhci_readw(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); in dwcmshc_set_uhs_signaling()
187 sdhci_writew(host, ctrl, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); in dwcmshc_set_uhs_signaling()
202 int reg = priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL; in dwcmshc_hs400_enhanced_strobe()
205 if (ios->enhanced_strobe) in dwcmshc_hs400_enhanced_strobe()
213 static void dwcmshc_rk3568_set_clock(struct sdhci_host *host, unsigned int clock) in dwcmshc_rk3568_set_clock()
217 struct rk35xx_priv *priv = dwc_priv->priv; in dwcmshc_rk3568_set_clock()
220 int err; in dwcmshc_rk3568_set_clock()
222 host->mmc->actual_clock = 0; in dwcmshc_rk3568_set_clock()
234 err = clk_set_rate(pltfm_host->clk, clock); in dwcmshc_rk3568_set_clock()
236 dev_err(mmc_dev(host->mmc), "fail to set clock %d", clock); in dwcmshc_rk3568_set_clock()
240 /* Disable cmd conflict check */ in dwcmshc_rk3568_set_clock()
241 reg = dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3; in dwcmshc_rk3568_set_clock()
277 if (priv->devtype == DWCMSHC_RK3568) in dwcmshc_rk3568_set_clock()
286 err = readl_poll_timeout(host->ioaddr + DWCMSHC_EMMC_DLL_STATUS0, in dwcmshc_rk3568_set_clock()
290 dev_err(mmc_dev(host->mmc), "DLL lock timeout!\n"); in dwcmshc_rk3568_set_clock()
295 0x3 << 17 | /* pre-change delay */ in dwcmshc_rk3568_set_clock()
296 0x3 << 19; /* post-change delay */ in dwcmshc_rk3568_set_clock()
297 sdhci_writel(host, extra, dwc_priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in dwcmshc_rk3568_set_clock()
299 if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200 || in dwcmshc_rk3568_set_clock()
300 host->mmc->ios.timing == MMC_TIMING_MMC_HS400) in dwcmshc_rk3568_set_clock()
301 txclk_tapnum = priv->txclk_tapnum; in dwcmshc_rk3568_set_clock()
303 if ((priv->devtype == DWCMSHC_RK3588) && host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { in dwcmshc_rk3568_set_clock()
330 struct rk35xx_priv *priv = dwc_priv->priv; in rk35xx_sdhci_reset()
332 if (mask & SDHCI_RESET_ALL && priv->reset) { in rk35xx_sdhci_reset()
333 reset_control_assert(priv->reset); in rk35xx_sdhci_reset()
335 reset_control_deassert(priv->reset); in rk35xx_sdhci_reset()
382 static int dwcmshc_rk35xx_init(struct sdhci_host *host, struct dwcmshc_priv *dwc_priv) in dwcmshc_rk35xx_init()
384 int err; in dwcmshc_rk35xx_init()
385 struct rk35xx_priv *priv = dwc_priv->priv; in dwcmshc_rk35xx_init()
387 priv->reset = devm_reset_control_array_get_optional_exclusive(mmc_dev(host->mmc)); in dwcmshc_rk35xx_init()
388 if (IS_ERR(priv->reset)) { in dwcmshc_rk35xx_init()
389 err = PTR_ERR(priv->reset); in dwcmshc_rk35xx_init()
390 dev_err(mmc_dev(host->mmc), "failed to get reset control %d\n", err); in dwcmshc_rk35xx_init()
394 priv->rockchip_clks[0].id = "axi"; in dwcmshc_rk35xx_init()
395 priv->rockchip_clks[1].id = "block"; in dwcmshc_rk35xx_init()
396 priv->rockchip_clks[2].id = "timer"; in dwcmshc_rk35xx_init()
397 err = devm_clk_bulk_get_optional(mmc_dev(host->mmc), RK35xx_MAX_CLKS, in dwcmshc_rk35xx_init()
398 priv->rockchip_clks); in dwcmshc_rk35xx_init()
400 dev_err(mmc_dev(host->mmc), "failed to get clocks %d\n", err); in dwcmshc_rk35xx_init()
404 err = clk_bulk_prepare_enable(RK35xx_MAX_CLKS, priv->rockchip_clks); in dwcmshc_rk35xx_init()
406 dev_err(mmc_dev(host->mmc), "failed to enable clocks %d\n", err); in dwcmshc_rk35xx_init()
410 if (of_property_read_u8(mmc_dev(host->mmc)->of_node, "rockchip,txclk-tapnum", in dwcmshc_rk35xx_init()
411 &priv->txclk_tapnum)) in dwcmshc_rk35xx_init()
412 priv->txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT; in dwcmshc_rk35xx_init()
414 /* Disable cmd conflict check */ in dwcmshc_rk35xx_init()
415 sdhci_writel(host, 0x0, dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3); in dwcmshc_rk35xx_init()
429 if (host->mmc->f_max <= 52000000) { in dwcmshc_rk35xx_postinit()
430 dev_info(mmc_dev(host->mmc), "Disabling HS200/HS400, frequency too low (%d)\n", in dwcmshc_rk35xx_postinit()
431 host->mmc->f_max); in dwcmshc_rk35xx_postinit()
432 host->mmc->caps2 &= ~(MMC_CAP2_HS200 | MMC_CAP2_HS400); in dwcmshc_rk35xx_postinit()
433 host->mmc->caps &= ~(MMC_CAP_3_3V_DDR | MMC_CAP_1_8V_DDR); in dwcmshc_rk35xx_postinit()
439 .compatible = "rockchip,rk3588-dwcmshc",
443 .compatible = "rockchip,rk3568-dwcmshc",
447 .compatible = "snps,dwcmshc-sdhci",
465 static int dwcmshc_probe(struct platform_device *pdev) in dwcmshc_probe()
467 struct device *dev = &pdev->dev; in dwcmshc_probe()
473 int err; in dwcmshc_probe()
476 pltfm_data = device_get_match_data(&pdev->dev); in dwcmshc_probe()
478 dev_err(&pdev->dev, "Error: No device match data found\n"); in dwcmshc_probe()
479 return -ENODEV; in dwcmshc_probe()
493 host->adma_table_cnt += extra; in dwcmshc_probe()
498 if (dev->of_node) { in dwcmshc_probe()
499 pltfm_host->clk = devm_clk_get(dev, "core"); in dwcmshc_probe()
500 if (IS_ERR(pltfm_host->clk)) { in dwcmshc_probe()
501 err = PTR_ERR(pltfm_host->clk); in dwcmshc_probe()
505 err = clk_prepare_enable(pltfm_host->clk); in dwcmshc_probe()
509 priv->bus_clk = devm_clk_get(dev, "bus"); in dwcmshc_probe()
510 if (!IS_ERR(priv->bus_clk)) in dwcmshc_probe()
511 clk_prepare_enable(priv->bus_clk); in dwcmshc_probe()
514 err = mmc_of_parse(host->mmc); in dwcmshc_probe()
520 priv->vendor_specific_area1 = in dwcmshc_probe()
523 host->mmc_host_ops.request = dwcmshc_request; in dwcmshc_probe()
524 host->mmc_host_ops.hs400_enhanced_strobe = dwcmshc_hs400_enhanced_strobe; in dwcmshc_probe()
527 rk_priv = devm_kzalloc(&pdev->dev, sizeof(struct rk35xx_priv), GFP_KERNEL); in dwcmshc_probe()
529 err = -ENOMEM; in dwcmshc_probe()
533 if (of_device_is_compatible(pdev->dev.of_node, "rockchip,rk3588-dwcmshc")) in dwcmshc_probe()
534 rk_priv->devtype = DWCMSHC_RK3588; in dwcmshc_probe()
536 rk_priv->devtype = DWCMSHC_RK3568; in dwcmshc_probe()
538 priv->priv = rk_priv; in dwcmshc_probe()
550 host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; in dwcmshc_probe()
577 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_probe()
578 clk_disable_unprepare(priv->bus_clk); in dwcmshc_probe()
581 rk_priv->rockchip_clks); in dwcmshc_probe()
603 struct rk35xx_priv *rk_priv = priv->priv; in dwcmshc_remove()
605 pm_runtime_get_sync(&pdev->dev); in dwcmshc_remove()
606 pm_runtime_disable(&pdev->dev); in dwcmshc_remove()
607 pm_runtime_put_noidle(&pdev->dev); in dwcmshc_remove()
613 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_remove()
614 clk_disable_unprepare(priv->bus_clk); in dwcmshc_remove()
617 rk_priv->rockchip_clks); in dwcmshc_remove()
622 static int dwcmshc_suspend(struct device *dev) in dwcmshc_suspend()
627 struct rk35xx_priv *rk_priv = priv->priv; in dwcmshc_suspend()
628 int ret; in dwcmshc_suspend()
636 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_suspend()
637 if (!IS_ERR(priv->bus_clk)) in dwcmshc_suspend()
638 clk_disable_unprepare(priv->bus_clk); in dwcmshc_suspend()
642 rk_priv->rockchip_clks); in dwcmshc_suspend()
647 static int dwcmshc_resume(struct device *dev) in dwcmshc_resume()
652 struct rk35xx_priv *rk_priv = priv->priv; in dwcmshc_resume()
653 int ret; in dwcmshc_resume()
655 ret = clk_prepare_enable(pltfm_host->clk); in dwcmshc_resume()
659 if (!IS_ERR(priv->bus_clk)) { in dwcmshc_resume()
660 ret = clk_prepare_enable(priv->bus_clk); in dwcmshc_resume()
667 rk_priv->rockchip_clks); in dwcmshc_resume()
681 rk_priv->rockchip_clks); in dwcmshc_resume()
683 if (!IS_ERR(priv->bus_clk)) in dwcmshc_resume()
684 clk_disable_unprepare(priv->bus_clk); in dwcmshc_resume()
686 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_resume()
704 static int dwcmshc_runtime_suspend(struct device *dev) in dwcmshc_runtime_suspend()
713 static int dwcmshc_runtime_resume(struct device *dev) in dwcmshc_runtime_resume()
732 .name = "sdhci-dwcmshc",