Lines Matching +full:imx7ulp +full:- +full:usdhc
1 // SPDX-License-Identifier: GPL-2.0
5 * derived from the OF-version.
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)
140 * open ended multi-blk IO. Otherwise the TC INT wouldn't
150 * The flag tells that the ESDHC controller is an USDHC block that is
162 * uSDHC: ADMA Length Mismatch Error occurs if the AHB read access is slow,
174 * uSDHC: At 1.8V due to the I/O timing limit, for SDR mode, SD card
218 * struct esdhc_platform_data - platform data for esdhc on i.MX
343 * USDHC has one limition, require the SDIO device a different
345 * the card init, but at this stage, mmc_host->card is not
361 { .compatible = "fsl,imx25-esdhc", .data = &esdhc_imx25_data, },
362 { .compatible = "fsl,imx35-esdhc", .data = &esdhc_imx35_data, },
363 { .compatible = "fsl,imx51-esdhc", .data = &esdhc_imx51_data, },
364 { .compatible = "fsl,imx53-esdhc", .data = &esdhc_imx53_data, },
365 { .compatible = "fsl,imx6sx-usdhc", .data = &usdhc_imx6sx_data, },
366 { .compatible = "fsl,imx6sl-usdhc", .data = &usdhc_imx6sl_data, },
367 { .compatible = "fsl,imx6sll-usdhc", .data = &usdhc_imx6sll_data, },
368 { .compatible = "fsl,imx6q-usdhc", .data = &usdhc_imx6q_data, },
369 { .compatible = "fsl,imx6ull-usdhc", .data = &usdhc_imx6ull_data, },
370 { .compatible = "fsl,imx7d-usdhc", .data = &usdhc_imx7d_data, },
371 { .compatible = "fsl,imx7ulp-usdhc", .data = &usdhc_imx7ulp_data, },
372 { .compatible = "fsl,imx8qxp-usdhc", .data = &usdhc_imx8qxp_data, },
373 { .compatible = "fsl,imx8mm-usdhc", .data = &usdhc_imx8mm_data, },
374 { .compatible = "fsl,imxrt1050-usdhc", .data = &usdhc_imxrt1050_data, },
375 { .compatible = "nxp,s32g2-usdhc", .data = &usdhc_s32g2_data, },
382 return data->socdata == &esdhc_imx25_data; in is_imx25_esdhc()
387 return data->socdata == &esdhc_imx53_data; in is_imx53_esdhc()
392 return !!(data->socdata->flags & ESDHC_FLAG_USDHC); in esdhc_is_usdhc()
397 void __iomem *base = host->ioaddr + (reg & ~0x3); in esdhc_clrset_le()
403 #define DRIVER_NAME "sdhci-esdhc-imx"
405 pr_err("%s: " DRIVER_NAME ": " f, mmc_hostname(host->mmc), ## x)
424 readw(host->ioaddr + ESDHC_DEBUG_SEL_AND_STATUS_REG)); in esdhc_dump_debug_regs()
436 ret = readl_poll_timeout(host->ioaddr + ESDHC_PRSSTAT, present_state, in esdhc_wait_for_card_clock_gate_off()
438 if (ret == -ETIMEDOUT) in esdhc_wait_for_card_clock_gate_off()
439 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()
450 buswidth = USDHC_GET_BUSWIDTH(readl(host->ioaddr + SDHCI_HOST_CONTROL)); in usdhc_auto_tuning_mode_sel_and_en()
465 * For USDHC, auto tuning circuit can not handle the async sdio in usdhc_auto_tuning_mode_sel_and_en()
475 if (imx_data->init_card_type == MMC_TYPE_SDIO) in usdhc_auto_tuning_mode_sel_and_en()
482 reg = readl(host->ioaddr + ESDHC_MIX_CTRL); in usdhc_auto_tuning_mode_sel_and_en()
484 writel(reg, host->ioaddr + ESDHC_MIX_CTRL); in usdhc_auto_tuning_mode_sel_and_en()
491 u32 val = readl(host->ioaddr + reg); in esdhc_readl_le()
497 /* move dat[0-3] bits */ in esdhc_readl_le()
504 /* ignore bit[0-15] as it stores cap_1 register val for mx6sl */ in esdhc_readl_le()
505 if (imx_data->socdata->flags & ESDHC_FLAG_HAVE_CAP1) in esdhc_readl_le()
523 if (imx_data->socdata->flags & ESDHC_FLAG_HAVE_CAP1) in esdhc_readl_le()
524 val = readl(host->ioaddr + SDHCI_CAPABILITIES) & 0xFFFF; in esdhc_readl_le()
537 if (IS_ERR_OR_NULL(imx_data->pins_100mhz)) in esdhc_readl_le()
539 if (IS_ERR_OR_NULL(imx_data->pins_200mhz)) in esdhc_readl_le()
561 if ((imx_data->multiblock_status == WAIT_FOR_INT) && in esdhc_readl_le()
564 writel(SDHCI_INT_RESPONSE, host->ioaddr + in esdhc_readl_le()
566 imx_data->multiblock_status = NO_CMD_PENDING; in esdhc_readl_le()
586 * and set D3CD bit will make eSDHC re-sample the card in esdhc_writel_le()
588 * re-sample it by the following steps. in esdhc_writel_le()
590 data = readl(host->ioaddr + SDHCI_HOST_CONTROL); in esdhc_writel_le()
592 writel(data, host->ioaddr + SDHCI_HOST_CONTROL); in esdhc_writel_le()
594 writel(data, host->ioaddr + SDHCI_HOST_CONTROL); in esdhc_writel_le()
603 if (unlikely((imx_data->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT) in esdhc_writel_le()
607 v = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writel_le()
609 writel(v, host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writel_le()
611 if (imx_data->multiblock_status == MULTIBLK_IN_PROCESS) in esdhc_writel_le()
616 writel(data, host->ioaddr + SDHCI_TRANSFER_MODE); in esdhc_writel_le()
617 imx_data->multiblock_status = WAIT_FOR_INT; in esdhc_writel_le()
621 writel(val, host->ioaddr + reg); in esdhc_writel_le()
635 * The usdhc register returns a wrong host version. in esdhc_readw_le()
643 val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_readw_le()
648 if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) in esdhc_readw_le()
649 val = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_readw_le()
650 else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) in esdhc_readw_le()
652 val = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS); in esdhc_readw_le()
667 u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_readw_le()
675 ret = readw(host->ioaddr + SDHCI_TRANSFER_MODE); in esdhc_readw_le()
681 return readw(host->ioaddr + reg); in esdhc_readw_le()
692 new_val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
697 writel(new_val, host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
702 new_val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
707 writel(new_val, host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
708 if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { in esdhc_writew_le()
709 u32 v = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS); in esdhc_writew_le()
710 u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writew_le()
725 writel(v, host->ioaddr + SDHCI_AUTO_CMD_STATUS); in esdhc_writew_le()
726 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writew_le()
730 if ((imx_data->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT) in esdhc_writew_le()
731 && (host->cmd->opcode == SD_IO_RW_EXTENDED) in esdhc_writew_le()
732 && (host->cmd->data->blocks > 1) in esdhc_writew_le()
733 && (host->cmd->data->flags & MMC_DATA_READ)) { in esdhc_writew_le()
735 v = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
737 writel(v, host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_writew_le()
742 u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writew_le()
749 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writew_le()
755 m = readl(host->ioaddr + ESDHC_WTMK_LVL); in esdhc_writew_le()
765 * tuning, when send tuning command, usdhc will in esdhc_writew_le()
778 writel(m, host->ioaddr + ESDHC_WTMK_LVL); in esdhc_writew_le()
784 imx_data->scratchpad = val; in esdhc_writew_le()
788 if (host->cmd->opcode == MMC_STOP_TRANSMISSION) in esdhc_writew_le()
791 if ((host->cmd->opcode == MMC_SET_BLOCK_COUNT) && in esdhc_writew_le()
792 (imx_data->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT)) in esdhc_writew_le()
793 imx_data->multiblock_status = MULTIBLK_IN_PROCESS; in esdhc_writew_le()
797 host->ioaddr + SDHCI_TRANSFER_MODE); in esdhc_writew_le()
799 writel(val << 16 | imx_data->scratchpad, in esdhc_writew_le()
800 host->ioaddr + SDHCI_TRANSFER_MODE); in esdhc_writew_le()
816 val = readl(host->ioaddr + reg); in esdhc_readb_le()
825 return readb(host->ioaddr + reg); in esdhc_readb_le()
865 new_val = readl(host->ioaddr + SDHCI_HOST_CONTROL); in esdhc_writeb_le()
883 * The reset on usdhc fails to clear MIX_CTRL register. in esdhc_writeb_le()
890 new_val = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writeb_le()
892 host->ioaddr + ESDHC_MIX_CTRL); in esdhc_writeb_le()
893 imx_data->is_ddr = 0; in esdhc_writeb_le()
911 return pltfm_host->clock; in esdhc_pltfm_get_max_clock()
918 return pltfm_host->clock / 256 / 16; in esdhc_pltfm_get_min_clock()
926 unsigned int host_clock = pltfm_host->clock; in esdhc_pltfm_set_clock()
927 int ddr_pre_div = imx_data->is_ddr ? 2 : 1; in esdhc_pltfm_set_clock()
934 val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_pltfm_set_clock()
936 host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_pltfm_set_clock()
941 host->mmc->actual_clock = 0; in esdhc_pltfm_set_clock()
951 val = readl(host->ioaddr + ESDHC_DLL_CTRL); in esdhc_pltfm_set_clock()
952 writel(val | BIT(10), host->ioaddr + ESDHC_DLL_CTRL); in esdhc_pltfm_set_clock()
953 temp = readl(host->ioaddr + ESDHC_DLL_CTRL); in esdhc_pltfm_set_clock()
954 writel(val, host->ioaddr + ESDHC_DLL_CTRL); in esdhc_pltfm_set_clock()
964 if ((imx_data->socdata->flags & ESDHC_FLAG_ERR010450) && in esdhc_pltfm_set_clock()
965 (!(host->quirks2 & SDHCI_QUIRK2_NO_1_8_V))) { in esdhc_pltfm_set_clock()
968 max_clock = imx_data->is_ddr ? 45000000 : 150000000; in esdhc_pltfm_set_clock()
980 host->mmc->actual_clock = host_clock / (div * pre_div * ddr_pre_div); in esdhc_pltfm_set_clock()
981 dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", in esdhc_pltfm_set_clock()
982 clock, host->mmc->actual_clock); in esdhc_pltfm_set_clock()
985 div--; in esdhc_pltfm_set_clock()
994 ret = readl_poll_timeout(host->ioaddr + ESDHC_PRSSTAT, temp, in esdhc_pltfm_set_clock()
996 if (ret == -ETIMEDOUT) in esdhc_pltfm_set_clock()
997 dev_warn(mmc_dev(host->mmc), "card clock still not stable in 100us!.\n"); in esdhc_pltfm_set_clock()
1000 val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_pltfm_set_clock()
1002 host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_pltfm_set_clock()
1011 struct esdhc_platform_data *boarddata = &imx_data->boarddata; in esdhc_pltfm_get_ro()
1013 switch (boarddata->wp_type) { in esdhc_pltfm_get_ro()
1015 return mmc_gpio_get_ro(host->mmc); in esdhc_pltfm_get_ro()
1017 return !(readl(host->ioaddr + SDHCI_PRESENT_STATE) & in esdhc_pltfm_get_ro()
1023 return -ENOSYS; in esdhc_pltfm_get_ro()
1055 ctrl = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_reset_tuning()
1057 if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) { in esdhc_reset_tuning()
1060 writel(ctrl, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_reset_tuning()
1061 writel(0, host->ioaddr + ESDHC_TUNE_CTRL_STATUS); in esdhc_reset_tuning()
1062 } else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { in esdhc_reset_tuning()
1063 writel(ctrl, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_reset_tuning()
1064 ctrl = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS); in esdhc_reset_tuning()
1067 writel(ctrl, host->ioaddr + SDHCI_AUTO_CMD_STATUS); in esdhc_reset_tuning()
1069 ret = readl_poll_timeout(host->ioaddr + SDHCI_AUTO_CMD_STATUS, in esdhc_reset_tuning()
1071 if (ret == -ETIMEDOUT) in esdhc_reset_tuning()
1072 dev_warn(mmc_dev(host->mmc), in esdhc_reset_tuning()
1076 * usdhc IP internal logic flag execute_tuning_with_clr_buf, which in esdhc_reset_tuning()
1079 ctrl = readl(host->ioaddr + SDHCI_INT_STATUS); in esdhc_reset_tuning()
1081 writel(ctrl, host->ioaddr + SDHCI_INT_STATUS); in esdhc_reset_tuning()
1092 imx_data->init_card_type = card->type; in usdhc_init_card()
1101 * i.MX uSDHC internally already uses a fixed optimized timing for in usdhc_execute_tuning()
1104 if (host->timing == MMC_TIMING_UHS_DDR50) in usdhc_execute_tuning()
1115 if (!err && !host->tuning_err) in usdhc_execute_tuning()
1130 /* IC suggest to reset USDHC before every tuning command */ in esdhc_prepare_tuning()
1132 ret = readb_poll_timeout(host->ioaddr + SDHCI_SOFTWARE_RESET, sw_rst, in esdhc_prepare_tuning()
1134 if (ret == -ETIMEDOUT) in esdhc_prepare_tuning()
1135 dev_warn(mmc_dev(host->mmc), in esdhc_prepare_tuning()
1138 reg = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_prepare_tuning()
1141 writel(reg, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_prepare_tuning()
1142 writel(val << 8, host->ioaddr + ESDHC_TUNE_CTRL_STATUS); in esdhc_prepare_tuning()
1143 dev_dbg(mmc_dev(host->mmc), in esdhc_prepare_tuning()
1145 val, readl(host->ioaddr + ESDHC_TUNE_CTRL_STATUS)); in esdhc_prepare_tuning()
1152 reg = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_post_tuning()
1154 writel(reg, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_post_tuning()
1165 if (!mmc_send_tuning(host->mmc, opcode, NULL)) in esdhc_executing_tuning()
1174 if (mmc_send_tuning(host->mmc, opcode, NULL)) { in esdhc_executing_tuning()
1175 max -= ESDHC_TUNE_CTRL_STEP; in esdhc_executing_tuning()
1184 ret = mmc_send_tuning(host->mmc, opcode, NULL); in esdhc_executing_tuning()
1187 dev_dbg(mmc_dev(host->mmc), "tuning %s at 0x%x ret %d\n", in esdhc_executing_tuning()
1198 m = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_hs400_enhanced_strobe()
1199 if (ios->enhanced_strobe) in esdhc_hs400_enhanced_strobe()
1203 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_hs400_enhanced_strobe()
1213 dev_dbg(mmc_dev(host->mmc), "change pinctrl state for uhs %d\n", uhs); in esdhc_change_pinstate()
1215 if (IS_ERR(imx_data->pinctrl) || in esdhc_change_pinstate()
1216 IS_ERR(imx_data->pins_100mhz) || in esdhc_change_pinstate()
1217 IS_ERR(imx_data->pins_200mhz)) in esdhc_change_pinstate()
1218 return -EINVAL; in esdhc_change_pinstate()
1223 pinctrl = imx_data->pins_100mhz; in esdhc_change_pinstate()
1228 pinctrl = imx_data->pins_200mhz; in esdhc_change_pinstate()
1232 return pinctrl_select_default_state(mmc_dev(host->mmc)); in esdhc_change_pinstate()
1235 return pinctrl_select_state(imx_data->pinctrl, pinctrl); in esdhc_change_pinstate()
1256 writel(readl(host->ioaddr + ESDHC_VENDOR_SPEC) & in esdhc_set_strobe_dll()
1258 host->ioaddr + ESDHC_VENDOR_SPEC); in esdhc_set_strobe_dll()
1263 host->ioaddr + ESDHC_STROBE_DLL_CTRL); in esdhc_set_strobe_dll()
1265 writel(0, host->ioaddr + ESDHC_STROBE_DLL_CTRL); in esdhc_set_strobe_dll()
1269 * for the uSDHC loopback read clock in esdhc_set_strobe_dll()
1271 if (imx_data->boarddata.strobe_dll_delay_target) in esdhc_set_strobe_dll()
1272 strobe_delay = imx_data->boarddata.strobe_dll_delay_target; in esdhc_set_strobe_dll()
1278 writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL); in esdhc_set_strobe_dll()
1281 ret = readl_poll_timeout(host->ioaddr + ESDHC_STROBE_DLL_STATUS, v, in esdhc_set_strobe_dll()
1283 if (ret == -ETIMEDOUT) in esdhc_set_strobe_dll()
1284 dev_warn(mmc_dev(host->mmc), in esdhc_set_strobe_dll()
1293 struct esdhc_platform_data *boarddata = &imx_data->boarddata; in esdhc_set_uhs_signaling()
1296 m = readl(host->ioaddr + ESDHC_MIX_CTRL); in esdhc_set_uhs_signaling()
1298 imx_data->is_ddr = 0; in esdhc_set_uhs_signaling()
1307 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_set_uhs_signaling()
1312 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_set_uhs_signaling()
1313 imx_data->is_ddr = 1; in esdhc_set_uhs_signaling()
1314 if (boarddata->delay_line) { in esdhc_set_uhs_signaling()
1316 v = boarddata->delay_line << in esdhc_set_uhs_signaling()
1321 writel(v, host->ioaddr + ESDHC_DLL_CTRL); in esdhc_set_uhs_signaling()
1326 writel(m, host->ioaddr + ESDHC_MIX_CTRL); in esdhc_set_uhs_signaling()
1327 imx_data->is_ddr = 1; in esdhc_set_uhs_signaling()
1329 host->ops->set_clock(host, host->clock); in esdhc_set_uhs_signaling()
1345 sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); in esdhc_reset()
1346 sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); in esdhc_reset()
1354 /* Doc Erratum: the uSDHC actual maximum timeout count is 1 << 29 */ in esdhc_get_max_timeout_count()
1377 cqhci_irq(host->mmc, intmask, cmd_error, data_error); in esdhc_cqhci_irq()
1414 struct cqhci_host *cq_host = host->mmc->cqe_private; in sdhci_esdhc_imx_hwinit()
1422 writel(ESDHC_WTMK_DEFAULT_VAL, host->ioaddr + ESDHC_WTMK_LVL); in sdhci_esdhc_imx_hwinit()
1426 * to zero if this usdhc is chosen to boot system. Change in sdhci_esdhc_imx_hwinit()
1435 writel(readl(host->ioaddr + SDHCI_HOST_CONTROL) in sdhci_esdhc_imx_hwinit()
1437 host->ioaddr + SDHCI_HOST_CONTROL); in sdhci_esdhc_imx_hwinit()
1443 if (!(imx_data->socdata->flags & ESDHC_FLAG_SKIP_ERR004536)) { in sdhci_esdhc_imx_hwinit()
1444 writel(readl(host->ioaddr + 0x6c) & ~BIT(7), in sdhci_esdhc_imx_hwinit()
1445 host->ioaddr + 0x6c); in sdhci_esdhc_imx_hwinit()
1449 writel(0x0, host->ioaddr + ESDHC_DLL_CTRL); in sdhci_esdhc_imx_hwinit()
1453 * ESDHC_VEND_SPEC2_EN_BUSY_IRQ, USDHC will generate a in sdhci_esdhc_imx_hwinit()
1460 if (imx_data->socdata->flags & ESDHC_FLAG_CQHCI) { in sdhci_esdhc_imx_hwinit()
1461 tmp = readl(host->ioaddr + ESDHC_VEND_SPEC2); in sdhci_esdhc_imx_hwinit()
1463 writel(tmp, host->ioaddr + ESDHC_VEND_SPEC2); in sdhci_esdhc_imx_hwinit()
1465 host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ; in sdhci_esdhc_imx_hwinit()
1468 if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { in sdhci_esdhc_imx_hwinit()
1469 tmp = readl(host->ioaddr + ESDHC_TUNING_CTRL); in sdhci_esdhc_imx_hwinit()
1477 if (imx_data->boarddata.tuning_start_tap) in sdhci_esdhc_imx_hwinit()
1478 tmp |= imx_data->boarddata.tuning_start_tap; in sdhci_esdhc_imx_hwinit()
1482 if (imx_data->boarddata.tuning_step) { in sdhci_esdhc_imx_hwinit()
1483 tmp |= imx_data->boarddata.tuning_step in sdhci_esdhc_imx_hwinit()
1495 * the buffer read ready interrupt immediately. If usdhc send in sdhci_esdhc_imx_hwinit()
1501 writel(tmp, host->ioaddr + ESDHC_TUNING_CTRL); in sdhci_esdhc_imx_hwinit()
1502 } else if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) { in sdhci_esdhc_imx_hwinit()
1508 tmp = readl(host->ioaddr + ESDHC_TUNING_CTRL); in sdhci_esdhc_imx_hwinit()
1510 writel(tmp, host->ioaddr + ESDHC_TUNING_CTRL); in sdhci_esdhc_imx_hwinit()
1533 struct cqhci_host *cq_host = mmc->cqe_private; in esdhc_cqe_enable()
1546 if (count-- == 0) { in esdhc_cqe_enable()
1547 dev_warn(mmc_dev(host->mmc), in esdhc_cqe_enable()
1560 if (host->flags & SDHCI_REQ_USE_DMA) in esdhc_cqe_enable()
1562 if (!(host->quirks2 & SDHCI_QUIRK2_SUPPORT_SINGLE)) in esdhc_cqe_enable()
1574 dev_err(mmc_dev(host->mmc), in esdhc_cqe_enable()
1597 struct device_node *np = pdev->dev.of_node; in sdhci_esdhc_imx_probe_dt()
1598 struct esdhc_platform_data *boarddata = &imx_data->boarddata; in sdhci_esdhc_imx_probe_dt()
1601 if (of_property_read_bool(np, "fsl,wp-controller")) in sdhci_esdhc_imx_probe_dt()
1602 boarddata->wp_type = ESDHC_WP_CONTROLLER; in sdhci_esdhc_imx_probe_dt()
1609 if (of_property_read_bool(np, "wp-gpios")) in sdhci_esdhc_imx_probe_dt()
1610 boarddata->wp_type = ESDHC_WP_GPIO; in sdhci_esdhc_imx_probe_dt()
1612 of_property_read_u32(np, "fsl,tuning-step", &boarddata->tuning_step); in sdhci_esdhc_imx_probe_dt()
1613 of_property_read_u32(np, "fsl,tuning-start-tap", in sdhci_esdhc_imx_probe_dt()
1614 &boarddata->tuning_start_tap); in sdhci_esdhc_imx_probe_dt()
1616 of_property_read_u32(np, "fsl,strobe-dll-delay-target", in sdhci_esdhc_imx_probe_dt()
1617 &boarddata->strobe_dll_delay_target); in sdhci_esdhc_imx_probe_dt()
1618 if (of_property_read_bool(np, "no-1-8-v")) in sdhci_esdhc_imx_probe_dt()
1619 host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V; in sdhci_esdhc_imx_probe_dt()
1621 if (of_property_read_u32(np, "fsl,delay-line", &boarddata->delay_line)) in sdhci_esdhc_imx_probe_dt()
1622 boarddata->delay_line = 0; in sdhci_esdhc_imx_probe_dt()
1624 mmc_of_parse_voltage(host->mmc, &host->ocr_mask); in sdhci_esdhc_imx_probe_dt()
1626 if (esdhc_is_usdhc(imx_data) && !IS_ERR(imx_data->pinctrl)) { in sdhci_esdhc_imx_probe_dt()
1627 imx_data->pins_100mhz = pinctrl_lookup_state(imx_data->pinctrl, in sdhci_esdhc_imx_probe_dt()
1629 imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl, in sdhci_esdhc_imx_probe_dt()
1634 ret = mmc_of_parse(host->mmc); in sdhci_esdhc_imx_probe_dt()
1639 if (!(host->mmc->caps & MMC_CAP_8_BIT_DATA)) in sdhci_esdhc_imx_probe_dt()
1640 host->mmc->caps2 &= ~(MMC_CAP2_HS400 | MMC_CAP2_HS400_ES); in sdhci_esdhc_imx_probe_dt()
1642 if (mmc_gpio_get_cd(host->mmc) >= 0) in sdhci_esdhc_imx_probe_dt()
1643 host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; in sdhci_esdhc_imx_probe_dt()
1665 imx_data->socdata = device_get_match_data(&pdev->dev); in sdhci_esdhc_imx_probe()
1667 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_imx_probe()
1668 cpu_latency_qos_add_request(&imx_data->pm_qos_req, 0); in sdhci_esdhc_imx_probe()
1670 imx_data->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); in sdhci_esdhc_imx_probe()
1671 if (IS_ERR(imx_data->clk_ipg)) { in sdhci_esdhc_imx_probe()
1672 err = PTR_ERR(imx_data->clk_ipg); in sdhci_esdhc_imx_probe()
1676 imx_data->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); in sdhci_esdhc_imx_probe()
1677 if (IS_ERR(imx_data->clk_ahb)) { in sdhci_esdhc_imx_probe()
1678 err = PTR_ERR(imx_data->clk_ahb); in sdhci_esdhc_imx_probe()
1682 imx_data->clk_per = devm_clk_get(&pdev->dev, "per"); in sdhci_esdhc_imx_probe()
1683 if (IS_ERR(imx_data->clk_per)) { in sdhci_esdhc_imx_probe()
1684 err = PTR_ERR(imx_data->clk_per); in sdhci_esdhc_imx_probe()
1688 pltfm_host->clk = imx_data->clk_per; in sdhci_esdhc_imx_probe()
1689 pltfm_host->clock = clk_get_rate(pltfm_host->clk); in sdhci_esdhc_imx_probe()
1690 err = clk_prepare_enable(imx_data->clk_per); in sdhci_esdhc_imx_probe()
1693 err = clk_prepare_enable(imx_data->clk_ipg); in sdhci_esdhc_imx_probe()
1696 err = clk_prepare_enable(imx_data->clk_ahb); in sdhci_esdhc_imx_probe()
1700 imx_data->pinctrl = devm_pinctrl_get(&pdev->dev); in sdhci_esdhc_imx_probe()
1701 if (IS_ERR(imx_data->pinctrl)) in sdhci_esdhc_imx_probe()
1702 dev_warn(mmc_dev(host->mmc), "could not get pinctrl\n"); in sdhci_esdhc_imx_probe()
1705 host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN; in sdhci_esdhc_imx_probe()
1706 host->mmc->caps |= MMC_CAP_1_8V_DDR | MMC_CAP_3_3V_DDR; in sdhci_esdhc_imx_probe()
1709 host->mmc->caps |= MMC_CAP_CD_WAKE; in sdhci_esdhc_imx_probe()
1711 if (!(imx_data->socdata->flags & ESDHC_FLAG_HS200)) in sdhci_esdhc_imx_probe()
1712 host->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200; in sdhci_esdhc_imx_probe()
1715 writel(0x0, host->ioaddr + ESDHC_MIX_CTRL); in sdhci_esdhc_imx_probe()
1716 writel(0x0, host->ioaddr + SDHCI_AUTO_CMD_STATUS); in sdhci_esdhc_imx_probe()
1717 writel(0x0, host->ioaddr + ESDHC_TUNE_CTRL_STATUS); in sdhci_esdhc_imx_probe()
1720 * Link usdhc specific mmc_host_ops execute_tuning function, in sdhci_esdhc_imx_probe()
1723 host->mmc_host_ops.execute_tuning = usdhc_execute_tuning; in sdhci_esdhc_imx_probe()
1726 * Link usdhc specific mmc_host_ops init card function, in sdhci_esdhc_imx_probe()
1729 host->mmc_host_ops.init_card = usdhc_init_card; in sdhci_esdhc_imx_probe()
1732 if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) in sdhci_esdhc_imx_probe()
1736 if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536) in sdhci_esdhc_imx_probe()
1737 host->quirks |= SDHCI_QUIRK_BROKEN_ADMA; in sdhci_esdhc_imx_probe()
1739 if (imx_data->socdata->flags & ESDHC_FLAG_HS400) in sdhci_esdhc_imx_probe()
1740 host->mmc->caps2 |= MMC_CAP2_HS400; in sdhci_esdhc_imx_probe()
1742 if (imx_data->socdata->flags & ESDHC_FLAG_BROKEN_AUTO_CMD23) in sdhci_esdhc_imx_probe()
1743 host->quirks2 |= SDHCI_QUIRK2_ACMD23_BROKEN; in sdhci_esdhc_imx_probe()
1745 if (imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) { in sdhci_esdhc_imx_probe()
1746 host->mmc->caps2 |= MMC_CAP2_HS400_ES; in sdhci_esdhc_imx_probe()
1747 host->mmc_host_ops.hs400_enhanced_strobe = in sdhci_esdhc_imx_probe()
1751 if (imx_data->socdata->flags & ESDHC_FLAG_CQHCI) { in sdhci_esdhc_imx_probe()
1752 host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD; in sdhci_esdhc_imx_probe()
1753 cq_host = devm_kzalloc(&pdev->dev, sizeof(*cq_host), GFP_KERNEL); in sdhci_esdhc_imx_probe()
1755 err = -ENOMEM; in sdhci_esdhc_imx_probe()
1759 cq_host->mmio = host->ioaddr + ESDHC_CQHCI_ADDR_OFFSET; in sdhci_esdhc_imx_probe()
1760 cq_host->ops = &esdhc_cqhci_ops; in sdhci_esdhc_imx_probe()
1762 err = cqhci_init(cq_host, host->mmc, false); in sdhci_esdhc_imx_probe()
1781 if ((host->mmc->pm_caps & MMC_PM_KEEP_POWER) && in sdhci_esdhc_imx_probe()
1782 (host->mmc->pm_caps & MMC_PM_WAKE_SDIO_IRQ)) in sdhci_esdhc_imx_probe()
1783 device_set_wakeup_capable(&pdev->dev, true); in sdhci_esdhc_imx_probe()
1785 pm_runtime_set_active(&pdev->dev); in sdhci_esdhc_imx_probe()
1786 pm_runtime_set_autosuspend_delay(&pdev->dev, 50); in sdhci_esdhc_imx_probe()
1787 pm_runtime_use_autosuspend(&pdev->dev); in sdhci_esdhc_imx_probe()
1788 pm_suspend_ignore_children(&pdev->dev, 1); in sdhci_esdhc_imx_probe()
1789 pm_runtime_enable(&pdev->dev); in sdhci_esdhc_imx_probe()
1794 clk_disable_unprepare(imx_data->clk_ahb); in sdhci_esdhc_imx_probe()
1796 clk_disable_unprepare(imx_data->clk_ipg); in sdhci_esdhc_imx_probe()
1798 clk_disable_unprepare(imx_data->clk_per); in sdhci_esdhc_imx_probe()
1800 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_imx_probe()
1801 cpu_latency_qos_remove_request(&imx_data->pm_qos_req); in sdhci_esdhc_imx_probe()
1813 pm_runtime_get_sync(&pdev->dev); in sdhci_esdhc_imx_remove()
1814 dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff); in sdhci_esdhc_imx_remove()
1815 pm_runtime_disable(&pdev->dev); in sdhci_esdhc_imx_remove()
1816 pm_runtime_put_noidle(&pdev->dev); in sdhci_esdhc_imx_remove()
1820 clk_disable_unprepare(imx_data->clk_per); in sdhci_esdhc_imx_remove()
1821 clk_disable_unprepare(imx_data->clk_ipg); in sdhci_esdhc_imx_remove()
1822 clk_disable_unprepare(imx_data->clk_ahb); in sdhci_esdhc_imx_remove()
1824 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_imx_remove()
1825 cpu_latency_qos_remove_request(&imx_data->pm_qos_req); in sdhci_esdhc_imx_remove()
1838 if (host->mmc->caps2 & MMC_CAP2_CQE) { in sdhci_esdhc_suspend()
1839 ret = cqhci_suspend(host->mmc); in sdhci_esdhc_suspend()
1844 if ((imx_data->socdata->flags & ESDHC_FLAG_STATE_LOST_IN_LPMODE) && in sdhci_esdhc_suspend()
1845 (host->tuning_mode != SDHCI_TUNING_MODE_1)) { in sdhci_esdhc_suspend()
1846 mmc_retune_timer_stop(host->mmc); in sdhci_esdhc_suspend()
1847 mmc_retune_needed(host->mmc); in sdhci_esdhc_suspend()
1850 if (host->tuning_mode != SDHCI_TUNING_MODE_3) in sdhci_esdhc_suspend()
1851 mmc_retune_needed(host->mmc); in sdhci_esdhc_suspend()
1861 ret = mmc_gpio_set_cd_wake(host->mmc, true); in sdhci_esdhc_suspend()
1875 /* re-initialize hw state in case it's lost in low power mode */ in sdhci_esdhc_resume()
1882 if (host->mmc->caps2 & MMC_CAP2_CQE) in sdhci_esdhc_resume()
1883 ret = cqhci_resume(host->mmc); in sdhci_esdhc_resume()
1886 ret = mmc_gpio_set_cd_wake(host->mmc, false); in sdhci_esdhc_resume()
1900 if (host->mmc->caps2 & MMC_CAP2_CQE) { in sdhci_esdhc_runtime_suspend()
1901 ret = cqhci_suspend(host->mmc); in sdhci_esdhc_runtime_suspend()
1910 if (host->tuning_mode != SDHCI_TUNING_MODE_3) in sdhci_esdhc_runtime_suspend()
1911 mmc_retune_needed(host->mmc); in sdhci_esdhc_runtime_suspend()
1913 imx_data->actual_clock = host->mmc->actual_clock; in sdhci_esdhc_runtime_suspend()
1915 clk_disable_unprepare(imx_data->clk_per); in sdhci_esdhc_runtime_suspend()
1916 clk_disable_unprepare(imx_data->clk_ipg); in sdhci_esdhc_runtime_suspend()
1917 clk_disable_unprepare(imx_data->clk_ahb); in sdhci_esdhc_runtime_suspend()
1919 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_runtime_suspend()
1920 cpu_latency_qos_remove_request(&imx_data->pm_qos_req); in sdhci_esdhc_runtime_suspend()
1932 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_runtime_resume()
1933 cpu_latency_qos_add_request(&imx_data->pm_qos_req, 0); in sdhci_esdhc_runtime_resume()
1935 if (imx_data->socdata->flags & ESDHC_FLAG_CLK_RATE_LOST_IN_PM_RUNTIME) in sdhci_esdhc_runtime_resume()
1936 clk_set_rate(imx_data->clk_per, pltfm_host->clock); in sdhci_esdhc_runtime_resume()
1938 err = clk_prepare_enable(imx_data->clk_ahb); in sdhci_esdhc_runtime_resume()
1942 err = clk_prepare_enable(imx_data->clk_per); in sdhci_esdhc_runtime_resume()
1946 err = clk_prepare_enable(imx_data->clk_ipg); in sdhci_esdhc_runtime_resume()
1950 esdhc_pltfm_set_clock(host, imx_data->actual_clock); in sdhci_esdhc_runtime_resume()
1956 if (host->mmc->caps2 & MMC_CAP2_CQE) in sdhci_esdhc_runtime_resume()
1957 err = cqhci_resume(host->mmc); in sdhci_esdhc_runtime_resume()
1962 clk_disable_unprepare(imx_data->clk_ipg); in sdhci_esdhc_runtime_resume()
1964 clk_disable_unprepare(imx_data->clk_per); in sdhci_esdhc_runtime_resume()
1966 clk_disable_unprepare(imx_data->clk_ahb); in sdhci_esdhc_runtime_resume()
1968 if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) in sdhci_esdhc_runtime_resume()
1969 cpu_latency_qos_remove_request(&imx_data->pm_qos_req); in sdhci_esdhc_runtime_resume()
1982 .name = "sdhci-esdhc-imx",