[U-Boot] [PATCH 0/4] omapl138_lcdk: fix MMC boot

From: Bartosz Golaszewski bgolaszewski@baylibre.com
Booting from MMC on omapl138-lcdk is currently broken after we enabled driver-model in SPL. While I know what's wrong - the bind() callback not being called - I can't for the life of me figure out how to fix it.
I'm still working on proper changes, but for now, I'd like to propose this series which fixes MMC boot with a workaround in which we call mmc_boot() manually from probe.
First two patches drop some legacy code that's no longer needed. The third patch adds a U_BOOT_DEVICE() for mmc as we don't yet have full DT support (also in-progress). The last patch adds the workaround to the davinci mmc driver.
This series depends on Adam Ford's patch increasing the pre-reloc malloc pool.
[1] https://patchwork.ozlabs.org/patch/1192574/
Bartosz Golaszewski (4): mmc: davinci: drop support for ti,dm6441-mmc mmc: davinci: drop struct davinci_mmc_plat board: omapl138_lcdk: add the mmc device to SPL mmc: davinci: fix mmc boot in SPL
arch/arm/mach-davinci/Kconfig | 1 + .../mach-davinci/include/mach/sdmmc_defs.h | 6 -- board/davinci/da8xxevm/omapl138_lcdk.c | 10 ++- drivers/mmc/davinci_mmc.c | 73 +++++++------------ 4 files changed, 36 insertions(+), 54 deletions(-)

