Lines Matching +full:init +full:- +full:delay
1 // SPDX-License-Identifier: GPL-2.0
11 #include <linux/arm-smccc.h>
14 #include <linux/dma-mapping.h>
24 #include "sdhci-pltfm.h"
41 /* Tuning and auto-tuning fields in AT_CTRL_R control register */
51 #define AT_CTRL_PRE_CHANGE_DLY 0x1 /* 2-cycle latency */
53 #define AT_CTRL_POST_CHANGE_DLY 0x3 /* 4-cycle latency */
151 #define PHY_PAD_TXSLEW_CTRL_P 0x3 /* Slew control for P-Type pad TX */
153 #define PHY_PAD_TXSLEW_CTRL_N 0x3 /* Slew control for N-Type pad TX */
154 #define PHY_PAD_TXSLEW_CTRL_N_SG2042 0x2 /* Slew control for N-Type pad TX for SG2042 */
156 /* PHY CLK delay line settings */
161 /* PHY CLK delay line delay code */
163 #define PHY_SDCLKDL_DC_INITIAL 0x40 /* initial delay code */
164 #define PHY_SDCLKDL_DC_DEFAULT 0x32 /* default delay code */
165 #define PHY_SDCLKDL_DC_HS400 0x18 /* delay code for HS400 mode */
170 /* PHY drift_cclk_rx delay line configuration setting */
173 #define PHY_ATDL_CNFG_INPSEL 0x3 /* delay line input source */
174 #define PHY_ATDL_CNFG_INPSEL_SG2042 0x2 /* delay line input source for SG2042 */
184 #define PHY_DLL_CNFG1_SLVDLY 0x2 /* DLL slave update delay input */
191 /* PHY DLL master and slave delay line configuration settings */
199 ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1)))
205 /* SMC call for BlueField-3 eMMC RST_N */
236 int (*init)(struct device *dev, struct sdhci_host *host, struct dwcmshc_priv *dwc_priv); member
248 return -EINVAL; in dwcmshc_get_enable_other_clks()
251 priv->other_clks[i].id = clk_ids[i]; in dwcmshc_get_enable_other_clks()
253 err = devm_clk_bulk_get_optional(dev, num_clks, priv->other_clks); in dwcmshc_get_enable_other_clks()
259 err = clk_bulk_prepare_enable(num_clks, priv->other_clks); in dwcmshc_get_enable_other_clks()
263 priv->num_other_clks = num_clks; in dwcmshc_get_enable_other_clks()
282 offset = addr & (SZ_128M - 1); in dwcmshc_adma_write_desc()
283 tmplen = SZ_128M - offset; in dwcmshc_adma_write_desc()
287 len -= tmplen; in dwcmshc_adma_write_desc()
295 if (pltfm_host->clk) in dwcmshc_get_max_clock()
298 return pltfm_host->clock; in dwcmshc_get_max_clock()
305 return clk_round_rate(pltfm_host->clk, ULONG_MAX); in rk35xx_get_max_clock()
314 * No matter V4 is enabled or not, ARGUMENT2 register is 32-bit in dwcmshc_check_auto_cmd23()
318 if (mrq->sbc && (mrq->sbc->arg & SDHCI_DWCMSHC_ARG2_STUFF)) in dwcmshc_check_auto_cmd23()
319 host->flags &= ~SDHCI_AUTO_CMD23; in dwcmshc_check_auto_cmd23()
321 host->flags |= SDHCI_AUTO_CMD23; in dwcmshc_check_auto_cmd23()
343 /* disable delay line */ in dwcmshc_phy_1_8v_init()
346 /* set delay line */ in dwcmshc_phy_1_8v_init()
347 sdhci_writeb(host, priv->delay_line, PHY_SDCLKDL_DC_R); in dwcmshc_phy_1_8v_init()
350 /* enable delay lane */ in dwcmshc_phy_1_8v_init()
394 /* disable delay line */ in dwcmshc_phy_3_3v_init()
397 /* set delay line */ in dwcmshc_phy_3_3v_init()
398 sdhci_writeb(host, priv->delay_line, PHY_SDCLKDL_DC_R); in dwcmshc_phy_3_3v_init()
401 /* enable delay lane */ in dwcmshc_phy_3_3v_init()
437 if (priv->flags & FLAG_IO_FIXED_1V8) in th1520_sdhci_set_phy()
442 if ((host->mmc->caps2 & emmc_caps) == emmc_caps) { in th1520_sdhci_set_phy()
443 emmc_ctrl = sdhci_readw(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); in th1520_sdhci_set_phy()
445 sdhci_writew(host, emmc_ctrl, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); in th1520_sdhci_set_phy()
477 ctrl = sdhci_readw(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); in dwcmshc_set_uhs_signaling()
479 sdhci_writew(host, ctrl, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); in dwcmshc_set_uhs_signaling()
484 if (priv->flags & FLAG_IO_FIXED_1V8) in dwcmshc_set_uhs_signaling()
497 priv->delay_line = PHY_SDCLKDL_DC_HS400; in th1520_set_uhs_signaling()
510 int reg = priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL; in dwcmshc_hs400_enhanced_strobe()
513 if (ios->enhanced_strobe) in dwcmshc_hs400_enhanced_strobe()
547 cqhci_irq(host->mmc, intmask, cmd_error, data_error); in dwcmshc_cqe_irq_handler()
566 * Selection of 32-bit/64-bit System Addressing: in dwcmshc_sdhci_cqe_enable()
567 * either 32-bit or 64-bit system addressing is selected by in dwcmshc_sdhci_cqe_enable()
568 * 64-bit Addressing bit in Host Control 2 register. in dwcmshc_sdhci_cqe_enable()
590 offset = addr & (SZ_128M - 1); in dwcmshc_set_tran_desc()
591 tmplen = SZ_128M - offset; in dwcmshc_set_tran_desc()
595 len -= tmplen; in dwcmshc_set_tran_desc()
596 *desc += cq_host->trans_desc_len; in dwcmshc_set_tran_desc()
609 struct rk35xx_priv *priv = dwc_priv->priv; in dwcmshc_rk3568_set_clock()
614 host->mmc->actual_clock = 0; in dwcmshc_rk3568_set_clock()
626 err = clk_set_rate(pltfm_host->clk, clock); in dwcmshc_rk3568_set_clock()
628 dev_err(mmc_dev(host->mmc), "fail to set clock %d", clock); in dwcmshc_rk3568_set_clock()
633 reg = dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3; in dwcmshc_rk3568_set_clock()
669 if (priv->devtype == DWCMSHC_RK3568) in dwcmshc_rk3568_set_clock()
673 /* Init DLL settings */ in dwcmshc_rk3568_set_clock()
678 err = readl_poll_timeout(host->ioaddr + DWCMSHC_EMMC_DLL_STATUS0, in dwcmshc_rk3568_set_clock()
682 dev_err(mmc_dev(host->mmc), "DLL lock timeout!\n"); in dwcmshc_rk3568_set_clock()
687 0x3 << 17 | /* pre-change delay */ in dwcmshc_rk3568_set_clock()
688 0x3 << 19; /* post-change delay */ in dwcmshc_rk3568_set_clock()
689 sdhci_writel(host, extra, dwc_priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in dwcmshc_rk3568_set_clock()
691 if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200 || in dwcmshc_rk3568_set_clock()
692 host->mmc->ios.timing == MMC_TIMING_MMC_HS400) in dwcmshc_rk3568_set_clock()
693 txclk_tapnum = priv->txclk_tapnum; in dwcmshc_rk3568_set_clock()
695 if ((priv->devtype == DWCMSHC_RK3588) && host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { in dwcmshc_rk3568_set_clock()
722 struct rk35xx_priv *priv = dwc_priv->priv; in rk35xx_sdhci_reset()
724 if (mask & SDHCI_RESET_ALL && priv->reset) { in rk35xx_sdhci_reset()
725 reset_control_assert(priv->reset); in rk35xx_sdhci_reset()
727 reset_control_deassert(priv->reset); in rk35xx_sdhci_reset()
742 return -ENOMEM; in dwcmshc_rk35xx_init()
744 if (of_device_is_compatible(dev->of_node, "rockchip,rk3588-dwcmshc")) in dwcmshc_rk35xx_init()
745 priv->devtype = DWCMSHC_RK3588; in dwcmshc_rk35xx_init()
747 priv->devtype = DWCMSHC_RK3568; in dwcmshc_rk35xx_init()
749 priv->reset = devm_reset_control_array_get_optional_exclusive(mmc_dev(host->mmc)); in dwcmshc_rk35xx_init()
750 if (IS_ERR(priv->reset)) { in dwcmshc_rk35xx_init()
751 err = PTR_ERR(priv->reset); in dwcmshc_rk35xx_init()
752 dev_err(mmc_dev(host->mmc), "failed to get reset control %d\n", err); in dwcmshc_rk35xx_init()
756 err = dwcmshc_get_enable_other_clks(mmc_dev(host->mmc), dwc_priv, in dwcmshc_rk35xx_init()
761 if (of_property_read_u8(mmc_dev(host->mmc)->of_node, "rockchip,txclk-tapnum", in dwcmshc_rk35xx_init()
762 &priv->txclk_tapnum)) in dwcmshc_rk35xx_init()
763 priv->txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT; in dwcmshc_rk35xx_init()
766 sdhci_writel(host, 0x0, dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3); in dwcmshc_rk35xx_init()
771 dwc_priv->priv = priv; in dwcmshc_rk35xx_init()
782 if (host->mmc->f_max <= 52000000) { in dwcmshc_rk35xx_postinit()
783 dev_info(mmc_dev(host->mmc), "Disabling HS200/HS400, frequency too low (%d)\n", in dwcmshc_rk35xx_postinit()
784 host->mmc->f_max); in dwcmshc_rk35xx_postinit()
785 host->mmc->caps2 &= ~(MMC_CAP2_HS200 | MMC_CAP2_HS400); in dwcmshc_rk35xx_postinit()
786 host->mmc->caps &= ~(MMC_CAP_3_3V_DDR | MMC_CAP_1_8V_DDR); in dwcmshc_rk35xx_postinit()
796 if (host->flags & SDHCI_HS400_TUNING) in th1520_execute_tuning()
801 val = sdhci_readl(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in th1520_execute_tuning()
805 * - center phase select code driven in block gap interval in th1520_execute_tuning()
806 * - disable reporting of framing errors in th1520_execute_tuning()
807 * - disable software managed tuning in th1520_execute_tuning()
808 * - disable user selection of sampling window edges, in th1520_execute_tuning()
816 * - enable auto-tuning in th1520_execute_tuning()
817 * - enable sampling window threshold in th1520_execute_tuning()
818 * - stop clocks during phase code change in th1520_execute_tuning()
819 * - set max latency in cycles between tx and rx clocks in th1520_execute_tuning()
820 * - set max latency in cycles to switch output phase in th1520_execute_tuning()
821 * - set max sampling window threshold value in th1520_execute_tuning()
828 sdhci_writel(host, val, priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in th1520_execute_tuning()
829 val = sdhci_readl(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in th1520_execute_tuning()
833 host->tuning_loop_count = 128; in th1520_execute_tuning()
834 host->tuning_err = __sdhci_execute_tuning(host, opcode); in th1520_execute_tuning()
835 if (host->tuning_err) { in th1520_execute_tuning()
836 /* disable auto-tuning upon tuning error */ in th1520_execute_tuning()
838 sdhci_writel(host, val, priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in th1520_execute_tuning()
839 dev_err(mmc_dev(host->mmc), "tuning failed: %d\n", host->tuning_err); in th1520_execute_tuning()
840 return -EIO; in th1520_execute_tuning()
855 /* The T-Head 1520 SoC does not comply with the SDHCI specification in th1520_sdhci_reset()
863 if (priv->flags & FLAG_IO_FIXED_1V8) { in th1520_sdhci_reset()
876 dwc_priv->delay_line = PHY_SDCLKDL_DC_DEFAULT; in th1520_init()
878 if (device_property_read_bool(dev, "mmc-ddr-1_8v") || in th1520_init()
879 device_property_read_bool(dev, "mmc-hs200-1_8v") || in th1520_init()
880 device_property_read_bool(dev, "mmc-hs400-1_8v")) in th1520_init()
881 dwc_priv->flags |= FLAG_IO_FIXED_1V8; in th1520_init()
883 dwc_priv->flags &= ~FLAG_IO_FIXED_1V8; in th1520_init()
891 if (dwc_priv->flags & FLAG_IO_FIXED_1V8) { in th1520_init()
892 host->flags &= ~SDHCI_SIGNALING_330; in th1520_init()
893 host->flags |= SDHCI_SIGNALING_180; in th1520_init()
909 if ((host->mmc->caps2 & emmc_caps) == emmc_caps) { in cv18xx_sdhci_reset()
910 val = sdhci_readl(host, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL); in cv18xx_sdhci_reset()
912 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL); in cv18xx_sdhci_reset()
915 val = sdhci_readl(host, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL); in cv18xx_sdhci_reset()
917 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL); in cv18xx_sdhci_reset()
919 val = sdhci_readl(host, priv->vendor_specific_area1 + CV18XX_SDHCI_PHY_CONFIG); in cv18xx_sdhci_reset()
921 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_PHY_CONFIG); in cv18xx_sdhci_reset()
927 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_PHY_TX_RX_DLY); in cv18xx_sdhci_reset()
941 val = sdhci_readl(host, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL); in cv18xx_sdhci_set_tap()
943 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL); in cv18xx_sdhci_set_tap()
948 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_PHY_TX_RX_DLY); in cv18xx_sdhci_set_tap()
950 sdhci_writel(host, 0, priv->vendor_specific_area1 + CV18XX_SDHCI_PHY_CONFIG); in cv18xx_sdhci_set_tap()
993 /* find the mininum delay first which can pass tuning */ in cv18xx_sdhci_execute_tuning()
996 if (!cv18xx_retry_tuning(host->mmc, opcode, NULL)) in cv18xx_sdhci_execute_tuning()
1001 /* find the maxinum delay which can not pass tuning */ in cv18xx_sdhci_execute_tuning()
1005 if (cv18xx_retry_tuning(host->mmc, opcode, NULL)) { in cv18xx_sdhci_execute_tuning()
1006 max -= CV18XX_TUNE_STEP; in cv18xx_sdhci_execute_tuning()
1012 win_length = max - min + 1; in cv18xx_sdhci_execute_tuning()
1026 /* use average delay to get the best timing */ in cv18xx_sdhci_execute_tuning()
1029 ret = mmc_send_tuning(host->mmc, opcode, NULL); in cv18xx_sdhci_execute_tuning()
1031 dev_dbg(mmc_dev(host->mmc), "tuning %s at 0x%x ret %d\n", in cv18xx_sdhci_execute_tuning()
1069 /* Configure delay line */ in sg2042_sdhci_phy_init()
1070 /* Enable fixed delay */ in sg2042_sdhci_phy_init()
1073 * Set delay line. in sg2042_sdhci_phy_init()
1080 /* Add 10 * 70ps = 0.7ns for output delay */ in sg2042_sdhci_phy_init()
1089 /* Set ATDL_CNFG, tuning clk not use for init */ in sg2042_sdhci_phy_init()
1112 return dwcmshc_get_enable_other_clks(mmc_dev(host->mmc), dwc_priv, in sg2042_init()
1134 pr_err("%s: RST_N failed.\n", mmc_hostname(host->mmc)); in dwcmshc_bf3_hw_reset()
1217 .init = dwcmshc_rk35xx_init,
1227 .init = th1520_init,
1244 .init = sg2042_init,
1263 host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD; in dwcmshc_cqhci_init()
1264 cq_host = devm_kzalloc(&pdev->dev, sizeof(*cq_host), GFP_KERNEL); in dwcmshc_cqhci_init()
1266 dev_err(mmc_dev(host->mmc), "Unable to setup CQE: not enough memory\n"); in dwcmshc_cqhci_init()
1279 dev_err(mmc_dev(host->mmc), "Unable to setup CQE: internal clock enable error\n"); in dwcmshc_cqhci_init()
1283 cq_host->mmio = host->ioaddr + priv->vendor_specific_area2; in dwcmshc_cqhci_init()
1284 cq_host->ops = &dwcmshc_cqhci_ops; in dwcmshc_cqhci_init()
1286 /* Enable using of 128-bit task descriptors */ in dwcmshc_cqhci_init()
1287 dma64 = host->flags & SDHCI_USE_64_BIT_DMA; in dwcmshc_cqhci_init()
1289 dev_dbg(mmc_dev(host->mmc), "128-bit task descriptors\n"); in dwcmshc_cqhci_init()
1290 cq_host->caps |= CQHCI_TASK_DESC_SZ_128; in dwcmshc_cqhci_init()
1292 err = cqhci_init(cq_host, host->mmc, dma64); in dwcmshc_cqhci_init()
1294 dev_err(mmc_dev(host->mmc), "Unable to setup CQE: error %d\n", err); in dwcmshc_cqhci_init()
1298 dev_dbg(mmc_dev(host->mmc), "CQE init done\n"); in dwcmshc_cqhci_init()
1308 devm_kfree(&pdev->dev, cq_host); in dwcmshc_cqhci_init()
1311 host->mmc->caps2 &= ~(MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD); in dwcmshc_cqhci_init()
1316 .compatible = "rockchip,rk3588-dwcmshc",
1320 .compatible = "rockchip,rk3568-dwcmshc",
1324 .compatible = "snps,dwcmshc-sdhci",
1328 .compatible = "sophgo,cv1800b-dwcmshc",
1332 .compatible = "sophgo,sg2002-dwcmshc",
1336 .compatible = "thead,th1520-dwcmshc",
1340 .compatible = "sophgo,sg2042-dwcmshc",
1360 struct device *dev = &pdev->dev; in dwcmshc_probe()
1368 pltfm_data = device_get_match_data(&pdev->dev); in dwcmshc_probe()
1370 dev_err(&pdev->dev, "Error: No device match data found\n"); in dwcmshc_probe()
1371 return -ENODEV; in dwcmshc_probe()
1374 host = sdhci_pltfm_init(pdev, &pltfm_data->pdata, in dwcmshc_probe()
1385 host->adma_table_cnt += extra; in dwcmshc_probe()
1390 if (dev->of_node) { in dwcmshc_probe()
1391 pltfm_host->clk = devm_clk_get(dev, "core"); in dwcmshc_probe()
1392 if (IS_ERR(pltfm_host->clk)) { in dwcmshc_probe()
1393 err = PTR_ERR(pltfm_host->clk); in dwcmshc_probe()
1397 err = clk_prepare_enable(pltfm_host->clk); in dwcmshc_probe()
1401 priv->bus_clk = devm_clk_get(dev, "bus"); in dwcmshc_probe()
1402 if (!IS_ERR(priv->bus_clk)) in dwcmshc_probe()
1403 clk_prepare_enable(priv->bus_clk); in dwcmshc_probe()
1406 err = mmc_of_parse(host->mmc); in dwcmshc_probe()
1412 priv->vendor_specific_area1 = in dwcmshc_probe()
1415 host->mmc_host_ops.request = dwcmshc_request; in dwcmshc_probe()
1416 host->mmc_host_ops.hs400_enhanced_strobe = dwcmshc_hs400_enhanced_strobe; in dwcmshc_probe()
1417 host->mmc_host_ops.execute_tuning = dwcmshc_execute_tuning; in dwcmshc_probe()
1419 if (pltfm_data->init) { in dwcmshc_probe()
1420 err = pltfm_data->init(&pdev->dev, host, priv); in dwcmshc_probe()
1434 host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; in dwcmshc_probe()
1445 if (device_property_read_bool(&pdev->dev, "supports-cqe")) { in dwcmshc_probe()
1446 priv->vendor_specific_area2 = in dwcmshc_probe()
1452 if (pltfm_data->postinit) in dwcmshc_probe()
1453 pltfm_data->postinit(host, priv); in dwcmshc_probe()
1469 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_probe()
1470 clk_disable_unprepare(priv->bus_clk); in dwcmshc_probe()
1471 clk_bulk_disable_unprepare(priv->num_other_clks, priv->other_clks); in dwcmshc_probe()
1494 pm_runtime_get_sync(&pdev->dev); in dwcmshc_remove()
1495 pm_runtime_disable(&pdev->dev); in dwcmshc_remove()
1496 pm_runtime_put_noidle(&pdev->dev); in dwcmshc_remove()
1502 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_remove()
1503 clk_disable_unprepare(priv->bus_clk); in dwcmshc_remove()
1504 clk_bulk_disable_unprepare(priv->num_other_clks, priv->other_clks); in dwcmshc_remove()
1518 if (host->mmc->caps2 & MMC_CAP2_CQE) { in dwcmshc_suspend()
1519 ret = cqhci_suspend(host->mmc); in dwcmshc_suspend()
1528 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_suspend()
1529 if (!IS_ERR(priv->bus_clk)) in dwcmshc_suspend()
1530 clk_disable_unprepare(priv->bus_clk); in dwcmshc_suspend()
1532 clk_bulk_disable_unprepare(priv->num_other_clks, priv->other_clks); in dwcmshc_suspend()
1544 ret = clk_prepare_enable(pltfm_host->clk); in dwcmshc_resume()
1548 if (!IS_ERR(priv->bus_clk)) { in dwcmshc_resume()
1549 ret = clk_prepare_enable(priv->bus_clk); in dwcmshc_resume()
1554 ret = clk_bulk_prepare_enable(priv->num_other_clks, priv->other_clks); in dwcmshc_resume()
1562 if (host->mmc->caps2 & MMC_CAP2_CQE) { in dwcmshc_resume()
1563 ret = cqhci_resume(host->mmc); in dwcmshc_resume()
1571 clk_bulk_disable_unprepare(priv->num_other_clks, priv->other_clks); in dwcmshc_resume()
1573 if (!IS_ERR(priv->bus_clk)) in dwcmshc_resume()
1574 clk_disable_unprepare(priv->bus_clk); in dwcmshc_resume()
1576 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_resume()
1622 .name = "sdhci-dwcmshc",