[U-Boot] [PATCH] MMC: disable multiblock rw on old rev OMAP3 silicon

Make existing field b_max field in struct mmc unconditional and use it instead of CONFIG_SYS_MMC_MAX_BLK_COUNT in mmc_bread and mmc_bwrite.
Initialize b_max to CONFIG_SYS_MMC_MAX_BLK_COUNT in mmc_register if it has not been initialized by the hw driver.
Initialize b_max to 1 in omap_hsmmc.c for old rev silicon OMAP3 to disable multi block rw.
Signed-off-by: John Rigby john.rigby@linaro.org --- drivers/mmc/mmc.c | 8 ++++---- drivers/mmc/omap_hsmmc.c | 8 ++++++++ include/mmc.h | 2 -- 3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index f27b7c7..f6d31f5 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -243,8 +243,7 @@ mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src) return 0;
do { - cur = (blocks_todo > CONFIG_SYS_MMC_MAX_BLK_COUNT) ? - CONFIG_SYS_MMC_MAX_BLK_COUNT : blocks_todo; + cur = (blocks_todo > mmc->b_max) ? mmc->b_max : blocks_todo; if(mmc_write_blocks(mmc, start, cur, src) != cur) return 0; blocks_todo -= cur; @@ -320,8 +319,7 @@ static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst) return 0;
do { - cur = (blocks_todo > CONFIG_SYS_MMC_MAX_BLK_COUNT) ? - CONFIG_SYS_MMC_MAX_BLK_COUNT : blocks_todo; + cur = (blocks_todo > mmc->b_max) ? mmc->b_max : blocks_todo; if(mmc_read_blocks(mmc, dst, start, cur) != cur) return 0; blocks_todo -= cur; @@ -1029,6 +1027,8 @@ int mmc_register(struct mmc *mmc) mmc->block_dev.removable = 1; mmc->block_dev.block_read = mmc_bread; mmc->block_dev.block_write = mmc_bwrite; + if (!mmc->b_max) + mmc->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
INIT_LIST_HEAD (&mmc->link);
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index 6f2280a..1fab249 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -465,6 +465,14 @@ int omap_mmc_init(int dev_index) mmc->f_min = 400000; mmc->f_max = 52000000;
+#if defined(CONFIG_OMAP34XX) + /* + * Silicon revs 2.1 and older do not support multiblock transfers. + */ + if (get_cpu_rev() <= CPU_3XX_ES21) + mmc->b_max = 1; +#endif + mmc_register(mmc);
return 0; diff --git a/include/mmc.h b/include/mmc.h index e0a56d9..b4197a7 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -283,9 +283,7 @@ struct mmc { struct mmc_cmd *cmd, struct mmc_data *data); void (*set_ios)(struct mmc *mmc); int (*init)(struct mmc *mmc); -#ifdef CONFIG_MMC_MBLOCK uint b_max; -#endif };
int mmc_register(struct mmc *mmc);

Make existing field b_max field in struct mmc unconditional and use it instead of CONFIG_SYS_MMC_MAX_BLK_COUNT in mmc_bread and mmc_bwrite.
Initialize b_max to CONFIG_SYS_MMC_MAX_BLK_COUNT in mmc_register if it has not been initialized by the hw driver.
Initialize b_max to 1 in omap_hsmmc.c for old rev silicon OMAP3 to disable multi block rw.
Signed-off-by: John Rigby john.rigby@linaro.org --- v2: Test cpu family and rev
drivers/mmc/mmc.c | 8 ++++---- drivers/mmc/omap_hsmmc.c | 8 ++++++++ include/mmc.h | 2 -- 3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index d69eaa1..59ca4df 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -144,8 +144,7 @@ mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src) return 0;
do { - cur = (blocks_todo > CONFIG_SYS_MMC_MAX_BLK_COUNT) ? - CONFIG_SYS_MMC_MAX_BLK_COUNT : blocks_todo; + cur = (blocks_todo > mmc->b_max) ? mmc->b_max : blocks_todo; if(mmc_write_blocks(mmc, start, cur, src) != cur) return 0; blocks_todo -= cur; @@ -217,8 +216,7 @@ static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst) return 0;
do { - cur = (blocks_todo > CONFIG_SYS_MMC_MAX_BLK_COUNT) ? - CONFIG_SYS_MMC_MAX_BLK_COUNT : blocks_todo; + cur = (blocks_todo > mmc->b_max) ? mmc->b_max : blocks_todo; if(mmc_read_blocks(mmc, dst, start, cur) != cur) return 0; blocks_todo -= cur; @@ -852,6 +850,8 @@ int mmc_register(struct mmc *mmc) mmc->block_dev.removable = 1; mmc->block_dev.block_read = mmc_bread; mmc->block_dev.block_write = mmc_bwrite; + if (!mmc->b_max) + mmc->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
INIT_LIST_HEAD (&mmc->link);
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index 6f2280a..685ff74 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -465,6 +465,14 @@ int omap_mmc_init(int dev_index) mmc->f_min = 400000; mmc->f_max = 52000000;
+#if defined(CONFIG_OMAP34XX) + /* + * 34XX silicon revs 2.1 and older do not support multiblock transfers. + */ + if ((get_cpu_family() == CPU_OMAP34XX) && (get_cpu_rev() <= CPU_3XX_ES21)) + mmc->b_max = 1; +#endif + mmc_register(mmc);
return 0; diff --git a/include/mmc.h b/include/mmc.h index fcd0fd1..91d0495 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -274,9 +274,7 @@ struct mmc { struct mmc_cmd *cmd, struct mmc_data *data); void (*set_ios)(struct mmc *mmc); int (*init)(struct mmc *mmc); -#ifdef CONFIG_MMC_MBLOCK uint b_max; -#endif };
int mmc_register(struct mmc *mmc);

On Apr 14, 2011, at 10:46 AM, John Rigby wrote:
Make existing field b_max field in struct mmc unconditional and use it instead of CONFIG_SYS_MMC_MAX_BLK_COUNT in mmc_bread and mmc_bwrite.
Initialize b_max to CONFIG_SYS_MMC_MAX_BLK_COUNT in mmc_register if it has not been initialized by the hw driver.
Initialize b_max to 1 in omap_hsmmc.c for old rev silicon OMAP3 to disable multi block rw.
Signed-off-by: John Rigby john.rigby@linaro.org
v2: Test cpu family and rev
drivers/mmc/mmc.c | 8 ++++---- drivers/mmc/omap_hsmmc.c | 8 ++++++++ include/mmc.h | 2 --
Please split apart the omap changes vs the generic changes.
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index d69eaa1..59ca4df 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -144,8 +144,7 @@ mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src) return 0;
do {
cur = (blocks_todo > CONFIG_SYS_MMC_MAX_BLK_COUNT) ?
CONFIG_SYS_MMC_MAX_BLK_COUNT : blocks_todo;
if(mmc_write_blocks(mmc, start, cur, src) != cur) return 0; blocks_todo -= cur;cur = (blocks_todo > mmc->b_max) ? mmc->b_max : blocks_todo;
@@ -217,8 +216,7 @@ static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst) return 0;
do {
cur = (blocks_todo > CONFIG_SYS_MMC_MAX_BLK_COUNT) ?
CONFIG_SYS_MMC_MAX_BLK_COUNT : blocks_todo;
if(mmc_read_blocks(mmc, dst, start, cur) != cur) return 0; blocks_todo -= cur;cur = (blocks_todo > mmc->b_max) ? mmc->b_max : blocks_todo;
@@ -852,6 +850,8 @@ int mmc_register(struct mmc *mmc) mmc->block_dev.removable = 1; mmc->block_dev.block_read = mmc_bread; mmc->block_dev.block_write = mmc_bwrite;
if (!mmc->b_max)
mmc->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
INIT_LIST_HEAD (&mmc->link);
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index 6f2280a..685ff74 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -465,6 +465,14 @@ int omap_mmc_init(int dev_index) mmc->f_min = 400000; mmc->f_max = 52000000;
+#if defined(CONFIG_OMAP34XX)
- /*
* 34XX silicon revs 2.1 and older do not support multiblock transfers.
*/
- if ((get_cpu_family() == CPU_OMAP34XX) && (get_cpu_rev() <= CPU_3XX_ES21))
mmc->b_max = 1;
+#endif
It would be better if we could avoid platform-specific code in the driver....but I see that there's already a lot of that, so I'll save that fight for another day. :)
mmc_register(mmc);
return 0; diff --git a/include/mmc.h b/include/mmc.h index fcd0fd1..91d0495 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -274,9 +274,7 @@ struct mmc { struct mmc_cmd *cmd, struct mmc_data *data); void (*set_ios)(struct mmc *mmc); int (*init)(struct mmc *mmc); -#ifdef CONFIG_MMC_MBLOCK uint b_max; -#endif
Can you go and remove CONFIG_MMC_MBLOCK from the 3 other places it appears? It seems to be unnecessary at the moment.
Andy

