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>
21 #include "sdhci-pltfm.h"
73 ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1)))
90 int vendor_specific_area1; /* P_VENDOR_SPECIFIC_AREA reg */
99 dma_addr_t addr, int len, unsigned int cmd) in dwcmshc_adma_write_desc() argument
101 int tmplen, offset; in dwcmshc_adma_write_desc()
104 sdhci_adma_write_desc(host, desc, addr, len, cmd); in dwcmshc_adma_write_desc()
108 offset = addr & (SZ_128M - 1); in dwcmshc_adma_write_desc()
109 tmplen = SZ_128M - offset; in dwcmshc_adma_write_desc()
110 sdhci_adma_write_desc(host, desc, addr, tmplen, cmd); in dwcmshc_adma_write_desc()
113 len -= tmplen; in dwcmshc_adma_write_desc()
114 sdhci_adma_write_desc(host, desc, addr, len, cmd); in dwcmshc_adma_write_desc()
117 static unsigned int dwcmshc_get_max_clock(struct sdhci_host *host) in dwcmshc_get_max_clock()
121 if (pltfm_host->clk) in dwcmshc_get_max_clock()
124 return pltfm_host->clock; in dwcmshc_get_max_clock()
133 * No matter V4 is enabled or not, ARGUMENT2 register is 32-bit in dwcmshc_check_auto_cmd23()
137 if (mrq->sbc && (mrq->sbc->arg & SDHCI_DWCMSHC_ARG2_STUFF)) in dwcmshc_check_auto_cmd23()
138 host->flags &= ~SDHCI_AUTO_CMD23; in dwcmshc_check_auto_cmd23()
140 host->flags |= SDHCI_AUTO_CMD23; in dwcmshc_check_auto_cmd23()
151 unsigned int timing) in dwcmshc_set_uhs_signaling()
174 /* set CARD_IS_EMMC bit to enable Data Strobe for HS400 */ in dwcmshc_set_uhs_signaling()
175 ctrl = sdhci_readw(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); in dwcmshc_set_uhs_signaling()
177 sdhci_writew(host, ctrl, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); in dwcmshc_set_uhs_signaling()
192 int reg = priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL; in dwcmshc_hs400_enhanced_strobe()
195 if (ios->enhanced_strobe) in dwcmshc_hs400_enhanced_strobe()
203 static void dwcmshc_rk3568_set_clock(struct sdhci_host *host, unsigned int clock) in dwcmshc_rk3568_set_clock()
207 struct rk35xx_priv *priv = dwc_priv->priv; in dwcmshc_rk3568_set_clock()
210 int err; in dwcmshc_rk3568_set_clock()
212 host->mmc->actual_clock = 0; in dwcmshc_rk3568_set_clock()
224 err = clk_set_rate(pltfm_host->clk, clock); in dwcmshc_rk3568_set_clock()
226 dev_err(mmc_dev(host->mmc), "fail to set clock %d", clock); in dwcmshc_rk3568_set_clock()
230 /* Disable cmd conflict check */ in dwcmshc_rk3568_set_clock()
231 reg = dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3; in dwcmshc_rk3568_set_clock()
264 if (priv->devtype == DWCMSHC_RK3568) in dwcmshc_rk3568_set_clock()
273 err = readl_poll_timeout(host->ioaddr + DWCMSHC_EMMC_DLL_STATUS0, in dwcmshc_rk3568_set_clock()
277 dev_err(mmc_dev(host->mmc), "DLL lock timeout!\n"); in dwcmshc_rk3568_set_clock()
282 0x2 << 17 | /* pre-change delay */ in dwcmshc_rk3568_set_clock()
283 0x3 << 19; /* post-change delay */ in dwcmshc_rk3568_set_clock()
284 sdhci_writel(host, extra, dwc_priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in dwcmshc_rk3568_set_clock()
286 if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200 || in dwcmshc_rk3568_set_clock()
287 host->mmc->ios.timing == MMC_TIMING_MMC_HS400) in dwcmshc_rk3568_set_clock()
288 txclk_tapnum = priv->txclk_tapnum; in dwcmshc_rk3568_set_clock()
290 if ((priv->devtype == DWCMSHC_RK3588) && host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { in dwcmshc_rk3568_set_clock()
317 struct rk35xx_priv *priv = dwc_priv->priv; in rk35xx_sdhci_reset()
319 if (mask & SDHCI_RESET_ALL && priv->reset) { in rk35xx_sdhci_reset()
320 reset_control_assert(priv->reset); in rk35xx_sdhci_reset()
322 reset_control_deassert(priv->reset); in rk35xx_sdhci_reset()
369 static int dwcmshc_rk35xx_init(struct sdhci_host *host, struct dwcmshc_priv *dwc_priv) in dwcmshc_rk35xx_init()
371 int err; in dwcmshc_rk35xx_init()
372 struct rk35xx_priv *priv = dwc_priv->priv; in dwcmshc_rk35xx_init()
374 priv->reset = devm_reset_control_array_get_optional_exclusive(mmc_dev(host->mmc)); in dwcmshc_rk35xx_init()
375 if (IS_ERR(priv->reset)) { in dwcmshc_rk35xx_init()
376 err = PTR_ERR(priv->reset); in dwcmshc_rk35xx_init()
377 dev_err(mmc_dev(host->mmc), "failed to get reset control %d\n", err); in dwcmshc_rk35xx_init()
381 priv->rockchip_clks[0].id = "axi"; in dwcmshc_rk35xx_init()
382 priv->rockchip_clks[1].id = "block"; in dwcmshc_rk35xx_init()
383 priv->rockchip_clks[2].id = "timer"; in dwcmshc_rk35xx_init()
384 err = devm_clk_bulk_get_optional(mmc_dev(host->mmc), RK35xx_MAX_CLKS, in dwcmshc_rk35xx_init()
385 priv->rockchip_clks); in dwcmshc_rk35xx_init()
387 dev_err(mmc_dev(host->mmc), "failed to get clocks %d\n", err); in dwcmshc_rk35xx_init()
391 err = clk_bulk_prepare_enable(RK35xx_MAX_CLKS, priv->rockchip_clks); in dwcmshc_rk35xx_init()
393 dev_err(mmc_dev(host->mmc), "failed to enable clocks %d\n", err); in dwcmshc_rk35xx_init()
397 if (of_property_read_u8(mmc_dev(host->mmc)->of_node, "rockchip,txclk-tapnum", in dwcmshc_rk35xx_init()
398 &priv->txclk_tapnum)) in dwcmshc_rk35xx_init()
399 priv->txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT; in dwcmshc_rk35xx_init()
401 /* Disable cmd conflict check */ in dwcmshc_rk35xx_init()
402 sdhci_writel(host, 0x0, dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3); in dwcmshc_rk35xx_init()
416 if (host->mmc->f_max <= 52000000) { in dwcmshc_rk35xx_postinit()
417 dev_info(mmc_dev(host->mmc), "Disabling HS200/HS400, frequency too low (%d)\n", in dwcmshc_rk35xx_postinit()
418 host->mmc->f_max); in dwcmshc_rk35xx_postinit()
419 host->mmc->caps2 &= ~(MMC_CAP2_HS200 | MMC_CAP2_HS400); in dwcmshc_rk35xx_postinit()
420 host->mmc->caps &= ~(MMC_CAP_3_3V_DDR | MMC_CAP_1_8V_DDR); in dwcmshc_rk35xx_postinit()
426 .compatible = "rockchip,rk3588-dwcmshc",
430 .compatible = "rockchip,rk3568-dwcmshc",
434 .compatible = "snps,dwcmshc-sdhci",
451 static int dwcmshc_probe(struct platform_device *pdev) in dwcmshc_probe()
453 struct device *dev = &pdev->dev; in dwcmshc_probe()
459 int err; in dwcmshc_probe()
462 pltfm_data = device_get_match_data(&pdev->dev); in dwcmshc_probe()
464 dev_err(&pdev->dev, "Error: No device match data found\n"); in dwcmshc_probe()
465 return -ENODEV; in dwcmshc_probe()
479 host->adma_table_cnt += extra; in dwcmshc_probe()
484 if (dev->of_node) { in dwcmshc_probe()
485 pltfm_host->clk = devm_clk_get(dev, "core"); in dwcmshc_probe()
486 if (IS_ERR(pltfm_host->clk)) { in dwcmshc_probe()
487 err = PTR_ERR(pltfm_host->clk); in dwcmshc_probe()
491 err = clk_prepare_enable(pltfm_host->clk); in dwcmshc_probe()
495 priv->bus_clk = devm_clk_get(dev, "bus"); in dwcmshc_probe()
496 if (!IS_ERR(priv->bus_clk)) in dwcmshc_probe()
497 clk_prepare_enable(priv->bus_clk); in dwcmshc_probe()
500 err = mmc_of_parse(host->mmc); in dwcmshc_probe()
506 priv->vendor_specific_area1 = in dwcmshc_probe()
509 host->mmc_host_ops.request = dwcmshc_request; in dwcmshc_probe()
510 host->mmc_host_ops.hs400_enhanced_strobe = dwcmshc_hs400_enhanced_strobe; in dwcmshc_probe()
513 rk_priv = devm_kzalloc(&pdev->dev, sizeof(struct rk35xx_priv), GFP_KERNEL); in dwcmshc_probe()
515 err = -ENOMEM; in dwcmshc_probe()
519 if (of_device_is_compatible(pdev->dev.of_node, "rockchip,rk3588-dwcmshc")) in dwcmshc_probe()
520 rk_priv->devtype = DWCMSHC_RK3588; in dwcmshc_probe()
522 rk_priv->devtype = DWCMSHC_RK3568; in dwcmshc_probe()
524 priv->priv = rk_priv; in dwcmshc_probe()
531 host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; in dwcmshc_probe()
549 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_probe()
550 clk_disable_unprepare(priv->bus_clk); in dwcmshc_probe()
553 rk_priv->rockchip_clks); in dwcmshc_probe()
559 static int dwcmshc_remove(struct platform_device *pdev) in dwcmshc_remove()
564 struct rk35xx_priv *rk_priv = priv->priv; in dwcmshc_remove()
568 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_remove()
569 clk_disable_unprepare(priv->bus_clk); in dwcmshc_remove()
572 rk_priv->rockchip_clks); in dwcmshc_remove()
579 static int dwcmshc_suspend(struct device *dev) in dwcmshc_suspend()
584 struct rk35xx_priv *rk_priv = priv->priv; in dwcmshc_suspend()
585 int ret; in dwcmshc_suspend()
591 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_suspend()
592 if (!IS_ERR(priv->bus_clk)) in dwcmshc_suspend()
593 clk_disable_unprepare(priv->bus_clk); in dwcmshc_suspend()
597 rk_priv->rockchip_clks); in dwcmshc_suspend()
602 static int dwcmshc_resume(struct device *dev) in dwcmshc_resume()
607 struct rk35xx_priv *rk_priv = priv->priv; in dwcmshc_resume()
608 int ret; in dwcmshc_resume()
610 ret = clk_prepare_enable(pltfm_host->clk); in dwcmshc_resume()
614 if (!IS_ERR(priv->bus_clk)) { in dwcmshc_resume()
615 ret = clk_prepare_enable(priv->bus_clk); in dwcmshc_resume()
622 rk_priv->rockchip_clks); in dwcmshc_resume()
635 .name = "sdhci-dwcmshc",