[PATCH 0/3] Add mmc-pwrseq file to use common function

Some Socs need to use H/W power-reset before probing eMMC. Its function can be resued with same behavior.
Jaehoon Chung (3): mmc: pwrseq: add mmc-pwrseq file to provide a generic interface mmc: meson_gx_mmc: use mmc_pwrseq instead of meson_mmc_pwrseq mmc: rockchip_dw_mmc: use mmc_pwrseq instead of rockchip_mmc_pwrseq
drivers/mmc/Kconfig | 8 ++++++ drivers/mmc/Makefile | 1 + drivers/mmc/meson_gx_mmc.c | 41 +++------------------------- drivers/mmc/mmc-pwrseq.c | 51 +++++++++++++++++++++++++++++++++++ drivers/mmc/rockchip_dw_mmc.c | 41 +++------------------------- include/mmc.h | 14 ++++++++++ 6 files changed, 80 insertions(+), 76 deletions(-) create mode 100644 drivers/mmc/mmc-pwrseq.c

Add mmc-pwrseq file to provide a generic interface.
Signed-off-by: Jaehoon Chung jh80.chung@samsung.com --- drivers/mmc/Kconfig | 8 +++++++ drivers/mmc/Makefile | 1 + drivers/mmc/mmc-pwrseq.c | 51 ++++++++++++++++++++++++++++++++++++++++ include/mmc.h | 14 +++++++++++ 4 files changed, 74 insertions(+) create mode 100644 drivers/mmc/mmc-pwrseq.c
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 14d79139864a..a88e4833be84 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -18,6 +18,14 @@ config MMC_WRITE help Enable write access to MMC and SD Cards
+config MMC_PWRSEQ + bool "HW reset support for eMMC" + depends on PWRSEQ + default y + help + Ths select Hardware reset support aka pwrseq-emmc for eMMC + devices. + config MMC_BROKEN_CD bool "Poll for broken card detection case" help diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 1c849cbab2f1..89d6af3db30b 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -6,6 +6,7 @@ obj-y += mmc.o obj-$(CONFIG_$(SPL_)DM_MMC) += mmc-uclass.o obj-$(CONFIG_$(SPL_)MMC_WRITE) += mmc_write.o +obj-$(CONFIG_MMC_PWRSEQ) += mmc-pwrseq.o obj-$(CONFIG_MMC_SDHCI_ADMA_HELPERS) += sdhci-adma.o
ifndef CONFIG_$(SPL_)BLK diff --git a/drivers/mmc/mmc-pwrseq.c b/drivers/mmc/mmc-pwrseq.c new file mode 100644 index 000000000000..2539f61323d1 --- /dev/null +++ b/drivers/mmc/mmc-pwrseq.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2021 SAMSUNG Electronics + * Jaehoon Chung jh80.chung@samsung.com + */ + +#include <common.h> +#include <dm.h> +#include <mmc.h> +#include <pwrseq.h> +#include <asm/gpio.h> +#include <linux/delay.h> + +int mmc_pwrseq_get_power(struct udevice *dev, struct mmc_config *cfg) +{ + /* Enable power if needed */ + return uclass_get_device_by_phandle(UCLASS_PWRSEQ, dev, "mmc-pwrseq", + &cfg->pwr_dev); +} + +static int mmc_pwrseq_set_power(struct udevice *dev, bool enable) +{ + struct gpio_desc reset; + int ret; + + ret = gpio_request_by_name(dev, "reset-gpios", 0, &reset, GPIOD_IS_OUT); + if (ret) + return ret; + dm_gpio_set_value(&reset, 1); + udelay(1); + dm_gpio_set_value(&reset, 0); + udelay(200); + + return 0; +} + +static const struct pwrseq_ops mmc_pwrseq_ops = { + .set_power = mmc_pwrseq_set_power, +}; + +static const struct udevice_id mmc_pwrseq_ids[] = { + { .compatible = "mmc-pwrseq-emmc" }, + { } +}; + +U_BOOT_DRIVER(mmc_pwrseq_drv) = { + .name = "mmc_pwrseq_emmc", + .id = UCLASS_PWRSEQ, + .of_match = mmc_pwrseq_ids, + .ops = &mmc_pwrseq_ops, +}; diff --git a/include/mmc.h b/include/mmc.h index 1d377e0281f1..637081415430 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -591,6 +591,9 @@ struct mmc_config { uint f_max; uint b_max; unsigned char part_type; +#ifdef CONFIG_MMC_PWRSEQ + struct udevice *pwr_dev; +#endif };
struct sd_ssr { @@ -801,6 +804,17 @@ int mmc_deinit(struct mmc *mmc); */ int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg);
+#ifdef CONFIG_MMC_PWRSEQ +/** + * mmc_pwrseq_get_power() - get a power device from device tree + * + * @dev: MMC device + * @cfg: MMC configuration + * @return 0 if OK, -ve on error + */ +int mmc_pwrseq_get_power(struct udevice *dev, struct mmc_config *cfg); +#endif + int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size);
/**

Use mmc_pwrseq instead of meson_mmc_pwrseq.
Signed-off-by: Jaehoon Chung jh80.chung@samsung.com --- drivers/mmc/meson_gx_mmc.c | 41 +++----------------------------------- 1 file changed, 3 insertions(+), 38 deletions(-)
diff --git a/drivers/mmc/meson_gx_mmc.c b/drivers/mmc/meson_gx_mmc.c index 8b6dfa3b9603..0ef140562cd2 100644 --- a/drivers/mmc/meson_gx_mmc.c +++ b/drivers/mmc/meson_gx_mmc.c @@ -292,12 +292,11 @@ static int meson_mmc_probe(struct udevice *dev)
mmc_set_clock(mmc, cfg->f_min, MMC_CLK_ENABLE);
-#ifdef CONFIG_PWRSEQ +#ifdef CONFIG_MMC_PWRSEQ /* Enable power if needed */ - ret = uclass_get_device_by_phandle(UCLASS_PWRSEQ, dev, "mmc-pwrseq", - &pwr_dev); + ret = mmc_pwrseq_get_power(dev, cfg); if (!ret) { - ret = pwrseq_set_power(pwr_dev, true); + ret = pwrseq_set_power(cfg->pwr_dev, true); if (ret) return ret; } @@ -342,37 +341,3 @@ U_BOOT_DRIVER(meson_mmc) = { .of_to_plat = meson_mmc_of_to_plat, .plat_auto = sizeof(struct meson_mmc_plat), }; - -#ifdef CONFIG_PWRSEQ -static int meson_mmc_pwrseq_set_power(struct udevice *dev, bool enable) -{ - struct gpio_desc reset; - int ret; - - ret = gpio_request_by_name(dev, "reset-gpios", 0, &reset, GPIOD_IS_OUT); - if (ret) - return ret; - dm_gpio_set_value(&reset, 1); - udelay(1); - dm_gpio_set_value(&reset, 0); - udelay(200); - - return 0; -} - -static const struct pwrseq_ops meson_mmc_pwrseq_ops = { - .set_power = meson_mmc_pwrseq_set_power, -}; - -static const struct udevice_id meson_mmc_pwrseq_ids[] = { - { .compatible = "mmc-pwrseq-emmc" }, - { } -}; - -U_BOOT_DRIVER(meson_mmc_pwrseq_drv) = { - .name = "mmc_pwrseq_emmc", - .id = UCLASS_PWRSEQ, - .of_match = meson_mmc_pwrseq_ids, - .ops = &meson_mmc_pwrseq_ops, -}; -#endif

