mmc: step power class after final selection of bus mode
Power class is changed once only after selection of bus modes including speed and bus-width finishes finally. Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> Tested-by: Jaehoon Chung <jh80.chung@samsung.com> Acked-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <chris@printf.net>
This commit is contained in:
parent
2415c0ef61
commit
2385049dd5
|
@ -724,17 +724,13 @@ static struct device_type mmc_type = {
|
|||
* extended CSD register, select it by executing the
|
||||
* mmc_switch command.
|
||||
*/
|
||||
static int mmc_select_powerclass(struct mmc_card *card,
|
||||
unsigned int bus_width)
|
||||
static int __mmc_select_powerclass(struct mmc_card *card,
|
||||
unsigned int bus_width)
|
||||
{
|
||||
int err = 0;
|
||||
struct mmc_host *host = card->host;
|
||||
struct mmc_ext_csd *ext_csd = &card->ext_csd;
|
||||
unsigned int pwrclass_val = 0;
|
||||
struct mmc_host *host;
|
||||
|
||||
BUG_ON(!card);
|
||||
|
||||
host = card->host;
|
||||
BUG_ON(!host);
|
||||
int err = 0;
|
||||
|
||||
/* Power class selection is supported for versions >= 4.0 */
|
||||
if (card->csd.mmca_vsn < CSD_SPEC_VER_4)
|
||||
|
@ -746,14 +742,14 @@ static int mmc_select_powerclass(struct mmc_card *card,
|
|||
|
||||
switch (1 << host->ios.vdd) {
|
||||
case MMC_VDD_165_195:
|
||||
if (host->ios.clock <= 26000000)
|
||||
pwrclass_val = card->ext_csd.raw_pwr_cl_26_195;
|
||||
else if (host->ios.clock <= 52000000)
|
||||
if (host->ios.clock <= MMC_HIGH_26_MAX_DTR)
|
||||
pwrclass_val = ext_csd->raw_pwr_cl_26_195;
|
||||
else if (host->ios.clock <= MMC_HIGH_52_MAX_DTR)
|
||||
pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ?
|
||||
card->ext_csd.raw_pwr_cl_52_195 :
|
||||
card->ext_csd.raw_pwr_cl_ddr_52_195;
|
||||
else if (host->ios.clock <= 200000000)
|
||||
pwrclass_val = card->ext_csd.raw_pwr_cl_200_195;
|
||||
ext_csd->raw_pwr_cl_52_195 :
|
||||
ext_csd->raw_pwr_cl_ddr_52_195;
|
||||
else if (host->ios.clock <= MMC_HS200_MAX_DTR)
|
||||
pwrclass_val = ext_csd->raw_pwr_cl_200_195;
|
||||
break;
|
||||
case MMC_VDD_27_28:
|
||||
case MMC_VDD_28_29:
|
||||
|
@ -764,14 +760,14 @@ static int mmc_select_powerclass(struct mmc_card *card,
|
|||
case MMC_VDD_33_34:
|
||||
case MMC_VDD_34_35:
|
||||
case MMC_VDD_35_36:
|
||||
if (host->ios.clock <= 26000000)
|
||||
pwrclass_val = card->ext_csd.raw_pwr_cl_26_360;
|
||||
else if (host->ios.clock <= 52000000)
|
||||
if (host->ios.clock <= MMC_HIGH_26_MAX_DTR)
|
||||
pwrclass_val = ext_csd->raw_pwr_cl_26_360;
|
||||
else if (host->ios.clock <= MMC_HIGH_52_MAX_DTR)
|
||||
pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ?
|
||||
card->ext_csd.raw_pwr_cl_52_360 :
|
||||
card->ext_csd.raw_pwr_cl_ddr_52_360;
|
||||
else if (host->ios.clock <= 200000000)
|
||||
pwrclass_val = card->ext_csd.raw_pwr_cl_200_360;
|
||||
ext_csd->raw_pwr_cl_52_360 :
|
||||
ext_csd->raw_pwr_cl_ddr_52_360;
|
||||
else if (host->ios.clock <= MMC_HS200_MAX_DTR)
|
||||
pwrclass_val = ext_csd->raw_pwr_cl_200_360;
|
||||
break;
|
||||
default:
|
||||
pr_warning("%s: Voltage range not supported "
|
||||
|
@ -797,6 +793,37 @@ static int mmc_select_powerclass(struct mmc_card *card,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int mmc_select_powerclass(struct mmc_card *card)
|
||||
{
|
||||
struct mmc_host *host = card->host;
|
||||
u32 bus_width, ext_csd_bits;
|
||||
int err, ddr;
|
||||
|
||||
/* Power class selection is supported for versions >= 4.0 */
|
||||
if (card->csd.mmca_vsn < CSD_SPEC_VER_4)
|
||||
return 0;
|
||||
|
||||
bus_width = host->ios.bus_width;
|
||||
/* Power class values are defined only for 4/8 bit bus */
|
||||
if (bus_width == MMC_BUS_WIDTH_1)
|
||||
return 0;
|
||||
|
||||
ddr = card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_52;
|
||||
if (ddr)
|
||||
ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
|
||||
EXT_CSD_DDR_BUS_WIDTH_8 : EXT_CSD_DDR_BUS_WIDTH_4;
|
||||
else
|
||||
ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
|
||||
EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4;
|
||||
|
||||
err = __mmc_select_powerclass(card, ext_csd_bits);
|
||||
if (err)
|
||||
pr_warn("%s: power class selection to bus width %d ddr %d failed\n",
|
||||
mmc_hostname(host), 1 << bus_width, ddr);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Selects the desired buswidth and switch to the HS200 mode
|
||||
* if bus width set without error
|
||||
|
@ -1158,11 +1185,6 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
|
|||
|
||||
ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
|
||||
EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4;
|
||||
err = mmc_select_powerclass(card, ext_csd_bits);
|
||||
if (err)
|
||||
pr_warning("%s: power class selection to bus width %d"
|
||||
" failed\n", mmc_hostname(card->host),
|
||||
1 << bus_width);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1191,12 +1213,6 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
|
|||
bus_width = bus_widths[idx];
|
||||
if (bus_width == MMC_BUS_WIDTH_1)
|
||||
ddr = 0; /* no DDR for 1-bit width */
|
||||
err = mmc_select_powerclass(card, ext_csd_bits[idx][0]);
|
||||
if (err)
|
||||
pr_warning("%s: power class selection to "
|
||||
"bus width %d failed\n",
|
||||
mmc_hostname(card->host),
|
||||
1 << bus_width);
|
||||
|
||||
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
|
||||
EXT_CSD_BUS_WIDTH,
|
||||
|
@ -1221,13 +1237,6 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
|
|||
}
|
||||
|
||||
if (!err && ddr) {
|
||||
err = mmc_select_powerclass(card, ext_csd_bits[idx][1]);
|
||||
if (err)
|
||||
pr_warning("%s: power class selection to "
|
||||
"bus width %d ddr %d failed\n",
|
||||
mmc_hostname(card->host),
|
||||
1 << bus_width, ddr);
|
||||
|
||||
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
|
||||
EXT_CSD_BUS_WIDTH,
|
||||
ext_csd_bits[idx][1],
|
||||
|
@ -1264,6 +1273,11 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Choose the power class with selected bus interface
|
||||
*/
|
||||
mmc_select_powerclass(card);
|
||||
|
||||
/*
|
||||
* Enable HPI feature (if supported)
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue