Lines Matching +full:phy +full:- +full:input +full:- +full:delay +full:- +full:legacy
1 // SPDX-License-Identifier: GPL-2.0
11 #include <linux/arm-smccc.h>
14 #include <linux/clk-provider.h>
15 #include <linux/dma-mapping.h>
29 #include "sdhci-pltfm.h"
31 #include "sdhci-cqhci.h"
48 /* Tuning and auto-tuning fields in AT_CTRL_R control register */
58 #define AT_CTRL_PRE_CHANGE_DLY 0x1 /* 2-cycle latency */
60 #define AT_CTRL_POST_CHANGE_DLY 0x3 /* 4-cycle latency */
122 /* PHY register area pointer */
125 /* PHY general configuration */
127 #define PHY_CNFG_RSTN_DEASSERT 0x1 /* Deassert PHY reset */
136 /* PHY command/response pad settings */
139 /* PHY data pad settings */
142 /* PHY clock pad settings */
145 /* PHY strobe pad settings */
148 /* PHY reset pad settings */
160 #define PHY_PAD_TXSLEW_CTRL_P 0x3 /* Slew control for P-Type pad TX */
162 #define PHY_PAD_TXSLEW_CTRL_N 0x3 /* Slew control for N-Type pad TX */
163 #define PHY_PAD_TXSLEW_CTRL_N_SG2042 0x2 /* Slew control for N-Type pad TX for SG2042 */
165 /* PHY CLK delay line settings */
170 /* PHY CLK delay line delay code */
172 #define PHY_SDCLKDL_DC_INITIAL 0x40 /* initial delay code */
173 #define PHY_SDCLKDL_DC_DEFAULT 0x32 /* default delay code */
174 #define PHY_SDCLKDL_DC_HS400 0x18 /* delay code for HS400 mode */
179 /* PHY drift_cclk_rx delay line configuration setting */
182 #define PHY_ATDL_CNFG_INPSEL 0x3 /* delay line input source */
183 #define PHY_ATDL_CNFG_INPSEL_SG2042 0x2 /* delay line input source for SG2042 */
185 /* PHY DLL control settings */
187 #define PHY_DLL_CTRL_DISABLE 0x0 /* PHY DLL is enabled */
188 #define PHY_DLL_CTRL_ENABLE 0x1 /* PHY DLL is disabled */
190 /* PHY DLL configuration register 1 */
193 #define PHY_DLL_CNFG1_SLVDLY 0x2 /* DLL slave update delay input */
194 #define PHY_DLL_CNFG1_WAITCYCLE 0x5 /* DLL wait cycle input */
196 /* PHY DLL configuration register 2 */
198 #define PHY_DLL_CNFG2_JUMPSTEP 0xa /* DLL jump step input */
200 /* PHY DLL master and slave delay line configuration settings */
205 /* PHY DLL offset setting register */
221 ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1)))
227 /* SMC call for BlueField-3 eMMC RST_N */
312 return -EINVAL; in dwcmshc_get_enable_other_clks()
315 priv->other_clks[i].id = clk_ids[i]; in dwcmshc_get_enable_other_clks()
317 err = devm_clk_bulk_get_optional(dev, num_clks, priv->other_clks); in dwcmshc_get_enable_other_clks()
323 err = clk_bulk_prepare_enable(num_clks, priv->other_clks); in dwcmshc_get_enable_other_clks()
327 priv->num_other_clks = num_clks; in dwcmshc_get_enable_other_clks()
346 offset = addr & (SZ_128M - 1); in dwcmshc_adma_write_desc()
347 tmplen = SZ_128M - offset; in dwcmshc_adma_write_desc()
351 len -= tmplen; in dwcmshc_adma_write_desc()
372 if (pltfm_host->clk) in dwcmshc_get_max_clock()
375 return pltfm_host->clock; in dwcmshc_get_max_clock()
382 return clk_round_rate(pltfm_host->clk, ULONG_MAX); in rk35xx_get_max_clock()
391 * No matter V4 is enabled or not, ARGUMENT2 register is 32-bit in dwcmshc_check_auto_cmd23()
395 if (mrq->sbc && (mrq->sbc->arg & SDHCI_DWCMSHC_ARG2_STUFF)) in dwcmshc_check_auto_cmd23()
396 host->flags &= ~SDHCI_AUTO_CMD23; in dwcmshc_check_auto_cmd23()
398 host->flags |= SDHCI_AUTO_CMD23; in dwcmshc_check_auto_cmd23()
415 if (priv->flags & FLAG_IO_FIXED_1V8 || in dwcmshc_phy_init()
416 host->mmc->ios.timing & MMC_SIGNAL_VOLTAGE_180) in dwcmshc_phy_init()
419 /* deassert phy reset & set tx drive strength */ in dwcmshc_phy_init()
425 /* disable delay line */ in dwcmshc_phy_init()
428 /* set delay line */ in dwcmshc_phy_init()
429 sdhci_writeb(host, priv->delay_line, PHY_SDCLKDL_DC_R); in dwcmshc_phy_init()
432 /* enable delay lane */ in dwcmshc_phy_init()
437 /* configure phy pads */ in dwcmshc_phy_init()
463 /* enable phy dll */ in dwcmshc_phy_init()
477 if ((host->mmc->caps2 & emmc_caps) == emmc_caps) { in th1520_sdhci_set_phy()
478 emmc_ctrl = sdhci_readw(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); in th1520_sdhci_set_phy()
480 sdhci_writew(host, emmc_ctrl, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); in th1520_sdhci_set_phy()
512 ctrl = sdhci_readw(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); in dwcmshc_set_uhs_signaling()
514 sdhci_writew(host, ctrl, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); in dwcmshc_set_uhs_signaling()
519 if (priv->flags & FLAG_IO_FIXED_1V8) in dwcmshc_set_uhs_signaling()
532 priv->delay_line = PHY_SDCLKDL_DC_HS400; in th1520_set_uhs_signaling()
545 int reg = priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL; in dwcmshc_hs400_enhanced_strobe()
548 if (ios->enhanced_strobe) in dwcmshc_hs400_enhanced_strobe()
582 cqhci_irq(host->mmc, intmask, cmd_error, data_error); in dwcmshc_cqe_irq_handler()
601 * Selection of 32-bit/64-bit System Addressing: in dwcmshc_sdhci_cqe_enable()
602 * either 32-bit or 64-bit system addressing is selected by in dwcmshc_sdhci_cqe_enable()
603 * 64-bit Addressing bit in Host Control 2 register. in dwcmshc_sdhci_cqe_enable()
625 offset = addr & (SZ_128M - 1); in dwcmshc_set_tran_desc()
626 tmplen = SZ_128M - offset; in dwcmshc_set_tran_desc()
630 len -= tmplen; in dwcmshc_set_tran_desc()
631 *desc += cq_host->trans_desc_len; in dwcmshc_set_tran_desc()
648 reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_SSC1); in rk35xx_sdhci_cqe_pre_enable()
650 sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_SSC1); in rk35xx_sdhci_cqe_pre_enable()
652 reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_CFG); in rk35xx_sdhci_cqe_pre_enable()
654 sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_CFG); in rk35xx_sdhci_cqe_pre_enable()
682 * either halted or disabled. Otherwise unexpected SDCHI legacy in rk35xx_sdhci_cqe_disable()
685 spin_lock_irqsave(&host->lock, flags); in rk35xx_sdhci_cqe_disable()
690 spin_unlock_irqrestore(&host->lock, flags); in rk35xx_sdhci_cqe_disable()
702 ctrl = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_CFG); in rk35xx_sdhci_cqe_post_disable()
704 sdhci_writel(host, ctrl, dwc_priv->vendor_specific_area2 + CQHCI_CFG); in rk35xx_sdhci_cqe_post_disable()
711 struct rk35xx_priv *priv = dwc_priv->priv; in dwcmshc_rk3568_set_clock()
716 host->mmc->actual_clock = 0; in dwcmshc_rk3568_set_clock()
728 err = clk_set_rate(pltfm_host->clk, clock); in dwcmshc_rk3568_set_clock()
730 dev_err(mmc_dev(host->mmc), "fail to set clock %d", clock); in dwcmshc_rk3568_set_clock()
735 reg = dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3; in dwcmshc_rk3568_set_clock()
752 * enhanced strobe first. PHY needs to configure the parameters in dwcmshc_rk3568_set_clock()
772 if (priv->devtype == DWCMSHC_RK3568) in dwcmshc_rk3568_set_clock()
781 err = readl_poll_timeout(host->ioaddr + DWCMSHC_EMMC_DLL_STATUS0, in dwcmshc_rk3568_set_clock()
785 dev_err(mmc_dev(host->mmc), "DLL lock timeout!\n"); in dwcmshc_rk3568_set_clock()
790 0x3 << 17 | /* pre-change delay */ in dwcmshc_rk3568_set_clock()
791 0x3 << 19; /* post-change delay */ in dwcmshc_rk3568_set_clock()
792 sdhci_writel(host, extra, dwc_priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in dwcmshc_rk3568_set_clock()
794 if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200 || in dwcmshc_rk3568_set_clock()
795 host->mmc->ios.timing == MMC_TIMING_MMC_HS400) in dwcmshc_rk3568_set_clock()
796 txclk_tapnum = priv->txclk_tapnum; in dwcmshc_rk3568_set_clock()
798 if ((priv->devtype == DWCMSHC_RK3588) && host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { in dwcmshc_rk3568_set_clock()
825 struct rk35xx_priv *priv = dwc_priv->priv; in rk35xx_sdhci_reset()
828 if ((host->mmc->caps2 & MMC_CAP2_CQE) && (mask & SDHCI_RESET_ALL)) in rk35xx_sdhci_reset()
829 cqhci_deactivate(host->mmc); in rk35xx_sdhci_reset()
831 if (mask & SDHCI_RESET_ALL && priv->reset) { in rk35xx_sdhci_reset()
832 reset_control_assert(priv->reset); in rk35xx_sdhci_reset()
834 reset_control_deassert(priv->reset); in rk35xx_sdhci_reset()
852 return -ENOMEM; in dwcmshc_rk35xx_init()
854 if (of_device_is_compatible(dev->of_node, "rockchip,rk3588-dwcmshc")) in dwcmshc_rk35xx_init()
855 priv->devtype = DWCMSHC_RK3588; in dwcmshc_rk35xx_init()
857 priv->devtype = DWCMSHC_RK3568; in dwcmshc_rk35xx_init()
859 priv->reset = devm_reset_control_array_get_optional_exclusive(mmc_dev(host->mmc)); in dwcmshc_rk35xx_init()
860 if (IS_ERR(priv->reset)) { in dwcmshc_rk35xx_init()
861 err = PTR_ERR(priv->reset); in dwcmshc_rk35xx_init()
862 dev_err(mmc_dev(host->mmc), "failed to get reset control %d\n", err); in dwcmshc_rk35xx_init()
866 err = dwcmshc_get_enable_other_clks(mmc_dev(host->mmc), dwc_priv, in dwcmshc_rk35xx_init()
871 if (of_property_read_u8(mmc_dev(host->mmc)->of_node, "rockchip,txclk-tapnum", in dwcmshc_rk35xx_init()
872 &priv->txclk_tapnum)) in dwcmshc_rk35xx_init()
873 priv->txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT; in dwcmshc_rk35xx_init()
876 sdhci_writel(host, 0x0, dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3); in dwcmshc_rk35xx_init()
881 dwc_priv->priv = priv; in dwcmshc_rk35xx_init()
892 if (host->mmc->f_max <= 52000000) { in dwcmshc_rk35xx_postinit()
893 dev_info(mmc_dev(host->mmc), "Disabling HS200/HS400, frequency too low (%d)\n", in dwcmshc_rk35xx_postinit()
894 host->mmc->f_max); in dwcmshc_rk35xx_postinit()
895 host->mmc->caps2 &= ~(MMC_CAP2_HS200 | MMC_CAP2_HS400); in dwcmshc_rk35xx_postinit()
896 host->mmc->caps &= ~(MMC_CAP_3_3V_DDR | MMC_CAP_1_8V_DDR); in dwcmshc_rk35xx_postinit()
902 struct device *dev = mmc_dev(host->mmc); in dwcmshc_rk3576_postinit()
908 * RK3576 is in, never come back the same way once it's run-time in dwcmshc_rk3576_postinit()
916 if (ret && ret != -EOPNOTSUPP) in dwcmshc_rk3576_postinit()
929 if (host->flags & SDHCI_HS400_TUNING) in th1520_execute_tuning()
934 val = sdhci_readl(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in th1520_execute_tuning()
938 * - center phase select code driven in block gap interval in th1520_execute_tuning()
939 * - disable reporting of framing errors in th1520_execute_tuning()
940 * - disable software managed tuning in th1520_execute_tuning()
941 * - disable user selection of sampling window edges, in th1520_execute_tuning()
949 * - enable auto-tuning in th1520_execute_tuning()
950 * - enable sampling window threshold in th1520_execute_tuning()
951 * - stop clocks during phase code change in th1520_execute_tuning()
952 * - set max latency in cycles between tx and rx clocks in th1520_execute_tuning()
953 * - set max latency in cycles to switch output phase in th1520_execute_tuning()
954 * - set max sampling window threshold value in th1520_execute_tuning()
961 sdhci_writel(host, val, priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in th1520_execute_tuning()
962 val = sdhci_readl(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in th1520_execute_tuning()
966 host->tuning_loop_count = 128; in th1520_execute_tuning()
967 host->tuning_err = __sdhci_execute_tuning(host, opcode); in th1520_execute_tuning()
968 if (host->tuning_err) { in th1520_execute_tuning()
969 /* disable auto-tuning upon tuning error */ in th1520_execute_tuning()
971 sdhci_writel(host, val, priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in th1520_execute_tuning()
972 dev_err(mmc_dev(host->mmc), "tuning failed: %d\n", host->tuning_err); in th1520_execute_tuning()
973 return -EIO; in th1520_execute_tuning()
988 if (priv->flags & FLAG_IO_FIXED_1V8) { in th1520_sdhci_reset()
1001 dwc_priv->delay_line = PHY_SDCLKDL_DC_DEFAULT; in th1520_init()
1003 if (device_property_read_bool(dev, "mmc-ddr-1_8v") || in th1520_init()
1004 device_property_read_bool(dev, "mmc-hs200-1_8v") || in th1520_init()
1005 device_property_read_bool(dev, "mmc-hs400-1_8v")) in th1520_init()
1006 dwc_priv->flags |= FLAG_IO_FIXED_1V8; in th1520_init()
1008 dwc_priv->flags &= ~FLAG_IO_FIXED_1V8; in th1520_init()
1016 if (dwc_priv->flags & FLAG_IO_FIXED_1V8) { in th1520_init()
1017 host->flags &= ~SDHCI_SIGNALING_330; in th1520_init()
1018 host->flags |= SDHCI_SIGNALING_180; in th1520_init()
1034 if ((host->mmc->caps2 & emmc_caps) == emmc_caps) { in cv18xx_sdhci_reset()
1035 val = sdhci_readl(host, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL); in cv18xx_sdhci_reset()
1037 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL); in cv18xx_sdhci_reset()
1040 val = sdhci_readl(host, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL); in cv18xx_sdhci_reset()
1042 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL); in cv18xx_sdhci_reset()
1044 val = sdhci_readl(host, priv->vendor_specific_area1 + CV18XX_SDHCI_PHY_CONFIG); in cv18xx_sdhci_reset()
1046 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_PHY_CONFIG); in cv18xx_sdhci_reset()
1052 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_PHY_TX_RX_DLY); in cv18xx_sdhci_reset()
1066 val = sdhci_readl(host, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL); in cv18xx_sdhci_set_tap()
1068 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL); in cv18xx_sdhci_set_tap()
1073 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_PHY_TX_RX_DLY); in cv18xx_sdhci_set_tap()
1075 sdhci_writel(host, 0, priv->vendor_specific_area1 + CV18XX_SDHCI_PHY_CONFIG); in cv18xx_sdhci_set_tap()
1118 /* find the mininum delay first which can pass tuning */ in cv18xx_sdhci_execute_tuning()
1121 if (!cv18xx_retry_tuning(host->mmc, opcode, NULL)) in cv18xx_sdhci_execute_tuning()
1126 /* find the maxinum delay which can not pass tuning */ in cv18xx_sdhci_execute_tuning()
1130 if (cv18xx_retry_tuning(host->mmc, opcode, NULL)) { in cv18xx_sdhci_execute_tuning()
1131 max -= CV18XX_TUNE_STEP; in cv18xx_sdhci_execute_tuning()
1137 win_length = max - min + 1; in cv18xx_sdhci_execute_tuning()
1151 /* use average delay to get the best timing */ in cv18xx_sdhci_execute_tuning()
1154 ret = mmc_send_tuning(host->mmc, opcode, NULL); in cv18xx_sdhci_execute_tuning()
1156 dev_dbg(mmc_dev(host->mmc), "tuning %s at 0x%x ret %d\n", in cv18xx_sdhci_execute_tuning()
1166 /* Asset phy reset & set tx drive strength */ in sg2042_sdhci_phy_init()
1174 /* Configure phy pads */ in sg2042_sdhci_phy_init()
1194 /* Configure delay line */ in sg2042_sdhci_phy_init()
1195 /* Enable fixed delay */ in sg2042_sdhci_phy_init()
1198 * Set delay line. in sg2042_sdhci_phy_init()
1205 /* Add 10 * 70ps = 0.7ns for output delay */ in sg2042_sdhci_phy_init()
1218 /* Deasset phy reset */ in sg2042_sdhci_phy_init()
1237 return dwcmshc_get_enable_other_clks(mmc_dev(host->mmc), dwc_priv, in sg2042_init()
1246 host->mmc->actual_clock = clock; in sdhci_eic7700_set_clock()
1253 clk_set_rate(pltfm_host->clk, clock); in sdhci_eic7700_set_clock()
1262 static void sdhci_eic7700_config_phy_delay(struct sdhci_host *host, int delay) in sdhci_eic7700_config_phy_delay() argument
1264 delay &= PHY_CLK_MAX_DELAY_MASK; in sdhci_eic7700_config_phy_delay()
1266 /* phy clk delay line config */ in sdhci_eic7700_config_phy_delay()
1268 sdhci_writeb(host, delay, PHY_SDCLKDL_DC_R); in sdhci_eic7700_config_phy_delay()
1277 struct eic7700_priv *priv = dwc_priv->priv; in sdhci_eic7700_config_phy()
1280 drv = FIELD_PREP(PHY_CNFG_PAD_SP_MASK, priv->drive_impedance & 0xF); in sdhci_eic7700_config_phy()
1281 drv |= FIELD_PREP(PHY_CNFG_PAD_SN_MASK, (priv->drive_impedance >> 4) & 0xF); in sdhci_eic7700_config_phy()
1283 if ((host->mmc->caps2 & emmc_caps) == emmc_caps) { in sdhci_eic7700_config_phy()
1284 val = sdhci_readw(host, dwc_priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); in sdhci_eic7700_config_phy()
1286 sdhci_writew(host, val, dwc_priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); in sdhci_eic7700_config_phy()
1289 /* reset phy, config phy's pad */ in sdhci_eic7700_config_phy()
1292 /* configure phy pads */ in sdhci_eic7700_config_phy()
1306 /* PHY strobe PAD setting (EMMC only) */ in sdhci_eic7700_config_phy()
1307 if ((host->mmc->caps2 & emmc_caps) == emmc_caps) { in sdhci_eic7700_config_phy()
1315 sdhci_eic7700_config_phy_delay(host, dwc_priv->delay_line); in sdhci_eic7700_config_phy()
1322 /* after reset all, the phy's config will be clear */ in sdhci_eic7700_reset()
1331 priv->reset = devm_reset_control_array_get_optional_exclusive(dev); in sdhci_eic7700_reset_init()
1332 if (IS_ERR(priv->reset)) { in sdhci_eic7700_reset_init()
1333 ret = PTR_ERR(priv->reset); in sdhci_eic7700_reset_init()
1338 ret = reset_control_assert(priv->reset); in sdhci_eic7700_reset_init()
1344 ret = reset_control_deassert(priv->reset); in sdhci_eic7700_reset_init()
1368 dev_warn(dev, "Invalid value %u for drive-impedance-ohms.\n", dr_ohm); in eic7700_convert_drive_impedance_ohm()
1376 int delay_min = -1; in sdhci_eic7700_delay_tuning()
1377 int delay_max = -1; in sdhci_eic7700_delay_tuning()
1379 int delay = 0; in sdhci_eic7700_delay_tuning() local
1385 ret = mmc_send_tuning(host->mmc, opcode, &cmd_error); in sdhci_eic7700_delay_tuning()
1387 host->ops->reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); in sdhci_eic7700_delay_tuning()
1389 if (delay_min != -1 && delay_max != -1) in sdhci_eic7700_delay_tuning()
1392 if (delay_min == -1) { in sdhci_eic7700_delay_tuning()
1401 if (delay_min == -1 && delay_max == -1) { in sdhci_eic7700_delay_tuning()
1402 pr_err("%s: delay code tuning failed!\n", mmc_hostname(host->mmc)); in sdhci_eic7700_delay_tuning()
1403 sdhci_eic7700_config_phy_delay(host, dwc_priv->delay_line); in sdhci_eic7700_delay_tuning()
1407 delay = (delay_min + delay_max) / 2; in sdhci_eic7700_delay_tuning()
1408 sdhci_eic7700_config_phy_delay(host, delay); in sdhci_eic7700_delay_tuning()
1418 int phase_code = -1; in sdhci_eic7700_phase_code_tuning()
1419 int code_range = -1; in sdhci_eic7700_phase_code_tuning()
1421 int code_min = -1; in sdhci_eic7700_phase_code_tuning()
1422 int code_max = -1; in sdhci_eic7700_phase_code_tuning()
1427 if ((host->mmc->caps2 & sd_caps) == sd_caps) in sdhci_eic7700_phase_code_tuning()
1432 sdhci_writew(host, i, priv->vendor_specific_area1 + DWCMSHC_AT_STAT); in sdhci_eic7700_phase_code_tuning()
1433 ret = mmc_send_tuning(host->mmc, opcode, &cmd_error); in sdhci_eic7700_phase_code_tuning()
1434 host->ops->reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); in sdhci_eic7700_phase_code_tuning()
1438 if (is_sd && code_min != -1 && code_max != -1) { in sdhci_eic7700_phase_code_tuning()
1439 if (code_max - code_min > code_range) { in sdhci_eic7700_phase_code_tuning()
1440 code_range = code_max - code_min; in sdhci_eic7700_phase_code_tuning()
1445 code_min = -1; in sdhci_eic7700_phase_code_tuning()
1446 code_max = -1; in sdhci_eic7700_phase_code_tuning()
1449 if (!is_sd && code_min != -1 && code_max != -1) in sdhci_eic7700_phase_code_tuning()
1453 if (code_min == -1) { in sdhci_eic7700_phase_code_tuning()
1460 if (code_max - code_min > code_range) { in sdhci_eic7700_phase_code_tuning()
1461 code_range = code_max - code_min; in sdhci_eic7700_phase_code_tuning()
1469 if ((is_sd && phase_code == -1) || in sdhci_eic7700_phase_code_tuning()
1470 (!is_sd && code_min == -1 && code_max == -1)) { in sdhci_eic7700_phase_code_tuning()
1471 pr_err("%s: phase code tuning failed!\n", mmc_hostname(host->mmc)); in sdhci_eic7700_phase_code_tuning()
1472 sdhci_writew(host, 0, priv->vendor_specific_area1 + DWCMSHC_AT_STAT); in sdhci_eic7700_phase_code_tuning()
1473 return -EIO; in sdhci_eic7700_phase_code_tuning()
1478 sdhci_writew(host, phase_code, priv->vendor_specific_area1 + DWCMSHC_AT_STAT); in sdhci_eic7700_phase_code_tuning()
1482 ret = mmc_send_tuning(host->mmc, opcode, &cmd_error); in sdhci_eic7700_phase_code_tuning()
1483 host->ops->reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); in sdhci_eic7700_phase_code_tuning()
1486 mmc_hostname(host->mmc), phase_code); in sdhci_eic7700_phase_code_tuning()
1507 val = sdhci_readl(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in sdhci_eic7700_executing_tuning()
1509 sdhci_writew(host, val, priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in sdhci_eic7700_executing_tuning()
1511 sdhci_writew(host, 0, priv->vendor_specific_area1 + DWCMSHC_AT_STAT); in sdhci_eic7700_executing_tuning()
1514 if ((host->mmc->caps2 & emmc_caps) == emmc_caps) { in sdhci_eic7700_executing_tuning()
1538 if (timing == MMC_TIMING_MMC_HS400 && host->clock == 200000000) { in sdhci_eic7700_set_uhs_signaling()
1539 val = sdhci_readl(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in sdhci_eic7700_set_uhs_signaling()
1541 /* 2-cycle latency */ in sdhci_eic7700_set_uhs_signaling()
1543 sdhci_writew(host, val, priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); in sdhci_eic7700_set_uhs_signaling()
1546 0x3, PHY_DLL_CNFG1_R);/* DLL wait cycle input */ in sdhci_eic7700_set_uhs_signaling()
1547 /* DLL jump step input */ in sdhci_eic7700_set_uhs_signaling()
1551 /* Sets the value of DLL's offset input */ in sdhci_eic7700_set_uhs_signaling()
1554 * Sets the value of DLL's olbt loadval input. Controls the Ibt in sdhci_eic7700_set_uhs_signaling()
1565 mmc_hostname(host->mmc), status); in sdhci_eic7700_set_uhs_signaling()
1572 mmc_hostname(host->mmc), status); in sdhci_eic7700_set_uhs_signaling()
1581 if ((host->mmc->caps2 & sd_caps) == sd_caps) in sdhci_eic7700_set_uhs_wrapper()
1598 return -ENOMEM; in eic7700_init()
1600 dwc_priv->priv = priv; in eic7700_init()
1602 ret = sdhci_eic7700_reset_init(dev, dwc_priv->priv); in eic7700_init()
1608 ret = of_parse_phandle_with_fixed_args(dev->of_node, "eswin,hsp-sp-csr", 2, 0, &args); in eic7700_init()
1610 dev_err(dev, "Fail to parse 'eswin,hsp-sp-csr' phandle (%d)\n", ret); in eic7700_init()
1616 dev_err(dev, "Failed to get regmap for 'eswin,hsp-sp-csr'\n"); in eic7700_init()
1631 * This signals that VDD is stable and permits transition to high-speed in eic7700_init()
1632 * modes (e.g., UHS-I). in eic7700_init()
1636 if ((host->mmc->caps2 & emmc_caps) == emmc_caps) in eic7700_init()
1637 dwc_priv->delay_line = PHY_DELAY_CODE_EMMC; in eic7700_init()
1639 dwc_priv->delay_line = PHY_DELAY_CODE_SD; in eic7700_init()
1641 if (!of_property_read_u32(dev->of_node, "eswin,drive-impedance-ohms", &val)) in eic7700_init()
1642 priv->drive_impedance = eic7700_convert_drive_impedance_ohm(dev, val); in eic7700_init()
1664 pr_err("%s: RST_N failed.\n", mmc_hostname(host->mmc)); in dwcmshc_bf3_hw_reset()
1840 host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD; in dwcmshc_cqhci_init()
1841 cq_host = devm_kzalloc(&pdev->dev, sizeof(*cq_host), GFP_KERNEL); in dwcmshc_cqhci_init()
1843 dev_err(mmc_dev(host->mmc), "Unable to setup CQE: not enough memory\n"); in dwcmshc_cqhci_init()
1856 dev_err(mmc_dev(host->mmc), "Unable to setup CQE: internal clock enable error\n"); in dwcmshc_cqhci_init()
1860 cq_host->mmio = host->ioaddr + priv->vendor_specific_area2; in dwcmshc_cqhci_init()
1861 if (pltfm_data->cqhci_host_ops) in dwcmshc_cqhci_init()
1862 cq_host->ops = pltfm_data->cqhci_host_ops; in dwcmshc_cqhci_init()
1864 cq_host->ops = &dwcmshc_cqhci_ops; in dwcmshc_cqhci_init()
1866 /* Enable using of 128-bit task descriptors */ in dwcmshc_cqhci_init()
1867 dma64 = host->flags & SDHCI_USE_64_BIT_DMA; in dwcmshc_cqhci_init()
1869 dev_dbg(mmc_dev(host->mmc), "128-bit task descriptors\n"); in dwcmshc_cqhci_init()
1870 cq_host->caps |= CQHCI_TASK_DESC_SZ_128; in dwcmshc_cqhci_init()
1872 err = cqhci_init(cq_host, host->mmc, dma64); in dwcmshc_cqhci_init()
1874 dev_err(mmc_dev(host->mmc), "Unable to setup CQE: error %d\n", err); in dwcmshc_cqhci_init()
1878 dev_dbg(mmc_dev(host->mmc), "CQE init done\n"); in dwcmshc_cqhci_init()
1888 devm_kfree(&pdev->dev, cq_host); in dwcmshc_cqhci_init()
1891 host->mmc->caps2 &= ~(MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD); in dwcmshc_cqhci_init()
1896 .compatible = "rockchip,rk3588-dwcmshc",
1900 .compatible = "rockchip,rk3576-dwcmshc",
1904 .compatible = "rockchip,rk3568-dwcmshc",
1908 .compatible = "snps,dwcmshc-sdhci",
1912 .compatible = "sophgo,cv1800b-dwcmshc",
1916 .compatible = "sophgo,sg2002-dwcmshc",
1920 .compatible = "thead,th1520-dwcmshc",
1924 .compatible = "sophgo,sg2042-dwcmshc",
1928 .compatible = "eswin,eic7700-dwcmshc",
1948 struct device *dev = &pdev->dev; in dwcmshc_probe()
1956 pltfm_data = device_get_match_data(&pdev->dev); in dwcmshc_probe()
1958 dev_err(&pdev->dev, "Error: No device match data found\n"); in dwcmshc_probe()
1959 return -ENODEV; in dwcmshc_probe()
1962 host = sdhci_pltfm_init(pdev, &pltfm_data->pdata, in dwcmshc_probe()
1973 host->adma_table_cnt += extra; in dwcmshc_probe()
1978 if (dev->of_node) { in dwcmshc_probe()
1979 pltfm_host->clk = devm_clk_get(dev, "core"); in dwcmshc_probe()
1980 if (IS_ERR(pltfm_host->clk)) in dwcmshc_probe()
1981 return dev_err_probe(dev, PTR_ERR(pltfm_host->clk), in dwcmshc_probe()
1984 err = clk_prepare_enable(pltfm_host->clk); in dwcmshc_probe()
1988 priv->bus_clk = devm_clk_get(dev, "bus"); in dwcmshc_probe()
1989 if (!IS_ERR(priv->bus_clk)) in dwcmshc_probe()
1990 clk_prepare_enable(priv->bus_clk); in dwcmshc_probe()
1993 err = mmc_of_parse(host->mmc); in dwcmshc_probe()
1999 priv->vendor_specific_area1 = in dwcmshc_probe()
2002 host->mmc_host_ops.request = dwcmshc_request; in dwcmshc_probe()
2003 host->mmc_host_ops.hs400_enhanced_strobe = dwcmshc_hs400_enhanced_strobe; in dwcmshc_probe()
2004 host->mmc_host_ops.execute_tuning = dwcmshc_execute_tuning; in dwcmshc_probe()
2006 if (pltfm_data->init) { in dwcmshc_probe()
2007 err = pltfm_data->init(&pdev->dev, host, priv); in dwcmshc_probe()
2021 host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; in dwcmshc_probe()
2032 if (device_property_read_bool(&pdev->dev, "supports-cqe")) { in dwcmshc_probe()
2033 priv->vendor_specific_area2 = in dwcmshc_probe()
2039 if (pltfm_data->postinit) in dwcmshc_probe()
2040 pltfm_data->postinit(host, priv); in dwcmshc_probe()
2056 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_probe()
2057 clk_disable_unprepare(priv->bus_clk); in dwcmshc_probe()
2058 clk_bulk_disable_unprepare(priv->num_other_clks, priv->other_clks); in dwcmshc_probe()
2079 pm_runtime_get_sync(&pdev->dev); in dwcmshc_remove()
2080 pm_runtime_disable(&pdev->dev); in dwcmshc_remove()
2081 pm_runtime_put_noidle(&pdev->dev); in dwcmshc_remove()
2087 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_remove()
2088 clk_disable_unprepare(priv->bus_clk); in dwcmshc_remove()
2089 clk_bulk_disable_unprepare(priv->num_other_clks, priv->other_clks); in dwcmshc_remove()
2101 if (host->mmc->caps2 & MMC_CAP2_CQE) { in dwcmshc_suspend()
2102 ret = cqhci_suspend(host->mmc); in dwcmshc_suspend()
2111 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_suspend()
2112 if (!IS_ERR(priv->bus_clk)) in dwcmshc_suspend()
2113 clk_disable_unprepare(priv->bus_clk); in dwcmshc_suspend()
2115 clk_bulk_disable_unprepare(priv->num_other_clks, priv->other_clks); in dwcmshc_suspend()
2127 ret = clk_prepare_enable(pltfm_host->clk); in dwcmshc_resume()
2131 if (!IS_ERR(priv->bus_clk)) { in dwcmshc_resume()
2132 ret = clk_prepare_enable(priv->bus_clk); in dwcmshc_resume()
2137 ret = clk_bulk_prepare_enable(priv->num_other_clks, priv->other_clks); in dwcmshc_resume()
2145 if (host->mmc->caps2 & MMC_CAP2_CQE) { in dwcmshc_resume()
2146 ret = cqhci_resume(host->mmc); in dwcmshc_resume()
2154 clk_bulk_disable_unprepare(priv->num_other_clks, priv->other_clks); in dwcmshc_resume()
2156 if (!IS_ERR(priv->bus_clk)) in dwcmshc_resume()
2157 clk_disable_unprepare(priv->bus_clk); in dwcmshc_resume()
2159 clk_disable_unprepare(pltfm_host->clk); in dwcmshc_resume()
2188 .name = "sdhci-dwcmshc",