
On 10/19/2017 11:45 PM, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Convert this driver to driver model. This driver is also used by VEXPRESS platforms which doesn't use driver model.
Tested on STM32F746 and STM32F769 platforms.
Signed-off-by: Christophe Priouzeau christophe.priouzeau@st.com Signed-off-by: Patrice Chotard patrice.chotard@st.com
drivers/mmc/Kconfig | 9 ++++ drivers/mmc/arm_pl180_mmci.c | 125 ++++++++++++++++++++++++++++++++++++++----- drivers/mmc/arm_pl180_mmci.h | 3 ++ 3 files changed, 125 insertions(+), 12 deletions(-)
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 94050836..62ce0af 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -33,6 +33,15 @@ config SPL_DM_MMC
if MMC
+config ARM_PL180_MMCI
- bool "ARM AMBA Multimedia Card Interface and compatible support"
- depends on DM_MMC && OF_CONTROL
- help
This selects the ARM(R) AMBA(R) PrimeCell Multimedia Card
Interface (PL180, PL181 and compatible) support.
If you have an ARM(R) platform with a Multimedia Card slot,
say Y or M here.
config SPL_MMC_TINY bool "Tiny MMC framework in SPL" help diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index 7898b0d..61dbbfb 100644 --- a/drivers/mmc/arm_pl180_mmci.c +++ b/drivers/mmc/arm_pl180_mmci.c @@ -12,12 +12,24 @@
/* #define DEBUG */
-#include <asm/io.h> #include "common.h" #include <errno.h> +#include <malloc.h> #include <mmc.h>
#include "arm_pl180_mmci.h" -#include <malloc.h>
+#include <asm/io.h>
+#ifdef CONFIG_DM_MMC +#include <dm.h> +DECLARE_GLOBAL_DATA_PTR;
+struct arm_pl180_mmc_plat {
- struct mmc_config cfg;
- struct mmc mmc;
+}; +#endif
static int wait_for_command_end(struct mmc *dev, struct mmc_cmd *cmd) { @@ -265,16 +277,6 @@ static int host_request(struct mmc *dev, return result; }
-/* MMC uses open drain drivers in the enumeration phase */ -static int mmc_host_reset(struct mmc *dev) -{
- struct pl180_mmc_host *host = dev->priv;
- writel(host->pwr_init, &host->base->power);
- return 0;
-}
static int host_set_ios(struct mmc *dev) { struct pl180_mmc_host *host = dev->priv; @@ -337,11 +339,23 @@ static int host_set_ios(struct mmc *dev) return 0; }
+#ifndef CONFIG_DM_MMC +/* MMC uses open drain drivers in the enumeration phase */ +static int mmc_host_reset(struct mmc *dev) +{
- struct pl180_mmc_host *host = dev->priv;
- writel(host->pwr_init, &host->base->power);
- return 0;
+}
static const struct mmc_ops arm_pl180_mmci_ops = { .send_cmd = host_request, .set_ios = host_set_ios, .init = mmc_host_reset, }; +#endif
/*
- mmc_host_init - initialize the mmc controller.
@@ -361,7 +375,9 @@ int arm_pl180_mmci_init(struct pl180_mmc_host *host, struct mmc **mmc) writel(sdi_u32, &host->base->mask0);
host->cfg.name = host->name; +#ifndef CONFIG_DM_MMC host->cfg.ops = &arm_pl180_mmci_ops; +#endif /* TODO remove the duplicates */ host->cfg.host_caps = host->caps; host->cfg.voltages = host->voltages; @@ -381,3 +397,88 @@ int arm_pl180_mmci_init(struct pl180_mmc_host *host, struct mmc **mmc)
return 0; }
+#ifdef CONFIG_DM_MMC +static int arm_pl180_mmc_probe(struct udevice *dev) +{
- struct arm_pl180_mmc_plat *pdata = dev_get_platdata(dev);
- struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
- struct mmc *mmc = &pdata->mmc;
- struct pl180_mmc_host *host = mmc->priv;
- int ret;
- strcpy(host->name, "MMC");
- host->pwr_init = INIT_PWR;
- host->clkdiv_init = SDI_CLKCR_CLKDIV_INIT_V1 | SDI_CLKCR_CLKEN |
SDI_CLKCR_HWFC_EN;
- host->voltages = VOLTAGE_WINDOW_SD;
- host->caps = 0;
- host->clock_in = 48000000;
Use the defined variable instead of 480000000.
- host->clock_min = 400000;
Ditto.
- host->clock_max = dev_read_u32_default(dev, "max-frequency", 48000000);
- host->version2 = dev_get_driver_data(dev);
- ret = arm_pl180_mmci_init(host, &mmc);
- if (ret) {
dev_err(dev, "arm_pl180_mmci init failed\n");
return ret;
- }
- mmc->dev = dev;
- dev->priv = host;
- upriv->mmc = mmc;
- return 0;
+}
+static int dm_host_request(struct udevice *dev, struct mmc_cmd *cmd,
struct mmc_data *data)
+{
- struct mmc *mmc = mmc_get_mmc_dev(dev);
- return host_request(mmc, cmd, data);
+}
+static int dm_host_set_ios(struct udevice *dev) +{
- struct mmc *mmc = mmc_get_mmc_dev(dev);
- return host_set_ios(mmc);
+}
+static const struct dm_mmc_ops arm_pl180_dm_mmc_ops = {
- .send_cmd = dm_host_request,
- .set_ios = dm_host_set_ios,
+};
+static int arm_pl180_mmc_ofdata_to_platdata(struct udevice *dev) +{
- struct arm_pl180_mmc_plat *pdata = dev_get_platdata(dev);
- struct mmc *mmc = &pdata->mmc;
- struct pl180_mmc_host *host = mmc->priv;
- fdt_addr_t addr;
- addr = devfdt_get_addr(dev);
- if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
- host->base = (void *)addr;
- return 0;
+}
+static const struct udevice_id arm_pl180_mmc_match[] = {
- { .compatible = "st,stm32f4xx-sdio", .data = VERSION1 },
- { /* sentinel */ }
+};
+U_BOOT_DRIVER(arm_pl180_mmc) = {
- .name = "arm_pl180_mmc",
- .id = UCLASS_MMC,
- .of_match = arm_pl180_mmc_match,
- .ops = &arm_pl180_dm_mmc_ops,
- .probe = arm_pl180_mmc_probe,
- .ofdata_to_platdata = arm_pl180_mmc_ofdata_to_platdata,
- .priv_auto_alloc_size = sizeof(struct pl180_mmc_host),
- .platdata_auto_alloc_size = sizeof(struct arm_pl180_mmc_plat),
+}; +#endif diff --git a/drivers/mmc/arm_pl180_mmci.h b/drivers/mmc/arm_pl180_mmci.h index 6e232f7..b935288 100644 --- a/drivers/mmc/arm_pl180_mmci.h +++ b/drivers/mmc/arm_pl180_mmci.h @@ -142,6 +142,9 @@
#define SDI_FIFO_BURST_SIZE 8
+#define VERSION1 false +#define VERSION2 true
Where do this use?
struct sdi_registers { u32 power; /* 0x00*/ u32 clock; /* 0x04*/