Hi Harish, On 2018/4/3 19:34, Harish Jenny K N 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.
Well, it's Ulf's call if it looks good to him, but I still don't like this patch, which adds freq limit for a specific wifi, especially in core driver, sorry. Another one could say "Hey, I have a buggy wifi that should only use 120MHz". So how would you name the quirk for that? Wifi is probably soldered on board, so why can't you limit the max-frequency = <150000000> there?
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
-- 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