On 01/02/2021 10:28, Jaehoon Chung wrote:
Use mmc_pwrseq instead of meson_mmc_pwrseq.
Signed-off-by: Jaehoon Chung jh80.chung@samsung.com
drivers/mmc/meson_gx_mmc.c | 41 +++----------------------------------- 1 file changed, 3 insertions(+), 38 deletions(-)
diff --git a/drivers/mmc/meson_gx_mmc.c b/drivers/mmc/meson_gx_mmc.c index 8b6dfa3b9603..0ef140562cd2 100644 --- a/drivers/mmc/meson_gx_mmc.c +++ b/drivers/mmc/meson_gx_mmc.c @@ -292,12 +292,11 @@ static int meson_mmc_probe(struct udevice *dev)
mmc_set_clock(mmc, cfg->f_min, MMC_CLK_ENABLE);
-#ifdef CONFIG_PWRSEQ +#ifdef CONFIG_MMC_PWRSEQ /* Enable power if needed */
- ret = uclass_get_device_by_phandle(UCLASS_PWRSEQ, dev, "mmc-pwrseq",
&pwr_dev);
- ret = mmc_pwrseq_get_power(dev, cfg); if (!ret) {
ret = pwrseq_set_power(pwr_dev, true);
if (ret) return ret; }ret = pwrseq_set_power(cfg->pwr_dev, true);
@@ -342,37 +341,3 @@ U_BOOT_DRIVER(meson_mmc) = { .of_to_plat = meson_mmc_of_to_plat, .plat_auto = sizeof(struct meson_mmc_plat), };
-#ifdef CONFIG_PWRSEQ -static int meson_mmc_pwrseq_set_power(struct udevice *dev, bool enable) -{
- struct gpio_desc reset;
- int ret;
- ret = gpio_request_by_name(dev, "reset-gpios", 0, &reset, GPIOD_IS_OUT);
- if (ret)
return ret;
- dm_gpio_set_value(&reset, 1);
- udelay(1);
- dm_gpio_set_value(&reset, 0);
- udelay(200);
- return 0;
-}
-static const struct pwrseq_ops meson_mmc_pwrseq_ops = {
- .set_power = meson_mmc_pwrseq_set_power,
-};
-static const struct udevice_id meson_mmc_pwrseq_ids[] = {
- { .compatible = "mmc-pwrseq-emmc" },
- { }
-};
-U_BOOT_DRIVER(meson_mmc_pwrseq_drv) = {
- .name = "mmc_pwrseq_emmc",
- .id = UCLASS_PWRSEQ,
- .of_match = meson_mmc_pwrseq_ids,
- .ops = &meson_mmc_pwrseq_ops,
-}; -#endif
Acked-by: Neil Armstrong narmstrong@baylibre.com
You should probably also update the amlogic defconfigs in this patchset, no ?
Neil

