Lines Matching +full:hs400 +full:- +full:cmd +full:- +full:int +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"
82 #define ESDHC_TUNE_CTRL_MAX ((1 << 7) - 1)
126 * There is an INT DMA ERR mismatch between eSDHC and STD SDHC SPEC:
128 * but bit28 is used as the INT DMA ERR in fsl eSDHC design.
129 * Define this macro DMA error INT for fsl eSDHC
137 * The CMDTYPE of the CMD register (offset 0xE) should be set to
139 * open ended multi-blk IO. Otherwise the TC INT wouldn't
169 /* The IP supports HS400 mode */
217 * struct esdhc_platform_data - platform data for esdhc on i.MX
228 int max_bus_width;
229 unsigned int delay_line;
230 unsigned int tuning_step; /* The delay cell steps in tuning procedure */
231 unsigned int tuning_start_tap; /* The start delay cell point in tuning procedure */
232 unsigned int strobe_dll_delay_target; /* The delay cell for strobe pad (read clock) */
338 unsigned int actual_clock;
341 MULTIBLK_IN_PROCESS, /* exact multiblock cmd in process */
342 WAIT_FOR_INT, /* sent CMD12, waiting for response INT */
349 { .compatible = "fsl,imx25-esdhc", .data = &esdhc_imx25_data, },
350 { .compatible = "fsl,imx35-esdhc", .data = &esdhc_imx35_data, },
351 { .compatible = "fsl,imx51-esdhc", .data = &esdhc_imx51_data, },
352 { .compatible = "fsl,imx53-esdhc", .data = &esdhc_imx53_data, },
353 { .compatible = "fsl,imx6sx-usdhc", .data = &usdhc_imx6sx_data, },
354 { .compatible = "fsl,imx6sl-usdhc", .data = &usdhc_imx6sl_data, },
355 { .compatible = "fsl,imx6sll-usdhc", .data = &usdhc_imx6sll_data, },
356 { .compatible = "fsl,imx6q-usdhc", .data = &usdhc_imx6q_data, },
357 { .compatible = "fsl,imx6ull-usdhc", .data = &usdhc_imx6ull_data, },
358 { .compatible = "fsl,imx7d-usdhc", .data = &usdhc_imx7d_data, },
359 { .compatible = "fsl,imx7ulp-usdhc", .data = &usdhc_imx7ulp_data, },
360 { .compatible = "fsl,imx8qxp-usdhc", .data = &usdhc_imx8qxp_data, },
361 { .compatible = "fsl,imx8mm-usdhc", .data = &usdhc_imx8mm_data, },
362 { .compatible = "fsl,imxrt1050-usdhc", .data = &usdhc_imxrt1050_data, },
363 { .compatible = "nxp,s32g2-usdhc", .data = &usdhc_s32g2_data, },
368 static inline int is_imx25_esdhc(struct pltfm_imx_data *data) in is_imx25_esdhc()
370 return data->socdata == &esdhc_imx25_data; in is_imx25_esdhc()
373 static inline int is_imx53_esdhc(struct pltfm_imx_data *data) in is_imx53_esdhc()
375 return data->socdata == &esdhc_imx53_data; in is_imx53_esdhc()
378 static inline int esdhc_is_usdhc(struct pltfm_imx_data *data) in esdhc_is_usdhc()
380 return !!(data->socdata->flags & ESDHC_FLAG_USDHC); in esdhc_is_usdhc()
383 static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, int reg) in esdhc_clrset_le()
385 void __iomem *base = host->ioaddr + (reg & ~0x3); in esdhc_clrset_le()
391 #define DRIVER_NAME "sdhci-esdhc-imx"
393 pr_err("%s: " DRIVER_NAME ": " f, mmc_hostname(host->mmc), ## x)
396 int i; in esdhc_dump_debug_regs()
398 "cmd debug status", in esdhc_dump_debug_regs()
412 readw(host->ioaddr + ESDHC_DEBUG_SEL_AND_STATUS_REG)); in esdhc_dump_debug_regs()
422 int ret; in esdhc_wait_for_card_clock_gate_off()
424 ret = readl_poll_timeout(host->ioaddr + ESDHC_PRSSTAT, present_state, in esdhc_wait_for_card_clock_gate_off()
426 if (ret == -ETIMEDOUT) in esdhc_wait_for_card_clock_gate_off()
427 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()
430 /* Enable the auto tuning circuit to check the CMD line and BUS line */
435 buswidth = USDHC_GET_BUSWIDTH(readl(host->ioaddr + SDHCI_HOST_CONTROL)); in usdhc_auto_tuning_mode_sel()
454 static u32 esdhc_readl_le(struct sdhci_host *host, int reg) in esdhc_readl_le()
458 u32 val = readl(host->ioaddr + reg); in esdhc_readl_le()
464 /* move dat[0-3] bits */ in esdhc_readl_le()
466 /* move cmd line bit */ in esdhc_readl_le()
471 /* ignore bit[0-15] as it stores cap_1 register val for mx6sl */ in esdhc_readl_le()
472 if (imx_data->socdata->flags & ESDHC_FLAG_HAVE_CAP1) in esdhc_readl_le()
490 if (imx_data->socdata->flags & ESDHC_FLAG_HAVE_CAP1) in esdhc_readl_le()
491 val = readl(host->ioaddr + SDHCI_CAPABILITIES) & 0xFFFF; in esdhc_readl_le()
504 if (IS_ERR_OR_NULL(imx_data->pins_100mhz)) in esdhc_readl_le()
506 if (IS_ERR_OR_NULL(imx_data->pins_200mhz)) in esdhc_readl_le()
528 if ((imx_data->multiblock_status == WAIT_FOR_INT) && in esdhc_readl_le()
531 writel(SDHCI_INT_RESPONSE, host->ioaddr + in esdhc_readl_le()
533 imx_data->multiblock_status = NO_CMD_PENDING; in esdhc_readl_le()
540 static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg) in esdhc_writel_le()
553 * and set D3CD bit will make eSDHC re-sample the card in esdhc_writel_le()
555 * re-sample it by the following steps. in esdhc_writel_le()
557 data = readl(host->ioaddr + SDHCI_HOST_CONTROL); in esdhc_writel_le()
559 writel(data, host->ioaddr + SDHCI_HOST_CONTROL); in esdhc_writel_le()
561 writel(data, host->ioaddr + SDHCI_HOST_CONTROL); in esdhc_writel_le()
570 if (unlikely((imx_data->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT) in esdhc_writel_le()
574 v = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writel_le()
576 writel(v, host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writel_le()
578 if (imx_data->multiblock_status == MULTIBLK_IN_PROCESS) in esdhc_writel_le()
583 writel(data, host->ioaddr + SDHCI_TRANSFER_MODE); in esdhc_writel_le()
584 imx_data->multiblock_status = WAIT_FOR_INT; in esdhc_writel_le()
588 writel(val, host->ioaddr + reg); in esdhc_writel_le()
591 static u16 esdhc_readw_le(struct sdhci_host *host, int reg) in esdhc_readw_le()
610 val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_readw_le()
615 if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) in esdhc_readw_le()
616 val = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_readw_le()
617 else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) in esdhc_readw_le()
619 val = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS); in esdhc_readw_le()
634 u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_readw_le()
642 ret = readw(host->ioaddr + SDHCI_TRANSFER_MODE); in esdhc_readw_le()
648 return readw(host->ioaddr + reg); in esdhc_readw_le()
651 static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) in esdhc_writew_le()
659 new_val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
664 writel(new_val, host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
669 new_val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
674 writel(new_val, host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
675 if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { in esdhc_writew_le()
676 u32 v = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS); in esdhc_writew_le()
677 u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writew_le()
695 writel(v, host->ioaddr + SDHCI_AUTO_CMD_STATUS); in esdhc_writew_le()
696 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writew_le()
700 if ((imx_data->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT) in esdhc_writew_le()
701 && (host->cmd->opcode == SD_IO_RW_EXTENDED) in esdhc_writew_le()
702 && (host->cmd->data->blocks > 1) in esdhc_writew_le()
703 && (host->cmd->data->flags & MMC_DATA_READ)) { in esdhc_writew_le()
705 v = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
707 writel(v, host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
712 u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writew_le()
719 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writew_le()
725 m = readl(host->ioaddr + ESDHC_WTMK_LVL); in esdhc_writew_le()
748 writel(m, host->ioaddr + ESDHC_WTMK_LVL); in esdhc_writew_le()
754 imx_data->scratchpad = val; in esdhc_writew_le()
758 if (host->cmd->opcode == MMC_STOP_TRANSMISSION) in esdhc_writew_le()
761 if ((host->cmd->opcode == MMC_SET_BLOCK_COUNT) && in esdhc_writew_le()
762 (imx_data->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT)) in esdhc_writew_le()
763 imx_data->multiblock_status = MULTIBLK_IN_PROCESS; in esdhc_writew_le()
767 host->ioaddr + SDHCI_TRANSFER_MODE); in esdhc_writew_le()
769 writel(val << 16 | imx_data->scratchpad, in esdhc_writew_le()
770 host->ioaddr + SDHCI_TRANSFER_MODE); in esdhc_writew_le()
779 static u8 esdhc_readb_le(struct sdhci_host *host, int reg) in esdhc_readb_le()
786 val = readl(host->ioaddr + reg); in esdhc_readb_le()
795 return readb(host->ioaddr + reg); in esdhc_readb_le()
798 static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg) in esdhc_writeb_le()
835 new_val = readl(host->ioaddr + SDHCI_HOST_CONTROL); in esdhc_writeb_le()
860 new_val = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writeb_le()
862 host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writeb_le()
863 imx_data->is_ddr = 0; in esdhc_writeb_le()
877 static unsigned int esdhc_pltfm_get_max_clock(struct sdhci_host *host) in esdhc_pltfm_get_max_clock()
881 return pltfm_host->clock; in esdhc_pltfm_get_max_clock()
884 static unsigned int esdhc_pltfm_get_min_clock(struct sdhci_host *host) in esdhc_pltfm_get_min_clock()
888 return pltfm_host->clock / 256 / 16; in esdhc_pltfm_get_min_clock()
892 unsigned int clock) in esdhc_pltfm_set_clock()
896 unsigned int host_clock = pltfm_host->clock; in esdhc_pltfm_set_clock()
897 int ddr_pre_div = imx_data->is_ddr ? 2 : 1; in esdhc_pltfm_set_clock()
898 int pre_div = 1; in esdhc_pltfm_set_clock()
899 int div = 1; in esdhc_pltfm_set_clock()
900 int ret; in esdhc_pltfm_set_clock()
904 val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_pltfm_set_clock()
906 host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_pltfm_set_clock()
911 host->mmc->actual_clock = 0; in esdhc_pltfm_set_clock()
921 val = readl(host->ioaddr + ESDHC_DLL_CTRL); in esdhc_pltfm_set_clock()
922 writel(val | BIT(10), host->ioaddr + ESDHC_DLL_CTRL); in esdhc_pltfm_set_clock()
923 temp = readl(host->ioaddr + ESDHC_DLL_CTRL); in esdhc_pltfm_set_clock()
924 writel(val, host->ioaddr + ESDHC_DLL_CTRL); in esdhc_pltfm_set_clock()
934 if (imx_data->socdata->flags & ESDHC_FLAG_ERR010450) { in esdhc_pltfm_set_clock()
935 unsigned int max_clock; in esdhc_pltfm_set_clock()
937 max_clock = imx_data->is_ddr ? 45000000 : 150000000; in esdhc_pltfm_set_clock()
949 host->mmc->actual_clock = host_clock / (div * pre_div * ddr_pre_div); in esdhc_pltfm_set_clock()
950 dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", in esdhc_pltfm_set_clock()
951 clock, host->mmc->actual_clock); in esdhc_pltfm_set_clock()
954 div--; in esdhc_pltfm_set_clock()
963 ret = readl_poll_timeout(host->ioaddr + ESDHC_PRSSTAT, temp, in esdhc_pltfm_set_clock()
965 if (ret == -ETIMEDOUT) in esdhc_pltfm_set_clock()
966 dev_warn(mmc_dev(host->mmc), "card clock still not stable in 100us!.\n"); in esdhc_pltfm_set_clock()
969 val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_pltfm_set_clock()
971 host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_pltfm_set_clock()
976 static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host) in esdhc_pltfm_get_ro()
980 struct esdhc_platform_data *boarddata = &imx_data->boarddata; in esdhc_pltfm_get_ro()
982 switch (boarddata->wp_type) { in esdhc_pltfm_get_ro()
984 return mmc_gpio_get_ro(host->mmc); in esdhc_pltfm_get_ro()
986 return !(readl(host->ioaddr + SDHCI_PRESENT_STATE) & in esdhc_pltfm_get_ro()
992 return -ENOSYS; in esdhc_pltfm_get_ro()
995 static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width) in esdhc_pltfm_set_bus_width()
1015 static int usdhc_execute_tuning(struct mmc_host *mmc, u32 opcode) in usdhc_execute_tuning()
1023 if (host->timing == MMC_TIMING_UHS_DDR50) in usdhc_execute_tuning()
1033 int ret; in esdhc_prepare_tuning()
1035 /* FIXME: delay a bit for card to be ready for next tuning due to errors */ in esdhc_prepare_tuning()
1040 ret = readb_poll_timeout(host->ioaddr + SDHCI_SOFTWARE_RESET, sw_rst, in esdhc_prepare_tuning()
1042 if (ret == -ETIMEDOUT) in esdhc_prepare_tuning()
1043 dev_warn(mmc_dev(host->mmc), in esdhc_prepare_tuning()
1046 reg = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_prepare_tuning()
1049 writel(reg, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_prepare_tuning()
1050 writel(val << 8, host->ioaddr + ESDHC_TUNE_CTRL_STATUS); in esdhc_prepare_tuning()
1051 dev_dbg(mmc_dev(host->mmc), in esdhc_prepare_tuning()
1052 "tuning with delay 0x%x ESDHC_TUNE_CTRL_STATUS 0x%x\n", in esdhc_prepare_tuning()
1053 val, readl(host->ioaddr + ESDHC_TUNE_CTRL_STATUS)); in esdhc_prepare_tuning()
1062 reg = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_post_tuning()
1065 writel(reg, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_post_tuning()
1068 static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode) in esdhc_executing_tuning()
1070 int min, max, avg, ret; in esdhc_executing_tuning()
1072 /* find the mininum delay first which can pass tuning */ in esdhc_executing_tuning()
1076 if (!mmc_send_tuning(host->mmc, opcode, NULL)) in esdhc_executing_tuning()
1081 /* find the maxinum delay which can not pass tuning */ in esdhc_executing_tuning()
1085 if (mmc_send_tuning(host->mmc, opcode, NULL)) { in esdhc_executing_tuning()
1086 max -= ESDHC_TUNE_CTRL_STEP; in esdhc_executing_tuning()
1092 /* use average delay to get the best timing */ in esdhc_executing_tuning()
1095 ret = mmc_send_tuning(host->mmc, opcode, NULL); in esdhc_executing_tuning()
1098 dev_dbg(mmc_dev(host->mmc), "tuning %s at 0x%x ret %d\n", in esdhc_executing_tuning()
1109 m = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_hs400_enhanced_strobe()
1110 if (ios->enhanced_strobe) in esdhc_hs400_enhanced_strobe()
1114 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_hs400_enhanced_strobe()
1117 static int esdhc_change_pinstate(struct sdhci_host *host, in esdhc_change_pinstate()
1118 unsigned int uhs) in esdhc_change_pinstate()
1124 dev_dbg(mmc_dev(host->mmc), "change pinctrl state for uhs %d\n", uhs); in esdhc_change_pinstate()
1126 if (IS_ERR(imx_data->pinctrl) || in esdhc_change_pinstate()
1127 IS_ERR(imx_data->pins_100mhz) || in esdhc_change_pinstate()
1128 IS_ERR(imx_data->pins_200mhz)) in esdhc_change_pinstate()
1129 return -EINVAL; in esdhc_change_pinstate()
1134 pinctrl = imx_data->pins_100mhz; in esdhc_change_pinstate()
1139 pinctrl = imx_data->pins_200mhz; in esdhc_change_pinstate()
1143 return pinctrl_select_default_state(mmc_dev(host->mmc)); in esdhc_change_pinstate()
1146 return pinctrl_select_state(imx_data->pinctrl, pinctrl); in esdhc_change_pinstate()
1150 * For HS400 eMMC, there is a data_strobe line. This signal is generated
1152 * in HS400 mode. The frequency of this signal follows the frequency of
1154 * edge of data_strobe line. Due to the time delay between CLK line and
1155 * data_strobe line, if the delay time is larger than one clock cycle,
1164 int ret; in esdhc_set_strobe_dll()
1167 writel(readl(host->ioaddr + ESDHC_VENDOR_SPEC) & in esdhc_set_strobe_dll()
1169 host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_set_strobe_dll()
1174 host->ioaddr + ESDHC_STROBE_DLL_CTRL); in esdhc_set_strobe_dll()
1176 writel(0, host->ioaddr + ESDHC_STROBE_DLL_CTRL); in esdhc_set_strobe_dll()
1179 * enable strobe dll ctrl and adjust the delay target in esdhc_set_strobe_dll()
1182 if (imx_data->boarddata.strobe_dll_delay_target) in esdhc_set_strobe_dll()
1183 strobe_delay = imx_data->boarddata.strobe_dll_delay_target; in esdhc_set_strobe_dll()
1189 writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL); in esdhc_set_strobe_dll()
1192 ret = readl_poll_timeout(host->ioaddr + ESDHC_STROBE_DLL_STATUS, v, in esdhc_set_strobe_dll()
1194 if (ret == -ETIMEDOUT) in esdhc_set_strobe_dll()
1195 dev_warn(mmc_dev(host->mmc), in esdhc_set_strobe_dll()
1196 "warning! HS400 strobe DLL status REF/SLV not lock in 50us, STROBE DLL status is %x!\n", v); in esdhc_set_strobe_dll()
1204 int ret; in esdhc_reset_tuning()
1208 if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) { in esdhc_reset_tuning()
1209 ctrl = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_reset_tuning()
1212 writel(ctrl, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_reset_tuning()
1213 writel(0, host->ioaddr + ESDHC_TUNE_CTRL_STATUS); in esdhc_reset_tuning()
1214 } else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { in esdhc_reset_tuning()
1215 ctrl = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS); in esdhc_reset_tuning()
1218 writel(ctrl, host->ioaddr + SDHCI_AUTO_CMD_STATUS); in esdhc_reset_tuning()
1220 ret = readl_poll_timeout(host->ioaddr + SDHCI_AUTO_CMD_STATUS, in esdhc_reset_tuning()
1222 if (ret == -ETIMEDOUT) in esdhc_reset_tuning()
1223 dev_warn(mmc_dev(host->mmc), in esdhc_reset_tuning()
1230 ctrl = readl(host->ioaddr + SDHCI_INT_STATUS); in esdhc_reset_tuning()
1232 writel(ctrl, host->ioaddr + SDHCI_INT_STATUS); in esdhc_reset_tuning()
1242 struct esdhc_platform_data *boarddata = &imx_data->boarddata; in esdhc_set_uhs_signaling()
1244 /* disable ddr mode and disable HS400 mode */ in esdhc_set_uhs_signaling()
1245 m = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_set_uhs_signaling()
1247 imx_data->is_ddr = 0; in esdhc_set_uhs_signaling()
1256 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_set_uhs_signaling()
1261 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_set_uhs_signaling()
1262 imx_data->is_ddr = 1; in esdhc_set_uhs_signaling()
1263 if (boarddata->delay_line) { in esdhc_set_uhs_signaling()
1265 v = boarddata->delay_line << in esdhc_set_uhs_signaling()
1270 writel(v, host->ioaddr + ESDHC_DLL_CTRL); in esdhc_set_uhs_signaling()
1275 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_set_uhs_signaling()
1276 imx_data->is_ddr = 1; in esdhc_set_uhs_signaling()
1278 host->ops->set_clock(host, host->clock); in esdhc_set_uhs_signaling()
1294 sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); in esdhc_reset()
1295 sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); in esdhc_reset()
1298 static unsigned int esdhc_get_max_timeout_count(struct sdhci_host *host) in esdhc_get_max_timeout_count()
1307 static void esdhc_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) in esdhc_set_timeout() argument
1320 int cmd_error = 0; in esdhc_cqhci_irq()
1321 int data_error = 0; in esdhc_cqhci_irq()
1326 cqhci_irq(host->mmc, intmask, cmd_error, data_error); in esdhc_cqhci_irq()
1363 struct cqhci_host *cq_host = host->mmc->cqe_private; in sdhci_esdhc_imx_hwinit()
1364 int tmp; in sdhci_esdhc_imx_hwinit()
1371 writel(ESDHC_WTMK_DEFAULT_VAL, host->ioaddr + ESDHC_WTMK_LVL); in sdhci_esdhc_imx_hwinit()
1384 writel(readl(host->ioaddr + SDHCI_HOST_CONTROL) in sdhci_esdhc_imx_hwinit()
1386 host->ioaddr + SDHCI_HOST_CONTROL); in sdhci_esdhc_imx_hwinit()
1392 if (!(imx_data->socdata->flags & ESDHC_FLAG_SKIP_ERR004536)) { in sdhci_esdhc_imx_hwinit()
1393 writel(readl(host->ioaddr + 0x6c) & ~BIT(7), in sdhci_esdhc_imx_hwinit()
1394 host->ioaddr + 0x6c); in sdhci_esdhc_imx_hwinit()
1397 /* disable DLL_CTRL delay line settings */ in sdhci_esdhc_imx_hwinit()
1398 writel(0x0, host->ioaddr + ESDHC_DLL_CTRL); in sdhci_esdhc_imx_hwinit()
1404 * When CQHCI use DCMD to send a CMD need R1b respons, in sdhci_esdhc_imx_hwinit()
1409 if (imx_data->socdata->flags & ESDHC_FLAG_CQHCI) { in sdhci_esdhc_imx_hwinit()
1410 tmp = readl(host->ioaddr + ESDHC_VEND_SPEC2); in sdhci_esdhc_imx_hwinit()
1412 writel(tmp, host->ioaddr + ESDHC_VEND_SPEC2); in sdhci_esdhc_imx_hwinit()
1414 host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ; in sdhci_esdhc_imx_hwinit()
1417 if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { in sdhci_esdhc_imx_hwinit()
1418 tmp = readl(host->ioaddr + ESDHC_TUNING_CTRL); in sdhci_esdhc_imx_hwinit()
1421 if (imx_data->boarddata.tuning_start_tap) { in sdhci_esdhc_imx_hwinit()
1423 tmp |= imx_data->boarddata.tuning_start_tap; in sdhci_esdhc_imx_hwinit()
1426 if (imx_data->boarddata.tuning_step) { in sdhci_esdhc_imx_hwinit()
1428 tmp |= imx_data->boarddata.tuning_step in sdhci_esdhc_imx_hwinit()
1432 /* Disable the CMD CRC check for tuning, if not, need to in sdhci_esdhc_imx_hwinit()
1433 * add some delay after every tuning command, because in sdhci_esdhc_imx_hwinit()
1435 * step once it detect the CMD CRC error, will not wait for in sdhci_esdhc_imx_hwinit()
1443 writel(tmp, host->ioaddr + ESDHC_TUNING_CTRL); in sdhci_esdhc_imx_hwinit()
1444 } else if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) { in sdhci_esdhc_imx_hwinit()
1450 tmp = readl(host->ioaddr + ESDHC_TUNING_CTRL); in sdhci_esdhc_imx_hwinit()
1452 writel(tmp, host->ioaddr + ESDHC_TUNING_CTRL); in sdhci_esdhc_imx_hwinit()
1475 struct cqhci_host *cq_host = mmc->cqe_private; in esdhc_cqe_enable()
1478 int count = 10; in esdhc_cqe_enable()
1488 if (count-- == 0) { in esdhc_cqe_enable()
1489 dev_warn(mmc_dev(host->mmc), in esdhc_cqe_enable()
1502 if (host->flags & SDHCI_REQ_USE_DMA) in esdhc_cqe_enable()
1504 if (!(host->quirks2 & SDHCI_QUIRK2_SUPPORT_SINGLE)) in esdhc_cqe_enable()
1516 dev_err(mmc_dev(host->mmc), in esdhc_cqe_enable()
1534 static int
1539 struct device_node *np = pdev->dev.of_node; in sdhci_esdhc_imx_probe_dt()
1540 struct esdhc_platform_data *boarddata = &imx_data->boarddata; in sdhci_esdhc_imx_probe_dt()
1541 int ret; in sdhci_esdhc_imx_probe_dt()
1543 if (of_get_property(np, "fsl,wp-controller", NULL)) in sdhci_esdhc_imx_probe_dt()
1544 boarddata->wp_type = ESDHC_WP_CONTROLLER; in sdhci_esdhc_imx_probe_dt()
1551 if (of_property_read_bool(np, "wp-gpios")) in sdhci_esdhc_imx_probe_dt()
1552 boarddata->wp_type = ESDHC_WP_GPIO; in sdhci_esdhc_imx_probe_dt()
1554 of_property_read_u32(np, "fsl,tuning-step", &boarddata->tuning_step); in sdhci_esdhc_imx_probe_dt()
1555 of_property_read_u32(np, "fsl,tuning-start-tap", in sdhci_esdhc_imx_probe_dt()
1556 &boarddata->tuning_start_tap); in sdhci_esdhc_imx_probe_dt()
1558 of_property_read_u32(np, "fsl,strobe-dll-delay-target", in sdhci_esdhc_imx_probe_dt()
1559 &boarddata->strobe_dll_delay_target); in sdhci_esdhc_imx_probe_dt()
1560 if (of_find_property(np, "no-1-8-v", NULL)) in sdhci_esdhc_imx_probe_dt()
1561 host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V; in sdhci_esdhc_imx_probe_dt()
1563 if (of_property_read_u32(np, "fsl,delay-line", &boarddata->delay_line)) in sdhci_esdhc_imx_probe_dt()
1564 boarddata->delay_line = 0; in sdhci_esdhc_imx_probe_dt()
1566 mmc_of_parse_voltage(host->mmc, &host->ocr_mask); in sdhci_esdhc_imx_probe_dt()
1568 if (esdhc_is_usdhc(imx_data) && !IS_ERR(imx_data->pinctrl)) { in sdhci_esdhc_imx_probe_dt()
1569 imx_data->pins_100mhz = pinctrl_lookup_state(imx_data->pinctrl, in sdhci_esdhc_imx_probe_dt()
1571 imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl, in sdhci_esdhc_imx_probe_dt()
1576 ret = mmc_of_parse(host->mmc); in sdhci_esdhc_imx_probe_dt()
1580 if (mmc_gpio_get_cd(host->mmc) >= 0) in sdhci_esdhc_imx_probe_dt()
1581 host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; in sdhci_esdhc_imx_probe_dt()
1586 static int sdhci_esdhc_imx_probe(struct platform_device *pdev) in sdhci_esdhc_imx_probe()
1591 int err; in sdhci_esdhc_imx_probe()
1603 imx_data->socdata = device_get_match_data(&pdev->dev); in sdhci_esdhc_imx_probe()
1605 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_imx_probe()
1606 cpu_latency_qos_add_request(&imx_data->pm_qos_req, 0); in sdhci_esdhc_imx_probe()
1608 imx_data->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); in sdhci_esdhc_imx_probe()
1609 if (IS_ERR(imx_data->clk_ipg)) { in sdhci_esdhc_imx_probe()
1610 err = PTR_ERR(imx_data->clk_ipg); in sdhci_esdhc_imx_probe()
1614 imx_data->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); in sdhci_esdhc_imx_probe()
1615 if (IS_ERR(imx_data->clk_ahb)) { in sdhci_esdhc_imx_probe()
1616 err = PTR_ERR(imx_data->clk_ahb); in sdhci_esdhc_imx_probe()
1620 imx_data->clk_per = devm_clk_get(&pdev->dev, "per"); in sdhci_esdhc_imx_probe()
1621 if (IS_ERR(imx_data->clk_per)) { in sdhci_esdhc_imx_probe()
1622 err = PTR_ERR(imx_data->clk_per); in sdhci_esdhc_imx_probe()
1626 pltfm_host->clk = imx_data->clk_per; in sdhci_esdhc_imx_probe()
1627 pltfm_host->clock = clk_get_rate(pltfm_host->clk); in sdhci_esdhc_imx_probe()
1628 err = clk_prepare_enable(imx_data->clk_per); in sdhci_esdhc_imx_probe()
1631 err = clk_prepare_enable(imx_data->clk_ipg); in sdhci_esdhc_imx_probe()
1634 err = clk_prepare_enable(imx_data->clk_ahb); in sdhci_esdhc_imx_probe()
1638 imx_data->pinctrl = devm_pinctrl_get(&pdev->dev); in sdhci_esdhc_imx_probe()
1639 if (IS_ERR(imx_data->pinctrl)) in sdhci_esdhc_imx_probe()
1640 dev_warn(mmc_dev(host->mmc), "could not get pinctrl\n"); in sdhci_esdhc_imx_probe()
1643 host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN; in sdhci_esdhc_imx_probe()
1644 host->mmc->caps |= MMC_CAP_1_8V_DDR | MMC_CAP_3_3V_DDR; in sdhci_esdhc_imx_probe()
1647 host->mmc->caps |= MMC_CAP_CD_WAKE; in sdhci_esdhc_imx_probe()
1649 if (!(imx_data->socdata->flags & ESDHC_FLAG_HS200)) in sdhci_esdhc_imx_probe()
1650 host->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200; in sdhci_esdhc_imx_probe()
1653 writel(0x0, host->ioaddr + ESDHC_MIX_CTRL); in sdhci_esdhc_imx_probe()
1654 writel(0x0, host->ioaddr + SDHCI_AUTO_CMD_STATUS); in sdhci_esdhc_imx_probe()
1655 writel(0x0, host->ioaddr + ESDHC_TUNE_CTRL_STATUS); in sdhci_esdhc_imx_probe()
1661 host->mmc_host_ops.execute_tuning = usdhc_execute_tuning; in sdhci_esdhc_imx_probe()
1668 if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) in sdhci_esdhc_imx_probe()
1672 if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536) in sdhci_esdhc_imx_probe()
1673 host->quirks |= SDHCI_QUIRK_BROKEN_ADMA; in sdhci_esdhc_imx_probe()
1675 if (host->mmc->caps & MMC_CAP_8_BIT_DATA && in sdhci_esdhc_imx_probe()
1676 imx_data->socdata->flags & ESDHC_FLAG_HS400) in sdhci_esdhc_imx_probe()
1677 host->mmc->caps2 |= MMC_CAP2_HS400; in sdhci_esdhc_imx_probe()
1679 if (imx_data->socdata->flags & ESDHC_FLAG_BROKEN_AUTO_CMD23) in sdhci_esdhc_imx_probe()
1680 host->quirks2 |= SDHCI_QUIRK2_ACMD23_BROKEN; in sdhci_esdhc_imx_probe()
1682 if (host->mmc->caps & MMC_CAP_8_BIT_DATA && in sdhci_esdhc_imx_probe()
1683 imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) { in sdhci_esdhc_imx_probe()
1684 host->mmc->caps2 |= MMC_CAP2_HS400_ES; in sdhci_esdhc_imx_probe()
1685 host->mmc_host_ops.hs400_enhanced_strobe = in sdhci_esdhc_imx_probe()
1689 if (imx_data->socdata->flags & ESDHC_FLAG_CQHCI) { in sdhci_esdhc_imx_probe()
1690 host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD; in sdhci_esdhc_imx_probe()
1691 cq_host = devm_kzalloc(&pdev->dev, sizeof(*cq_host), GFP_KERNEL); in sdhci_esdhc_imx_probe()
1693 err = -ENOMEM; in sdhci_esdhc_imx_probe()
1697 cq_host->mmio = host->ioaddr + ESDHC_CQHCI_ADDR_OFFSET; in sdhci_esdhc_imx_probe()
1698 cq_host->ops = &esdhc_cqhci_ops; in sdhci_esdhc_imx_probe()
1700 err = cqhci_init(cq_host, host->mmc, false); in sdhci_esdhc_imx_probe()
1715 if ((host->mmc->pm_caps & MMC_PM_KEEP_POWER) && in sdhci_esdhc_imx_probe()
1716 (host->mmc->pm_caps & MMC_PM_WAKE_SDIO_IRQ)) in sdhci_esdhc_imx_probe()
1717 device_set_wakeup_capable(&pdev->dev, true); in sdhci_esdhc_imx_probe()
1719 pm_runtime_set_active(&pdev->dev); in sdhci_esdhc_imx_probe()
1720 pm_runtime_set_autosuspend_delay(&pdev->dev, 50); in sdhci_esdhc_imx_probe()
1721 pm_runtime_use_autosuspend(&pdev->dev); in sdhci_esdhc_imx_probe()
1722 pm_suspend_ignore_children(&pdev->dev, 1); in sdhci_esdhc_imx_probe()
1723 pm_runtime_enable(&pdev->dev); in sdhci_esdhc_imx_probe()
1728 clk_disable_unprepare(imx_data->clk_ahb); in sdhci_esdhc_imx_probe()
1730 clk_disable_unprepare(imx_data->clk_ipg); in sdhci_esdhc_imx_probe()
1732 clk_disable_unprepare(imx_data->clk_per); in sdhci_esdhc_imx_probe()
1734 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_imx_probe()
1735 cpu_latency_qos_remove_request(&imx_data->pm_qos_req); in sdhci_esdhc_imx_probe()
1740 static int sdhci_esdhc_imx_remove(struct platform_device *pdev) in sdhci_esdhc_imx_remove()
1745 int dead; in sdhci_esdhc_imx_remove()
1747 pm_runtime_get_sync(&pdev->dev); in sdhci_esdhc_imx_remove()
1748 dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff); in sdhci_esdhc_imx_remove()
1749 pm_runtime_disable(&pdev->dev); in sdhci_esdhc_imx_remove()
1750 pm_runtime_put_noidle(&pdev->dev); in sdhci_esdhc_imx_remove()
1754 clk_disable_unprepare(imx_data->clk_per); in sdhci_esdhc_imx_remove()
1755 clk_disable_unprepare(imx_data->clk_ipg); in sdhci_esdhc_imx_remove()
1756 clk_disable_unprepare(imx_data->clk_ahb); in sdhci_esdhc_imx_remove()
1758 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_imx_remove()
1759 cpu_latency_qos_remove_request(&imx_data->pm_qos_req); in sdhci_esdhc_imx_remove()
1767 static int sdhci_esdhc_suspend(struct device *dev) in sdhci_esdhc_suspend()
1772 int ret; in sdhci_esdhc_suspend()
1774 if (host->mmc->caps2 & MMC_CAP2_CQE) { in sdhci_esdhc_suspend()
1775 ret = cqhci_suspend(host->mmc); in sdhci_esdhc_suspend()
1780 if ((imx_data->socdata->flags & ESDHC_FLAG_STATE_LOST_IN_LPMODE) && in sdhci_esdhc_suspend()
1781 (host->tuning_mode != SDHCI_TUNING_MODE_1)) { in sdhci_esdhc_suspend()
1782 mmc_retune_timer_stop(host->mmc); in sdhci_esdhc_suspend()
1783 mmc_retune_needed(host->mmc); in sdhci_esdhc_suspend()
1786 if (host->tuning_mode != SDHCI_TUNING_MODE_3) in sdhci_esdhc_suspend()
1787 mmc_retune_needed(host->mmc); in sdhci_esdhc_suspend()
1797 ret = mmc_gpio_set_cd_wake(host->mmc, true); in sdhci_esdhc_suspend()
1802 static int sdhci_esdhc_resume(struct device *dev) in sdhci_esdhc_resume()
1805 int ret; in sdhci_esdhc_resume()
1811 /* re-initialize hw state in case it's lost in low power mode */ in sdhci_esdhc_resume()
1818 if (host->mmc->caps2 & MMC_CAP2_CQE) in sdhci_esdhc_resume()
1819 ret = cqhci_resume(host->mmc); in sdhci_esdhc_resume()
1822 ret = mmc_gpio_set_cd_wake(host->mmc, false); in sdhci_esdhc_resume()
1829 static int sdhci_esdhc_runtime_suspend(struct device *dev) in sdhci_esdhc_runtime_suspend()
1834 int ret; in sdhci_esdhc_runtime_suspend()
1836 if (host->mmc->caps2 & MMC_CAP2_CQE) { in sdhci_esdhc_runtime_suspend()
1837 ret = cqhci_suspend(host->mmc); in sdhci_esdhc_runtime_suspend()
1846 if (host->tuning_mode != SDHCI_TUNING_MODE_3) in sdhci_esdhc_runtime_suspend()
1847 mmc_retune_needed(host->mmc); in sdhci_esdhc_runtime_suspend()
1849 imx_data->actual_clock = host->mmc->actual_clock; in sdhci_esdhc_runtime_suspend()
1851 clk_disable_unprepare(imx_data->clk_per); in sdhci_esdhc_runtime_suspend()
1852 clk_disable_unprepare(imx_data->clk_ipg); in sdhci_esdhc_runtime_suspend()
1853 clk_disable_unprepare(imx_data->clk_ahb); in sdhci_esdhc_runtime_suspend()
1855 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_runtime_suspend()
1856 cpu_latency_qos_remove_request(&imx_data->pm_qos_req); in sdhci_esdhc_runtime_suspend()
1861 static int sdhci_esdhc_runtime_resume(struct device *dev) in sdhci_esdhc_runtime_resume()
1866 int err; in sdhci_esdhc_runtime_resume()
1868 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_runtime_resume()
1869 cpu_latency_qos_add_request(&imx_data->pm_qos_req, 0); in sdhci_esdhc_runtime_resume()
1871 if (imx_data->socdata->flags & ESDHC_FLAG_CLK_RATE_LOST_IN_PM_RUNTIME) in sdhci_esdhc_runtime_resume()
1872 clk_set_rate(imx_data->clk_per, pltfm_host->clock); in sdhci_esdhc_runtime_resume()
1874 err = clk_prepare_enable(imx_data->clk_ahb); in sdhci_esdhc_runtime_resume()
1878 err = clk_prepare_enable(imx_data->clk_per); in sdhci_esdhc_runtime_resume()
1882 err = clk_prepare_enable(imx_data->clk_ipg); in sdhci_esdhc_runtime_resume()
1886 esdhc_pltfm_set_clock(host, imx_data->actual_clock); in sdhci_esdhc_runtime_resume()
1892 if (host->mmc->caps2 & MMC_CAP2_CQE) in sdhci_esdhc_runtime_resume()
1893 err = cqhci_resume(host->mmc); in sdhci_esdhc_runtime_resume()
1898 clk_disable_unprepare(imx_data->clk_ipg); in sdhci_esdhc_runtime_resume()
1900 clk_disable_unprepare(imx_data->clk_per); in sdhci_esdhc_runtime_resume()
1902 clk_disable_unprepare(imx_data->clk_ahb); in sdhci_esdhc_runtime_resume()
1904 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_runtime_resume()
1905 cpu_latency_qos_remove_request(&imx_data->pm_qos_req); in sdhci_esdhc_runtime_resume()
1918 .name = "sdhci-esdhc-imx",