On 3 April 2018 at 13:34, Harish Jenny K N <harish_kandiga@xxxxxxxxxx> wrote: > This patch adds a quirk to handle broken UHS which > can be used to reduce the SDIO clock rate for some > chips with broken UHS. I would rather not limit the quirk to UHS mode, but instead make it a generic quirk for limiting the clock frequency for a card. I believe this will be useful for any error prone cards. Hence, I suggest to re-name the quirk to "MMC_QUIRK_LIMIT_CLK_RATE". Additionally, while adding the quirk, let's make it possible to pick the clock rate depending on the "card id" as to avoid having one quirk per frequency. Kind regards Uffe > > Signed-off-by: Harish Jenny K N <harish_kandiga@xxxxxxxxxx> > --- > drivers/mmc/core/card.h | 5 +++++ > drivers/mmc/core/sdio.c | 19 +++++++++++++++++++ > include/linux/mmc/card.h | 2 ++ > 3 files changed, 26 insertions(+) > > diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h > index 9c821ee..e6c7dad 100644 > --- a/drivers/mmc/core/card.h > +++ b/drivers/mmc/core/card.h > @@ -221,4 +221,9 @@ static inline int mmc_card_broken_hpi(const struct mmc_card *c) > return c->quirks & MMC_QUIRK_BROKEN_HPI; > } > > +static inline int mmc_card_broken_uhs(const struct mmc_card *c) > +{ > + return c->quirks & MMC_QUIRK_BROKEN_UHS; > +} > + > #endif > diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c > index c599a62..d3fcc4c 100644 > --- a/drivers/mmc/core/sdio.c > +++ b/drivers/mmc/core/sdio.c > @@ -444,6 +444,7 @@ static int sdio_set_bus_speed_mode(struct mmc_card *card) > unsigned int bus_speed, timing; > int err; > unsigned char speed; > + unsigned char cccr; > > /* > * If the host doesn't support any of the UHS-I modes, fallback on > @@ -460,6 +461,24 @@ static int sdio_set_bus_speed_mode(struct mmc_card *card) > timing = MMC_TIMING_UHS_SDR104; > card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR; > card->sd_bus_speed = UHS_SDR104_BUS_SPEED; > + > + err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_CCCR, > + 0, &cccr); > + if (err) > + return err; > + > + if ((cccr & 0x0f) >= SDIO_CCCR_REV_3_00) { > + if (mmc_host_uhs(card->host) && > + mmc_card_broken_uhs(card)) { > + /* > + * Reduce the max clock rate to > + * 150MHz for SD_MODE_UHS_SDR104. > + */ > + card->sw_caps.uhs_max_dtr = > + UHS_SDR104_REDUCED_DTR; > + } > + } > + > } else if ((card->host->caps & MMC_CAP_UHS_DDR50) && > (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) { > bus_speed = SDIO_SPEED_DDR50; > diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h > index 279b390..daab735 100644 > --- a/include/linux/mmc/card.h > +++ b/include/linux/mmc/card.h > @@ -152,6 +152,7 @@ struct sd_switch_caps { > unsigned int uhs_max_dtr; > #define HIGH_SPEED_MAX_DTR 50000000 > #define UHS_SDR104_MAX_DTR 208000000 > +#define UHS_SDR104_REDUCED_DTR 150000000 > #define UHS_SDR50_MAX_DTR 100000000 > #define UHS_DDR50_MAX_DTR 50000000 > #define UHS_SDR25_MAX_DTR UHS_DDR50_MAX_DTR > @@ -268,6 +269,7 @@ struct mmc_card { > #define MMC_QUIRK_BROKEN_IRQ_POLLING (1<<11) /* Polling SDIO_CCCR_INTx could create a fake interrupt */ > #define MMC_QUIRK_TRIM_BROKEN (1<<12) /* Skip trim */ > #define MMC_QUIRK_BROKEN_HPI (1<<13) /* Disable broken HPI support */ > +#define MMC_QUIRK_BROKEN_UHS (1<<14) /* Broken UHS */ > > bool reenable_cmdq; /* Re-enable Command Queue */ > > -- > 1.9.1 > > -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html