| From: Stefan Agner <stefan@agner.ch> |
| Date: Wed, 4 Jul 2018 17:07:45 +0200 |
| Subject: mmc: sdhci-esdhc-imx: allow 1.8V modes without 100/200MHz pinctrl |
| states |
| |
| commit 92748beac07c471d995fbec642b63572dc01b3dc upstream. |
| |
| If pinctrl nodes for 100/200MHz are missing, the controller should |
| not select any mode which need signal frequencies 100MHz or higher. |
| To prevent such speed modes the driver currently uses the quirk flag |
| SDHCI_QUIRK2_NO_1_8_V. This works nicely for SD cards since 1.8V |
| signaling is required for all faster modes and slower modes use 3.3V |
| signaling only. |
| |
| However, there are eMMC modes which use 1.8V signaling and run below |
| 100MHz, e.g. DDR52 at 1.8V. With using SDHCI_QUIRK2_NO_1_8_V this |
| mode is prevented. When using a fixed 1.8V regulator as vqmmc-supply |
| the stack has no valid mode to use. In this tenuous situation the |
| kernel continuously prints voltage switching errors: |
| mmc1: Switching to 3.3V signalling voltage failed |
| |
| Avoid using SDHCI_QUIRK2_NO_1_8_V and prevent faster modes by |
| altering the SDHCI capability register. With that the stack is able |
| to select 1.8V modes even if no faster pinctrl states are available: |
| # cat /sys/kernel/debug/mmc1/ios |
| ... |
| timing spec: 8 (mmc DDR52) |
| signal voltage: 1 (1.80 V) |
| ... |
| |
| Link: http://lkml.kernel.org/r/20180628081331.13051-1-stefan@agner.ch |
| Signed-off-by: Stefan Agner <stefan@agner.ch> |
| Fixes: ad93220de7da ("mmc: sdhci-esdhc-imx: change pinctrl state according |
| to uhs mode") |
| Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> |
| [bwh: Backported to 3.16: |
| - There is no SDHCI_SUPPORT_HS400 flag to clear |
| - Adjust context] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| --- a/drivers/mmc/host/sdhci-esdhc-imx.c |
| +++ b/drivers/mmc/host/sdhci-esdhc-imx.c |
| @@ -261,6 +261,15 @@ static u32 esdhc_readl_le(struct sdhci_h |
| val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104 |
| | SDHCI_SUPPORT_SDR50 |
| | SDHCI_USE_SDR50_TUNING; |
| + |
| + /* |
| + * Do not advertise faster UHS modes if there are no |
| + * pinctrl states for 100MHz/200MHz. |
| + */ |
| + if (IS_ERR_OR_NULL(imx_data->pins_100mhz) || |
| + IS_ERR_OR_NULL(imx_data->pins_200mhz)) |
| + val &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_DDR50 |
| + | SDHCI_SUPPORT_SDR104); |
| } |
| } |
| |
| @@ -1108,15 +1117,6 @@ static int sdhci_esdhc_imx_probe(struct |
| ESDHC_PINCTRL_STATE_100MHZ); |
| imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl, |
| ESDHC_PINCTRL_STATE_200MHZ); |
| - if (IS_ERR(imx_data->pins_100mhz) || |
| - IS_ERR(imx_data->pins_200mhz)) { |
| - dev_warn(mmc_dev(host->mmc), |
| - "could not get ultra high speed state, work on normal mode\n"); |
| - /* fall back to not support uhs by specify no 1.8v quirk */ |
| - host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V; |
| - } |
| - } else { |
| - host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V; |
| } |
| |
| err = sdhci_add_host(host); |