Make existing field b_max field in struct mmc unconditional and use it instead of CONFIG_SYS_MMC_MAX_BLK_COUNT in mmc_bread and mmc_bwrite.
Initialize b_max to CONFIG_SYS_MMC_MAX_BLK_COUNT in mmc_register if it has not been initialized by the hw driver.
Initialize b_max to 0 in all callers to mmc_register.
Signed-off-by: John Rigby john.rigby@linaro.org --- V2: Split generic b_max support from omap specific use of b_max
drivers/mmc/bfin_sdh.c | 2 ++ drivers/mmc/davinci_mmc.c | 3 +-- drivers/mmc/gen_atmel_mci.c | 2 ++ drivers/mmc/mmc.c | 8 ++++---- drivers/mmc/mxcmmc.c | 2 ++ drivers/mmc/omap_hsmmc.c | 2 ++ drivers/mmc/s5p_mmc.c | 1 + include/mmc.h | 2 -- 8 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c index 31b6459..bc9057f 100644 --- a/drivers/mmc/bfin_sdh.c +++ b/drivers/mmc/bfin_sdh.c @@ -257,6 +257,8 @@ int bfin_mmc_init(bd_t *bis) mmc->f_min = mmc->f_max >> 9; mmc->block_dev.part_type = PART_TYPE_DOS;
+ mmc->b_max = 0; + mmc_register(mmc);
return 0; diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c index d5d19eb..5d918e6 100644 --- a/drivers/mmc/davinci_mmc.c +++ b/drivers/mmc/davinci_mmc.c @@ -394,9 +394,8 @@ int davinci_mmc_init(bd_t *bis, struct davinci_mmc *host) mmc->voltages = host->voltages; mmc->host_caps = host->host_caps;
-#ifdef CONFIG_MMC_MBLOCK mmc->b_max = DAVINCI_MAX_BLOCKS; -#endif + mmc_register(mmc);
return 0; diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index 2984d64..6577925 100644 --- a/drivers/mmc/gen_atmel_mci.c +++ b/drivers/mmc/gen_atmel_mci.c @@ -348,6 +348,8 @@ int atmel_mci_init(void *regs) mmc->f_min = get_mci_clk_rate() / (2*256); mmc->f_max = get_mci_clk_rate() / (2*1);
+ mmc->b_max = 0; + mmc_register(mmc);
return 0; diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index f27b7c7..f6d31f5 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -243,8 +243,7 @@ mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src) return 0;
do { - cur = (blocks_todo > CONFIG_SYS_MMC_MAX_BLK_COUNT) ? - CONFIG_SYS_MMC_MAX_BLK_COUNT : blocks_todo; + cur = (blocks_todo > mmc->b_max) ? mmc->b_max : blocks_todo; if(mmc_write_blocks(mmc, start, cur, src) != cur) return 0; blocks_todo -= cur; @@ -320,8 +319,7 @@ static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst) return 0;
do { - cur = (blocks_todo > CONFIG_SYS_MMC_MAX_BLK_COUNT) ? - CONFIG_SYS_MMC_MAX_BLK_COUNT : blocks_todo; + cur = (blocks_todo > mmc->b_max) ? mmc->b_max : blocks_todo; if(mmc_read_blocks(mmc, dst, start, cur) != cur) return 0; blocks_todo -= cur; @@ -1029,6 +1027,8 @@ int mmc_register(struct mmc *mmc) mmc->block_dev.removable = 1; mmc->block_dev.block_read = mmc_bread; mmc->block_dev.block_write = mmc_bwrite; + if (!mmc->b_max) + mmc->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
INIT_LIST_HEAD (&mmc->link);
diff --git a/drivers/mmc/mxcmmc.c b/drivers/mmc/mxcmmc.c index 5963953..ab1fc82 100644 --- a/drivers/mmc/mxcmmc.c +++ b/drivers/mmc/mxcmmc.c @@ -511,6 +511,8 @@ static int mxcmci_initialize(bd_t *bis) mmc->f_min = imx_get_perclk2() >> 7; mmc->f_max = imx_get_perclk2() >> 1;
+ mmc->b_max = 0; + mmc_register(mmc);
return 0; diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index 6f2280a..dcbde89 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -465,6 +465,8 @@ int omap_mmc_init(int dev_index) mmc->f_min = 400000; mmc->f_max = 52000000;
+ mmc->b_max = 0; + mmc_register(mmc);
return 0; diff --git a/drivers/mmc/s5p_mmc.c b/drivers/mmc/s5p_mmc.c index 0323800..668c28b 100644 --- a/drivers/mmc/s5p_mmc.c +++ b/drivers/mmc/s5p_mmc.c @@ -466,6 +466,7 @@ static int s5p_mmc_initialize(int dev_index, int bus_width)
mmc_host[dev_index].clock = 0; mmc_host[dev_index].reg = s5p_get_base_mmc(dev_index); + mmc->m_bmax = 0; mmc_register(mmc);
return 0; diff --git a/include/mmc.h b/include/mmc.h index e0a56d9..b4197a7 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -283,9 +283,7 @@ struct mmc { struct mmc_cmd *cmd, struct mmc_data *data); void (*set_ios)(struct mmc *mmc); int (*init)(struct mmc *mmc); -#ifdef CONFIG_MMC_MBLOCK uint b_max; -#endif };
int mmc_register(struct mmc *mmc);

Signed-off-by: John Rigby john.rigby@linaro.org --- V2: split out omap_hsmmc use of b_max into separate patch
drivers/mmc/omap_hsmmc.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index dcbde89..a2a6d55 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -467,6 +467,14 @@ int omap_mmc_init(int dev_index)
mmc->b_max = 0;
+#if defined(CONFIG_OMAP34XX) + /* + * Silicon revs 2.1 and older do not support multiblock transfers. + */ + if (get_cpu_rev() <= CPU_3XX_ES21) + mmc->b_max = 1; +#endif + mmc_register(mmc);
return 0;

Signed-off-by: John Rigby john.rigby@linaro.org --- V3: use get_cpu_family and get_cpu_rev in test, previous patch also disabled multiblock on beagle-xm
drivers/mmc/omap_hsmmc.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index dcbde89..957b987 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -467,6 +467,14 @@ int omap_mmc_init(int dev_index)
mmc->b_max = 0;
+#if defined(CONFIG_OMAP34XX) + /* + * Silicon revs 2.1 and older do not support multiblock transfers. + */ + if ((get_cpu_family() == CPU_OMAP34XX) && (get_cpu_rev() <= CPU_3XX_ES21)) + mmc->b_max = 1; +#endif + mmc_register(mmc);
return 0;
participants (2)
-
Andy Fleming
-
John Rigby