[PATCH 0/4] Add support for eMMC on ST-Ericsson Ux500(v2)

This patch series adds support for the eMMC on ST-Ericsson Ux500:
1. Some minor fixes+cleanup for the arm_pl180_mmci driver. 3. Add the necessary configuration for ST-Ericsson Ux500v2.
This was tested on the u8500 "stemmy" board that is already present in U-Boot.
Stephan Gerhold (4): mmc: arm_pl180_mmci: Don't bind to all arm,primecell devices mmc: arm_pl180_mmci: Simplify code using dev_read_addr_ptr() mmc: arm_pl180_mmci: Simplify code using mmc_of_parse() mmc: arm_pl180_mmci: Add configuration for ST-Ericsson Ux500v2
drivers/mmc/arm_pl180_mmci.c | 48 ++++++++++++++++-------------------- drivers/mmc/arm_pl180_mmci.h | 1 + 2 files changed, 22 insertions(+), 27 deletions(-)

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 patrice.chotard@st.com Fixes: 6f41d1a17e20 ("mmc: arm_pl180_mmci: Sync compatible with kernel") Signed-off-by: Stephan Gerhold stephan@gerhold.net ---
drivers/mmc/arm_pl180_mmci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index b2d1b4f9aa..5d1ee64356 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 */ } };

Hi Stephan
On 7/6/21 4:54 PM, Stephan Gerhold wrote:
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 patrice.chotard@st.com Fixes: 6f41d1a17e20 ("mmc: arm_pl180_mmci: Sync compatible with kernel") Signed-off-by: Stephan Gerhold stephan@gerhold.net
drivers/mmc/arm_pl180_mmci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index b2d1b4f9aa..5d1ee64356 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 */ }
};
Reviewed-by: Patrice Chotard patrice.chotard@foss.st.com Tested-by: Patrice Chotard patrice.chotard@foss.st.com on stm32f769-disco
Thanks Patrice

On 7/6/21 11:54 PM, Stephan Gerhold wrote:
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 patrice.chotard@st.com Fixes: 6f41d1a17e20 ("mmc: arm_pl180_mmci: Sync compatible with kernel") Signed-off-by: Stephan Gerhold stephan@gerhold.net
Reviewed-by: Jaehoon Chung jh80.chung@samsung.com
Best Regards, Jaehoon Chung
drivers/mmc/arm_pl180_mmci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index b2d1b4f9aa..5d1ee64356 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 */ }
};

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 stephan@gerhold.net ---
drivers/mmc/arm_pl180_mmci.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index 5d1ee64356..e632eed03f 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; }

Hi Stephan
On 7/6/21 4:54 PM, Stephan Gerhold wrote:
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 stephan@gerhold.net
drivers/mmc/arm_pl180_mmci.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index 5d1ee64356..e632eed03f 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;
}
Reviewed-by: Patrice Chotard patrice.chotard@foss.st.com Tested-by: Patrice Chotard patrice.chotard@foss.st.com on stm32f769-disco
Thanks Patrice

On 7/6/21 11:54 PM, Stephan Gerhold wrote:
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 stephan@gerhold.net
Reviewed-by: Jaehoon Chung jh80.chung@samsung.com
Best Regards, Jaehoon Chung
drivers/mmc/arm_pl180_mmci.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index 5d1ee64356..e632eed03f 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;
}

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 stephan@gerhold.net ---
drivers/mmc/arm_pl180_mmci.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-)
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index e632eed03f..809b86570a 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;

Hi Stephan
On 7/6/21 4:54 PM, Stephan Gerhold wrote:
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 stephan@gerhold.net
drivers/mmc/arm_pl180_mmci.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-)
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index e632eed03f..809b86570a 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;
Reviewed-by: Patrice Chotard patrice.chotard@foss.st.com Tested-by: Patrice Chotard patrice.chotard@foss.st.com on stm32f769-disco
Thanks Patrice

