On 18 July 2012 11:52, Aaron Lu <aaron.lu@xxxxxxx> wrote: > Hi Chris, > > On Wed, Jul 18, 2012 at 01:28:40AM -0400, Chris Ball wrote: >> Hi Aaron, >> >> On Wed, Jul 18 2012, Aaron Lu wrote: >> > Is the following patch OK? This is based on top of current mmc-next with >> > the previous one in tree. Not sure if this is what you want though. >> >> Yes, that's perfect; squashed into the original patch and pushed out >> to mmc-next. Thanks! >> >> Having there be so many MAX_CURRENT defines -- and having them be >> split in the middle between CAP_ and CAP2_ -- is starting to feel >> a bit awkward. > > I agree. > >> Does anyone have ideas on how that might be tidied up, >> since we have an opportunity to come up with a better plan >> before this gets merged soon? > > What about we add three fields in mmc_host to store the max current > value for 3.3v/3.0v/1.8v and use that when needed instead of the cap > setting of the host? > > I've prepared the following code, please check if this is better than > the current one: > > diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c > index 312b78d..2232004 100644 > --- a/drivers/mmc/core/sd.c > +++ b/drivers/mmc/core/sd.c > @@ -517,11 +517,36 @@ static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status) > return 0; > } > > +/* Get host's max current setting at its current voltage */ > +static u32 sd_get_host_max_current(struct mmc_host *host) > +{ > + u32 voltage, max_current; > + > + voltage = 1 << host->ios.vdd; > + switch (voltage) { > + case MMC_VDD_165_195: > + max_current = host->max_current_180; > + break; > + case MMC_VDD_29_30: > + case MMC_VDD_30_31: > + max_current = host->max_current_300; > + break; > + case MMC_VDD_32_33: > + case MMC_VDD_33_34: > + max_current = host->max_current_330; > + break; > + default: > + max_current = 0; > + } > + > + return max_current; > +} > + > static int sd_set_current_limit(struct mmc_card *card, u8 *status) > { > int current_limit = SD_SET_CURRENT_NO_CHANGE; > int err; > - u32 voltage; > + u32 max_current; > > /* > * Current limit switch is only defined for SDR50, SDR104, and DDR50 > @@ -535,9 +560,9 @@ static int sd_set_current_limit(struct mmc_card *card, u8 *status) > > /* > * Host has different current capabilities when operating at > - * different voltages, so find out the current voltage first. > + * different voltages, so find out its max current first. > */ > - voltage = 1 << card->host->ios.vdd; > + max_current = sd_get_host_max_current(card->host); > > /* > * We only check host's capability here, if we set a limit that is > @@ -547,34 +572,15 @@ static int sd_set_current_limit(struct mmc_card *card, u8 *status) > * when we set current limit to 400/600/800ma, the card will draw its > * maximum 300ma from the host. > */ > - if (voltage == MMC_VDD_165_195) { > - if (card->host->caps & MMC_CAP_MAX_CURRENT_800_180) > - current_limit = SD_SET_CURRENT_LIMIT_800; > - else if (card->host->caps & MMC_CAP_MAX_CURRENT_600_180) > - current_limit = SD_SET_CURRENT_LIMIT_600; > - else if (card->host->caps & MMC_CAP_MAX_CURRENT_400_180) > - current_limit = SD_SET_CURRENT_LIMIT_400; > - else if (card->host->caps & MMC_CAP_MAX_CURRENT_200_180) > - current_limit = SD_SET_CURRENT_LIMIT_200; > - } else if (voltage & (MMC_VDD_29_30 | MMC_VDD_30_31)) { > - if (card->host->caps & MMC_CAP_MAX_CURRENT_800_300) > - current_limit = SD_SET_CURRENT_LIMIT_800; > - else if (card->host->caps & MMC_CAP_MAX_CURRENT_600_300) > - current_limit = SD_SET_CURRENT_LIMIT_600; > - else if (card->host->caps & MMC_CAP_MAX_CURRENT_400_300) > - current_limit = SD_SET_CURRENT_LIMIT_400; > - else if (card->host->caps & MMC_CAP_MAX_CURRENT_200_300) > - current_limit = SD_SET_CURRENT_LIMIT_200; > - } else if (voltage & (MMC_VDD_32_33 | MMC_VDD_33_34)) { > - if (card->host->caps & MMC_CAP_MAX_CURRENT_800_330) > - current_limit = SD_SET_CURRENT_LIMIT_800; > - else if (card->host->caps & MMC_CAP_MAX_CURRENT_600_330) > - current_limit = SD_SET_CURRENT_LIMIT_600; > - else if (card->host->caps & MMC_CAP_MAX_CURRENT_400_330) > - current_limit = SD_SET_CURRENT_LIMIT_400; > - else if (card->host->caps & MMC_CAP_MAX_CURRENT_200_330) > - current_limit = SD_SET_CURRENT_LIMIT_200; > - } > + > + if (max_current >= 800) > + current_limit = SD_SET_CURRENT_LIMIT_800; > + else if (max_current >= 600) > + current_limit = SD_SET_CURRENT_LIMIT_600; > + else if (max_current >= 400) > + current_limit = SD_SET_CURRENT_LIMIT_400; > + else if (max_current >= 200) > + current_limit = SD_SET_CURRENT_LIMIT_200; > > if (current_limit != SD_SET_CURRENT_NO_CHANGE) { > err = mmc_sd_switch(card, 1, 3, current_limit, status); > @@ -707,6 +713,7 @@ struct device_type sd_type = { > int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr) > { > int err; > + u32 max_current; > > /* > * Since we're changing the OCR value, we seem to > @@ -734,9 +741,12 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr) > MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50)) > ocr |= SD_OCR_S18R; > > - /* If the host can supply more than 150mA, XPC should be set to 1. */ > - if (host->caps & (MMC_CAP_SET_XPC_330 | MMC_CAP_SET_XPC_300 | > - MMC_CAP_SET_XPC_180)) > + /* > + * If the host can supply more than 150mA at current voltage, > + * XPC should be set to 1. > + */ > + max_current = sd_get_host_max_current(host); > + if (max_current > 150) > ocr |= SD_OCR_XPC; > > try_again: > diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c > index 455a093..a72ad30 100644 > --- a/drivers/mmc/host/sdhci.c > +++ b/drivers/mmc/host/sdhci.c > @@ -2906,73 +2906,30 @@ int sdhci_add_host(struct sdhci_host *host) > } > > if (caps[0] & SDHCI_CAN_VDD_330) { > - int max_current_330; > - > ocr_avail |= MMC_VDD_32_33 | MMC_VDD_33_34; > > - max_current_330 = ((max_current_caps & > + mmc->max_current_330 = ((max_current_caps & > SDHCI_MAX_CURRENT_330_MASK) >> > SDHCI_MAX_CURRENT_330_SHIFT) * > SDHCI_MAX_CURRENT_MULTIPLIER; > > - if (max_current_330 > 150) > - mmc->caps |= MMC_CAP_SET_XPC_330; > - > - /* Maximum current capabilities of the host at 3.3V */ > - if (max_current_330 >= 800) > - mmc->caps |= MMC_CAP_MAX_CURRENT_800_330; > - else if (max_current_330 >= 600) > - mmc->caps |= MMC_CAP_MAX_CURRENT_600_330; > - else if (max_current_330 >= 400) > - mmc->caps |= MMC_CAP_MAX_CURRENT_400_330; > - else if (max_current_330 >= 200) > - mmc->caps |= MMC_CAP_MAX_CURRENT_200_330; > } > if (caps[0] & SDHCI_CAN_VDD_300) { > - int max_current_300; > - > ocr_avail |= MMC_VDD_29_30 | MMC_VDD_30_31; > > - max_current_300 = ((max_current_caps & > + mmc->max_current_300 = ((max_current_caps & > SDHCI_MAX_CURRENT_300_MASK) >> > SDHCI_MAX_CURRENT_300_SHIFT) * > SDHCI_MAX_CURRENT_MULTIPLIER; > > - if (max_current_300 > 150) > - mmc->caps |= MMC_CAP_SET_XPC_300; > - > - /* Maximum current capabilities of the host at 3.0V */ > - if (max_current_300 >= 800) > - mmc->caps |= MMC_CAP_MAX_CURRENT_800_300; > - else if (max_current_300 >= 600) > - mmc->caps |= MMC_CAP_MAX_CURRENT_600_300; > - else if (max_current_300 >= 400) > - mmc->caps |= MMC_CAP_MAX_CURRENT_400_300; > - else if (max_current_300 >= 200) > - mmc->caps |= MMC_CAP_MAX_CURRENT_200_300; > } > if (caps[0] & SDHCI_CAN_VDD_180) { > - int max_current_180; > - > ocr_avail |= MMC_VDD_165_195; > > - max_current_180 = ((max_current_caps & > + mmc->max_current_180 = ((max_current_caps & > SDHCI_MAX_CURRENT_180_MASK) >> > SDHCI_MAX_CURRENT_180_SHIFT) * > SDHCI_MAX_CURRENT_MULTIPLIER; > - > - if (max_current_180 > 150) > - mmc->caps |= MMC_CAP_SET_XPC_180; > - > - /* Maximum current capabilities of the host at 1.8V */ > - if (max_current_180 >= 800) > - mmc->caps |= MMC_CAP_MAX_CURRENT_800_180; > - else if (max_current_180 >= 600) > - mmc->caps |= MMC_CAP_MAX_CURRENT_600_180; > - else if (max_current_180 >= 400) > - mmc->caps |= MMC_CAP_MAX_CURRENT_400_180; > - else if (max_current_180 >= 200) > - mmc->caps |= MMC_CAP_MAX_CURRENT_200_180; > } > > mmc->ocr_avail = ocr_avail; > diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h > index 79d8921..8d2c052 100644 > --- a/include/linux/mmc/host.h > +++ b/include/linux/mmc/host.h > @@ -189,6 +189,9 @@ struct mmc_host { > u32 ocr_avail_sd; /* SD-specific OCR */ > u32 ocr_avail_mmc; /* MMC-specific OCR */ > struct notifier_block pm_notify; > + u32 max_current_330; > + u32 max_current_300; > + u32 max_current_180; > > #define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */ > #define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */ > @@ -232,16 +235,9 @@ struct mmc_host { > #define MMC_CAP_UHS_SDR50 (1 << 17) /* Host supports UHS SDR50 mode */ > #define MMC_CAP_UHS_SDR104 (1 << 18) /* Host supports UHS SDR104 mode */ > #define MMC_CAP_UHS_DDR50 (1 << 19) /* Host supports UHS DDR50 mode */ > -#define MMC_CAP_SET_XPC_330 (1 << 20) /* Host supports >150mA current at 3.3V */ > -#define MMC_CAP_SET_XPC_300 (1 << 21) /* Host supports >150mA current at 3.0V */ > -#define MMC_CAP_SET_XPC_180 (1 << 22) /* Host supports >150mA current at 1.8V */ > #define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */ > #define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */ > #define MMC_CAP_DRIVER_TYPE_D (1 << 25) /* Host supports Driver Type D */ > -#define MMC_CAP_MAX_CURRENT_200_180 (1 << 26) /* Host max current limit is 200mA at 1.8V */ > -#define MMC_CAP_MAX_CURRENT_400_180 (1 << 27) /* Host max current limit is 400mA at 1.8V */ > -#define MMC_CAP_MAX_CURRENT_600_180 (1 << 28) /* Host max current limit is 600mA at 1.8V */ > -#define MMC_CAP_MAX_CURRENT_800_180 (1 << 29) /* Host max current limit is 800mA at 1.8V */ > #define MMC_CAP_CMD23 (1 << 30) /* CMD23 supported. */ > #define MMC_CAP_HW_RESET (1 << 31) /* Hardware reset */ > > @@ -261,14 +257,6 @@ struct mmc_host { > #define MMC_CAP2_HC_ERASE_SZ (1 << 9) /* High-capacity erase size */ > #define MMC_CAP2_CD_ACTIVE_HIGH (1 << 10) /* Card-detect signal active high */ > #define MMC_CAP2_RO_ACTIVE_HIGH (1 << 11) /* Write-protect signal active high */ > -#define MMC_CAP_MAX_CURRENT_200_300 (1 << 12) /* Host max current limit is 200mA at 3.0V */ > -#define MMC_CAP_MAX_CURRENT_400_300 (1 << 13) /* Host max current limit is 400mA at 3.0V */ > -#define MMC_CAP_MAX_CURRENT_600_300 (1 << 14) /* Host max current limit is 600mA at 3.0V */ > -#define MMC_CAP_MAX_CURRENT_800_300 (1 << 15) /* Host max current limit is 800mA at 3.0V */ > -#define MMC_CAP_MAX_CURRENT_200_330 (1 << 16) /* Host max current limit is 200mA at 3.3V */ > -#define MMC_CAP_MAX_CURRENT_400_330 (1 << 17) /* Host max current limit is 400mA at 3.3V */ > -#define MMC_CAP_MAX_CURRENT_600_330 (1 << 18) /* Host max current limit is 600mA at 3.3V */ > -#define MMC_CAP_MAX_CURRENT_800_330 (1 << 19) /* Host max current limit is 800mA at 3.3V */ > #define MMC_CAP2_PACKED_RD (1 << 20) /* Allow packed read */ > #define MMC_CAP2_PACKED_WR (1 << 21) /* Allow packed write */ > #define MMC_CAP2_PACKED_CMD (MMC_CAP2_PACKED_RD | \ > Looks like a better solution than earlier one. Reviewed By: Girish K S <girish.shivananjappa@xxxxxxxxxx> Chris, How about the holes created by removal of caps2 macros. Will they be adjusted to follow the sequence or left as it is for future use. > > Thanks, > Aaron > -- 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