From: Bartosz Golaszewski bgolaszewski@baylibre.com
The DM family of DaVinci SoCs is no longer supported. Drop the irrelevant code from the driver.
Signed-off-by: Bartosz Golaszewski bgolaszewski@baylibre.com --- .../mach-davinci/include/mach/sdmmc_defs.h | 6 --- board/davinci/da8xxevm/omapl138_lcdk.c | 1 - drivers/mmc/davinci_mmc.c | 42 +++---------------- 3 files changed, 5 insertions(+), 44 deletions(-)
diff --git a/arch/arm/mach-davinci/include/mach/sdmmc_defs.h b/arch/arm/mach-davinci/include/mach/sdmmc_defs.h index 5755c45f91..46f6391aa2 100644 --- a/arch/arm/mach-davinci/include/mach/sdmmc_defs.h +++ b/arch/arm/mach-davinci/include/mach/sdmmc_defs.h @@ -149,15 +149,9 @@ struct davinci_mmc { uint input_clk; /* Input clock to MMC controller */ uint host_caps; /* Host capabilities */ uint voltages; /* Host supported voltages */ - uint version; /* MMC Controller version */ struct mmc_config cfg; };
-enum { - MMC_CTLR_VERSION_1 = 0, /* DM644x and DM355 */ - MMC_CTLR_VERSION_2, /* DA830 */ -}; - int davinci_mmc_init(bd_t *bis, struct davinci_mmc *host);
#endif /* _SDMMC_DEFS_H */ diff --git a/board/davinci/da8xxevm/omapl138_lcdk.c b/board/davinci/da8xxevm/omapl138_lcdk.c index 27a51d6a78..d4cda0a8a7 100644 --- a/board/davinci/da8xxevm/omapl138_lcdk.c +++ b/board/davinci/da8xxevm/omapl138_lcdk.c @@ -342,7 +342,6 @@ static struct davinci_mmc mmc_sd0 = { .reg_base = (struct davinci_mmc_regs *)DAVINCI_MMC_SD0_BASE, .host_caps = MMC_MODE_4BIT, /* DA850 supports only 4-bit SD/MMC */ .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, - .version = MMC_CTLR_VERSION_2, };
int board_mmc_init(bd_t *bis) diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c index 0d63279db0..370b18cc78 100644 --- a/drivers/mmc/davinci_mmc.c +++ b/drivers/mmc/davinci_mmc.c @@ -26,16 +26,10 @@ #define clear_bit(addr, val) set_val((addr), (get_val(addr) & ~(val)))
#ifdef CONFIG_DM_MMC -struct davinci_of_data { - const char *name; - u8 version; -}; - /* Davinci MMC board definitions */ struct davinci_mmc_priv { struct davinci_mmc_regs *reg_base; /* Register base address */ uint input_clk; /* Input clock to MMC controller */ - uint version; /* MMC Controller version */ struct gpio_desc cd_gpio; /* Card Detect GPIO */ struct gpio_desc wp_gpio; /* Write Protect GPIO */ }; @@ -173,7 +167,7 @@ davinci_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data *
/* Clear status registers */ mmcstatus = get_val(®s->mmcst0); - fifo_words = (host->version == MMC_CTLR_VERSION_2) ? 16 : 8; + fifo_words = 16; fifo_bytes = fifo_words << 2;
/* Wait for any previous busy signal to be cleared */ @@ -211,8 +205,7 @@ davinci_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data * set_val(®s->mmcfifoctl, (MMCFIFOCTL_FIFOLEV | MMCFIFOCTL_FIFORST));
- if (host->version == MMC_CTLR_VERSION_2) - cmddata |= MMCCMD_DMATRIG; + cmddata |= MMCCMD_DMATRIG;
cmddata |= MMCCMD_WDATX; if (data->flags == MMC_DATA_READ) { @@ -494,18 +487,13 @@ static int davinci_mmc_probe(struct udevice *dev) struct davinci_mmc_plat *plat = dev_get_platdata(dev); struct davinci_mmc_priv *priv = dev_get_priv(dev); struct mmc_config *cfg = &plat->cfg; - struct davinci_of_data *data = - (struct davinci_of_data *)dev_get_driver_data(dev); + cfg->f_min = 200000; cfg->f_max = 25000000; cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34, cfg->host_caps = MMC_MODE_4BIT, /* DA850 supports only 4-bit SD/MMC */ cfg->b_max = DAVINCI_MAX_BLOCKS; - - if (data) { - cfg->name = data->name; - priv->version = data->version; - } + cfg->name = "da830-mmc";
priv->reg_base = (struct davinci_mmc_regs *)dev_read_addr(dev); priv->input_clk = clk_get(DAVINCI_MMCSD_CLKID); @@ -528,28 +516,8 @@ static int davinci_mmc_bind(struct udevice *dev) return mmc_bind(dev, &plat->mmc, &plat->cfg); }
- -const struct davinci_of_data davinci_mmc_host_info[] = { - { - .name = "dm6441-mmc", - .version = MMC_CTLR_VERSION_1, - }, - { - .name = "da830-mmc", - .version = MMC_CTLR_VERSION_2, - }, - {}, -}; - static const struct udevice_id davinci_mmc_ids[] = { - { - .compatible = "ti,dm6441-mmc", - .data = (ulong) &davinci_mmc_host_info[MMC_CTLR_VERSION_1] - }, - { - .compatible = "ti,da830-mmc", - .data = (ulong) &davinci_mmc_host_info[MMC_CTLR_VERSION_2] - }, + { .compatible = "ti,da830-mmc" }, {}, };

On Thu, Nov 14, 2019 at 04:10:28PM +0100, Bartosz Golaszewski wrote:
From: Bartosz Golaszewski bgolaszewski@baylibre.com
The DM family of DaVinci SoCs is no longer supported. Drop the irrelevant code from the driver.
Signed-off-by: Bartosz Golaszewski bgolaszewski@baylibre.com
Applied to u-boot/master, thanks!

