diff options
| -rw-r--r-- | drivers/mmc/host/sdhci-esdhc-imx.c | 86 |
1 files changed, 41 insertions, 45 deletions
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 83023fa6fa34..c84c808ab00b 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c | |||
| @@ -95,22 +95,37 @@ | |||
| 95 | */ | 95 | */ |
| 96 | #define ESDHC_FLAG_USDHC BIT(3) | 96 | #define ESDHC_FLAG_USDHC BIT(3) |
| 97 | 97 | ||
| 98 | enum imx_esdhc_type { | 98 | struct esdhc_soc_data { |
| 99 | IMX25_ESDHC, | 99 | u32 flags; |
| 100 | IMX35_ESDHC, | 100 | }; |
| 101 | IMX51_ESDHC, | 101 | |
| 102 | IMX53_ESDHC, | 102 | static struct esdhc_soc_data esdhc_imx25_data = { |
| 103 | IMX6Q_USDHC, | 103 | .flags = ESDHC_FLAG_ENGCM07207, |
| 104 | }; | ||
| 105 | |||
| 106 | static struct esdhc_soc_data esdhc_imx35_data = { | ||
| 107 | .flags = ESDHC_FLAG_ENGCM07207, | ||
| 108 | }; | ||
| 109 | |||
| 110 | static struct esdhc_soc_data esdhc_imx51_data = { | ||
| 111 | .flags = 0, | ||
| 112 | }; | ||
| 113 | |||
| 114 | static struct esdhc_soc_data esdhc_imx53_data = { | ||
| 115 | .flags = ESDHC_FLAG_MULTIBLK_NO_INT, | ||
| 116 | }; | ||
| 117 | |||
| 118 | static struct esdhc_soc_data usdhc_imx6q_data = { | ||
| 119 | .flags = ESDHC_FLAG_USDHC, | ||
| 104 | }; | 120 | }; |
| 105 | 121 | ||
| 106 | struct pltfm_imx_data { | 122 | struct pltfm_imx_data { |
| 107 | int flags; | ||
| 108 | u32 scratchpad; | 123 | u32 scratchpad; |
| 109 | enum imx_esdhc_type devtype; | ||
| 110 | struct pinctrl *pinctrl; | 124 | struct pinctrl *pinctrl; |
| 111 | struct pinctrl_state *pins_default; | 125 | struct pinctrl_state *pins_default; |
| 112 | struct pinctrl_state *pins_100mhz; | 126 | struct pinctrl_state *pins_100mhz; |
| 113 | struct pinctrl_state *pins_200mhz; | 127 | struct pinctrl_state *pins_200mhz; |
| 128 | const struct esdhc_soc_data *socdata; | ||
| 114 | struct esdhc_platform_data boarddata; | 129 | struct esdhc_platform_data boarddata; |
| 115 | struct clk *clk_ipg; | 130 | struct clk *clk_ipg; |
| 116 | struct clk *clk_ahb; | 131 | struct clk *clk_ahb; |
| @@ -126,13 +141,13 @@ struct pltfm_imx_data { | |||
| 126 | static struct platform_device_id imx_esdhc_devtype[] = { | 141 | static struct platform_device_id imx_esdhc_devtype[] = { |
| 127 | { | 142 | { |
| 128 | .name = "sdhci-esdhc-imx25", | 143 | .name = "sdhci-esdhc-imx25", |
| 129 | .driver_data = IMX25_ESDHC, | 144 | .driver_data = (kernel_ulong_t) &esdhc_imx25_data, |
| 130 | }, { | 145 | }, { |
| 131 | .name = "sdhci-esdhc-imx35", | 146 | .name = "sdhci-esdhc-imx35", |
| 132 | .driver_data = IMX35_ESDHC, | 147 | .driver_data = (kernel_ulong_t) &esdhc_imx35_data, |
| 133 | }, { | 148 | }, { |
| 134 | .name = "sdhci-esdhc-imx51", | 149 | .name = "sdhci-esdhc-imx51", |
| 135 | .driver_data = IMX51_ESDHC, | 150 | .driver_data = (kernel_ulong_t) &esdhc_imx51_data, |
| 136 | }, { | 151 | }, { |
| 137 | /* sentinel */ | 152 | /* sentinel */ |
| 138 | } | 153 | } |
| @@ -140,43 +155,33 @@ static struct platform_device_id imx_esdhc_devtype[] = { | |||
| 140 | MODULE_DEVICE_TABLE(platform, imx_esdhc_devtype); | 155 | MODULE_DEVICE_TABLE(platform, imx_esdhc_devtype); |
| 141 | 156 | ||
| 142 | static const struct of_device_id imx_esdhc_dt_ids[] = { | 157 | static const struct of_device_id imx_esdhc_dt_ids[] = { |
| 143 | { .compatible = "fsl,imx25-esdhc", .data = (void *) IMX25_ESDHC, }, | 158 | { .compatible = "fsl,imx25-esdhc", .data = &esdhc_imx25_data, }, |
| 144 | { .compatible = "fsl,imx35-esdhc", .data = (void *) IMX35_ESDHC, }, | 159 | { .compatible = "fsl,imx35-esdhc", .data = &esdhc_imx35_data, }, |
| 145 | { .compatible = "fsl,imx51-esdhc", .data = (void *) IMX51_ESDHC, }, | 160 | { .compatible = "fsl,imx51-esdhc", .data = &esdhc_imx51_data, }, |
| 146 | { .compatible = "fsl,imx53-esdhc", .data = (void *) IMX53_ESDHC, }, | 161 | { .compatible = "fsl,imx53-esdhc", .data = &esdhc_imx53_data, }, |
| 147 | { .compatible = "fsl,imx6q-usdhc", .data = (void *) IMX6Q_USDHC, }, | 162 | { .compatible = "fsl,imx6q-usdhc", .data = &usdhc_imx6q_data, }, |
| 148 | { /* sentinel */ } | 163 | { /* sentinel */ } |
| 149 | }; | 164 | }; |
| 150 | MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids); | 165 | MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids); |
| 151 | 166 | ||
| 152 | static inline int is_imx25_esdhc(struct pltfm_imx_data *data) | 167 | static inline int is_imx25_esdhc(struct pltfm_imx_data *data) |
| 153 | { | 168 | { |
| 154 | return data->devtype == IMX25_ESDHC; | 169 | return data->socdata == &esdhc_imx25_data; |
| 155 | } | ||
| 156 | |||
| 157 | static inline int is_imx35_esdhc(struct pltfm_imx_data *data) | ||
| 158 | { | ||
| 159 | return data->devtype == IMX35_ESDHC; | ||
| 160 | } | ||
| 161 | |||
| 162 | static inline int is_imx51_esdhc(struct pltfm_imx_data *data) | ||
| 163 | { | ||
| 164 | return data->devtype == IMX51_ESDHC; | ||
| 165 | } | 170 | } |
| 166 | 171 | ||
| 167 | static inline int is_imx53_esdhc(struct pltfm_imx_data *data) | 172 | static inline int is_imx53_esdhc(struct pltfm_imx_data *data) |
| 168 | { | 173 | { |
| 169 | return data->devtype == IMX53_ESDHC; | 174 | return data->socdata == &esdhc_imx53_data; |
| 170 | } | 175 | } |
| 171 | 176 | ||
| 172 | static inline int is_imx6q_usdhc(struct pltfm_imx_data *data) | 177 | static inline int is_imx6q_usdhc(struct pltfm_imx_data *data) |
| 173 | { | 178 | { |
| 174 | return data->devtype == IMX6Q_USDHC; | 179 | return data->socdata == &usdhc_imx6q_data; |
| 175 | } | 180 | } |
| 176 | 181 | ||
| 177 | static inline int esdhc_is_usdhc(struct pltfm_imx_data *data) | 182 | static inline int esdhc_is_usdhc(struct pltfm_imx_data *data) |
| 178 | { | 183 | { |
| 179 | return !!(data->flags & ESDHC_FLAG_USDHC); | 184 | return !!(data->socdata->flags & ESDHC_FLAG_USDHC); |
| 180 | } | 185 | } |
| 181 | 186 | ||
| 182 | static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, int reg) | 187 | static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, int reg) |
| @@ -274,7 +279,7 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg) | |||
| 274 | } | 279 | } |
| 275 | } | 280 | } |
| 276 | 281 | ||
| 277 | if (unlikely((imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT) | 282 | if (unlikely((imx_data->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT) |
| 278 | && (reg == SDHCI_INT_STATUS) | 283 | && (reg == SDHCI_INT_STATUS) |
| 279 | && (val & SDHCI_INT_DATA_END))) { | 284 | && (val & SDHCI_INT_DATA_END))) { |
| 280 | u32 v; | 285 | u32 v; |
| @@ -373,7 +378,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) | |||
| 373 | writel(new_val , host->ioaddr + ESDHC_MIX_CTRL); | 378 | writel(new_val , host->ioaddr + ESDHC_MIX_CTRL); |
| 374 | return; | 379 | return; |
| 375 | case SDHCI_TRANSFER_MODE: | 380 | case SDHCI_TRANSFER_MODE: |
| 376 | if ((imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT) | 381 | if ((imx_data->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT) |
| 377 | && (host->cmd->opcode == SD_IO_RW_EXTENDED) | 382 | && (host->cmd->opcode == SD_IO_RW_EXTENDED) |
| 378 | && (host->cmd->data->blocks > 1) | 383 | && (host->cmd->data->blocks > 1) |
| 379 | && (host->cmd->data->flags & MMC_DATA_READ)) { | 384 | && (host->cmd->data->flags & MMC_DATA_READ)) { |
| @@ -405,7 +410,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) | |||
| 405 | val |= SDHCI_CMD_ABORTCMD; | 410 | val |= SDHCI_CMD_ABORTCMD; |
| 406 | 411 | ||
| 407 | if ((host->cmd->opcode == MMC_SET_BLOCK_COUNT) && | 412 | if ((host->cmd->opcode == MMC_SET_BLOCK_COUNT) && |
| 408 | (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)) | 413 | (imx_data->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT)) |
| 409 | imx_data->multiblock_status = MULTIBLK_IN_PROCESS; | 414 | imx_data->multiblock_status = MULTIBLK_IN_PROCESS; |
| 410 | 415 | ||
| 411 | if (esdhc_is_usdhc(imx_data)) | 416 | if (esdhc_is_usdhc(imx_data)) |
| @@ -861,16 +866,10 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) | |||
| 861 | goto free_sdhci; | 866 | goto free_sdhci; |
| 862 | } | 867 | } |
| 863 | 868 | ||
| 864 | imx_data->devtype = of_id ? (enum imx_esdhc_type) of_id->data : | 869 | imx_data->socdata = of_id ? of_id->data : (struct esdhc_soc_data *) |
| 865 | pdev->id_entry->driver_data; | 870 | pdev->id_entry->driver_data; |
| 866 | pltfm_host->priv = imx_data; | 871 | pltfm_host->priv = imx_data; |
| 867 | 872 | ||
| 868 | if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data)) | ||
| 869 | imx_data->flags |= ESDHC_FLAG_ENGCM07207; | ||
| 870 | |||
| 871 | if (is_imx6q_usdhc(imx_data)) | ||
| 872 | imx_data->flags |= ESDHC_FLAG_USDHC; | ||
| 873 | |||
| 874 | imx_data->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); | 873 | imx_data->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); |
| 875 | if (IS_ERR(imx_data->clk_ipg)) { | 874 | if (IS_ERR(imx_data->clk_ipg)) { |
| 876 | err = PTR_ERR(imx_data->clk_ipg); | 875 | err = PTR_ERR(imx_data->clk_ipg); |
| @@ -911,14 +910,11 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) | |||
| 911 | 910 | ||
| 912 | host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; | 911 | host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; |
| 913 | 912 | ||
| 914 | if (imx_data->flags & ESDHC_FLAG_ENGCM07207) | 913 | if (imx_data->socdata->flags & ESDHC_FLAG_ENGCM07207) |
| 915 | /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */ | 914 | /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */ |
| 916 | host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK | 915 | host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK |
| 917 | | SDHCI_QUIRK_BROKEN_ADMA; | 916 | | SDHCI_QUIRK_BROKEN_ADMA; |
| 918 | 917 | ||
| 919 | if (is_imx53_esdhc(imx_data)) | ||
| 920 | imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT; | ||
| 921 | |||
| 922 | /* | 918 | /* |
| 923 | * The imx6q ROM code will change the default watermark level setting | 919 | * The imx6q ROM code will change the default watermark level setting |
| 924 | * to something insane. Change it back here. | 920 | * to something insane. Change it back here. |