On 7/6/21 11:54 PM, Stephan Gerhold wrote:
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 stephan@gerhold.net
Reviewed-by: Jaehoon Chung jh80.chung@samsung.com
Best Regards, Jaehoon Chung
drivers/mmc/arm_pl180_mmci.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-)
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index e632eed03f..809b86570a 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;

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 linus.walleij@linaro.org Signed-off-by: Stephan Gerhold stephan@gerhold.net ---
drivers/mmc/arm_pl180_mmci.c | 22 +++++++++++++++------- drivers/mmc/arm_pl180_mmci.h | 1 + 2 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index 809b86570a..f99b5f997e 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); diff --git a/drivers/mmc/arm_pl180_mmci.h b/drivers/mmc/arm_pl180_mmci.h index 61ee96a112..15c29beadb 100644 --- a/drivers/mmc/arm_pl180_mmci.h +++ b/drivers/mmc/arm_pl180_mmci.h @@ -142,6 +142,7 @@ #define SDI_FIFO_BURST_SIZE 8
#define STM32_MMCI_ID 0x00880180 +#define UX500V2_MMCI_ID 0x10480180
struct sdi_registers { u32 power; /* 0x00*/

Hi Stephan
On 7/6/21 4:54 PM, Stephan Gerhold wrote:
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 linus.walleij@linaro.org Signed-off-by: Stephan Gerhold stephan@gerhold.net
drivers/mmc/arm_pl180_mmci.c | 22 +++++++++++++++------- drivers/mmc/arm_pl180_mmci.h | 1 + 2 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index 809b86570a..f99b5f997e 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;
default: host->version2 = true; }break;
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);
diff --git a/drivers/mmc/arm_pl180_mmci.h b/drivers/mmc/arm_pl180_mmci.h index 61ee96a112..15c29beadb 100644 --- a/drivers/mmc/arm_pl180_mmci.h +++ b/drivers/mmc/arm_pl180_mmci.h @@ -142,6 +142,7 @@ #define SDI_FIFO_BURST_SIZE 8
#define STM32_MMCI_ID 0x00880180 +#define UX500V2_MMCI_ID 0x10480180
struct sdi_registers { u32 power; /* 0x00*/
Reviewed-by: Patrice Chotard patrice.chotard@foss.st.com Tested-by: Patrice Chotard patrice.chotard@foss.st.com on stm32f769-disco
Thanks Patrice

On 7/6/21 11:54 PM, Stephan Gerhold wrote:
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 linus.walleij@linaro.org Signed-off-by: Stephan Gerhold stephan@gerhold.net
Reviewed-by: Jaehoon Chung jh80.chung@samsung.com
Best Regards, Jaehoon Chung
drivers/mmc/arm_pl180_mmci.c | 22 +++++++++++++++------- drivers/mmc/arm_pl180_mmci.h | 1 + 2 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index 809b86570a..f99b5f997e 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;
default: host->version2 = true; }break;
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);
diff --git a/drivers/mmc/arm_pl180_mmci.h b/drivers/mmc/arm_pl180_mmci.h index 61ee96a112..15c29beadb 100644 --- a/drivers/mmc/arm_pl180_mmci.h +++ b/drivers/mmc/arm_pl180_mmci.h @@ -142,6 +142,7 @@ #define SDI_FIFO_BURST_SIZE 8
#define STM32_MMCI_ID 0x00880180 +#define UX500V2_MMCI_ID 0x10480180
struct sdi_registers { u32 power; /* 0x00*/

On Tue, Jul 6, 2021 at 4:55 PM Stephan Gerhold stephan@gerhold.net wrote:
This patch series adds support for the eMMC on ST-Ericsson Ux500:
- Some minor fixes+cleanup for the arm_pl180_mmci driver.
- Add the necessary configuration for ST-Ericsson Ux500v2.
This was tested on the u8500 "stemmy" board that is already present in U-Boot.
The series: Reviewed-by: Linus Walleij linus.walleij@linaro.org
Yours, Linus Walleij
participants (4)
-
Jaehoon Chung
-
Linus Walleij
-
Patrice CHOTARD
-
Stephan Gerhold