From: Bartosz Golaszewski bgolaszewski@baylibre.com
struct mmc_config & struct mmc don't need to be exported over platform data, but can instead be private in the driver.
Remove struct davinci_mmc_plat.
Signed-off-by: Bartosz Golaszewski bgolaszewski@baylibre.com --- drivers/mmc/davinci_mmc.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c index 370b18cc78..a27a039f9b 100644 --- a/drivers/mmc/davinci_mmc.c +++ b/drivers/mmc/davinci_mmc.c @@ -32,10 +32,6 @@ struct davinci_mmc_priv { uint input_clk; /* Input clock to MMC controller */ struct gpio_desc cd_gpio; /* Card Detect GPIO */ struct gpio_desc wp_gpio; /* Write Protect GPIO */ -}; - -struct davinci_mmc_plat -{ struct mmc_config cfg; struct mmc mmc; }; @@ -484,9 +480,8 @@ int davinci_mmc_init(bd_t *bis, struct davinci_mmc *host) static int davinci_mmc_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); - struct davinci_mmc_plat *plat = dev_get_platdata(dev); struct davinci_mmc_priv *priv = dev_get_priv(dev); - struct mmc_config *cfg = &plat->cfg; + struct mmc_config *cfg = &priv->cfg;
cfg->f_min = 200000; cfg->f_max = 25000000; @@ -504,16 +499,16 @@ static int davinci_mmc_probe(struct udevice *dev) gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, GPIOD_IS_IN); #endif
- upriv->mmc = &plat->mmc; + upriv->mmc = &priv->mmc;
return davinci_dm_mmc_init(dev); }
static int davinci_mmc_bind(struct udevice *dev) { - struct davinci_mmc_plat *plat = dev_get_platdata(dev); + struct davinci_mmc_priv *priv = dev_get_priv(dev);
- return mmc_bind(dev, &plat->mmc, &plat->cfg); + return mmc_bind(dev, &priv->mmc, &priv->cfg); }
static const struct udevice_id davinci_mmc_ids[] = { @@ -530,7 +525,6 @@ U_BOOT_DRIVER(davinci_mmc_drv) = { #endif .probe = davinci_mmc_probe, .ops = &davinci_mmc_ops, - .platdata_auto_alloc_size = sizeof(struct davinci_mmc_plat), .priv_auto_alloc_size = sizeof(struct davinci_mmc_priv), }; #endif

On Thu, Nov 14, 2019 at 04:10:29PM +0100, Bartosz Golaszewski wrote:
From: Bartosz Golaszewski bgolaszewski@baylibre.com
struct mmc_config & struct mmc don't need to be exported over platform data, but can instead be private in the driver.
Remove struct davinci_mmc_plat.
Signed-off-by: Bartosz Golaszewski bgolaszewski@baylibre.com
Applied to u-boot/master, thanks!

On Thu, Nov 14, 2019 at 9:10 AM Bartosz Golaszewski brgl@bgdev.pl wrote:
From: Bartosz Golaszewski bgolaszewski@baylibre.com
struct mmc_config & struct mmc don't need to be exported over platform data, but can instead be private in the driver.
Remove struct davinci_mmc_plat.
This patch appears to break the da850-evm.
With the pending release of 2020.01, is there any way we can revert before release and try to apply this going forward with more time to test?
As of now, the da850-evm cannot read/write from the MMC card from U-Boot which includes MMC booting.
adam
Signed-off-by: Bartosz Golaszewski bgolaszewski@baylibre.com
drivers/mmc/davinci_mmc.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c index 370b18cc78..a27a039f9b 100644 --- a/drivers/mmc/davinci_mmc.c +++ b/drivers/mmc/davinci_mmc.c @@ -32,10 +32,6 @@ struct davinci_mmc_priv { uint input_clk; /* Input clock to MMC controller */ struct gpio_desc cd_gpio; /* Card Detect GPIO */ struct gpio_desc wp_gpio; /* Write Protect GPIO */ -};
-struct davinci_mmc_plat -{ struct mmc_config cfg; struct mmc mmc; }; @@ -484,9 +480,8 @@ int davinci_mmc_init(bd_t *bis, struct davinci_mmc *host) static int davinci_mmc_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
struct davinci_mmc_plat *plat = dev_get_platdata(dev); struct davinci_mmc_priv *priv = dev_get_priv(dev);
struct mmc_config *cfg = &plat->cfg;
struct mmc_config *cfg = &priv->cfg; cfg->f_min = 200000; cfg->f_max = 25000000;
@@ -504,16 +499,16 @@ static int davinci_mmc_probe(struct udevice *dev) gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, GPIOD_IS_IN); #endif
upriv->mmc = &plat->mmc;
upriv->mmc = &priv->mmc; return davinci_dm_mmc_init(dev);
}
static int davinci_mmc_bind(struct udevice *dev) {
struct davinci_mmc_plat *plat = dev_get_platdata(dev);
struct davinci_mmc_priv *priv = dev_get_priv(dev);
return mmc_bind(dev, &plat->mmc, &plat->cfg);
return mmc_bind(dev, &priv->mmc, &priv->cfg);
}
static const struct udevice_id davinci_mmc_ids[] = { @@ -530,7 +525,6 @@ U_BOOT_DRIVER(davinci_mmc_drv) = { #endif .probe = davinci_mmc_probe, .ops = &davinci_mmc_ops,
.platdata_auto_alloc_size = sizeof(struct davinci_mmc_plat), .priv_auto_alloc_size = sizeof(struct davinci_mmc_priv),
};
#endif
2.23.0

pt., 3 sty 2020 o 17:01 Adam Ford aford173@gmail.com napisał(a):
On Thu, Nov 14, 2019 at 9:10 AM Bartosz Golaszewski brgl@bgdev.pl wrote:
From: Bartosz Golaszewski bgolaszewski@baylibre.com
struct mmc_config & struct mmc don't need to be exported over platform data, but can instead be private in the driver.
Remove struct davinci_mmc_plat.
This patch appears to break the da850-evm.
With the pending release of 2020.01, is there any way we can revert before release and try to apply this going forward with more time to test?
As of now, the da850-evm cannot read/write from the MMC card from U-Boot which includes MMC booting.
This is strange, this change doesn't seem to affect the logic.
This isn't revertible automatically anymore, due to other patches that came before and after. We can probably try to revert it manually.
Bart

On Fri, Jan 03, 2020 at 05:50:38PM +0100, Bartosz Golaszewski wrote:
pt., 3 sty 2020 o 17:01 Adam Ford aford173@gmail.com napisał(a):
On Thu, Nov 14, 2019 at 9:10 AM Bartosz Golaszewski brgl@bgdev.pl wrote:
From: Bartosz Golaszewski bgolaszewski@baylibre.com
struct mmc_config & struct mmc don't need to be exported over platform data, but can instead be private in the driver.
Remove struct davinci_mmc_plat.
This patch appears to break the da850-evm.
With the pending release of 2020.01, is there any way we can revert before release and try to apply this going forward with more time to test?
As of now, the da850-evm cannot read/write from the MMC card from U-Boot which includes MMC booting.
This is strange, this change doesn't seem to affect the logic.
This isn't revertible automatically anymore, due to other patches that came before and after. We can probably try to revert it manually.
Doing a git revert and fixing up the one hunk that didn't go cleanly is easy, should I push that?

On Fri, Jan 3, 2020 at 10:59 AM Tom Rini trini@konsulko.com wrote:
On Fri, Jan 03, 2020 at 05:50:38PM +0100, Bartosz Golaszewski wrote:
pt., 3 sty 2020 o 17:01 Adam Ford aford173@gmail.com napisał(a):
On Thu, Nov 14, 2019 at 9:10 AM Bartosz Golaszewski brgl@bgdev.pl wrote:
From: Bartosz Golaszewski bgolaszewski@baylibre.com
struct mmc_config & struct mmc don't need to be exported over platform data, but can instead be private in the driver.
Remove struct davinci_mmc_plat.
This patch appears to break the da850-evm.
With the pending release of 2020.01, is there any way we can revert before release and try to apply this going forward with more time to test?
As of now, the da850-evm cannot read/write from the MMC card from U-Boot which includes MMC booting.
This is strange, this change doesn't seem to affect the logic.
This isn't revertible automatically anymore, due to other patches that came before and after. We can probably try to revert it manually.
Doing a git revert and fixing up the one hunk that didn't go cleanly is easy, should I push that?
That would make me happy. :-) I don't know about Bartosz.
If you have a patch, I can quickly test it today.
adam
-- Tom

