Message ID | 2eabee23243f240ed0999311e4cc50e5b0154fb6.1568209763.git.michal.simek@xilinx.com |
---|---|
State | Deferred |
Headers | show |
Series | [U-Boot,RFC] mmc: sdhci: add support for switching to UHS-I modes on ZynqMP Platform | expand |
On 11. 09. 19 15:49, Michal Simek wrote: > From: T Karthik Reddy <t.karthik.reddy@xilinx.com> > > This patch adds support for switching to UHS-I modes on ZynqMP platform. > There is one issue with the ZynqMP ZCU102 where it is not able to power > cycle the SD card. Due to this once the card is initialized in UHS-I > mode it cannot be reinitialized in UHS-I mode again. So to solve this > issue there are some of the checks are made in place to ensure that the > card operates in UHS-I mode even on reinitialization. This will enable > the SD host controller to run SD at UHS-I mode in u-boot if it was > running at UHS-I mode already. > > Signed-off-by: T Karthik Reddy <t.karthik.reddy@xilinx.com> > Signed-off-by: Michal Simek <michal.simek@xilinx.com> > --- > > drivers/mmc/mmc.c | 20 ++++++++++++++++++++ > include/mmc.h | 2 ++ > 2 files changed, 22 insertions(+) > > diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c > index c8f71cd0c1b6..3d25f11942ff 100644 > --- a/drivers/mmc/mmc.c > +++ b/drivers/mmc/mmc.c > @@ -1711,6 +1711,26 @@ static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps) > /* Restrict card's capabilities by what the host can do */ > caps = card_caps & mmc->host_caps; > > + /* > + * If the card is already in 1.8V and the system doesn't have > + * mechanism to power cycle the SD card, it will respond with no 1.8V > + * supported in OCR response. Below check will confirm if the above > + * condition has occurred. > + * > + * If the host is supporting UHS modes and the card is supporting SD > + * specification 3.0 and above, it can operate at UHS modes. > + */ > +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) > + if (!uhs_en && !(mmc_host_is_spi(mmc)) && > + mmc->scr[0] & SD_SCR0_SPEC3 && > + (mmc->card_caps & MMC_MODE_MASK) >= MMC_CAP(UHS_SDR50) && > + (mmc->host_caps & MMC_MODE_MASK) >= MMC_CAP(UHS_SDR50)) { > + uhs_en = true; > + err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_180); > + if (err) > + return err; > + } > +#endif > if (!uhs_en) > caps &= ~UHS_CAPS; > > diff --git a/include/mmc.h b/include/mmc.h > index 686ba0065654..e959ffef2948 100644 > --- a/include/mmc.h > +++ b/include/mmc.h > @@ -66,6 +66,7 @@ > #define MMC_MODE_HS200 MMC_CAP(MMC_HS_200) > #define MMC_MODE_HS400 MMC_CAP(MMC_HS_400) > #define MMC_MODE_HS400_ES MMC_CAP(MMC_HS_400_ES) > +#define MMC_MODE_MASK (MMC_CAP(MMC_MODES_END) - 1) > > #define MMC_CAP_NONREMOVABLE BIT(14) > #define MMC_CAP_NEEDS_POLL BIT(15) > @@ -140,6 +141,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx) > /* SCR definitions in different words */ > #define SD_HIGHSPEED_BUSY 0x00020000 > #define SD_HIGHSPEED_SUPPORTED 0x00020000 > +#define SD_SCR0_SPEC3 BIT(15) > > #define UHS_SDR12_BUS_SPEED 0 > #define HIGH_SPEED_BUS_SPEED 1 > Peng: Any comment about this patch? Thanks, Michal
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index c8f71cd0c1b6..3d25f11942ff 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1711,6 +1711,26 @@ static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps) /* Restrict card's capabilities by what the host can do */ caps = card_caps & mmc->host_caps; + /* + * If the card is already in 1.8V and the system doesn't have + * mechanism to power cycle the SD card, it will respond with no 1.8V + * supported in OCR response. Below check will confirm if the above + * condition has occurred. + * + * If the host is supporting UHS modes and the card is supporting SD + * specification 3.0 and above, it can operate at UHS modes. + */ +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) + if (!uhs_en && !(mmc_host_is_spi(mmc)) && + mmc->scr[0] & SD_SCR0_SPEC3 && + (mmc->card_caps & MMC_MODE_MASK) >= MMC_CAP(UHS_SDR50) && + (mmc->host_caps & MMC_MODE_MASK) >= MMC_CAP(UHS_SDR50)) { + uhs_en = true; + err = mmc_set_signal_voltage(mmc, MMC_SIGNAL_VOLTAGE_180); + if (err) + return err; + } +#endif if (!uhs_en) caps &= ~UHS_CAPS; diff --git a/include/mmc.h b/include/mmc.h index 686ba0065654..e959ffef2948 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -66,6 +66,7 @@ #define MMC_MODE_HS200 MMC_CAP(MMC_HS_200) #define MMC_MODE_HS400 MMC_CAP(MMC_HS_400) #define MMC_MODE_HS400_ES MMC_CAP(MMC_HS_400_ES) +#define MMC_MODE_MASK (MMC_CAP(MMC_MODES_END) - 1) #define MMC_CAP_NONREMOVABLE BIT(14) #define MMC_CAP_NEEDS_POLL BIT(15) @@ -140,6 +141,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx) /* SCR definitions in different words */ #define SD_HIGHSPEED_BUSY 0x00020000 #define SD_HIGHSPEED_SUPPORTED 0x00020000 +#define SD_SCR0_SPEC3 BIT(15) #define UHS_SDR12_BUS_SPEED 0 #define HIGH_SPEED_BUS_SPEED 1