Hi Neil,
On 2/4/21 11:05 PM, Neil Armstrong wrote:
On 01/02/2021 10:28, Jaehoon Chung wrote:
Use mmc_pwrseq instead of meson_mmc_pwrseq.
Signed-off-by: Jaehoon Chung jh80.chung@samsung.com
drivers/mmc/meson_gx_mmc.c | 41 +++----------------------------------- 1 file changed, 3 insertions(+), 38 deletions(-)
diff --git a/drivers/mmc/meson_gx_mmc.c b/drivers/mmc/meson_gx_mmc.c index 8b6dfa3b9603..0ef140562cd2 100644 --- a/drivers/mmc/meson_gx_mmc.c +++ b/drivers/mmc/meson_gx_mmc.c @@ -292,12 +292,11 @@ static int meson_mmc_probe(struct udevice *dev)
mmc_set_clock(mmc, cfg->f_min, MMC_CLK_ENABLE);
-#ifdef CONFIG_PWRSEQ +#ifdef CONFIG_MMC_PWRSEQ /* Enable power if needed */
- ret = uclass_get_device_by_phandle(UCLASS_PWRSEQ, dev, "mmc-pwrseq",
&pwr_dev);
- ret = mmc_pwrseq_get_power(dev, cfg); if (!ret) {
ret = pwrseq_set_power(pwr_dev, true);
if (ret) return ret; }ret = pwrseq_set_power(cfg->pwr_dev, true);
@@ -342,37 +341,3 @@ U_BOOT_DRIVER(meson_mmc) = { .of_to_plat = meson_mmc_of_to_plat, .plat_auto = sizeof(struct meson_mmc_plat), };
-#ifdef CONFIG_PWRSEQ -static int meson_mmc_pwrseq_set_power(struct udevice *dev, bool enable) -{
- struct gpio_desc reset;
- int ret;
- ret = gpio_request_by_name(dev, "reset-gpios", 0, &reset, GPIOD_IS_OUT);
- if (ret)
return ret;
- dm_gpio_set_value(&reset, 1);
- udelay(1);
- dm_gpio_set_value(&reset, 0);
- udelay(200);
- return 0;
-}
-static const struct pwrseq_ops meson_mmc_pwrseq_ops = {
- .set_power = meson_mmc_pwrseq_set_power,
-};
-static const struct udevice_id meson_mmc_pwrseq_ids[] = {
- { .compatible = "mmc-pwrseq-emmc" },
- { }
-};
-U_BOOT_DRIVER(meson_mmc_pwrseq_drv) = {
- .name = "mmc_pwrseq_emmc",
- .id = UCLASS_PWRSEQ,
- .of_match = meson_mmc_pwrseq_ids,
- .ops = &meson_mmc_pwrseq_ops,
-}; -#endif
Acked-by: Neil Armstrong narmstrong@baylibre.com
You should probably also update the amlogic defconfigs in this patchset, no ?
Amlogic defconfigs are already enabled CONFIG_PWRSEQ. CONFIG_MMC_PWRSEQ is depends on CONFIG_PWRSEQ and it will be enabled by default. So it didn't need to update any defconfig..
But Now after listened your mention, my thinking is changed. Because some boards can be used only CONFIG_PWRSEQ without CONFIG_MMC_PWRSEQ.
Thanks for pointing out. I will update amlogic defconfigs.
If i misunderstood something, let me know, plz.
Best Regards, Jaehoon Chung
Neil