From: Bartosz Golaszewski bgolaszewski@baylibre.com
We don't have full device-tree support in SPL yet - add an appropriate U_BOOT_DEVICE() to the board file.
Signed-off-by: Bartosz Golaszewski bgolaszewski@baylibre.com --- arch/arm/mach-davinci/Kconfig | 1 + board/davinci/da8xxevm/omapl138_lcdk.c | 9 +++++++++ 2 files changed, 10 insertions(+)
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index adc50922c8..8a81c07881 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -14,6 +14,7 @@ config TARGET_OMAPL138_LCDK bool "OMAPL138 LCDK" select SOC_DA8XX select SUPPORT_SPL + select SPL_BOARD_INIT
config TARGET_LEGOEV3 bool "LEGO MINDSTORMS EV3" diff --git a/board/davinci/da8xxevm/omapl138_lcdk.c b/board/davinci/da8xxevm/omapl138_lcdk.c index d4cda0a8a7..608a7f28eb 100644 --- a/board/davinci/da8xxevm/omapl138_lcdk.c +++ b/board/davinci/da8xxevm/omapl138_lcdk.c @@ -366,4 +366,13 @@ U_BOOT_DEVICE(omapl138_uart) = { .name = "ns16550_serial", .platdata = &serial_pdata, }; + +U_BOOT_DEVICE(omapl138_mmc) = { + .name = "davinci_mmc", +}; + +void spl_board_init(void) +{ + davinci_configure_pin_mux(mmc0_pins, ARRAY_SIZE(mmc0_pins)); +} #endif

