Lines Matching +full:mmc +full:- +full:card

1 // SPDX-License-Identifier: GPL-2.0
5 * derived from the OF-version.
20 #include <linux/mmc/host.h>
21 #include <linux/mmc/mmc.h>
22 #include <linux/mmc/sdio.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)
148 * open ended multi-blk IO. Otherwise the TC INT wouldn't
171 * when reading data from the card
182 * uSDHC: At 1.8V due to the I/O timing limit, for SDR mode, SD card
183 * clock can't exceed 150MHz, for DDR mode, SD card clock can't exceed 45MHz.
219 ESDHC_WP_CONTROLLER, /* mmc controller internal WP */
225 ESDHC_CD_CONTROLLER, /* mmc controller internal CD */
227 ESDHC_CD_PERMANENT, /* no CD, card permanently wired to host */
231 * struct esdhc_platform_data - platform data for esdhc on i.MX
365 * register setting. Driver has to recognize card type during
366 * the card init, but at this stage, mmc_host->card is not
367 * available. So involve this field to save the card type
368 * during card init through usdhc_init_card().
382 { .compatible = "fsl,imx25-esdhc", .data = &esdhc_imx25_data, },
383 { .compatible = "fsl,imx35-esdhc", .data = &esdhc_imx35_data, },
384 { .compatible = "fsl,imx51-esdhc", .data = &esdhc_imx51_data, },
385 { .compatible = "fsl,imx53-esdhc", .data = &esdhc_imx53_data, },
386 { .compatible = "fsl,imx6sx-usdhc", .data = &usdhc_imx6sx_data, },
387 { .compatible = "fsl,imx6sl-usdhc", .data = &usdhc_imx6sl_data, },
388 { .compatible = "fsl,imx6sll-usdhc", .data = &usdhc_imx6sll_data, },
389 { .compatible = "fsl,imx6q-usdhc", .data = &usdhc_imx6q_data, },
390 { .compatible = "fsl,imx6ull-usdhc", .data = &usdhc_imx6ull_data, },
391 { .compatible = "fsl,imx7d-usdhc", .data = &usdhc_imx7d_data, },
392 { .compatible = "fsl,imx7ulp-usdhc", .data = &usdhc_imx7ulp_data, },
393 { .compatible = "fsl,imx8qxp-usdhc", .data = &usdhc_imx8qxp_data, },
394 { .compatible = "fsl,imx8mm-usdhc", .data = &usdhc_imx8mm_data, },
395 { .compatible = "fsl,imxrt1050-usdhc", .data = &usdhc_imxrt1050_data, },
396 { .compatible = "nxp,s32g2-usdhc", .data = &usdhc_s32g2_data, },
403 return data->socdata == &esdhc_imx25_data; in is_imx25_esdhc()
408 return data->socdata == &esdhc_imx53_data; in is_imx53_esdhc()
413 return !!(data->socdata->flags & ESDHC_FLAG_USDHC); in esdhc_is_usdhc()
418 void __iomem *base = host->ioaddr + (reg & ~0x3); in esdhc_clrset_le()
424 #define DRIVER_NAME "sdhci-esdhc-imx"
426 pr_err("%s: " DRIVER_NAME ": " f, mmc_hostname(host->mmc), ## x)
445 readw(host->ioaddr + ESDHC_DEBUG_SEL_AND_STATUS_REG)); in esdhc_dump_debug_regs()
457 ret = readl_poll_timeout(host->ioaddr + ESDHC_PRSSTAT, present_state, in esdhc_wait_for_card_clock_gate_off()
459 if (ret == -ETIMEDOUT) in esdhc_wait_for_card_clock_gate_off()
460 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()
471 buswidth = USDHC_GET_BUSWIDTH(readl(host->ioaddr + SDHCI_HOST_CONTROL)); in usdhc_auto_tuning_mode_sel_and_en()
496 if (imx_data->init_card_type == MMC_TYPE_SDIO) in usdhc_auto_tuning_mode_sel_and_en()
503 reg = readl(host->ioaddr + ESDHC_MIX_CTRL); in usdhc_auto_tuning_mode_sel_and_en()
505 writel(reg, host->ioaddr + ESDHC_MIX_CTRL); in usdhc_auto_tuning_mode_sel_and_en()
512 u32 val = readl(host->ioaddr + reg); in esdhc_readl_le()
518 /* move dat[0-3] bits */ in esdhc_readl_le()
525 /* ignore bit[0-15] as it stores cap_1 register val for mx6sl */ in esdhc_readl_le()
526 if (imx_data->socdata->flags & ESDHC_FLAG_HAVE_CAP1) in esdhc_readl_le()
544 if (imx_data->socdata->flags & ESDHC_FLAG_HAVE_CAP1) in esdhc_readl_le()
545 val = readl(host->ioaddr + SDHCI_CAPABILITIES) & 0xFFFF; in esdhc_readl_le()
558 if (IS_ERR_OR_NULL(imx_data->pins_100mhz)) in esdhc_readl_le()
560 if (IS_ERR_OR_NULL(imx_data->pins_200mhz)) in esdhc_readl_le()
582 if ((imx_data->multiblock_status == WAIT_FOR_INT) && in esdhc_readl_le()
585 writel(SDHCI_INT_RESPONSE, host->ioaddr + in esdhc_readl_le()
587 imx_data->multiblock_status = NO_CMD_PENDING; in esdhc_readl_le()
605 * card interrupt. This is an eSDHC controller problem in esdhc_writel_le()
607 * and set D3CD bit will make eSDHC re-sample the card in esdhc_writel_le()
608 * interrupt. In case a card interrupt was lost, in esdhc_writel_le()
609 * re-sample it by the following steps. in esdhc_writel_le()
611 data = readl(host->ioaddr + SDHCI_HOST_CONTROL); in esdhc_writel_le()
613 writel(data, host->ioaddr + SDHCI_HOST_CONTROL); in esdhc_writel_le()
615 writel(data, host->ioaddr + SDHCI_HOST_CONTROL); in esdhc_writel_le()
624 if (unlikely((imx_data->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT) in esdhc_writel_le()
628 v = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writel_le()
630 writel(v, host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writel_le()
632 if (imx_data->multiblock_status == MULTIBLK_IN_PROCESS) in esdhc_writel_le()
637 writel(data, host->ioaddr + SDHCI_TRANSFER_MODE); in esdhc_writel_le()
638 imx_data->multiblock_status = WAIT_FOR_INT; in esdhc_writel_le()
642 writel(val, host->ioaddr + reg); in esdhc_writel_le()
664 val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_readw_le()
669 if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) in esdhc_readw_le()
670 val = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_readw_le()
671 else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) in esdhc_readw_le()
673 val = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS); in esdhc_readw_le()
688 u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_readw_le()
696 ret = readw(host->ioaddr + SDHCI_TRANSFER_MODE); in esdhc_readw_le()
702 return readw(host->ioaddr + reg); in esdhc_readw_le()
713 new_val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
718 writel(new_val, host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
723 new_val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
728 writel(new_val, host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
729 if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { in esdhc_writew_le()
730 u32 v = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS); in esdhc_writew_le()
731 u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writew_le()
746 writel(v, host->ioaddr + SDHCI_AUTO_CMD_STATUS); in esdhc_writew_le()
747 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writew_le()
751 if ((imx_data->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT) in esdhc_writew_le()
752 && (host->cmd->opcode == SD_IO_RW_EXTENDED) in esdhc_writew_le()
753 && (host->cmd->data->blocks > 1) in esdhc_writew_le()
754 && (host->cmd->data->flags & MMC_DATA_READ)) { in esdhc_writew_le()
756 v = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
758 writel(v, host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
763 u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writew_le()
770 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writew_le()
776 m = readl(host->ioaddr + ESDHC_WTMK_LVL); in esdhc_writew_le()
799 writel(m, host->ioaddr + ESDHC_WTMK_LVL); in esdhc_writew_le()
805 imx_data->scratchpad = val; in esdhc_writew_le()
809 if (host->cmd->opcode == MMC_STOP_TRANSMISSION) in esdhc_writew_le()
812 if ((host->cmd->opcode == MMC_SET_BLOCK_COUNT) && in esdhc_writew_le()
813 (imx_data->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT)) in esdhc_writew_le()
814 imx_data->multiblock_status = MULTIBLK_IN_PROCESS; in esdhc_writew_le()
818 host->ioaddr + SDHCI_TRANSFER_MODE); in esdhc_writew_le()
820 writel(val << 16 | imx_data->scratchpad, in esdhc_writew_le()
821 host->ioaddr + SDHCI_TRANSFER_MODE); in esdhc_writew_le()
837 val = readl(host->ioaddr + reg); in esdhc_readb_le()
846 return readb(host->ioaddr + reg); in esdhc_readb_le()
891 new_val = readl(host->ioaddr + SDHCI_HOST_CONTROL); in esdhc_writeb_le()
900 * tells that software reset should not affect card in esdhc_writeb_le()
903 * will stop those clocks that card detection circuit in esdhc_writeb_le()
905 * back to keep card detection circuit functional. in esdhc_writeb_le()
916 new_val = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writeb_le()
918 host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writeb_le()
919 imx_data->is_ddr = 0; in esdhc_writeb_le()
937 return pltfm_host->clock; in esdhc_pltfm_get_max_clock()
944 return pltfm_host->clock / 256 / 16; in esdhc_pltfm_get_min_clock()
952 unsigned int host_clock = pltfm_host->clock; in esdhc_pltfm_set_clock()
953 int ddr_pre_div = imx_data->is_ddr ? 2 : 1; in esdhc_pltfm_set_clock()
960 val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_pltfm_set_clock()
962 host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_pltfm_set_clock()
967 host->mmc->actual_clock = 0; in esdhc_pltfm_set_clock()
977 val = readl(host->ioaddr + ESDHC_DLL_CTRL); in esdhc_pltfm_set_clock()
978 writel(val | BIT(10), host->ioaddr + ESDHC_DLL_CTRL); in esdhc_pltfm_set_clock()
979 temp = readl(host->ioaddr + ESDHC_DLL_CTRL); in esdhc_pltfm_set_clock()
980 writel(val, host->ioaddr + ESDHC_DLL_CTRL); in esdhc_pltfm_set_clock()
990 if ((imx_data->socdata->flags & ESDHC_FLAG_ERR010450) && in esdhc_pltfm_set_clock()
991 (!(host->quirks2 & SDHCI_QUIRK2_NO_1_8_V))) { in esdhc_pltfm_set_clock()
994 max_clock = imx_data->is_ddr ? 45000000 : 150000000; in esdhc_pltfm_set_clock()
1006 host->mmc->actual_clock = host_clock / (div * pre_div * ddr_pre_div); in esdhc_pltfm_set_clock()
1007 dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", in esdhc_pltfm_set_clock()
1008 clock, host->mmc->actual_clock); in esdhc_pltfm_set_clock()
1011 div--; in esdhc_pltfm_set_clock()
1019 /* need to wait the bit 3 of the PRSSTAT to be set, make sure card clock is stable */ in esdhc_pltfm_set_clock()
1020 ret = readl_poll_timeout(host->ioaddr + ESDHC_PRSSTAT, temp, in esdhc_pltfm_set_clock()
1022 if (ret == -ETIMEDOUT) in esdhc_pltfm_set_clock()
1023 dev_warn(mmc_dev(host->mmc), "card clock still not stable in 100us!.\n"); in esdhc_pltfm_set_clock()
1026 val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_pltfm_set_clock()
1028 host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_pltfm_set_clock()
1037 struct esdhc_platform_data *boarddata = &imx_data->boarddata; in esdhc_pltfm_get_ro()
1039 switch (boarddata->wp_type) { in esdhc_pltfm_get_ro()
1041 return mmc_gpio_get_ro(host->mmc); in esdhc_pltfm_get_ro()
1043 return !(readl(host->ioaddr + SDHCI_PRESENT_STATE) & in esdhc_pltfm_get_ro()
1049 return -ENOSYS; in esdhc_pltfm_get_ro()
1081 ctrl = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_reset_tuning()
1083 if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) { in esdhc_reset_tuning()
1086 writel(ctrl, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_reset_tuning()
1087 writel(0, host->ioaddr + ESDHC_TUNE_CTRL_STATUS); in esdhc_reset_tuning()
1088 } else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { in esdhc_reset_tuning()
1089 writel(ctrl, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_reset_tuning()
1094 tuning_ctrl = readl(host->ioaddr + ESDHC_TUNING_CTRL); in esdhc_reset_tuning()
1097 writel(tuning_ctrl, host->ioaddr + ESDHC_TUNING_CTRL); in esdhc_reset_tuning()
1101 sys_ctrl = readl(host->ioaddr + ESDHC_SYSTEM_CONTROL); in esdhc_reset_tuning()
1103 writel(sys_ctrl, host->ioaddr + ESDHC_SYSTEM_CONTROL); in esdhc_reset_tuning()
1105 ctrl = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS); in esdhc_reset_tuning()
1108 writel(ctrl, host->ioaddr + SDHCI_AUTO_CMD_STATUS); in esdhc_reset_tuning()
1110 ret = readl_poll_timeout(host->ioaddr + SDHCI_AUTO_CMD_STATUS, in esdhc_reset_tuning()
1112 if (ret == -ETIMEDOUT) in esdhc_reset_tuning()
1113 dev_warn(mmc_dev(host->mmc), in esdhc_reset_tuning()
1120 ctrl = readl(host->ioaddr + SDHCI_INT_STATUS); in esdhc_reset_tuning()
1122 writel(ctrl, host->ioaddr + SDHCI_INT_STATUS); in esdhc_reset_tuning()
1127 static void usdhc_init_card(struct mmc_host *mmc, struct mmc_card *card) in usdhc_init_card() argument
1129 struct sdhci_host *host = mmc_priv(mmc); in usdhc_init_card()
1133 imx_data->init_card_type = card->type; in usdhc_init_card()
1136 static int usdhc_execute_tuning(struct mmc_host *mmc, u32 opcode) in usdhc_execute_tuning() argument
1138 struct sdhci_host *host = mmc_priv(mmc); in usdhc_execute_tuning()
1145 if (host->timing == MMC_TIMING_UHS_DDR50) in usdhc_execute_tuning()
1154 err = sdhci_execute_tuning(mmc, opcode); in usdhc_execute_tuning()
1156 if (!err && !host->tuning_err) in usdhc_execute_tuning()
1168 /* FIXME: delay a bit for card to be ready for next tuning due to errors */ in esdhc_prepare_tuning()
1173 ret = readb_poll_timeout(host->ioaddr + SDHCI_SOFTWARE_RESET, sw_rst, in esdhc_prepare_tuning()
1175 if (ret == -ETIMEDOUT) in esdhc_prepare_tuning()
1176 dev_warn(mmc_dev(host->mmc), in esdhc_prepare_tuning()
1179 reg = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_prepare_tuning()
1182 writel(reg, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_prepare_tuning()
1184 host->ioaddr + ESDHC_TUNE_CTRL_STATUS); in esdhc_prepare_tuning()
1185 dev_dbg(mmc_dev(host->mmc), in esdhc_prepare_tuning()
1187 val, readl(host->ioaddr + ESDHC_TUNE_CTRL_STATUS)); in esdhc_prepare_tuning()
1189 /* set RST_FIFO to reset the async FIFO, and wat it to self-clear */ in esdhc_prepare_tuning()
1190 sys_ctrl = readl(host->ioaddr + ESDHC_SYSTEM_CONTROL); in esdhc_prepare_tuning()
1192 writel(sys_ctrl, host->ioaddr + ESDHC_SYSTEM_CONTROL); in esdhc_prepare_tuning()
1193 ret = readl_poll_timeout(host->ioaddr + ESDHC_SYSTEM_CONTROL, sys_ctrl, in esdhc_prepare_tuning()
1195 if (ret == -ETIMEDOUT) in esdhc_prepare_tuning()
1196 dev_warn(mmc_dev(host->mmc), in esdhc_prepare_tuning()
1204 reg = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_post_tuning()
1206 writel(reg, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_post_tuning()
1226 if (!mmc_send_tuning(host->mmc, opcode, NULL)) in esdhc_executing_tuning()
1235 if (mmc_send_tuning(host->mmc, opcode, NULL)) { in esdhc_executing_tuning()
1236 max -= ESDHC_TUNE_CTRL_STEP; in esdhc_executing_tuning()
1242 win_length = max - min + 1; in esdhc_executing_tuning()
1260 * for the auto-tuning logic. According to hardware suggest, need in esdhc_executing_tuning()
1266 avg - ESDHC_AUTO_TUNING_WINDOW) | in esdhc_executing_tuning()
1272 writel(clk_tune_ctrl_status, host->ioaddr + ESDHC_TUNE_CTRL_STATUS); in esdhc_executing_tuning()
1273 ret = readl_poll_timeout(host->ioaddr + ESDHC_TUNE_CTRL_STATUS, temp, in esdhc_executing_tuning()
1277 if (ret == -ETIMEDOUT) in esdhc_executing_tuning()
1278 dev_warn(mmc_dev(host->mmc), in esdhc_executing_tuning()
1281 ret = mmc_send_tuning(host->mmc, opcode, NULL); in esdhc_executing_tuning()
1284 dev_dbg(mmc_dev(host->mmc), "tuning %s at 0x%x ret %d\n", in esdhc_executing_tuning()
1290 static void esdhc_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios) in esdhc_hs400_enhanced_strobe() argument
1292 struct sdhci_host *host = mmc_priv(mmc); in esdhc_hs400_enhanced_strobe()
1295 m = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_hs400_enhanced_strobe()
1296 if (ios->enhanced_strobe) in esdhc_hs400_enhanced_strobe()
1300 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_hs400_enhanced_strobe()
1310 dev_dbg(mmc_dev(host->mmc), "change pinctrl state for uhs %d\n", uhs); in esdhc_change_pinstate()
1312 if (IS_ERR(imx_data->pinctrl) || in esdhc_change_pinstate()
1313 IS_ERR(imx_data->pins_100mhz) || in esdhc_change_pinstate()
1314 IS_ERR(imx_data->pins_200mhz)) in esdhc_change_pinstate()
1315 return -EINVAL; in esdhc_change_pinstate()
1320 pinctrl = imx_data->pins_100mhz; in esdhc_change_pinstate()
1325 pinctrl = imx_data->pins_200mhz; in esdhc_change_pinstate()
1329 return pinctrl_select_default_state(mmc_dev(host->mmc)); in esdhc_change_pinstate()
1332 return pinctrl_select_state(imx_data->pinctrl, pinctrl); in esdhc_change_pinstate()
1353 writel(readl(host->ioaddr + ESDHC_VENDOR_SPEC) & in esdhc_set_strobe_dll()
1355 host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_set_strobe_dll()
1360 host->ioaddr + ESDHC_STROBE_DLL_CTRL); in esdhc_set_strobe_dll()
1362 writel(0, host->ioaddr + ESDHC_STROBE_DLL_CTRL); in esdhc_set_strobe_dll()
1368 if (imx_data->boarddata.strobe_dll_delay_target) in esdhc_set_strobe_dll()
1369 strobe_delay = imx_data->boarddata.strobe_dll_delay_target; in esdhc_set_strobe_dll()
1375 writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL); in esdhc_set_strobe_dll()
1378 ret = readl_poll_timeout(host->ioaddr + ESDHC_STROBE_DLL_STATUS, v, in esdhc_set_strobe_dll()
1380 if (ret == -ETIMEDOUT) in esdhc_set_strobe_dll()
1381 dev_warn(mmc_dev(host->mmc), in esdhc_set_strobe_dll()
1390 struct esdhc_platform_data *boarddata = &imx_data->boarddata; in esdhc_set_uhs_signaling()
1393 m = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_set_uhs_signaling()
1395 imx_data->is_ddr = 0; in esdhc_set_uhs_signaling()
1404 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_set_uhs_signaling()
1409 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_set_uhs_signaling()
1410 imx_data->is_ddr = 1; in esdhc_set_uhs_signaling()
1411 if (boarddata->delay_line) { in esdhc_set_uhs_signaling()
1413 v = boarddata->delay_line << in esdhc_set_uhs_signaling()
1418 writel(v, host->ioaddr + ESDHC_DLL_CTRL); in esdhc_set_uhs_signaling()
1423 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_set_uhs_signaling()
1424 imx_data->is_ddr = 1; in esdhc_set_uhs_signaling()
1426 host->ops->set_clock(host, host->clock); in esdhc_set_uhs_signaling()
1442 sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); in esdhc_reset()
1443 sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); in esdhc_reset()
1463 cqhci_irq(host->mmc, intmask, cmd_error, data_error); in esdhc_cqhci_irq()
1471 /* eMMC spec requires minimum 1us, here delay between 1-10us */ in esdhc_hw_reset()
1475 /* eMMC spec requires minimum 200us, here delay between 200-300us */ in esdhc_hw_reset()
1511 struct cqhci_host *cq_host = host->mmc->cqe_private; in sdhci_esdhc_imx_hwinit()
1519 writel(ESDHC_WTMK_DEFAULT_VAL, host->ioaddr + ESDHC_WTMK_LVL); in sdhci_esdhc_imx_hwinit()
1532 writel(readl(host->ioaddr + SDHCI_HOST_CONTROL) in sdhci_esdhc_imx_hwinit()
1534 host->ioaddr + SDHCI_HOST_CONTROL); in sdhci_esdhc_imx_hwinit()
1540 if (!(imx_data->socdata->flags & ESDHC_FLAG_SKIP_ERR004536)) { in sdhci_esdhc_imx_hwinit()
1541 writel(readl(host->ioaddr + 0x6c) & ~BIT(7), in sdhci_esdhc_imx_hwinit()
1542 host->ioaddr + 0x6c); in sdhci_esdhc_imx_hwinit()
1546 writel(0x0, host->ioaddr + ESDHC_DLL_CTRL); in sdhci_esdhc_imx_hwinit()
1557 if (imx_data->socdata->flags & ESDHC_FLAG_CQHCI) { in sdhci_esdhc_imx_hwinit()
1558 tmp = readl(host->ioaddr + ESDHC_VEND_SPEC2); in sdhci_esdhc_imx_hwinit()
1560 writel(tmp, host->ioaddr + ESDHC_VEND_SPEC2); in sdhci_esdhc_imx_hwinit()
1562 host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ; in sdhci_esdhc_imx_hwinit()
1565 if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { in sdhci_esdhc_imx_hwinit()
1566 tmp = readl(host->ioaddr + ESDHC_TUNING_CTRL); in sdhci_esdhc_imx_hwinit()
1574 if (imx_data->boarddata.tuning_start_tap) in sdhci_esdhc_imx_hwinit()
1575 tmp |= imx_data->boarddata.tuning_start_tap; in sdhci_esdhc_imx_hwinit()
1579 if (imx_data->boarddata.tuning_step) { in sdhci_esdhc_imx_hwinit()
1580 tmp |= imx_data->boarddata.tuning_step in sdhci_esdhc_imx_hwinit()
1601 * the card side to finally send out the tuning data, trigger in sdhci_esdhc_imx_hwinit()
1603 * the next tuning command some eMMC card will stuck, can't in sdhci_esdhc_imx_hwinit()
1608 writel(tmp, host->ioaddr + ESDHC_TUNING_CTRL); in sdhci_esdhc_imx_hwinit()
1609 } else if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) { in sdhci_esdhc_imx_hwinit()
1615 tmp = readl(host->ioaddr + ESDHC_TUNING_CTRL); in sdhci_esdhc_imx_hwinit()
1617 writel(tmp, host->ioaddr + ESDHC_TUNING_CTRL); in sdhci_esdhc_imx_hwinit()
1621 * On i.MX8MM, we are running Dual Linux OS, with 1st Linux using SD Card in sdhci_esdhc_imx_hwinit()
1645 * SD/eMMC do not need this tuning save because it will re-init in sdhc_esdhc_tuning_save()
1652 if (host->timing == MMC_TIMING_UHS_SDR50 || in sdhc_esdhc_tuning_save()
1653 host->timing == MMC_TIMING_UHS_SDR104) { in sdhc_esdhc_tuning_save()
1654 reg = readl(host->ioaddr + ESDHC_TUNE_CTRL_STATUS); in sdhc_esdhc_tuning_save()
1656 imx_data->boarddata.saved_tuning_delay_cell = reg; in sdhc_esdhc_tuning_save()
1666 if (host->timing == MMC_TIMING_UHS_SDR50 || in sdhc_esdhc_tuning_restore()
1667 host->timing == MMC_TIMING_UHS_SDR104) { in sdhc_esdhc_tuning_restore()
1673 * when trigger re-tuning. in sdhc_esdhc_tuning_restore()
1675 reg = readl(host->ioaddr + ESDHC_TUNING_CTRL); in sdhc_esdhc_tuning_restore()
1677 writel(reg, host->ioaddr + ESDHC_TUNING_CTRL); in sdhc_esdhc_tuning_restore()
1679 reg = readl(host->ioaddr + ESDHC_MIX_CTRL); in sdhc_esdhc_tuning_restore()
1681 writel(reg, host->ioaddr + ESDHC_MIX_CTRL); in sdhc_esdhc_tuning_restore()
1684 imx_data->boarddata.saved_tuning_delay_cell) | in sdhc_esdhc_tuning_restore()
1689 host->ioaddr + ESDHC_TUNE_CTRL_STATUS); in sdhc_esdhc_tuning_restore()
1694 static void esdhc_cqe_enable(struct mmc_host *mmc) in esdhc_cqe_enable() argument
1696 struct sdhci_host *host = mmc_priv(mmc); in esdhc_cqe_enable()
1697 struct cqhci_host *cq_host = mmc->cqe_private; in esdhc_cqe_enable()
1710 if (count-- == 0) { in esdhc_cqe_enable()
1711 dev_warn(mmc_dev(host->mmc), in esdhc_cqe_enable()
1724 if (host->flags & SDHCI_REQ_USE_DMA) in esdhc_cqe_enable()
1726 if (!(host->quirks2 & SDHCI_QUIRK2_SUPPORT_SINGLE)) in esdhc_cqe_enable()
1738 dev_err(mmc_dev(host->mmc), in esdhc_cqe_enable()
1742 sdhci_cqe_enable(mmc); in esdhc_cqe_enable()
1745 static void esdhc_sdhci_dumpregs(struct mmc_host *mmc) in esdhc_sdhci_dumpregs() argument
1747 sdhci_dumpregs(mmc_priv(mmc)); in esdhc_sdhci_dumpregs()
1761 struct device_node *np = pdev->dev.of_node; in sdhci_esdhc_imx_probe_dt()
1762 struct esdhc_platform_data *boarddata = &imx_data->boarddata; in sdhci_esdhc_imx_probe_dt()
1765 if (of_property_read_bool(np, "fsl,wp-controller")) in sdhci_esdhc_imx_probe_dt()
1766 boarddata->wp_type = ESDHC_WP_CONTROLLER; in sdhci_esdhc_imx_probe_dt()
1773 if (of_property_present(np, "wp-gpios")) in sdhci_esdhc_imx_probe_dt()
1774 boarddata->wp_type = ESDHC_WP_GPIO; in sdhci_esdhc_imx_probe_dt()
1776 of_property_read_u32(np, "fsl,tuning-step", &boarddata->tuning_step); in sdhci_esdhc_imx_probe_dt()
1777 of_property_read_u32(np, "fsl,tuning-start-tap", in sdhci_esdhc_imx_probe_dt()
1778 &boarddata->tuning_start_tap); in sdhci_esdhc_imx_probe_dt()
1780 of_property_read_u32(np, "fsl,strobe-dll-delay-target", in sdhci_esdhc_imx_probe_dt()
1781 &boarddata->strobe_dll_delay_target); in sdhci_esdhc_imx_probe_dt()
1782 if (of_property_read_bool(np, "no-1-8-v")) in sdhci_esdhc_imx_probe_dt()
1783 host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V; in sdhci_esdhc_imx_probe_dt()
1785 if (of_property_read_u32(np, "fsl,delay-line", &boarddata->delay_line)) in sdhci_esdhc_imx_probe_dt()
1786 boarddata->delay_line = 0; in sdhci_esdhc_imx_probe_dt()
1788 mmc_of_parse_voltage(host->mmc, &host->ocr_mask); in sdhci_esdhc_imx_probe_dt()
1790 if (esdhc_is_usdhc(imx_data) && !IS_ERR(imx_data->pinctrl)) { in sdhci_esdhc_imx_probe_dt()
1791 imx_data->pins_100mhz = pinctrl_lookup_state(imx_data->pinctrl, in sdhci_esdhc_imx_probe_dt()
1793 imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl, in sdhci_esdhc_imx_probe_dt()
1798 ret = mmc_of_parse(host->mmc); in sdhci_esdhc_imx_probe_dt()
1803 if (!(host->mmc->caps & MMC_CAP_8_BIT_DATA)) in sdhci_esdhc_imx_probe_dt()
1804 host->mmc->caps2 &= ~(MMC_CAP2_HS400 | MMC_CAP2_HS400_ES); in sdhci_esdhc_imx_probe_dt()
1806 if (mmc_gpio_get_cd(host->mmc) >= 0) in sdhci_esdhc_imx_probe_dt()
1807 host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; in sdhci_esdhc_imx_probe_dt()
1829 imx_data->socdata = device_get_match_data(&pdev->dev); in sdhci_esdhc_imx_probe()
1831 host->quirks |= imx_data->socdata->quirks; in sdhci_esdhc_imx_probe()
1832 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_imx_probe()
1833 cpu_latency_qos_add_request(&imx_data->pm_qos_req, 0); in sdhci_esdhc_imx_probe()
1835 imx_data->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); in sdhci_esdhc_imx_probe()
1836 if (IS_ERR(imx_data->clk_ipg)) { in sdhci_esdhc_imx_probe()
1837 err = PTR_ERR(imx_data->clk_ipg); in sdhci_esdhc_imx_probe()
1841 imx_data->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); in sdhci_esdhc_imx_probe()
1842 if (IS_ERR(imx_data->clk_ahb)) { in sdhci_esdhc_imx_probe()
1843 err = PTR_ERR(imx_data->clk_ahb); in sdhci_esdhc_imx_probe()
1847 imx_data->clk_per = devm_clk_get(&pdev->dev, "per"); in sdhci_esdhc_imx_probe()
1848 if (IS_ERR(imx_data->clk_per)) { in sdhci_esdhc_imx_probe()
1849 err = PTR_ERR(imx_data->clk_per); in sdhci_esdhc_imx_probe()
1853 pltfm_host->clk = imx_data->clk_per; in sdhci_esdhc_imx_probe()
1854 err = clk_prepare_enable(imx_data->clk_per); in sdhci_esdhc_imx_probe()
1857 err = clk_prepare_enable(imx_data->clk_ipg); in sdhci_esdhc_imx_probe()
1860 err = clk_prepare_enable(imx_data->clk_ahb); in sdhci_esdhc_imx_probe()
1864 pltfm_host->clock = clk_get_rate(pltfm_host->clk); in sdhci_esdhc_imx_probe()
1865 if (!pltfm_host->clock) { in sdhci_esdhc_imx_probe()
1866 dev_err(mmc_dev(host->mmc), "could not get clk rate\n"); in sdhci_esdhc_imx_probe()
1867 err = -EINVAL; in sdhci_esdhc_imx_probe()
1871 imx_data->pinctrl = devm_pinctrl_get(&pdev->dev); in sdhci_esdhc_imx_probe()
1872 if (IS_ERR(imx_data->pinctrl)) in sdhci_esdhc_imx_probe()
1873 dev_warn(mmc_dev(host->mmc), "could not get pinctrl\n"); in sdhci_esdhc_imx_probe()
1876 host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN; in sdhci_esdhc_imx_probe()
1877 host->mmc->caps |= MMC_CAP_1_8V_DDR | MMC_CAP_3_3V_DDR; in sdhci_esdhc_imx_probe()
1880 if (!(imx_data->socdata->flags & ESDHC_FLAG_SKIP_CD_WAKE)) in sdhci_esdhc_imx_probe()
1881 host->mmc->caps |= MMC_CAP_CD_WAKE; in sdhci_esdhc_imx_probe()
1883 if (!(imx_data->socdata->flags & ESDHC_FLAG_HS200)) in sdhci_esdhc_imx_probe()
1884 host->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200; in sdhci_esdhc_imx_probe()
1887 writel(0x0, host->ioaddr + ESDHC_MIX_CTRL); in sdhci_esdhc_imx_probe()
1888 writel(0x0, host->ioaddr + SDHCI_AUTO_CMD_STATUS); in sdhci_esdhc_imx_probe()
1889 writel(0x0, host->ioaddr + ESDHC_TUNE_CTRL_STATUS); in sdhci_esdhc_imx_probe()
1895 host->mmc_host_ops.execute_tuning = usdhc_execute_tuning; in sdhci_esdhc_imx_probe()
1898 * Link usdhc specific mmc_host_ops init card function, in sdhci_esdhc_imx_probe()
1899 * to distinguish the card type. in sdhci_esdhc_imx_probe()
1901 host->mmc_host_ops.init_card = usdhc_init_card; in sdhci_esdhc_imx_probe()
1903 host->max_timeout_count = 0xF; in sdhci_esdhc_imx_probe()
1906 if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) in sdhci_esdhc_imx_probe()
1910 if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536) in sdhci_esdhc_imx_probe()
1911 host->quirks |= SDHCI_QUIRK_BROKEN_ADMA; in sdhci_esdhc_imx_probe()
1913 if (imx_data->socdata->flags & ESDHC_FLAG_HS400) in sdhci_esdhc_imx_probe()
1914 host->mmc->caps2 |= MMC_CAP2_HS400; in sdhci_esdhc_imx_probe()
1916 if (imx_data->socdata->flags & ESDHC_FLAG_BROKEN_AUTO_CMD23) in sdhci_esdhc_imx_probe()
1917 host->quirks2 |= SDHCI_QUIRK2_ACMD23_BROKEN; in sdhci_esdhc_imx_probe()
1919 if (imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) { in sdhci_esdhc_imx_probe()
1920 host->mmc->caps2 |= MMC_CAP2_HS400_ES; in sdhci_esdhc_imx_probe()
1921 host->mmc_host_ops.hs400_enhanced_strobe = in sdhci_esdhc_imx_probe()
1925 if (imx_data->socdata->flags & ESDHC_FLAG_CQHCI) { in sdhci_esdhc_imx_probe()
1926 host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD; in sdhci_esdhc_imx_probe()
1927 cq_host = devm_kzalloc(&pdev->dev, sizeof(*cq_host), GFP_KERNEL); in sdhci_esdhc_imx_probe()
1929 err = -ENOMEM; in sdhci_esdhc_imx_probe()
1933 cq_host->mmio = host->ioaddr + ESDHC_CQHCI_ADDR_OFFSET; in sdhci_esdhc_imx_probe()
1934 cq_host->ops = &esdhc_cqhci_ops; in sdhci_esdhc_imx_probe()
1936 err = cqhci_init(cq_host, host->mmc, false); in sdhci_esdhc_imx_probe()
1955 if ((host->mmc->pm_caps & MMC_PM_KEEP_POWER) && in sdhci_esdhc_imx_probe()
1956 (host->mmc->pm_caps & MMC_PM_WAKE_SDIO_IRQ)) in sdhci_esdhc_imx_probe()
1957 device_set_wakeup_capable(&pdev->dev, true); in sdhci_esdhc_imx_probe()
1959 pm_runtime_set_active(&pdev->dev); in sdhci_esdhc_imx_probe()
1960 pm_runtime_set_autosuspend_delay(&pdev->dev, 50); in sdhci_esdhc_imx_probe()
1961 pm_runtime_use_autosuspend(&pdev->dev); in sdhci_esdhc_imx_probe()
1962 pm_suspend_ignore_children(&pdev->dev, 1); in sdhci_esdhc_imx_probe()
1963 pm_runtime_enable(&pdev->dev); in sdhci_esdhc_imx_probe()
1968 clk_disable_unprepare(imx_data->clk_ahb); in sdhci_esdhc_imx_probe()
1970 clk_disable_unprepare(imx_data->clk_ipg); in sdhci_esdhc_imx_probe()
1972 clk_disable_unprepare(imx_data->clk_per); in sdhci_esdhc_imx_probe()
1974 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_imx_probe()
1975 cpu_latency_qos_remove_request(&imx_data->pm_qos_req); in sdhci_esdhc_imx_probe()
1987 pm_runtime_get_sync(&pdev->dev); in sdhci_esdhc_imx_remove()
1988 dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff); in sdhci_esdhc_imx_remove()
1989 pm_runtime_disable(&pdev->dev); in sdhci_esdhc_imx_remove()
1990 pm_runtime_put_noidle(&pdev->dev); in sdhci_esdhc_imx_remove()
1994 clk_disable_unprepare(imx_data->clk_per); in sdhci_esdhc_imx_remove()
1995 clk_disable_unprepare(imx_data->clk_ipg); in sdhci_esdhc_imx_remove()
1996 clk_disable_unprepare(imx_data->clk_ahb); in sdhci_esdhc_imx_remove()
1998 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_imx_remove()
1999 cpu_latency_qos_remove_request(&imx_data->pm_qos_req); in sdhci_esdhc_imx_remove()
2017 * invoke its ->runtime_resume callback (needs_force_resume = 1). in sdhci_esdhc_suspend()
2021 if ((imx_data->socdata->flags & ESDHC_FLAG_STATE_LOST_IN_LPMODE) && in sdhci_esdhc_suspend()
2022 (host->tuning_mode != SDHCI_TUNING_MODE_1)) { in sdhci_esdhc_suspend()
2023 mmc_retune_timer_stop(host->mmc); in sdhci_esdhc_suspend()
2024 mmc_retune_needed(host->mmc); in sdhci_esdhc_suspend()
2032 if (mmc_card_keep_power(host->mmc) && mmc_card_wake_sdio_irq(host->mmc) && in sdhci_esdhc_suspend()
2038 disable_irq(host->irq); in sdhci_esdhc_suspend()
2048 ret = mmc_gpio_set_cd_wake(host->mmc, true); in sdhci_esdhc_suspend()
2052 * uSDHC IP supports in-band SDIO wakeup even without clock. in sdhci_esdhc_suspend()
2068 ret = mmc_gpio_set_cd_wake(host->mmc, false); in sdhci_esdhc_resume()
2072 /* re-initialize hw state in case it's lost in low power mode */ in sdhci_esdhc_resume()
2075 if (host->irq_wake_enabled) { in sdhci_esdhc_resume()
2077 enable_irq(host->irq); in sdhci_esdhc_resume()
2084 if (mmc_card_keep_power(host->mmc) && mmc_card_wake_sdio_irq(host->mmc) && in sdhci_esdhc_resume()
2103 if (host->mmc->caps2 & MMC_CAP2_CQE) { in sdhci_esdhc_runtime_suspend()
2104 ret = cqhci_suspend(host->mmc); in sdhci_esdhc_runtime_suspend()
2113 if (host->tuning_mode != SDHCI_TUNING_MODE_3) in sdhci_esdhc_runtime_suspend()
2114 mmc_retune_needed(host->mmc); in sdhci_esdhc_runtime_suspend()
2116 imx_data->actual_clock = host->mmc->actual_clock; in sdhci_esdhc_runtime_suspend()
2118 clk_disable_unprepare(imx_data->clk_per); in sdhci_esdhc_runtime_suspend()
2119 clk_disable_unprepare(imx_data->clk_ipg); in sdhci_esdhc_runtime_suspend()
2120 clk_disable_unprepare(imx_data->clk_ahb); in sdhci_esdhc_runtime_suspend()
2122 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_runtime_suspend()
2123 cpu_latency_qos_remove_request(&imx_data->pm_qos_req); in sdhci_esdhc_runtime_suspend()
2135 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_runtime_resume()
2136 cpu_latency_qos_add_request(&imx_data->pm_qos_req, 0); in sdhci_esdhc_runtime_resume()
2138 if (imx_data->socdata->flags & ESDHC_FLAG_CLK_RATE_LOST_IN_PM_RUNTIME) in sdhci_esdhc_runtime_resume()
2139 clk_set_rate(imx_data->clk_per, pltfm_host->clock); in sdhci_esdhc_runtime_resume()
2141 err = clk_prepare_enable(imx_data->clk_ahb); in sdhci_esdhc_runtime_resume()
2145 err = clk_prepare_enable(imx_data->clk_per); in sdhci_esdhc_runtime_resume()
2149 err = clk_prepare_enable(imx_data->clk_ipg); in sdhci_esdhc_runtime_resume()
2153 esdhc_pltfm_set_clock(host, imx_data->actual_clock); in sdhci_esdhc_runtime_resume()
2159 if (host->mmc->caps2 & MMC_CAP2_CQE) in sdhci_esdhc_runtime_resume()
2160 err = cqhci_resume(host->mmc); in sdhci_esdhc_runtime_resume()
2165 clk_disable_unprepare(imx_data->clk_ipg); in sdhci_esdhc_runtime_resume()
2167 clk_disable_unprepare(imx_data->clk_per); in sdhci_esdhc_runtime_resume()
2169 clk_disable_unprepare(imx_data->clk_ahb); in sdhci_esdhc_runtime_resume()
2171 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_runtime_resume()
2172 cpu_latency_qos_remove_request(&imx_data->pm_qos_req); in sdhci_esdhc_runtime_resume()
2185 .name = "sdhci-esdhc-imx",