OSDN Git Service

mmc: sdhci-esdhc-imx: add HS400_ES support for i.MX8QXP
authorBOUGH CHEN <haibo.chen@nxp.com>
Mon, 7 Jan 2019 10:11:32 +0000 (10:11 +0000)
committerUlf Hansson <ulf.hansson@linaro.org>
Mon, 25 Feb 2019 07:40:58 +0000 (08:40 +0100)
Add an new esdhc_soc_data for i.MX8QXP, and add HS400_ES mode
support.

Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
[Ulf: Rebased on top of latest changes]
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/host/sdhci-esdhc-imx.c

index b2187c5..52a9382 100644 (file)
@@ -50,6 +50,7 @@
 #define  ESDHC_MIX_CTRL_AUTO_TUNE_EN   (1 << 24)
 #define  ESDHC_MIX_CTRL_FBCLK_SEL      (1 << 25)
 #define  ESDHC_MIX_CTRL_HS400_EN       (1 << 26)
+#define  ESDHC_MIX_CTRL_HS400_ES_EN    (1 << 27)
 /* Bits 3 and 6 are not SDHCI standard definitions */
 #define  ESDHC_MIX_CTRL_SDHCI_MASK     0xb7
 /* Tuning bits */
  * exceed 150MHz, for DDR mode, SD card clock can't exceed 45MHz.
  */
 #define ESDHC_FLAG_ERR010450           BIT(10)
+/* The IP supports HS400ES mode */
+#define ESDHC_FLAG_HS400_ES            BIT(11)
 
 struct esdhc_soc_data {
        u32 flags;
@@ -192,6 +195,12 @@ static const struct esdhc_soc_data usdhc_imx7d_data = {
                        | ESDHC_FLAG_HS400,
 };
 
+static struct esdhc_soc_data usdhc_imx8qxp_data = {
+       .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
+                       | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
+                       | ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES,
+};
+
 struct pltfm_imx_data {
        u32 scratchpad;
        struct pinctrl *pinctrl;
@@ -238,6 +247,7 @@ static const struct of_device_id imx_esdhc_dt_ids[] = {
        { .compatible = "fsl,imx6q-usdhc", .data = &usdhc_imx6q_data, },
        { .compatible = "fsl,imx6ull-usdhc", .data = &usdhc_imx6ull_data, },
        { .compatible = "fsl,imx7d-usdhc", .data = &usdhc_imx7d_data, },
+       { .compatible = "fsl,imx8qxp-usdhc", .data = &usdhc_imx8qxp_data, },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids);
@@ -896,6 +906,19 @@ static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
        return ret;
 }
 
+static void esdhc_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+       struct sdhci_host *host = mmc_priv(mmc);
+       u32 m;
+
+       m = readl(host->ioaddr + ESDHC_MIX_CTRL);
+       if (ios->enhanced_strobe)
+               m |= ESDHC_MIX_CTRL_HS400_ES_EN;
+       else
+               m &= ~ESDHC_MIX_CTRL_HS400_ES_EN;
+       writel(m, host->ioaddr + ESDHC_MIX_CTRL);
+}
+
 static int esdhc_change_pinstate(struct sdhci_host *host,
                                                unsigned int uhs)
 {
@@ -1377,6 +1400,12 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
        if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
                host->quirks2 |= SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400;
 
+       if (imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) {
+               host->mmc->caps2 |= MMC_CAP2_HS400_ES;
+               host->mmc_host_ops.hs400_enhanced_strobe =
+                                       esdhc_hs400_enhanced_strobe;
+       }
+
        if (of_id)
                err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
        else