Lines Matching +full:read +full:- +full:strobe +full:- +full:delay
1 // SPDX-License-Identifier: GPL-2.0
5 * derived from the OF-version.
14 #include <linux/delay.h>
23 #include <linux/mmc/slot-gpio.h>
28 #include "sdhci-cqhci.h"
29 #include "sdhci-pltfm.h"
30 #include "sdhci-esdhc.h"
85 #define ESDHC_TUNE_CTRL_MAX ((1 << 7) - 1)
91 /* strobe dll register */
148 * open ended multi-blk IO. Otherwise the TC INT wouldn't
170 * uSDHC: ADMA Length Mismatch Error occurs if the AHB read access is slow,
234 * struct esdhc_platform_data - platform data for esdhc on i.MX
247 unsigned int tuning_step; /* The delay cell steps in tuning procedure */
248 unsigned int tuning_start_tap; /* The start delay cell point in tuning procedure */
249 unsigned int strobe_dll_delay_target; /* The delay cell for strobe pad (read clock) */
250 unsigned int saved_tuning_delay_cell; /* save the value of tuning delay cell */
378 * the card init, but at this stage, mmc_host->card is not
394 { .compatible = "fsl,imx25-esdhc", .data = &esdhc_imx25_data, },
395 { .compatible = "fsl,imx35-esdhc", .data = &esdhc_imx35_data, },
396 { .compatible = "fsl,imx51-esdhc", .data = &esdhc_imx51_data, },
397 { .compatible = "fsl,imx53-esdhc", .data = &esdhc_imx53_data, },
398 { .compatible = "fsl,imx6sx-usdhc", .data = &usdhc_imx6sx_data, },
399 { .compatible = "fsl,imx6sl-usdhc", .data = &usdhc_imx6sl_data, },
400 { .compatible = "fsl,imx6sll-usdhc", .data = &usdhc_imx6sll_data, },
401 { .compatible = "fsl,imx6q-usdhc", .data = &usdhc_imx6q_data, },
402 { .compatible = "fsl,imx6ull-usdhc", .data = &usdhc_imx6ull_data, },
403 { .compatible = "fsl,imx7d-usdhc", .data = &usdhc_imx7d_data, },
404 { .compatible = "fsl,imx7ulp-usdhc", .data = &usdhc_imx7ulp_data, },
405 { .compatible = "fsl,imx8qxp-usdhc", .data = &usdhc_imx8qxp_data, },
406 { .compatible = "fsl,imx8mm-usdhc", .data = &usdhc_imx8mm_data, },
407 { .compatible = "fsl,imx94-usdhc", .data = &usdhc_imx95_data, },
408 { .compatible = "fsl,imx95-usdhc", .data = &usdhc_imx95_data, },
409 { .compatible = "fsl,imxrt1050-usdhc", .data = &usdhc_imxrt1050_data, },
410 { .compatible = "nxp,s32g2-usdhc", .data = &usdhc_s32g2_data, },
417 return data->socdata == &esdhc_imx25_data; in is_imx25_esdhc()
422 return data->socdata == &esdhc_imx53_data; in is_imx53_esdhc()
427 return !!(data->socdata->flags & ESDHC_FLAG_USDHC); in esdhc_is_usdhc()
432 void __iomem *base = host->ioaddr + (reg & ~0x3); in esdhc_clrset_le()
438 #define DRIVER_NAME "sdhci-esdhc-imx"
440 pr_err("%s: " DRIVER_NAME ": " f, mmc_hostname(host->mmc), ## x)
459 readw(host->ioaddr + ESDHC_DEBUG_SEL_AND_STATUS_REG)); in esdhc_dump_debug_regs()
471 ret = readl_poll_timeout(host->ioaddr + ESDHC_PRSSTAT, present_state, in esdhc_wait_for_card_clock_gate_off()
473 if (ret == -ETIMEDOUT) in esdhc_wait_for_card_clock_gate_off()
474 dev_warn(mmc_dev(host->mmc), "%s: card clock still not gate off in 100us!.\n", __func__); in esdhc_wait_for_card_clock_gate_off()
485 buswidth = USDHC_GET_BUSWIDTH(readl(host->ioaddr + SDHCI_HOST_CONTROL)); in usdhc_auto_tuning_mode_sel_and_en()
505 * DAT[1], and adjust the delay cell wrongly. in usdhc_auto_tuning_mode_sel_and_en()
510 if (imx_data->init_card_type == MMC_TYPE_SDIO) in usdhc_auto_tuning_mode_sel_and_en()
517 reg = readl(host->ioaddr + ESDHC_MIX_CTRL); in usdhc_auto_tuning_mode_sel_and_en()
519 writel(reg, host->ioaddr + ESDHC_MIX_CTRL); in usdhc_auto_tuning_mode_sel_and_en()
526 u32 val = readl(host->ioaddr + reg); in esdhc_readl_le()
532 /* move dat[0-3] bits */ in esdhc_readl_le()
539 /* ignore bit[0-15] as it stores cap_1 register val for mx6sl */ in esdhc_readl_le()
540 if (imx_data->socdata->flags & ESDHC_FLAG_HAVE_CAP1) in esdhc_readl_le()
558 if (imx_data->socdata->flags & ESDHC_FLAG_HAVE_CAP1) in esdhc_readl_le()
559 val = readl(host->ioaddr + SDHCI_CAPABILITIES) & 0xFFFF; in esdhc_readl_le()
572 if (IS_ERR_OR_NULL(imx_data->pins_100mhz)) in esdhc_readl_le()
574 if (IS_ERR_OR_NULL(imx_data->pins_200mhz)) in esdhc_readl_le()
596 if ((imx_data->multiblock_status == WAIT_FOR_INT) && in esdhc_readl_le()
599 writel(SDHCI_INT_RESPONSE, host->ioaddr + in esdhc_readl_le()
601 imx_data->multiblock_status = NO_CMD_PENDING; in esdhc_readl_le()
621 * and set D3CD bit will make eSDHC re-sample the card in esdhc_writel_le()
623 * re-sample it by the following steps. in esdhc_writel_le()
625 data = readl(host->ioaddr + SDHCI_HOST_CONTROL); in esdhc_writel_le()
627 writel(data, host->ioaddr + SDHCI_HOST_CONTROL); in esdhc_writel_le()
629 writel(data, host->ioaddr + SDHCI_HOST_CONTROL); in esdhc_writel_le()
638 if (unlikely((imx_data->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT) in esdhc_writel_le()
642 v = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writel_le()
644 writel(v, host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writel_le()
646 if (imx_data->multiblock_status == MULTIBLK_IN_PROCESS) in esdhc_writel_le()
651 writel(data, host->ioaddr + SDHCI_TRANSFER_MODE); in esdhc_writel_le()
652 imx_data->multiblock_status = WAIT_FOR_INT; in esdhc_writel_le()
656 writel(val, host->ioaddr + reg); in esdhc_writel_le()
678 val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_readw_le()
683 if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) in esdhc_readw_le()
684 val = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_readw_le()
685 else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) in esdhc_readw_le()
687 val = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS); in esdhc_readw_le()
702 u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_readw_le()
710 ret = readw(host->ioaddr + SDHCI_TRANSFER_MODE); in esdhc_readw_le()
716 return readw(host->ioaddr + reg); in esdhc_readw_le()
727 new_val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
732 writel(new_val, host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
737 new_val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
742 writel(new_val, host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
743 if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { in esdhc_writew_le()
744 u32 v = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS); in esdhc_writew_le()
755 writel(v, host->ioaddr + SDHCI_AUTO_CMD_STATUS); in esdhc_writew_le()
759 if ((imx_data->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT) in esdhc_writew_le()
760 && (host->cmd->opcode == SD_IO_RW_EXTENDED) in esdhc_writew_le()
761 && (host->cmd->data->blocks > 1) in esdhc_writew_le()
762 && (host->cmd->data->flags & MMC_DATA_READ)) { in esdhc_writew_le()
764 v = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
766 writel(v, host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
771 u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writew_le()
778 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writew_le()
784 m = readl(host->ioaddr + ESDHC_WTMK_LVL); in esdhc_writew_le()
807 writel(m, host->ioaddr + ESDHC_WTMK_LVL); in esdhc_writew_le()
813 imx_data->scratchpad = val; in esdhc_writew_le()
817 if (host->cmd->opcode == MMC_STOP_TRANSMISSION) in esdhc_writew_le()
820 if ((host->cmd->opcode == MMC_SET_BLOCK_COUNT) && in esdhc_writew_le()
821 (imx_data->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT)) in esdhc_writew_le()
822 imx_data->multiblock_status = MULTIBLK_IN_PROCESS; in esdhc_writew_le()
826 host->ioaddr + SDHCI_TRANSFER_MODE); in esdhc_writew_le()
828 writel(val << 16 | imx_data->scratchpad, in esdhc_writew_le()
829 host->ioaddr + SDHCI_TRANSFER_MODE); in esdhc_writew_le()
845 val = readl(host->ioaddr + reg); in esdhc_readb_le()
854 return readb(host->ioaddr + reg); in esdhc_readb_le()
899 new_val = readl(host->ioaddr + SDHCI_HOST_CONTROL); in esdhc_writeb_le()
924 new_val = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writeb_le()
926 host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writeb_le()
927 imx_data->is_ddr = 0; in esdhc_writeb_le()
945 return pltfm_host->clock; in esdhc_pltfm_get_max_clock()
952 return pltfm_host->clock / 256 / 16; in esdhc_pltfm_get_min_clock()
960 unsigned int host_clock = pltfm_host->clock; in esdhc_pltfm_set_clock()
961 int ddr_pre_div = imx_data->is_ddr ? 2 : 1; in esdhc_pltfm_set_clock()
968 val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_pltfm_set_clock()
970 host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_pltfm_set_clock()
975 host->mmc->actual_clock = 0; in esdhc_pltfm_set_clock()
985 val = readl(host->ioaddr + ESDHC_DLL_CTRL); in esdhc_pltfm_set_clock()
986 writel(val | BIT(10), host->ioaddr + ESDHC_DLL_CTRL); in esdhc_pltfm_set_clock()
987 temp = readl(host->ioaddr + ESDHC_DLL_CTRL); in esdhc_pltfm_set_clock()
988 writel(val, host->ioaddr + ESDHC_DLL_CTRL); in esdhc_pltfm_set_clock()
998 if ((imx_data->socdata->flags & ESDHC_FLAG_ERR010450) && in esdhc_pltfm_set_clock()
999 (!(host->quirks2 & SDHCI_QUIRK2_NO_1_8_V))) { in esdhc_pltfm_set_clock()
1002 max_clock = imx_data->is_ddr ? 45000000 : 150000000; in esdhc_pltfm_set_clock()
1014 host->mmc->actual_clock = host_clock / (div * pre_div * ddr_pre_div); in esdhc_pltfm_set_clock()
1015 dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", in esdhc_pltfm_set_clock()
1016 clock, host->mmc->actual_clock); in esdhc_pltfm_set_clock()
1019 div--; in esdhc_pltfm_set_clock()
1028 ret = readl_poll_timeout(host->ioaddr + ESDHC_PRSSTAT, temp, in esdhc_pltfm_set_clock()
1030 if (ret == -ETIMEDOUT) in esdhc_pltfm_set_clock()
1031 dev_warn(mmc_dev(host->mmc), "card clock still not stable in 100us!.\n"); in esdhc_pltfm_set_clock()
1034 val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_pltfm_set_clock()
1036 host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_pltfm_set_clock()
1045 struct esdhc_platform_data *boarddata = &imx_data->boarddata; in esdhc_pltfm_get_ro()
1047 switch (boarddata->wp_type) { in esdhc_pltfm_get_ro()
1049 return mmc_gpio_get_ro(host->mmc); in esdhc_pltfm_get_ro()
1051 return !(readl(host->ioaddr + SDHCI_PRESENT_STATE) & in esdhc_pltfm_get_ro()
1057 return -ENOSYS; in esdhc_pltfm_get_ro()
1089 ctrl = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_reset_tuning()
1091 if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) { in esdhc_reset_tuning()
1093 writel(ctrl, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_reset_tuning()
1094 writel(0, host->ioaddr + ESDHC_TUNE_CTRL_STATUS); in esdhc_reset_tuning()
1095 } else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { in esdhc_reset_tuning()
1096 writel(ctrl, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_reset_tuning()
1101 tuning_ctrl = readl(host->ioaddr + ESDHC_TUNING_CTRL); in esdhc_reset_tuning()
1104 writel(tuning_ctrl, host->ioaddr + ESDHC_TUNING_CTRL); in esdhc_reset_tuning()
1108 sys_ctrl = readl(host->ioaddr + ESDHC_SYSTEM_CONTROL); in esdhc_reset_tuning()
1110 writel(sys_ctrl, host->ioaddr + ESDHC_SYSTEM_CONTROL); in esdhc_reset_tuning()
1112 ctrl = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS); in esdhc_reset_tuning()
1115 writel(ctrl, host->ioaddr + SDHCI_AUTO_CMD_STATUS); in esdhc_reset_tuning()
1117 ret = readl_poll_timeout(host->ioaddr + SDHCI_AUTO_CMD_STATUS, in esdhc_reset_tuning()
1119 if (ret == -ETIMEDOUT) in esdhc_reset_tuning()
1120 dev_warn(mmc_dev(host->mmc), in esdhc_reset_tuning()
1127 ctrl = readl(host->ioaddr + SDHCI_INT_STATUS); in esdhc_reset_tuning()
1129 writel(ctrl, host->ioaddr + SDHCI_INT_STATUS); in esdhc_reset_tuning()
1140 imx_data->init_card_type = card->type; in usdhc_init_card()
1152 if (host->timing == MMC_TIMING_UHS_DDR50) in usdhc_execute_tuning()
1158 * correct delay cell. in usdhc_execute_tuning()
1163 if (!err && !host->tuning_err) in usdhc_execute_tuning()
1175 /* FIXME: delay a bit for card to be ready for next tuning due to errors */ in esdhc_prepare_tuning()
1180 ret = readb_poll_timeout(host->ioaddr + SDHCI_SOFTWARE_RESET, sw_rst, in esdhc_prepare_tuning()
1182 if (ret == -ETIMEDOUT) in esdhc_prepare_tuning()
1183 dev_warn(mmc_dev(host->mmc), in esdhc_prepare_tuning()
1186 reg = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_prepare_tuning()
1188 writel(reg, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_prepare_tuning()
1190 host->ioaddr + ESDHC_TUNE_CTRL_STATUS); in esdhc_prepare_tuning()
1191 dev_dbg(mmc_dev(host->mmc), in esdhc_prepare_tuning()
1192 "tuning with delay 0x%x ESDHC_TUNE_CTRL_STATUS 0x%x\n", in esdhc_prepare_tuning()
1193 val, readl(host->ioaddr + ESDHC_TUNE_CTRL_STATUS)); in esdhc_prepare_tuning()
1195 /* set RST_FIFO to reset the async FIFO, and wat it to self-clear */ in esdhc_prepare_tuning()
1196 sys_ctrl = readl(host->ioaddr + ESDHC_SYSTEM_CONTROL); in esdhc_prepare_tuning()
1198 writel(sys_ctrl, host->ioaddr + ESDHC_SYSTEM_CONTROL); in esdhc_prepare_tuning()
1199 ret = readl_poll_timeout(host->ioaddr + ESDHC_SYSTEM_CONTROL, sys_ctrl, in esdhc_prepare_tuning()
1201 if (ret == -ETIMEDOUT) in esdhc_prepare_tuning()
1202 dev_warn(mmc_dev(host->mmc), in esdhc_prepare_tuning()
1210 reg = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_post_tuning()
1212 writel(reg, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_post_tuning()
1216 * find the largest pass window, and use the average delay of this
1229 /* find the mininum delay first which can pass tuning */ in esdhc_executing_tuning()
1232 if (!mmc_send_tuning(host->mmc, opcode, NULL)) in esdhc_executing_tuning()
1237 /* find the maxinum delay which can not pass tuning */ in esdhc_executing_tuning()
1241 if (mmc_send_tuning(host->mmc, opcode, NULL)) { in esdhc_executing_tuning()
1242 max -= ESDHC_TUNE_CTRL_STEP; in esdhc_executing_tuning()
1248 win_length = max - min + 1; in esdhc_executing_tuning()
1260 /* use average delay to get the best timing */ in esdhc_executing_tuning()
1265 * adjust the delay according to tuning window, make preparation in esdhc_executing_tuning()
1266 * for the auto-tuning logic. According to hardware suggest, need in esdhc_executing_tuning()
1272 avg - ESDHC_AUTO_TUNING_WINDOW) | in esdhc_executing_tuning()
1278 writel(clk_tune_ctrl_status, host->ioaddr + ESDHC_TUNE_CTRL_STATUS); in esdhc_executing_tuning()
1279 ret = readl_poll_timeout(host->ioaddr + ESDHC_TUNE_CTRL_STATUS, temp, in esdhc_executing_tuning()
1283 if (ret == -ETIMEDOUT) in esdhc_executing_tuning()
1284 dev_warn(mmc_dev(host->mmc), in esdhc_executing_tuning()
1287 ret = mmc_send_tuning(host->mmc, opcode, NULL); in esdhc_executing_tuning()
1290 dev_dbg(mmc_dev(host->mmc), "tuning %s at 0x%x ret %d\n", in esdhc_executing_tuning()
1301 m = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_hs400_enhanced_strobe()
1302 if (ios->enhanced_strobe) in esdhc_hs400_enhanced_strobe()
1306 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_hs400_enhanced_strobe()
1316 dev_dbg(mmc_dev(host->mmc), "change pinctrl state for uhs %d\n", uhs); in esdhc_change_pinstate()
1318 if (IS_ERR(imx_data->pinctrl) || in esdhc_change_pinstate()
1319 IS_ERR(imx_data->pins_100mhz) || in esdhc_change_pinstate()
1320 IS_ERR(imx_data->pins_200mhz)) in esdhc_change_pinstate()
1321 return -EINVAL; in esdhc_change_pinstate()
1326 pinctrl = imx_data->pins_100mhz; in esdhc_change_pinstate()
1331 pinctrl = imx_data->pins_200mhz; in esdhc_change_pinstate()
1335 return pinctrl_select_default_state(mmc_dev(host->mmc)); in esdhc_change_pinstate()
1338 return pinctrl_select_state(imx_data->pinctrl, pinctrl); in esdhc_change_pinstate()
1346 * edge of data_strobe line. Due to the time delay between CLK line and
1347 * data_strobe line, if the delay time is larger than one clock cycle,
1348 * then CLK and data_strobe line will be misaligned, read error shows up.
1358 /* disable clock before enabling strobe dll */ in esdhc_set_strobe_dll()
1359 writel(readl(host->ioaddr + ESDHC_VENDOR_SPEC) & in esdhc_set_strobe_dll()
1361 host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_set_strobe_dll()
1364 /* force a reset on strobe dll */ in esdhc_set_strobe_dll()
1366 host->ioaddr + ESDHC_STROBE_DLL_CTRL); in esdhc_set_strobe_dll()
1367 /* clear the reset bit on strobe dll before any setting */ in esdhc_set_strobe_dll()
1368 writel(0, host->ioaddr + ESDHC_STROBE_DLL_CTRL); in esdhc_set_strobe_dll()
1371 * enable strobe dll ctrl and adjust the delay target in esdhc_set_strobe_dll()
1372 * for the uSDHC loopback read clock in esdhc_set_strobe_dll()
1374 if (imx_data->boarddata.strobe_dll_delay_target) in esdhc_set_strobe_dll()
1375 strobe_delay = imx_data->boarddata.strobe_dll_delay_target; in esdhc_set_strobe_dll()
1381 writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL); in esdhc_set_strobe_dll()
1384 ret = readl_poll_timeout(host->ioaddr + ESDHC_STROBE_DLL_STATUS, v, in esdhc_set_strobe_dll()
1386 if (ret == -ETIMEDOUT) in esdhc_set_strobe_dll()
1387 dev_warn(mmc_dev(host->mmc), in esdhc_set_strobe_dll()
1388 "warning! HS400 strobe DLL status REF/SLV not lock in 50us, STROBE DLL status is %x!\n", v); in esdhc_set_strobe_dll()
1396 struct esdhc_platform_data *boarddata = &imx_data->boarddata; in esdhc_set_uhs_signaling()
1399 m = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_set_uhs_signaling()
1401 imx_data->is_ddr = 0; in esdhc_set_uhs_signaling()
1410 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_set_uhs_signaling()
1415 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_set_uhs_signaling()
1416 imx_data->is_ddr = 1; in esdhc_set_uhs_signaling()
1417 if (boarddata->delay_line) { in esdhc_set_uhs_signaling()
1419 v = boarddata->delay_line << in esdhc_set_uhs_signaling()
1424 writel(v, host->ioaddr + ESDHC_DLL_CTRL); in esdhc_set_uhs_signaling()
1429 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_set_uhs_signaling()
1430 imx_data->is_ddr = 1; in esdhc_set_uhs_signaling()
1431 /* update clock after enable DDR for strobe DLL lock */ in esdhc_set_uhs_signaling()
1432 host->ops->set_clock(host, host->clock); in esdhc_set_uhs_signaling()
1441 if (!(imx_data->socdata->flags & ESDHC_FLAG_DUMMY_PAD) && in esdhc_set_uhs_signaling()
1449 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_set_uhs_signaling()
1458 sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); in esdhc_reset()
1459 sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); in esdhc_reset()
1479 cqhci_irq(host->mmc, intmask, cmd_error, data_error); in esdhc_cqhci_irq()
1487 /* eMMC spec requires minimum 1us, here delay between 1-10us */ in esdhc_hw_reset()
1491 /* eMMC spec requires minimum 200us, here delay between 200-300us */ in esdhc_hw_reset()
1527 struct cqhci_host *cq_host = host->mmc->cqe_private; in sdhci_esdhc_imx_hwinit()
1535 writel(ESDHC_WTMK_DEFAULT_VAL, host->ioaddr + ESDHC_WTMK_LVL); in sdhci_esdhc_imx_hwinit()
1548 writel(readl(host->ioaddr + SDHCI_HOST_CONTROL) in sdhci_esdhc_imx_hwinit()
1550 host->ioaddr + SDHCI_HOST_CONTROL); in sdhci_esdhc_imx_hwinit()
1556 if (!(imx_data->socdata->flags & ESDHC_FLAG_SKIP_ERR004536)) { in sdhci_esdhc_imx_hwinit()
1557 writel(readl(host->ioaddr + 0x6c) & ~BIT(7), in sdhci_esdhc_imx_hwinit()
1558 host->ioaddr + 0x6c); in sdhci_esdhc_imx_hwinit()
1561 /* disable DLL_CTRL delay line settings */ in sdhci_esdhc_imx_hwinit()
1562 writel(0x0, host->ioaddr + ESDHC_DLL_CTRL); in sdhci_esdhc_imx_hwinit()
1573 if (imx_data->socdata->flags & ESDHC_FLAG_CQHCI) { in sdhci_esdhc_imx_hwinit()
1574 tmp = readl(host->ioaddr + ESDHC_VEND_SPEC2); in sdhci_esdhc_imx_hwinit()
1576 writel(tmp, host->ioaddr + ESDHC_VEND_SPEC2); in sdhci_esdhc_imx_hwinit()
1578 host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ; in sdhci_esdhc_imx_hwinit()
1581 if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { in sdhci_esdhc_imx_hwinit()
1582 tmp = readl(host->ioaddr + ESDHC_TUNING_CTRL); in sdhci_esdhc_imx_hwinit()
1590 if (imx_data->boarddata.tuning_start_tap) in sdhci_esdhc_imx_hwinit()
1591 tmp |= imx_data->boarddata.tuning_start_tap; in sdhci_esdhc_imx_hwinit()
1595 if (imx_data->boarddata.tuning_step) { in sdhci_esdhc_imx_hwinit()
1596 tmp |= imx_data->boarddata.tuning_step in sdhci_esdhc_imx_hwinit()
1614 * add some delay after every tuning command, because in sdhci_esdhc_imx_hwinit()
1618 * the buffer read ready interrupt immediately. If usdhc send in sdhci_esdhc_imx_hwinit()
1624 writel(tmp, host->ioaddr + ESDHC_TUNING_CTRL); in sdhci_esdhc_imx_hwinit()
1625 } else if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) { in sdhci_esdhc_imx_hwinit()
1631 tmp = readl(host->ioaddr + ESDHC_TUNING_CTRL); in sdhci_esdhc_imx_hwinit()
1633 writel(tmp, host->ioaddr + ESDHC_TUNING_CTRL); in sdhci_esdhc_imx_hwinit()
1661 * SD/eMMC do not need this tuning save because it will re-init in sdhc_esdhc_tuning_save()
1663 * Here save the tuning delay value for SDIO device since it may in sdhc_esdhc_tuning_save()
1668 if (host->timing == MMC_TIMING_UHS_SDR50 || in sdhc_esdhc_tuning_save()
1669 host->timing == MMC_TIMING_UHS_SDR104) { in sdhc_esdhc_tuning_save()
1670 reg = readl(host->ioaddr + ESDHC_TUNE_CTRL_STATUS); in sdhc_esdhc_tuning_save()
1672 imx_data->boarddata.saved_tuning_delay_cell = reg; in sdhc_esdhc_tuning_save()
1682 if (host->timing == MMC_TIMING_UHS_SDR50 || in sdhc_esdhc_tuning_restore()
1683 host->timing == MMC_TIMING_UHS_SDR104) { in sdhc_esdhc_tuning_restore()
1685 * restore the tuning delay value actually is a in sdhc_esdhc_tuning_restore()
1689 * when trigger re-tuning. in sdhc_esdhc_tuning_restore()
1691 reg = readl(host->ioaddr + ESDHC_TUNING_CTRL); in sdhc_esdhc_tuning_restore()
1693 writel(reg, host->ioaddr + ESDHC_TUNING_CTRL); in sdhc_esdhc_tuning_restore()
1695 reg = readl(host->ioaddr + ESDHC_MIX_CTRL); in sdhc_esdhc_tuning_restore()
1697 if (!(imx_data->socdata->flags & ESDHC_FLAG_DUMMY_PAD)) in sdhc_esdhc_tuning_restore()
1699 writel(reg, host->ioaddr + ESDHC_MIX_CTRL); in sdhc_esdhc_tuning_restore()
1702 imx_data->boarddata.saved_tuning_delay_cell) | in sdhc_esdhc_tuning_restore()
1707 host->ioaddr + ESDHC_TUNE_CTRL_STATUS); in sdhc_esdhc_tuning_restore()
1715 struct cqhci_host *cq_host = mmc->cqe_private; in esdhc_cqe_enable()
1721 * CQE gets stuck if it sees Buffer Read Enable bit set, which can be in esdhc_cqe_enable()
1728 if (count-- == 0) { in esdhc_cqe_enable()
1729 dev_warn(mmc_dev(host->mmc), in esdhc_cqe_enable()
1730 "CQE may get stuck because the Buffer Read Enable bit is set\n"); in esdhc_cqe_enable()
1742 if (host->flags & SDHCI_REQ_USE_DMA) in esdhc_cqe_enable()
1744 if (!(host->quirks2 & SDHCI_QUIRK2_SUPPORT_SINGLE)) in esdhc_cqe_enable()
1756 dev_err(mmc_dev(host->mmc), in esdhc_cqe_enable()
1779 struct device_node *np = pdev->dev.of_node; in sdhci_esdhc_imx_probe_dt()
1780 struct esdhc_platform_data *boarddata = &imx_data->boarddata; in sdhci_esdhc_imx_probe_dt()
1783 if (of_property_read_bool(np, "fsl,wp-controller")) in sdhci_esdhc_imx_probe_dt()
1784 boarddata->wp_type = ESDHC_WP_CONTROLLER; in sdhci_esdhc_imx_probe_dt()
1791 if (of_property_present(np, "wp-gpios")) in sdhci_esdhc_imx_probe_dt()
1792 boarddata->wp_type = ESDHC_WP_GPIO; in sdhci_esdhc_imx_probe_dt()
1794 of_property_read_u32(np, "fsl,tuning-step", &boarddata->tuning_step); in sdhci_esdhc_imx_probe_dt()
1795 of_property_read_u32(np, "fsl,tuning-start-tap", in sdhci_esdhc_imx_probe_dt()
1796 &boarddata->tuning_start_tap); in sdhci_esdhc_imx_probe_dt()
1798 of_property_read_u32(np, "fsl,strobe-dll-delay-target", in sdhci_esdhc_imx_probe_dt()
1799 &boarddata->strobe_dll_delay_target); in sdhci_esdhc_imx_probe_dt()
1800 if (of_property_read_bool(np, "no-1-8-v")) in sdhci_esdhc_imx_probe_dt()
1801 host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V; in sdhci_esdhc_imx_probe_dt()
1803 if (of_property_read_u32(np, "fsl,delay-line", &boarddata->delay_line)) in sdhci_esdhc_imx_probe_dt()
1804 boarddata->delay_line = 0; in sdhci_esdhc_imx_probe_dt()
1806 mmc_of_parse_voltage(host->mmc, &host->ocr_mask); in sdhci_esdhc_imx_probe_dt()
1808 if (esdhc_is_usdhc(imx_data) && !IS_ERR(imx_data->pinctrl)) { in sdhci_esdhc_imx_probe_dt()
1809 imx_data->pins_100mhz = pinctrl_lookup_state(imx_data->pinctrl, in sdhci_esdhc_imx_probe_dt()
1811 imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl, in sdhci_esdhc_imx_probe_dt()
1816 ret = mmc_of_parse(host->mmc); in sdhci_esdhc_imx_probe_dt()
1821 if (!(host->mmc->caps & MMC_CAP_8_BIT_DATA)) in sdhci_esdhc_imx_probe_dt()
1822 host->mmc->caps2 &= ~(MMC_CAP2_HS400 | MMC_CAP2_HS400_ES); in sdhci_esdhc_imx_probe_dt()
1824 if (mmc_gpio_get_cd(host->mmc) >= 0) in sdhci_esdhc_imx_probe_dt()
1825 host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; in sdhci_esdhc_imx_probe_dt()
1847 imx_data->socdata = device_get_match_data(&pdev->dev); in sdhci_esdhc_imx_probe()
1849 host->quirks |= imx_data->socdata->quirks; in sdhci_esdhc_imx_probe()
1850 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_imx_probe()
1851 cpu_latency_qos_add_request(&imx_data->pm_qos_req, 0); in sdhci_esdhc_imx_probe()
1853 imx_data->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); in sdhci_esdhc_imx_probe()
1854 if (IS_ERR(imx_data->clk_ipg)) { in sdhci_esdhc_imx_probe()
1855 err = PTR_ERR(imx_data->clk_ipg); in sdhci_esdhc_imx_probe()
1859 imx_data->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); in sdhci_esdhc_imx_probe()
1860 if (IS_ERR(imx_data->clk_ahb)) { in sdhci_esdhc_imx_probe()
1861 err = PTR_ERR(imx_data->clk_ahb); in sdhci_esdhc_imx_probe()
1865 imx_data->clk_per = devm_clk_get(&pdev->dev, "per"); in sdhci_esdhc_imx_probe()
1866 if (IS_ERR(imx_data->clk_per)) { in sdhci_esdhc_imx_probe()
1867 err = PTR_ERR(imx_data->clk_per); in sdhci_esdhc_imx_probe()
1871 pltfm_host->clk = imx_data->clk_per; in sdhci_esdhc_imx_probe()
1872 err = clk_prepare_enable(imx_data->clk_per); in sdhci_esdhc_imx_probe()
1875 err = clk_prepare_enable(imx_data->clk_ipg); in sdhci_esdhc_imx_probe()
1878 err = clk_prepare_enable(imx_data->clk_ahb); in sdhci_esdhc_imx_probe()
1882 pltfm_host->clock = clk_get_rate(pltfm_host->clk); in sdhci_esdhc_imx_probe()
1883 if (!pltfm_host->clock) { in sdhci_esdhc_imx_probe()
1884 dev_err(mmc_dev(host->mmc), "could not get clk rate\n"); in sdhci_esdhc_imx_probe()
1885 err = -EINVAL; in sdhci_esdhc_imx_probe()
1889 imx_data->pinctrl = devm_pinctrl_get(&pdev->dev); in sdhci_esdhc_imx_probe()
1890 if (IS_ERR(imx_data->pinctrl)) in sdhci_esdhc_imx_probe()
1891 dev_warn(mmc_dev(host->mmc), "could not get pinctrl\n"); in sdhci_esdhc_imx_probe()
1894 host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN; in sdhci_esdhc_imx_probe()
1895 host->mmc->caps |= MMC_CAP_1_8V_DDR | MMC_CAP_3_3V_DDR; in sdhci_esdhc_imx_probe()
1898 if (!(imx_data->socdata->flags & ESDHC_FLAG_SKIP_CD_WAKE)) in sdhci_esdhc_imx_probe()
1899 host->mmc->caps |= MMC_CAP_CD_WAKE; in sdhci_esdhc_imx_probe()
1901 if (!(imx_data->socdata->flags & ESDHC_FLAG_HS200)) in sdhci_esdhc_imx_probe()
1902 host->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200; in sdhci_esdhc_imx_probe()
1905 writel(0x0, host->ioaddr + ESDHC_MIX_CTRL); in sdhci_esdhc_imx_probe()
1906 writel(0x0, host->ioaddr + SDHCI_AUTO_CMD_STATUS); in sdhci_esdhc_imx_probe()
1907 writel(0x0, host->ioaddr + ESDHC_TUNE_CTRL_STATUS); in sdhci_esdhc_imx_probe()
1913 host->mmc_host_ops.execute_tuning = usdhc_execute_tuning; in sdhci_esdhc_imx_probe()
1919 host->mmc_host_ops.init_card = usdhc_init_card; in sdhci_esdhc_imx_probe()
1921 host->max_timeout_count = 0xF; in sdhci_esdhc_imx_probe()
1924 if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) in sdhci_esdhc_imx_probe()
1928 if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536) in sdhci_esdhc_imx_probe()
1929 host->quirks |= SDHCI_QUIRK_BROKEN_ADMA; in sdhci_esdhc_imx_probe()
1931 if (imx_data->socdata->flags & ESDHC_FLAG_HS400) in sdhci_esdhc_imx_probe()
1932 host->mmc->caps2 |= MMC_CAP2_HS400; in sdhci_esdhc_imx_probe()
1934 if (imx_data->socdata->flags & ESDHC_FLAG_BROKEN_AUTO_CMD23) in sdhci_esdhc_imx_probe()
1935 host->quirks2 |= SDHCI_QUIRK2_ACMD23_BROKEN; in sdhci_esdhc_imx_probe()
1937 if (imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) { in sdhci_esdhc_imx_probe()
1938 host->mmc->caps2 |= MMC_CAP2_HS400_ES; in sdhci_esdhc_imx_probe()
1939 host->mmc_host_ops.hs400_enhanced_strobe = in sdhci_esdhc_imx_probe()
1943 if (imx_data->socdata->flags & ESDHC_FLAG_CQHCI) { in sdhci_esdhc_imx_probe()
1944 host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD; in sdhci_esdhc_imx_probe()
1945 cq_host = devm_kzalloc(&pdev->dev, sizeof(*cq_host), GFP_KERNEL); in sdhci_esdhc_imx_probe()
1947 err = -ENOMEM; in sdhci_esdhc_imx_probe()
1951 cq_host->mmio = host->ioaddr + ESDHC_CQHCI_ADDR_OFFSET; in sdhci_esdhc_imx_probe()
1952 cq_host->ops = &esdhc_cqhci_ops; in sdhci_esdhc_imx_probe()
1954 err = cqhci_init(cq_host, host->mmc, false); in sdhci_esdhc_imx_probe()
1973 if ((host->mmc->pm_caps & MMC_PM_KEEP_POWER) && in sdhci_esdhc_imx_probe()
1974 (host->mmc->pm_caps & MMC_PM_WAKE_SDIO_IRQ)) in sdhci_esdhc_imx_probe()
1975 device_set_wakeup_capable(&pdev->dev, true); in sdhci_esdhc_imx_probe()
1977 pm_runtime_set_active(&pdev->dev); in sdhci_esdhc_imx_probe()
1978 pm_runtime_set_autosuspend_delay(&pdev->dev, 50); in sdhci_esdhc_imx_probe()
1979 pm_runtime_use_autosuspend(&pdev->dev); in sdhci_esdhc_imx_probe()
1980 pm_suspend_ignore_children(&pdev->dev, 1); in sdhci_esdhc_imx_probe()
1981 pm_runtime_enable(&pdev->dev); in sdhci_esdhc_imx_probe()
1986 clk_disable_unprepare(imx_data->clk_ahb); in sdhci_esdhc_imx_probe()
1988 clk_disable_unprepare(imx_data->clk_ipg); in sdhci_esdhc_imx_probe()
1990 clk_disable_unprepare(imx_data->clk_per); in sdhci_esdhc_imx_probe()
1992 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_imx_probe()
1993 cpu_latency_qos_remove_request(&imx_data->pm_qos_req); in sdhci_esdhc_imx_probe()
2004 pm_runtime_get_sync(&pdev->dev); in sdhci_esdhc_imx_remove()
2005 dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff); in sdhci_esdhc_imx_remove()
2006 pm_runtime_disable(&pdev->dev); in sdhci_esdhc_imx_remove()
2007 pm_runtime_put_noidle(&pdev->dev); in sdhci_esdhc_imx_remove()
2011 clk_disable_unprepare(imx_data->clk_per); in sdhci_esdhc_imx_remove()
2012 clk_disable_unprepare(imx_data->clk_ipg); in sdhci_esdhc_imx_remove()
2013 clk_disable_unprepare(imx_data->clk_ahb); in sdhci_esdhc_imx_remove()
2015 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_imx_remove()
2016 cpu_latency_qos_remove_request(&imx_data->pm_qos_req); in sdhci_esdhc_imx_remove()
2032 * invoke its ->runtime_resume callback (needs_force_resume = 1). in sdhci_esdhc_suspend()
2036 if ((imx_data->socdata->flags & ESDHC_FLAG_STATE_LOST_IN_LPMODE) && in sdhci_esdhc_suspend()
2037 (host->tuning_mode != SDHCI_TUNING_MODE_1)) { in sdhci_esdhc_suspend()
2038 mmc_retune_timer_stop(host->mmc); in sdhci_esdhc_suspend()
2039 mmc_retune_needed(host->mmc); in sdhci_esdhc_suspend()
2044 * to save the tuning delay value just in case the usdhc in sdhci_esdhc_suspend()
2047 if (mmc_card_keep_power(host->mmc) && mmc_card_wake_sdio_irq(host->mmc) && in sdhci_esdhc_suspend()
2053 disable_irq(host->irq); in sdhci_esdhc_suspend()
2071 ret = mmc_gpio_set_cd_wake(host->mmc, true); in sdhci_esdhc_suspend()
2075 * uSDHC IP supports in-band SDIO wakeup even without clock. in sdhci_esdhc_suspend()
2091 ret = mmc_gpio_set_cd_wake(host->mmc, false); in sdhci_esdhc_resume()
2095 /* re-initialize hw state in case it's lost in low power mode */ in sdhci_esdhc_resume()
2098 if (host->irq_wake_enabled) { in sdhci_esdhc_resume()
2100 enable_irq(host->irq); in sdhci_esdhc_resume()
2104 * restore the saved tuning delay value for the device which keep in sdhci_esdhc_resume()
2107 if (mmc_card_keep_power(host->mmc) && mmc_card_wake_sdio_irq(host->mmc) && in sdhci_esdhc_resume()
2125 if (host->mmc->caps2 & MMC_CAP2_CQE) { in sdhci_esdhc_runtime_suspend()
2126 ret = cqhci_suspend(host->mmc); in sdhci_esdhc_runtime_suspend()
2133 if (host->tuning_mode != SDHCI_TUNING_MODE_3) in sdhci_esdhc_runtime_suspend()
2134 mmc_retune_needed(host->mmc); in sdhci_esdhc_runtime_suspend()
2136 imx_data->actual_clock = host->mmc->actual_clock; in sdhci_esdhc_runtime_suspend()
2138 clk_disable_unprepare(imx_data->clk_per); in sdhci_esdhc_runtime_suspend()
2139 clk_disable_unprepare(imx_data->clk_ipg); in sdhci_esdhc_runtime_suspend()
2140 clk_disable_unprepare(imx_data->clk_ahb); in sdhci_esdhc_runtime_suspend()
2142 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_runtime_suspend()
2143 cpu_latency_qos_remove_request(&imx_data->pm_qos_req); in sdhci_esdhc_runtime_suspend()
2155 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_runtime_resume()
2156 cpu_latency_qos_add_request(&imx_data->pm_qos_req, 0); in sdhci_esdhc_runtime_resume()
2158 if (imx_data->socdata->flags & ESDHC_FLAG_CLK_RATE_LOST_IN_PM_RUNTIME) in sdhci_esdhc_runtime_resume()
2159 clk_set_rate(imx_data->clk_per, pltfm_host->clock); in sdhci_esdhc_runtime_resume()
2161 err = clk_prepare_enable(imx_data->clk_ahb); in sdhci_esdhc_runtime_resume()
2165 err = clk_prepare_enable(imx_data->clk_per); in sdhci_esdhc_runtime_resume()
2169 err = clk_prepare_enable(imx_data->clk_ipg); in sdhci_esdhc_runtime_resume()
2173 esdhc_pltfm_set_clock(host, imx_data->actual_clock); in sdhci_esdhc_runtime_resume()
2177 if (host->mmc->caps2 & MMC_CAP2_CQE) in sdhci_esdhc_runtime_resume()
2178 err = cqhci_resume(host->mmc); in sdhci_esdhc_runtime_resume()
2183 clk_disable_unprepare(imx_data->clk_per); in sdhci_esdhc_runtime_resume()
2185 clk_disable_unprepare(imx_data->clk_ahb); in sdhci_esdhc_runtime_resume()
2187 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_runtime_resume()
2188 cpu_latency_qos_remove_request(&imx_data->pm_qos_req); in sdhci_esdhc_runtime_resume()
2201 .name = "sdhci-esdhc-imx",