From 936e9cd39260559b6c3f931038fe3f2173e43605 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Tue, 6 Jul 2021 16:54:33 +0200 Subject: mmc: arm_pl180_mmci: Don't bind to all arm, primecell devices The arm,primecell compatible is used for lots of different types of devices, e.g. I2C, SPI, coresight, ... We really should not bind the MMC driver to all of them. Looking through the device trees in U-Boot there seems to be always a second compatible string for the pl180 device, either arm,pl180 (already listed) or arm,pl18x. Add the "arm,pl18x" compatible to the list but remove the generic "arm,primecell". Note that on Linux these compatibles cannot be found in drivers because AMBA/primecell devices are matched based on their peripheral ID instead of the compatible. This fixes the following error messages when booting the ST-Ericsson U8500 "stemmy" board with the arm_pl180_mmci driver enabled: MMC: ptm@801ae000 - probe failed: -38 ptm@801af000 - probe failed: -38 funnel@801a6000 - probe failed: -38 tpiu@80190000 - probe failed: -38 etb@801a4000 - probe failed: -38 Cc: Patrice Chotard Fixes: 6f41d1a17e20 ("mmc: arm_pl180_mmci: Sync compatible with kernel") Signed-off-by: Stephan Gerhold Reviewed-by: Patrice Chotard Tested-by: Patrice Chotard on stm32f769-disco Reviewed-by: Jaehoon Chung --- drivers/mmc/arm_pl180_mmci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mmc/arm_pl180_mmci.c') diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index b2d1b4f9aa9..5d1ee64356e 100644 --- a/drivers/mmc/arm_pl180_mmci.c +++ b/drivers/mmc/arm_pl180_mmci.c @@ -539,7 +539,7 @@ static int arm_pl180_mmc_of_to_plat(struct udevice *dev) static const struct udevice_id arm_pl180_mmc_match[] = { { .compatible = "arm,pl180" }, - { .compatible = "arm,primecell" }, + { .compatible = "arm,pl18x" }, { /* sentinel */ } }; -- cgit v1.2.3 From 19e1da0c66454bd6206a4badfdc0077d7fd76aed Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Tue, 6 Jul 2021 16:54:34 +0200 Subject: mmc: arm_pl180_mmci: Simplify code using dev_read_addr_ptr() Simplify the code a bit by using dev_read_addr_ptr() instead of dev_read_addr(). This avoids having to cast explicitly to void*. Signed-off-by: Stephan Gerhold Reviewed-by: Patrice Chotard Tested-by: Patrice Chotard on stm32f769-disco Reviewed-by: Jaehoon Chung --- drivers/mmc/arm_pl180_mmci.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/mmc/arm_pl180_mmci.c') diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index 5d1ee64356e..e632eed03fa 100644 --- a/drivers/mmc/arm_pl180_mmci.c +++ b/drivers/mmc/arm_pl180_mmci.c @@ -526,14 +526,11 @@ static const struct dm_mmc_ops arm_pl180_dm_mmc_ops = { static int arm_pl180_mmc_of_to_plat(struct udevice *dev) { struct pl180_mmc_host *host = dev_get_priv(dev); - fdt_addr_t addr; - addr = dev_read_addr(dev); - if (addr == FDT_ADDR_T_NONE) + host->base = dev_read_addr_ptr(dev); + if (!host->base) return -EINVAL; - host->base = (void *)addr; - return 0; } -- cgit v1.2.3 From 4daf2ec357c1c22ec0dc8db206add877f6632bc8 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Tue, 6 Jul 2021 16:54:35 +0200 Subject: mmc: arm_pl180_mmci: Simplify code using mmc_of_parse() Simplify the code a bit by using the common mmc_of_parse() function instead of duplicating the device tree parsing code. We can still get a default value for cfg->f_max by assigning it before calling mmc_of_parse(). Another advantage of this refactoring is that we parse more properties now, e.g. "non-removable" can be used to disable CD entirely. Signed-off-by: Stephan Gerhold Reviewed-by: Patrice Chotard Tested-by: Patrice Chotard on stm32f769-disco Reviewed-by: Jaehoon Chung --- drivers/mmc/arm_pl180_mmci.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) (limited to 'drivers/mmc/arm_pl180_mmci.c') diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index e632eed03fa..809b86570af 100644 --- a/drivers/mmc/arm_pl180_mmci.c +++ b/drivers/mmc/arm_pl180_mmci.c @@ -424,7 +424,6 @@ static int arm_pl180_mmc_probe(struct udevice *dev) struct pl180_mmc_host *host = dev_get_priv(dev); struct mmc_config *cfg = &pdata->cfg; struct clk clk; - u32 bus_width; u32 periphid; int ret; @@ -457,24 +456,14 @@ static int arm_pl180_mmc_probe(struct udevice *dev) cfg->voltages = VOLTAGE_WINDOW_SD; cfg->host_caps = 0; cfg->f_min = host->clock_in / (2 * (SDI_CLKCR_CLKDIV_INIT_V1 + 1)); - cfg->f_max = dev_read_u32_default(dev, "max-frequency", MMC_CLOCK_MAX); + cfg->f_max = MMC_CLOCK_MAX; cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; gpio_request_by_name(dev, "cd-gpios", 0, &host->cd_gpio, GPIOD_IS_IN); - bus_width = dev_read_u32_default(dev, "bus-width", 1); - switch (bus_width) { - case 8: - cfg->host_caps |= MMC_MODE_8BIT; - /* Hosts capable of 8-bit transfers can also do 4 bits */ - case 4: - cfg->host_caps |= MMC_MODE_4BIT; - break; - case 1: - break; - default: - dev_err(dev, "Invalid bus-width value %u\n", bus_width); - } + ret = mmc_of_parse(dev, cfg); + if (ret) + return ret; arm_pl180_mmc_init(host); mmc->priv = host; -- cgit v1.2.3 From d890f23406c00e3af5c63d76a9991e2e79d84096 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Tue, 6 Jul 2021 16:54:36 +0200 Subject: mmc: arm_pl180_mmci: Add configuration for ST-Ericsson Ux500v2 For the eMMC on ST-Ericsson Ux500v2 we need slightly different configuration values. Use the existing switch statement to match the peripheral ID of Ux500v2 (0x10480180) and override the necessary values to make the eMMC work on devices with ST-Ericsson Ux500. Cc: Linus Walleij Signed-off-by: Stephan Gerhold Reviewed-by: Patrice Chotard Tested-by: Patrice Chotard on stm32f769-disco Reviewed-by: Jaehoon Chung --- drivers/mmc/arm_pl180_mmci.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'drivers/mmc/arm_pl180_mmci.c') diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index 809b86570af..f99b5f997e2 100644 --- a/drivers/mmc/arm_pl180_mmci.c +++ b/drivers/mmc/arm_pl180_mmci.c @@ -443,22 +443,30 @@ static int arm_pl180_mmc_probe(struct udevice *dev) SDI_CLKCR_HWFC_EN; host->clock_in = clk_get_rate(&clk); + cfg->name = dev->name; + cfg->voltages = VOLTAGE_WINDOW_SD; + cfg->host_caps = 0; + cfg->f_min = host->clock_in / (2 * (SDI_CLKCR_CLKDIV_INIT_V1 + 1)); + cfg->f_max = MMC_CLOCK_MAX; + cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; + periphid = dev_read_u32_default(dev, "arm,primecell-periphid", 0); switch (periphid) { case STM32_MMCI_ID: /* stm32 variant */ host->version2 = false; break; + case UX500V2_MMCI_ID: + host->pwr_init = SDI_PWR_OPD | SDI_PWR_PWRCTRL_ON; + host->clkdiv_init = SDI_CLKCR_CLKDIV_INIT_V2 | SDI_CLKCR_CLKEN | + SDI_CLKCR_HWFC_EN; + cfg->voltages = VOLTAGE_WINDOW_MMC; + cfg->f_min = host->clock_in / (2 + SDI_CLKCR_CLKDIV_INIT_V2); + host->version2 = true; + break; default: host->version2 = true; } - cfg->name = dev->name; - cfg->voltages = VOLTAGE_WINDOW_SD; - cfg->host_caps = 0; - cfg->f_min = host->clock_in / (2 * (SDI_CLKCR_CLKDIV_INIT_V1 + 1)); - cfg->f_max = MMC_CLOCK_MAX; - cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; - gpio_request_by_name(dev, "cd-gpios", 0, &host->cd_gpio, GPIOD_IS_IN); ret = mmc_of_parse(dev, cfg); -- cgit v1.2.3