Fix some corner cases in bus width setting
cover Fix some corner cases in bus width setting
Among other fixes, the commit 786e8f818c25265d12d5d06e257fe2b1ba516134 "mmc: Fix handling of bus widths and DDR card capabilities" changed bus width setting code so that if the attempt to switch to last 1-bit width item fails, the whole initialization fails. This seems to be more correct than earlier ignoring of such error, but this makes sense if the bus width was actually switched. But if all the switching commands fail (e.g. because the card does not support bus width switching at all), then we could just skip last switching to default bus width and treat it as a success.
Also, MMC cards of earlier versions than MMC standard version 4.0 do not support wider bus widths, so it doesn't make sense to even try to switch the bus width for such cards.
Andrew Gabbasov (2):
mmc: Avoid redundant switching to 1-bit bus width for MMC cards
mmc: Skip changing bus width for MMC cards earlier than version 4.0
drivers/mmc/mmc.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
Signature · 1 line
2.1.0
PATCH 1/2 mmc: Avoid redundant switching to 1-bit bus width for MMC cards
If all the commands switching an MMC card to 4- or 8-bit bus width fail, and the bus width for the controller and the driver is still set to default 1 bit, there is no need to send one more command to switch the card to 1-bit bus width. Also, if the card or host controller do not support wider bus widths, there is no need to send a switch command at all.
However, if one of switch commands succeeds, but the subsequent ext_csd fields comparison fails, the card should be switched to some other bus width (next in the list for the loop), or to default 1-bit bus width as a last resort. That's why it would be incorrect to just remove the 1-bit bus width case from the list, it should still be processed in some cases.
--- drivers/mmc/mmc.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/mmc/mmc.c +12 -0
@@ -1139,6 +1139,18 @@ static int mmc_startup(struct mmc *mmc)unsigned int caps = ext_to_hostcaps[extw];/* +* If the bus width is still not changed, +* don't try to set the default again. +* Otherwise, recover from switch attempts +* by switching to 1-bit bus width. +*/ +if ((extw ==EXT_CSD_BUS_WIDTH_1 ) && + (mmc->bus_width ==1 )) { + err =0 ; +break ; + } + +/* * Check to make sure the card and controller support * these capabilities */
Signature · 1 line
2.1.0
PATCH 1/2 mmc: Avoid redundant switching to 1-bit bus width for MMC cards
Hi Andrew,
Quoted 46 lines · Andrew Gabbasov
If all the commands switching an MMC card to 4- or 8-bit bus width fail, and the bus width for the controller and the driver is still set to default 1 bit, there is no need to send one more command to switch the card to 1-bit bus width. Also, if the card or host controller do not support wider bus widths, there is no need to send a switch command at all.
However, if one of switch commands succeeds, but the subsequent
ext_csdfields comparison fails, the card should be switched to some other bus width (next in the list for the loop), or to default 1-bit bus width as a last resort. That's why it would be incorrect to just remove the 1-bit bus width case from the list, it should still be processed in some cases.Signed-off-by Andrew Gabbasov <[email protected]>Tested-by Alexey Brodkin <[email protected]>---
drivers/mmc/mmc.c| 12 ++++++++++++1 file changed, 12 insertions(+)drivers/mmc/mmc.c +12
-0@@ -1139,6 +1139,18 @@ static int mmc_startup(struct mmc *mmc)unsigned int caps = ext_to_hostcaps[extw];/* +* If the bus width is still not changed, +* don't try to set the default again. +* Otherwise, recover from switch attempts +* by switching to 1-bit bus width. +*/ +if ((extw ==EXT_CSD_BUS_WIDTH_1 ) && + (mmc->bus_width ==1 )) { + err =0 ; +break ; + } + +/* * Check to make sure the card and controller support * these capabilities */ Signature · 1 line
2.1.0
Patch looks fine; taken the liberty to remove the superfluous parentheses at the if statement.
Regards
? Pantelis
PATCH 2/2 mmc: Skip changing bus width for MMC cards earlier than version 4.0
In reply to Andrew GabbasovWider bus widths (larger than default 1 bit) appeared in MMC standard version 4.0. So, for MMC cards of any earlier version trying to change the bus width (including ext_csd comparison) does not make any sense. It may work incorrectly and at least cause unnecessary timeouts. So, just skip the entire bus width related activity for earlier versions.
--- drivers/mmc/mmc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/mmc/mmc.c +5 -2
@@ -486,7 +486,7 @@ static int mmc_change_freq(struct mmc *mmc)char cardtype;int err; - mmc->card_caps =MMC_MODE_4BIT |MMC_MODE_8BIT ; + mmc->card_caps =0 ;if (mmc_host_is_spi (mmc))return 0 ;
@@ -495,6 +495,8 @@ static int mmc_change_freq(struct mmc *mmc)if (mmc->version <MMC_VERSION_4 )return 0 ; + mmc->card_caps |=MMC_MODE_4BIT |MMC_MODE_8BIT ; + err =mmc_send_ext_csd (mmc, ext_csd);if (err)
@@ -1107,7 +1109,8 @@ static int mmc_startup(struct mmc *mmc) mmc->tran_speed =50000000 ; else mmc->tran_speed = 25000000; - }else { + }else if (mmc->version >=MMC_VERSION_4 ) { +/* Only version 4 of MMC supports wider bus widths */ int idx;/* An array of possible bus widths in order of preference */
Signature · 1 line
2.1.0
PATCH 2/2 mmc: Skip changing bus width for MMC cards earlier than version 4.0
Hi Pantelis,
Quoted 8 lines · Andrew Gabbasov
Wider bus widths (larger than default 1 bit) appeared in MMC standard version 4.0. So, for MMC cards of any earlier version trying to change the bus width (including
ext_csdcomparison) does not make any sense. It may work incorrectly and at least cause unnecessary timeouts. So, just skip the entire bus width related activity for earlier versions.Signed-off-by Andrew Gabbasov <[email protected]>Tested-by Alexey Brodkin <[email protected]>
This change fixes regression introduced in
https://patchwork.ozlabs.org/patch/416442/ for MMC cards.
Please consider applying if you don't have any objections.
Regards,
Alexey
Pantelis Antoniou
AppliedPATCH 2/2 mmc: Skip changing bus width for MMC cards earlier than version 4.0
In reply to Andrew GabbasovHi Andrew,
Quoted 48 lines · Andrew Gabbasov
Wider bus widths (larger than default 1 bit) appeared in MMC standard version 4.0. So, for MMC cards of any earlier version trying to change the bus width (including
ext_csdcomparison) does not make any sense. It may work incorrectly and at least cause unnecessary timeouts. So, just skip the entire bus width related activity for earlier versions.Signed-off-by Andrew Gabbasov <[email protected]>Tested-by Alexey Brodkin <[email protected]>---
drivers/mmc/mmc.c| 7 +++++--1 file changed, 5 insertions(+), 2 deletions(-)drivers/mmc/mmc.c +5
-2@@ -486,7 +486,7 @@ static int mmc_change_freq(struct mmc *mmc)char cardtype;int err; - mmc->card_caps =MMC_MODE_4BIT |MMC_MODE_8BIT ; + mmc->card_caps =0 ;if (mmc_host_is_spi (mmc))return 0 ;@@ -495,6 +495,8 @@ static int mmc_change_freq(struct mmc *mmc)if (mmc->version <MMC_VERSION_4 )return 0 ; + mmc->card_caps |=MMC_MODE_4BIT |MMC_MODE_8BIT ; + err =mmc_send_ext_csd (mmc, ext_csd);if (err)@@ -1107,7 +1109,8 @@ static int mmc_startup(struct mmc *mmc) mmc->tran_speed =50000000 ; else mmc->tran_speed = 25000000; - }else { + }else if (mmc->version >=MMC_VERSION_4 ) { +/* Only version 4 of MMC supports wider bus widths */ int idx;/* An array of possible bus widths in order of preference */ Signature · 1 line
2.1.0
Applied, thanks.
? Pantelis