On Thu, Nov 14, 2019 at 04:10:30PM +0100, Bartosz Golaszewski wrote:
From: Bartosz Golaszewski bgolaszewski@baylibre.com
We don't have full device-tree support in SPL yet - add an appropriate U_BOOT_DEVICE() to the board file.
Signed-off-by: Bartosz Golaszewski bgolaszewski@baylibre.com
Applied to u-boot/master, thanks!

From: Bartosz Golaszewski bgolaszewski@baylibre.com
The MMC boot is currently broken on omapl138-lcdk after enabling the driver model in SPL. The main problem is the driver's bind callback not being called after probe in SPL (even with the DM_FLAG_PRE_RELOC flag specified).
While a proper fix is still being worked on, this hacky changeset at least fixes the MMC boot on this platform by calling mmc_bind() manually from probe().
Signed-off-by: Bartosz Golaszewski bgolaszewski@baylibre.com --- drivers/mmc/davinci_mmc.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c index a27a039f9b..c3f7b57665 100644 --- a/drivers/mmc/davinci_mmc.c +++ b/drivers/mmc/davinci_mmc.c @@ -482,6 +482,9 @@ static int davinci_mmc_probe(struct udevice *dev) struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct davinci_mmc_priv *priv = dev_get_priv(dev); struct mmc_config *cfg = &priv->cfg; +#ifdef CONFIG_SPL_BUILD + int ret; +#endif
cfg->f_min = 200000; cfg->f_max = 25000000; @@ -501,6 +504,20 @@ static int davinci_mmc_probe(struct udevice *dev)
upriv->mmc = &priv->mmc;
+#ifdef CONFIG_SPL_BUILD + /* + * FIXME This is a temporary workaround to enable the driver model in + * SPL on omapl138-lcdk. For some reason the bind() callback is not + * being called in SPL for MMC which breaks the mmc boot - the hack + * is to call mmc_bind() from probe(). We also don't have full DT + * support in SPL, hence the hard-coded base register address. + */ + priv->reg_base = (struct davinci_mmc_regs *)DAVINCI_MMC_SD0_BASE; + ret = mmc_bind(dev, &priv->mmc, &priv->cfg); + if (ret) + return ret; +#endif + return davinci_dm_mmc_init(dev); }