Use mmc_pwrseq instead of rockchip_mmc_pwrseq.
Signed-off-by: Jaehoon Chung jh80.chung@samsung.com --- drivers/mmc/rockchip_dw_mmc.c | 41 +++-------------------------------- 1 file changed, 3 insertions(+), 38 deletions(-)
diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c index 1be3c1741fd4..0664f6e5aef4 100644 --- a/drivers/mmc/rockchip_dw_mmc.c +++ b/drivers/mmc/rockchip_dw_mmc.c @@ -136,12 +136,11 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
host->fifo_mode = priv->fifo_mode;
-#ifdef CONFIG_PWRSEQ +#ifdef CONFIG_MMC_PWRSEQ /* Enable power if needed */ - ret = uclass_get_device_by_phandle(UCLASS_PWRSEQ, dev, "mmc-pwrseq", - &pwr_dev); + ret = mmc_pwrseq_get_power(dev, &plat->cfg); if (!ret) { - ret = pwrseq_set_power(pwr_dev, true); + ret = pwrseq_set_power(&plat->cfg->pwr_dev, true); if (ret) return ret; } @@ -182,37 +181,3 @@ U_BOOT_DRIVER(rockchip_rk3288_dw_mshc) = {
DM_DRIVER_ALIAS(rockchip_rk3288_dw_mshc, rockchip_rk3328_dw_mshc) DM_DRIVER_ALIAS(rockchip_rk3288_dw_mshc, rockchip_rk3368_dw_mshc) - -#ifdef CONFIG_PWRSEQ -static int rockchip_dwmmc_pwrseq_set_power(struct udevice *dev, bool enable) -{ - struct gpio_desc reset; - int ret; - - ret = gpio_request_by_name(dev, "reset-gpios", 0, &reset, GPIOD_IS_OUT); - if (ret) - return ret; - dm_gpio_set_value(&reset, 1); - udelay(1); - dm_gpio_set_value(&reset, 0); - udelay(200); - - return 0; -} - -static const struct pwrseq_ops rockchip_dwmmc_pwrseq_ops = { - .set_power = rockchip_dwmmc_pwrseq_set_power, -}; - -static const struct udevice_id rockchip_dwmmc_pwrseq_ids[] = { - { .compatible = "mmc-pwrseq-emmc" }, - { } -}; - -U_BOOT_DRIVER(rockchip_dwmmc_pwrseq_drv) = { - .name = "mmc_pwrseq_emmc", - .id = UCLASS_PWRSEQ, - .of_match = rockchip_dwmmc_pwrseq_ids, - .ops = &rockchip_dwmmc_pwrseq_ops, -}; -#endif
participants (2)
-
Jaehoon Chung
-
Neil Armstrong