On Thu, Nov 14, 2019 at 04:10:31PM +0100, Bartosz Golaszewski wrote:
From: Bartosz Golaszewski bgolaszewski@baylibre.com
The MMC boot is currently broken on omapl138-lcdk after enabling the driver model in SPL. The main problem is the driver's bind callback not being called after probe in SPL (even with the DM_FLAG_PRE_RELOC flag specified).
While a proper fix is still being worked on, this hacky changeset at least fixes the MMC boot on this platform by calling mmc_bind() manually from probe().
Signed-off-by: Bartosz Golaszewski bgolaszewski@baylibre.com
Applied to u-boot/master, thanks!

czw., 14 lis 2019 o 16:10 Bartosz Golaszewski brgl@bgdev.pl napisał(a):
From: Bartosz Golaszewski bgolaszewski@baylibre.com
Booting from MMC on omapl138-lcdk is currently broken after we enabled driver-model in SPL. While I know what's wrong - the bind() callback not being called - I can't for the life of me figure out how to fix it.
I'm still working on proper changes, but for now, I'd like to propose this series which fixes MMC boot with a workaround in which we call mmc_boot() manually from probe.
First two patches drop some legacy code that's no longer needed. The third patch adds a U_BOOT_DEVICE() for mmc as we don't yet have full DT support (also in-progress). The last patch adds the workaround to the davinci mmc driver.
This series depends on Adam Ford's patch increasing the pre-reloc malloc pool.
[1] https://patchwork.ozlabs.org/patch/1192574/
Bartosz Golaszewski (4): mmc: davinci: drop support for ti,dm6441-mmc mmc: davinci: drop struct davinci_mmc_plat board: omapl138_lcdk: add the mmc device to SPL mmc: davinci: fix mmc boot in SPL
arch/arm/mach-davinci/Kconfig | 1 + .../mach-davinci/include/mach/sdmmc_defs.h | 6 -- board/davinci/da8xxevm/omapl138_lcdk.c | 10 ++- drivers/mmc/davinci_mmc.c | 73 +++++++------------ 4 files changed, 36 insertions(+), 54 deletions(-)
-- 2.23.0
Gentle ping.
Bart

On Mon, Dec 2, 2019 at 3:32 AM Bartosz Golaszewski brgl@bgdev.pl wrote:
czw., 14 lis 2019 o 16:10 Bartosz Golaszewski brgl@bgdev.pl napisał(a):
From: Bartosz Golaszewski bgolaszewski@baylibre.com
Booting from MMC on omapl138-lcdk is currently broken after we enabled driver-model in SPL. While I know what's wrong - the bind() callback not being called - I can't for the life of me figure out how to fix it.
I'm still working on proper changes, but for now, I'd like to propose this series which fixes MMC boot with a workaround in which we call mmc_boot() manually from probe.
First two patches drop some legacy code that's no longer needed. The third patch adds a U_BOOT_DEVICE() for mmc as we don't yet have full DT support (also in-progress). The last patch adds the workaround to the davinci mmc driver.
This series depends on Adam Ford's patch increasing the pre-reloc malloc pool.
[1] https://patchwork.ozlabs.org/patch/1192574/
Bartosz Golaszewski (4): mmc: davinci: drop support for ti,dm6441-mmc mmc: davinci: drop struct davinci_mmc_plat board: omapl138_lcdk: add the mmc device to SPL mmc: davinci: fix mmc boot in SPL
arch/arm/mach-davinci/Kconfig | 1 + .../mach-davinci/include/mach/sdmmc_defs.h | 6 -- board/davinci/da8xxevm/omapl138_lcdk.c | 10 ++- drivers/mmc/davinci_mmc.c | 73 +++++++------------ 4 files changed, 36 insertions(+), 54 deletions(-)
-- 2.23.0
Gentle ping.
I wonder if having a 'fixes:' tag would help move things along.
adam
Bart
participants (3)
-
Adam Ford
-
Bartosz Golaszewski
-
Tom Rini