[PATCH v2 0/8] Convert mvebu_mmc driver to driver model

This series converts the existing mvebu_mmc driver to the driver model. Only two boards in the u-boot tree were using this: openrd and sheevaplug. The openrd board does currently not support driver model at all. Given the deadlines for conversion, this patch series drops MMC support for that board. The sheevaplug should still work but I don't have hardware to test it on. I've tested the driver on an out of tree Kirkwood board.
CC: Rick Thomas rick.thomas@pobox.com CC: Chris Packham judge.packham@gmail.com CC: Vagrant Cascadian vagrant@debian.org
Thanks for the feedback :)! Changes in v2: - Fixed patch style by sending patch through patman + git send-email - Add commit text
Harm Berntsen (8): configs: remove unused CONFIG_SYS_MMC_BASE defs configs: openrd: remove non-dm MMC driver configs: sheevaplug: remove non-dm MMC driver arm: kirkwood: remove non-dm MMC driver init configs: remove obsolete CONFIG_SYS_MMC_BASE configs: remove obsolete CONFIG_MVEBU_MMC mmc: mvebu: convert to driver model configs: sheevaplug: enable driver-model based MMC
arch/arm/mach-kirkwood/cpu.c | 7 - configs/sheevaplug_defconfig | 2 + drivers/mmc/Kconfig | 9 + drivers/mmc/mvebu_mmc.c | 309 ++++++++++++++++++------------ include/configs/clearfog.h | 5 - include/configs/controlcenterdc.h | 5 - include/configs/db-88f6820-gp.h | 5 - include/configs/helios4.h | 5 - include/configs/openrd.h | 5 - include/configs/sheevaplug.h | 8 - include/mvebu_mmc.h | 13 +- scripts/config_whitelist.txt | 2 - 12 files changed, 196 insertions(+), 179 deletions(-)

These boards use an MMC driver that does not use this definition
Signed-off-by: Harm Berntsen harm.berntsen@nedap.com Reviewed-by: Stefan Roese sr@denx.de CC: Stefan Roese sr@denx.de CC: Mario Six mario.six@gdsys.cc CC: Dennis Gilmore dgilmore@redhat.com ---
(no changes since v1)
include/configs/clearfog.h | 5 ----- include/configs/controlcenterdc.h | 5 ----- include/configs/db-88f6820-gp.h | 5 ----- include/configs/helios4.h | 5 ----- 4 files changed, 20 deletions(-)
diff --git a/include/configs/clearfog.h b/include/configs/clearfog.h index 5441da8c9c..c9852a72b9 100644 --- a/include/configs/clearfog.h +++ b/include/configs/clearfog.h @@ -19,11 +19,6 @@ */ #define CONFIG_SYS_TCLK 250000000 /* 250MHz */
-/* - * SDIO/MMC Card Configuration - */ -#define CONFIG_SYS_MMC_BASE MVEBU_SDIO_BASE - /* USB/EHCI configuration */ #define CONFIG_EHCI_IS_TDI
diff --git a/include/configs/controlcenterdc.h b/include/configs/controlcenterdc.h index f53d48d427..869b94bc9b 100644 --- a/include/configs/controlcenterdc.h +++ b/include/configs/controlcenterdc.h @@ -24,11 +24,6 @@
#define CONFIG_LOADADDR 1000000
-/* - * SDIO/MMC Card Configuration - */ -#define CONFIG_SYS_MMC_BASE MVEBU_SDIO_BASE - /* * SATA/SCSI/AHCI configuration */ diff --git a/include/configs/db-88f6820-gp.h b/include/configs/db-88f6820-gp.h index d4207be1d3..ed851bc670 100644 --- a/include/configs/db-88f6820-gp.h +++ b/include/configs/db-88f6820-gp.h @@ -19,11 +19,6 @@ #define CONFIG_SYS_I2C_SLAVE 0x0 #define CONFIG_SYS_I2C_SPEED 100000
-/* - * SDIO/MMC Card Configuration - */ -#define CONFIG_SYS_MMC_BASE MVEBU_SDIO_BASE - /* * SATA/SCSI/AHCI configuration */ diff --git a/include/configs/helios4.h b/include/configs/helios4.h index 396870a67f..2cda05c85a 100644 --- a/include/configs/helios4.h +++ b/include/configs/helios4.h @@ -19,11 +19,6 @@ */ #define CONFIG_SYS_TCLK 250000000 /* 250MHz */
-/* - * SDIO/MMC Card Configuration - */ -#define CONFIG_SYS_MMC_BASE MVEBU_SDIO_BASE - /* USB/EHCI configuration */ #define CONFIG_EHCI_IS_TDI

Unfortunately this board has no DM support at all. We are also way past the deadline for driver model support for various devices on this board.
Signed-off-by: Harm Berntsen harm.berntsen@nedap.com Reviewed-by: Stefan Roese sr@denx.de CC: Stefan Roese sr@denx.de ---
(no changes since v1)
include/configs/openrd.h | 5 ----- 1 file changed, 5 deletions(-)
diff --git a/include/configs/openrd.h b/include/configs/openrd.h index e9fd0fc749..03b9393c9b 100644 --- a/include/configs/openrd.h +++ b/include/configs/openrd.h @@ -74,9 +74,4 @@ #define CONFIG_SYS_ATA_IDE1_OFFSET MV_SATA_PORT1_OFFSET #endif /*CONFIG_MVSATA_IDE*/
-#ifdef CONFIG_CMD_MMC -#define CONFIG_MVEBU_MMC -#define CONFIG_SYS_MMC_BASE KW_SDIO_BASE -#endif /* CONFIG_CMD_MMC */ - #endif /* _CONFIG_OPENRD_BASE_H */

This will be replaced with the driver model version
Signed-off-by: Harm Berntsen harm.berntsen@nedap.com Reviewed-by: Stefan Roese sr@denx.de CC: Prafulla Wadaskar prafulla@marvell.com CC: Stefan Roese sr@denx.de CC: Tom Rini trini@konsulko.com ---
(no changes since v1)
include/configs/sheevaplug.h | 8 -------- 1 file changed, 8 deletions(-)
diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h index e1f8fb8ac8..abe8418984 100644 --- a/include/configs/sheevaplug.h +++ b/include/configs/sheevaplug.h @@ -50,14 +50,6 @@ #define CONFIG_PHY_BASE_ADR 0 #endif /* CONFIG_CMD_NET */
-/* - * SDIO/MMC Card Configuration - */ -#ifdef CONFIG_CMD_MMC -#define CONFIG_MVEBU_MMC -#define CONFIG_SYS_MMC_BASE KW_SDIO_BASE -#endif /* CONFIG_CMD_MMC */ - /* * SATA driver configuration */

No board uses this driver any more: remove it.
Signed-off-by: Harm Berntsen harm.berntsen@nedap.com Reviewed-by: Stefan Roese sr@denx.de CC: Gerald Kerma drEagle@doukki.net CC: Stefan Roese sr@denx.de CC: Pantelis Antoniou panto@antoniou-consulting.com ---
(no changes since v1)
arch/arm/mach-kirkwood/cpu.c | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/arch/arm/mach-kirkwood/cpu.c b/arch/arm/mach-kirkwood/cpu.c index 9c818fa45e..339ae7fd20 100644 --- a/arch/arm/mach-kirkwood/cpu.c +++ b/arch/arm/mach-kirkwood/cpu.c @@ -279,10 +279,3 @@ int cpu_eth_init(struct bd_info *bis) } #endif
-#ifdef CONFIG_MVEBU_MMC -int board_mmc_init(struct bd_info *bis) -{ - mvebu_mmc_init(bis); - return 0; -} -#endif /* CONFIG_MVEBU_MMC */

All usages of this have been removed
Signed-off-by: Harm Berntsen harm.berntsen@nedap.com Reviewed-by: Simon Glass sjg@chromium.org CC: Simon Glass sjg@chromium.org ---
(no changes since v1)
scripts/config_whitelist.txt | 1 - 1 file changed, 1 deletion(-)
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 85857a746c..1e27373e5b 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -2907,7 +2907,6 @@ CONFIG_SYS_MIPS_TIMER_FREQ CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR -CONFIG_SYS_MMC_BASE CONFIG_SYS_MMC_CD_PIN CONFIG_SYS_MMC_CLK_OD CONFIG_SYS_MMC_MAX_BLK_COUNT

All usages of this have been removed
Signed-off-by: Harm Berntsen harm.berntsen@nedap.com Reviewed-by: Simon Glass sjg@chromium.org CC: Simon Glass sjg@chromium.org ---
(no changes since v1)
scripts/config_whitelist.txt | 1 - 1 file changed, 1 deletion(-)
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 1e27373e5b..2fdee6be65 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -1077,7 +1077,6 @@ CONFIG_MTD_UBI_GLUEBI CONFIG_MTD_UBI_MODULE CONFIG_MULTI_CS CONFIG_MUSB_HOST -CONFIG_MVEBU_MMC CONFIG_MVGBE_PORTS CONFIG_MVMFP_V2 CONFIG_MVS

On 30.03.21 10:19, Harm Berntsen wrote:
All usages of this have been removed
Signed-off-by: Harm Berntsen harm.berntsen@nedap.com Reviewed-by: Simon Glass sjg@chromium.org CC: Simon Glass sjg@chromium.org
Reviewed-by: Stefan Roese sr@denx.de
Thanks, Stefan
(no changes since v1)
scripts/config_whitelist.txt | 1 - 1 file changed, 1 deletion(-)
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 1e27373e5b..2fdee6be65 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -1077,7 +1077,6 @@ CONFIG_MTD_UBI_GLUEBI CONFIG_MTD_UBI_MODULE CONFIG_MULTI_CS CONFIG_MUSB_HOST -CONFIG_MVEBU_MMC CONFIG_MVGBE_PORTS CONFIG_MVMFP_V2 CONFIG_MVS
Viele Grüße, Stefan

This is a straightforward conversion of the old, non-dm driver. It was done in-place as the deadline for non-dm MMC has passed. Previous commits ensured that no board depends on the old, non-dm variant. Tested on a Kirkwood based board with eMMC.
Signed-off-by: Harm Berntsen harm.berntsen@nedap.com Tested-by: Harm Berntsen harm.berntsen@nedap.com Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Stefan Roese sr@denx.de CC: Pantelis Antoniou panto@antoniou-consulting.com CC: Stefan Roese sr@denx.de CC: Gerald Kerma drEagle@doukki.net CC: Simon Glass sjg@chromium.org ---
Changes in v2: - Fixed patch style by sending patch through patman + git send-email
drivers/mmc/Kconfig | 9 ++ drivers/mmc/mvebu_mmc.c | 309 +++++++++++++++++++++++----------------- include/mvebu_mmc.h | 13 +- 3 files changed, 194 insertions(+), 137 deletions(-)
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index f8ca52efb6..de9ab8a387 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -326,6 +326,15 @@ config MMC_OCTEONTX
If unsure, say N.
+config MVEBU_MMC + bool "Kirkwood MMC controller support" + depends on DM_MMC && BLK && ARCH_KIRKWOOD + help + Support for MMC host controller on Kirkwood SoCs. + If you are on a Kirkwood architecture, say Y here. + + If unsure, say N. + config PXA_MMC_GENERIC bool "Support for MMC controllers on PXA" help diff --git a/drivers/mmc/mvebu_mmc.c b/drivers/mmc/mvebu_mmc.c index 8ec1f57a1b..fea55c61ed 100644 --- a/drivers/mmc/mvebu_mmc.c +++ b/drivers/mmc/mvebu_mmc.c @@ -11,60 +11,67 @@ #include <errno.h> #include <log.h> #include <malloc.h> +#include <dm.h> +#include <fdtdec.h> #include <part.h> #include <mmc.h> -#include <asm/global_data.h> #include <asm/io.h> #include <asm/arch/cpu.h> #include <asm/arch/soc.h> #include <mvebu_mmc.h> - -DECLARE_GLOBAL_DATA_PTR; - -#define DRIVER_NAME "MVEBU_MMC" +#include <dm/device_compat.h>
#define MVEBU_TARGET_DRAM 0
#define TIMEOUT_DELAY 5*CONFIG_SYS_HZ /* wait 5 seconds */
-static void mvebu_mmc_write(u32 offs, u32 val) +static inline void *get_regbase(const struct mmc *mmc) { - writel(val, CONFIG_SYS_MMC_BASE + (offs)); + struct mvebu_mmc_plat *pdata = mmc->priv; + + return pdata->iobase; }
-static u32 mvebu_mmc_read(u32 offs) +static void mvebu_mmc_write(const struct mmc *mmc, u32 offs, u32 val) { - return readl(CONFIG_SYS_MMC_BASE + (offs)); + writel(val, get_regbase(mmc) + (offs)); }
-static int mvebu_mmc_setup_data(struct mmc_data *data) +static u32 mvebu_mmc_read(const struct mmc *mmc, u32 offs) { + return readl(get_regbase(mmc) + (offs)); +} + +static int mvebu_mmc_setup_data(struct udevice *dev, struct mmc_data *data) +{ + struct mvebu_mmc_plat *pdata = dev_get_plat(dev); + struct mmc *mmc = &pdata->mmc; u32 ctrl_reg;
- debug("%s, data %s : blocks=%d blksz=%d\n", DRIVER_NAME, - (data->flags & MMC_DATA_READ) ? "read" : "write", - data->blocks, data->blocksize); + dev_dbg(dev, "data %s : blocks=%d blksz=%d\n", + (data->flags & MMC_DATA_READ) ? "read" : "write", + data->blocks, data->blocksize);
/* default to maximum timeout */ - ctrl_reg = mvebu_mmc_read(SDIO_HOST_CTRL); + ctrl_reg = mvebu_mmc_read(mmc, SDIO_HOST_CTRL); ctrl_reg |= SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX); - mvebu_mmc_write(SDIO_HOST_CTRL, ctrl_reg); + mvebu_mmc_write(mmc, SDIO_HOST_CTRL, ctrl_reg);
if (data->flags & MMC_DATA_READ) { - mvebu_mmc_write(SDIO_SYS_ADDR_LOW, (u32)data->dest & 0xffff); - mvebu_mmc_write(SDIO_SYS_ADDR_HI, (u32)data->dest >> 16); + mvebu_mmc_write(mmc, SDIO_SYS_ADDR_LOW, (u32)data->dest & 0xffff); + mvebu_mmc_write(mmc, SDIO_SYS_ADDR_HI, (u32)data->dest >> 16); } else { - mvebu_mmc_write(SDIO_SYS_ADDR_LOW, (u32)data->src & 0xffff); - mvebu_mmc_write(SDIO_SYS_ADDR_HI, (u32)data->src >> 16); + mvebu_mmc_write(mmc, SDIO_SYS_ADDR_LOW, (u32)data->src & 0xffff); + mvebu_mmc_write(mmc, SDIO_SYS_ADDR_HI, (u32)data->src >> 16); }
- mvebu_mmc_write(SDIO_BLK_COUNT, data->blocks); - mvebu_mmc_write(SDIO_BLK_SIZE, data->blocksize); + mvebu_mmc_write(mmc, SDIO_BLK_COUNT, data->blocks); + mvebu_mmc_write(mmc, SDIO_BLK_SIZE, data->blocksize);
return 0; }
-static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, +static int mvebu_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data *data) { ulong start; @@ -72,12 +79,14 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, ushort resptype = 0; ushort xfertype = 0; ushort resp_indx = 0; + struct mvebu_mmc_plat *pdata = dev_get_plat(dev); + struct mmc *mmc = &pdata->mmc;
- debug("%s: cmdidx [0x%x] resp_type[0x%x] cmdarg[0x%x]\n", - DRIVER_NAME, cmd->cmdidx, cmd->resp_type, cmd->cmdarg); + dev_dbg(dev, "cmdidx [0x%x] resp_type[0x%x] cmdarg[0x%x]\n", + cmd->cmdidx, cmd->resp_type, cmd->cmdarg);
- debug("%s: cmd %d (hw state 0x%04x)\n", DRIVER_NAME, - cmd->cmdidx, mvebu_mmc_read(SDIO_HW_STATE)); + dev_dbg(dev, "cmd %d (hw state 0x%04x)\n", + cmd->cmdidx, mvebu_mmc_read(mmc, SDIO_HW_STATE));
/* * Hardware weirdness. The FIFO_EMPTY bit of the HW_STATE @@ -88,26 +97,26 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, * this bit comes to good sense (which eventually happens by * itself) then the new transfer simply fails with a timeout. */ - if (!(mvebu_mmc_read(SDIO_HW_STATE) & CMD_FIFO_EMPTY)) { + if (!(mvebu_mmc_read(mmc, SDIO_HW_STATE) & CMD_FIFO_EMPTY)) { ushort hw_state, count = 0;
start = get_timer(0); do { - hw_state = mvebu_mmc_read(SDIO_HW_STATE); + hw_state = mvebu_mmc_read(mmc, SDIO_HW_STATE); if ((get_timer(0) - start) > TIMEOUT_DELAY) { printf("%s : FIFO_EMPTY bit missing\n", - DRIVER_NAME); + dev->name); break; } count++; } while (!(hw_state & CMD_FIFO_EMPTY)); - debug("%s *** wait for FIFO_EMPTY bit (hw=0x%04x, count=%d, jiffies=%ld)\n", - DRIVER_NAME, hw_state, count, (get_timer(0) - (start))); + dev_dbg(dev, "*** wait for FIFO_EMPTY bit (hw=0x%04x, count=%d, jiffies=%ld)\n", + hw_state, count, (get_timer(0) - (start))); }
/* Clear status */ - mvebu_mmc_write(SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK); - mvebu_mmc_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK); + mvebu_mmc_write(mmc, SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK); + mvebu_mmc_write(mmc, SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK);
resptype = SDIO_CMD_INDEX(cmd->cmdidx);
@@ -133,11 +142,10 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, }
if (data) { - int err = mvebu_mmc_setup_data(data); + int err = mvebu_mmc_setup_data(dev, data);
if (err) { - debug("%s: command DATA error :%x\n", - DRIVER_NAME, err); + dev_dbg(dev, "command DATA error :%x\n", err); return err; }
@@ -154,34 +162,33 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, }
/* Setting cmd arguments */ - mvebu_mmc_write(SDIO_ARG_LOW, cmd->cmdarg & 0xffff); - mvebu_mmc_write(SDIO_ARG_HI, cmd->cmdarg >> 16); + mvebu_mmc_write(mmc, SDIO_ARG_LOW, cmd->cmdarg & 0xffff); + mvebu_mmc_write(mmc, SDIO_ARG_HI, cmd->cmdarg >> 16);
/* Setting Xfer mode */ - mvebu_mmc_write(SDIO_XFER_MODE, xfertype); + mvebu_mmc_write(mmc, SDIO_XFER_MODE, xfertype);
/* Sending command */ - mvebu_mmc_write(SDIO_CMD, resptype); + mvebu_mmc_write(mmc, SDIO_CMD, resptype);
start = get_timer(0);
- while (!((mvebu_mmc_read(SDIO_NOR_INTR_STATUS)) & waittype)) { - if (mvebu_mmc_read(SDIO_NOR_INTR_STATUS) & SDIO_NOR_ERROR) { - debug("%s: error! cmdidx : %d, err reg: %04x\n", - DRIVER_NAME, cmd->cmdidx, - mvebu_mmc_read(SDIO_ERR_INTR_STATUS)); - if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) & + while (!((mvebu_mmc_read(mmc, SDIO_NOR_INTR_STATUS)) & waittype)) { + if (mvebu_mmc_read(mmc, SDIO_NOR_INTR_STATUS) & SDIO_NOR_ERROR) { + dev_dbg(dev, "error! cmdidx : %d, err reg: %04x\n", + cmd->cmdidx, + mvebu_mmc_read(mmc, SDIO_ERR_INTR_STATUS)); + if (mvebu_mmc_read(mmc, SDIO_ERR_INTR_STATUS) & (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT)) { - debug("%s: command READ timed out\n", - DRIVER_NAME); + dev_dbg(dev, "command READ timed out\n"); return -ETIMEDOUT; } - debug("%s: command READ error\n", DRIVER_NAME); + dev_dbg(dev, "command READ error\n"); return -ECOMM; }
if ((get_timer(0) - start) > TIMEOUT_DELAY) { - debug("%s: command timed out\n", DRIVER_NAME); + dev_dbg(dev, "command timed out\n"); return -ETIMEDOUT; } } @@ -191,8 +198,7 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, uint response[8];
for (resp_indx = 0; resp_indx < 8; resp_indx++) - response[resp_indx] - = mvebu_mmc_read(SDIO_RSP(resp_indx)); + response[resp_indx] = mvebu_mmc_read(mmc, SDIO_RSP(resp_indx));
cmd->response[0] = ((response[0] & 0x03ff) << 22) | ((response[1] & 0xffff) << 6) | @@ -209,8 +215,7 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, uint response[3];
for (resp_indx = 0; resp_indx < 3; resp_indx++) - response[resp_indx] - = mvebu_mmc_read(SDIO_RSP(resp_indx)); + response[resp_indx] = mvebu_mmc_read(mmc, SDIO_RSP(resp_indx));
cmd->response[0] = ((response[2] & 0x003f) << (8 - 8)) | ((response[1] & 0xffff) << (14 - 8)) | @@ -225,64 +230,71 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, cmd->response[3] = 0; }
- debug("%s: resp[0x%x] ", DRIVER_NAME, cmd->resp_type); + dev_dbg(dev, "resp[0x%x] ", cmd->resp_type); debug("[0x%x] ", cmd->response[0]); debug("[0x%x] ", cmd->response[1]); debug("[0x%x] ", cmd->response[2]); debug("[0x%x] ", cmd->response[3]); debug("\n");
- if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) & + if (mvebu_mmc_read(mmc, SDIO_ERR_INTR_STATUS) & (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT)) return -ETIMEDOUT;
return 0; }
-static void mvebu_mmc_power_up(void) +static void mvebu_mmc_power_up(struct udevice *dev) { - debug("%s: power up\n", DRIVER_NAME); + struct mvebu_mmc_plat *pdata = dev_get_plat(dev); + struct mmc *mmc = &pdata->mmc; + + dev_dbg(dev, "power up\n");
/* disable interrupts */ - mvebu_mmc_write(SDIO_NOR_INTR_EN, 0); - mvebu_mmc_write(SDIO_ERR_INTR_EN, 0); + mvebu_mmc_write(mmc, SDIO_NOR_INTR_EN, 0); + mvebu_mmc_write(mmc, SDIO_ERR_INTR_EN, 0);
/* SW reset */ - mvebu_mmc_write(SDIO_SW_RESET, SDIO_SW_RESET_NOW); + mvebu_mmc_write(mmc, SDIO_SW_RESET, SDIO_SW_RESET_NOW);
- mvebu_mmc_write(SDIO_XFER_MODE, 0); + mvebu_mmc_write(mmc, SDIO_XFER_MODE, 0);
/* enable status */ - mvebu_mmc_write(SDIO_NOR_STATUS_EN, SDIO_POLL_MASK); - mvebu_mmc_write(SDIO_ERR_STATUS_EN, SDIO_POLL_MASK); + mvebu_mmc_write(mmc, SDIO_NOR_STATUS_EN, SDIO_POLL_MASK); + mvebu_mmc_write(mmc, SDIO_ERR_STATUS_EN, SDIO_POLL_MASK);
/* enable interrupts status */ - mvebu_mmc_write(SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK); - mvebu_mmc_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK); + mvebu_mmc_write(mmc, SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK); + mvebu_mmc_write(mmc, SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK); }
-static void mvebu_mmc_set_clk(unsigned int clock) +static void mvebu_mmc_set_clk(struct udevice *dev, unsigned int clock) { unsigned int m; + struct mvebu_mmc_plat *pdata = dev_get_plat(dev); + struct mmc *mmc = &pdata->mmc;
if (clock == 0) { - debug("%s: clock off\n", DRIVER_NAME); - mvebu_mmc_write(SDIO_XFER_MODE, SDIO_XFER_MODE_STOP_CLK); - mvebu_mmc_write(SDIO_CLK_DIV, MVEBU_MMC_BASE_DIV_MAX); + dev_dbg(dev, "clock off\n"); + mvebu_mmc_write(mmc, SDIO_XFER_MODE, SDIO_XFER_MODE_STOP_CLK); + mvebu_mmc_write(mmc, SDIO_CLK_DIV, MVEBU_MMC_BASE_DIV_MAX); } else { m = MVEBU_MMC_BASE_FAST_CLOCK/(2*clock) - 1; if (m > MVEBU_MMC_BASE_DIV_MAX) m = MVEBU_MMC_BASE_DIV_MAX; - mvebu_mmc_write(SDIO_CLK_DIV, m & MVEBU_MMC_BASE_DIV_MAX); - debug("%s: clock (%d) div : %d\n", DRIVER_NAME, clock, m); + mvebu_mmc_write(mmc, SDIO_CLK_DIV, m & MVEBU_MMC_BASE_DIV_MAX); + dev_dbg(dev, "clock (%d) div : %d\n", clock, m); } }
-static void mvebu_mmc_set_bus(unsigned int bus) +static void mvebu_mmc_set_bus(struct udevice *dev, unsigned int bus) { + struct mvebu_mmc_plat *pdata = dev_get_plat(dev); + struct mmc *mmc = &pdata->mmc; u32 ctrl_reg = 0;
- ctrl_reg = mvebu_mmc_read(SDIO_HOST_CTRL); + ctrl_reg = mvebu_mmc_read(mmc, SDIO_HOST_CTRL); ctrl_reg &= ~SDIO_HOST_CTRL_DATA_WIDTH_4_BITS;
switch (bus) { @@ -306,23 +318,26 @@ static void mvebu_mmc_set_bus(unsigned int bus)
ctrl_reg |= SDIO_HOST_CTRL_CARD_TYPE_MEM_ONLY;
- debug("%s: ctrl 0x%04x: %s %s %s\n", DRIVER_NAME, ctrl_reg, - (ctrl_reg & SDIO_HOST_CTRL_PUSH_PULL_EN) ? - "push-pull" : "open-drain", - (ctrl_reg & SDIO_HOST_CTRL_DATA_WIDTH_4_BITS) ? - "4bit-width" : "1bit-width", - (ctrl_reg & SDIO_HOST_CTRL_HI_SPEED_EN) ? - "high-speed" : ""); + dev_dbg(dev, "ctrl 0x%04x: %s %s %s\n", ctrl_reg, + (ctrl_reg & SDIO_HOST_CTRL_PUSH_PULL_EN) ? + "push-pull" : "open-drain", + (ctrl_reg & SDIO_HOST_CTRL_DATA_WIDTH_4_BITS) ? + "4bit-width" : "1bit-width", + (ctrl_reg & SDIO_HOST_CTRL_HI_SPEED_EN) ? + "high-speed" : "");
- mvebu_mmc_write(SDIO_HOST_CTRL, ctrl_reg); + mvebu_mmc_write(mmc, SDIO_HOST_CTRL, ctrl_reg); }
-static int mvebu_mmc_set_ios(struct mmc *mmc) +static int mvebu_mmc_set_ios(struct udevice *dev) { - debug("%s: bus[%d] clock[%d]\n", DRIVER_NAME, - mmc->bus_width, mmc->clock); - mvebu_mmc_set_bus(mmc->bus_width); - mvebu_mmc_set_clk(mmc->clock); + struct mvebu_mmc_plat *pdata = dev_get_plat(dev); + struct mmc *mmc = &pdata->mmc; + + dev_dbg(dev, "bus[%d] clock[%d]\n", + mmc->bus_width, mmc->clock); + mvebu_mmc_set_bus(dev, mmc->bus_width); + mvebu_mmc_set_clk(dev, mmc->clock);
return 0; } @@ -330,13 +345,13 @@ static int mvebu_mmc_set_ios(struct mmc *mmc) /* * Set window register. */ -static void mvebu_window_setup(void) +static void mvebu_window_setup(const struct mmc *mmc) { int i;
for (i = 0; i < 4; i++) { - mvebu_mmc_write(WINDOW_CTRL(i), 0); - mvebu_mmc_write(WINDOW_BASE(i), 0); + mvebu_mmc_write(mmc, WINDOW_CTRL(i), 0); + mvebu_mmc_write(mmc, WINDOW_BASE(i), 0); } for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { u32 size, base, attrib; @@ -364,79 +379,119 @@ static void mvebu_window_setup(void) size = gd->bd->bi_dram[i].size; base = gd->bd->bi_dram[i].start; if (size && attrib) { - mvebu_mmc_write(WINDOW_CTRL(i), + mvebu_mmc_write(mmc, WINDOW_CTRL(i), MVCPU_WIN_CTRL_DATA(size, MVEBU_TARGET_DRAM, attrib, MVCPU_WIN_ENABLE)); } else { - mvebu_mmc_write(WINDOW_CTRL(i), MVCPU_WIN_DISABLE); + mvebu_mmc_write(mmc, WINDOW_CTRL(i), MVCPU_WIN_DISABLE); } - mvebu_mmc_write(WINDOW_BASE(i), base); + mvebu_mmc_write(mmc, WINDOW_BASE(i), base); } }
-static int mvebu_mmc_initialize(struct mmc *mmc) +static int mvebu_mmc_initialize(struct udevice *dev) { - debug("%s: mvebu_mmc_initialize\n", DRIVER_NAME); + struct mvebu_mmc_plat *pdata = dev_get_plat(dev); + struct mmc *mmc = &pdata->mmc; + + dev_dbg(dev, "%s\n", __func__);
/* * Setting host parameters * Initial Host Ctrl : Timeout : max , Normal Speed mode, * 4-bit data mode, Big Endian, SD memory Card, Push_pull CMD Line */ - mvebu_mmc_write(SDIO_HOST_CTRL, + mvebu_mmc_write(mmc, SDIO_HOST_CTRL, SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX) | SDIO_HOST_CTRL_DATA_WIDTH_4_BITS | SDIO_HOST_CTRL_BIG_ENDIAN | SDIO_HOST_CTRL_PUSH_PULL_EN | SDIO_HOST_CTRL_CARD_TYPE_MEM_ONLY);
- mvebu_mmc_write(SDIO_CLK_CTRL, 0); + mvebu_mmc_write(mmc, SDIO_CLK_CTRL, 0);
/* enable status */ - mvebu_mmc_write(SDIO_NOR_STATUS_EN, SDIO_POLL_MASK); - mvebu_mmc_write(SDIO_ERR_STATUS_EN, SDIO_POLL_MASK); + mvebu_mmc_write(mmc, SDIO_NOR_STATUS_EN, SDIO_POLL_MASK); + mvebu_mmc_write(mmc, SDIO_ERR_STATUS_EN, SDIO_POLL_MASK);
/* disable interrupts */ - mvebu_mmc_write(SDIO_NOR_INTR_EN, 0); - mvebu_mmc_write(SDIO_ERR_INTR_EN, 0); + mvebu_mmc_write(mmc, SDIO_NOR_INTR_EN, 0); + mvebu_mmc_write(mmc, SDIO_ERR_INTR_EN, 0);
- mvebu_window_setup(); + mvebu_window_setup(mmc);
/* SW reset */ - mvebu_mmc_write(SDIO_SW_RESET, SDIO_SW_RESET_NOW); + mvebu_mmc_write(mmc, SDIO_SW_RESET, SDIO_SW_RESET_NOW);
return 0; }
-static const struct mmc_ops mvebu_mmc_ops = { - .send_cmd = mvebu_mmc_send_cmd, - .set_ios = mvebu_mmc_set_ios, - .init = mvebu_mmc_initialize, -}; - -static struct mmc_config mvebu_mmc_cfg = { - .name = DRIVER_NAME, - .ops = &mvebu_mmc_ops, - .f_min = MVEBU_MMC_BASE_FAST_CLOCK / MVEBU_MMC_BASE_DIV_MAX, - .f_max = MVEBU_MMC_CLOCKRATE_MAX, - .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, - .host_caps = MMC_MODE_4BIT | MMC_MODE_HS | - MMC_MODE_HS_52MHz, - .part_type = PART_TYPE_DOS, - .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT, -}; - -int mvebu_mmc_init(struct bd_info *bis) +static int mvebu_mmc_of_to_plat(struct udevice *dev) { - struct mmc *mmc; + struct mvebu_mmc_plat *pdata = dev_get_plat(dev); + fdt_addr_t addr;
- mvebu_mmc_power_up(); + addr = dev_read_addr(dev); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL;
- mmc = mmc_create(&mvebu_mmc_cfg, bis); - if (mmc == NULL) - return -1; + pdata->iobase = (void *)addr;
return 0; } + +static int mvebu_mmc_probe(struct udevice *dev) +{ + struct mvebu_mmc_plat *pdata = dev_get_plat(dev); + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct mmc *mmc = &pdata->mmc; + struct mmc_config *cfg = &pdata->cfg; + + cfg->name = dev->name; + cfg->f_min = MVEBU_MMC_BASE_FAST_CLOCK / MVEBU_MMC_BASE_DIV_MAX; + cfg->f_max = MVEBU_MMC_CLOCKRATE_MAX; + cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; + cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_HS | MMC_MODE_HS_52MHz; + cfg->part_type = PART_TYPE_DOS; + cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; + + mmc->cfg = cfg; + mmc->priv = pdata; + mmc->dev = dev; + upriv->mmc = mmc; + + mvebu_mmc_power_up(dev); + mvebu_mmc_initialize(dev); + + return 0; +} + +static const struct dm_mmc_ops mvebu_dm_mmc_ops = { + .send_cmd = mvebu_mmc_send_cmd, + .set_ios = mvebu_mmc_set_ios, +}; + +static int mvebu_mmc_bind(struct udevice *dev) +{ + struct mvebu_mmc_plat *pdata = dev_get_plat(dev); + + return mmc_bind(dev, &pdata->mmc, &pdata->cfg); +} + +static const struct udevice_id mvebu_mmc_match[] = { + { .compatible = "marvell,orion-sdio" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(mvebu_mmc) = { + .name = "mvebu_mmc", + .id = UCLASS_MMC, + .of_match = mvebu_mmc_match, + .ops = &mvebu_dm_mmc_ops, + .probe = mvebu_mmc_probe, + .bind = mvebu_mmc_bind, + .of_to_plat = mvebu_mmc_of_to_plat, + .plat_auto = sizeof(struct mvebu_mmc_plat), +}; diff --git a/include/mvebu_mmc.h b/include/mvebu_mmc.h index a35e5a12ce..e75c3fa328 100644 --- a/include/mvebu_mmc.h +++ b/include/mvebu_mmc.h @@ -258,17 +258,10 @@ /* Hardware reset */ #define MMC_CAP_HW_RESET (1 << 31)
-struct mvebu_mmc_cfg { - u32 mvebu_mmc_base; - u32 mvebu_mmc_clk; - u8 max_bus_width; +struct mvebu_mmc_plat { + void *iobase; struct mmc_config cfg; + struct mmc mmc; };
-/* - * Functions prototypes - */ - -int mvebu_mmc_init(struct bd_info *bis); - #endif /* __MVEBU_MMC_H__ */

On 3/30/21 5:19 PM, Harm Berntsen wrote:
This is a straightforward conversion of the old, non-dm driver. It was done in-place as the deadline for non-dm MMC has passed. Previous commits ensured that no board depends on the old, non-dm variant. Tested on a Kirkwood based board with eMMC.
Signed-off-by: Harm Berntsen harm.berntsen@nedap.com Tested-by: Harm Berntsen harm.berntsen@nedap.com Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Stefan Roese sr@denx.de CC: Pantelis Antoniou panto@antoniou-consulting.com CC: Stefan Roese sr@denx.de CC: Gerald Kerma drEagle@doukki.net CC: Simon Glass sjg@chromium.org
Reviewed-by: Jaehoon Chung jh80.chung@samsung.com
Best Regards, Jaehoon Chung
Changes in v2:
- Fixed patch style by sending patch through patman + git send-email
drivers/mmc/Kconfig | 9 ++ drivers/mmc/mvebu_mmc.c | 309 +++++++++++++++++++++++----------------- include/mvebu_mmc.h | 13 +- 3 files changed, 194 insertions(+), 137 deletions(-)
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index f8ca52efb6..de9ab8a387 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -326,6 +326,15 @@ config MMC_OCTEONTX
If unsure, say N.
+config MVEBU_MMC
- bool "Kirkwood MMC controller support"
- depends on DM_MMC && BLK && ARCH_KIRKWOOD
- help
Support for MMC host controller on Kirkwood SoCs.
If you are on a Kirkwood architecture, say Y here.
If unsure, say N.
config PXA_MMC_GENERIC bool "Support for MMC controllers on PXA" help diff --git a/drivers/mmc/mvebu_mmc.c b/drivers/mmc/mvebu_mmc.c index 8ec1f57a1b..fea55c61ed 100644 --- a/drivers/mmc/mvebu_mmc.c +++ b/drivers/mmc/mvebu_mmc.c @@ -11,60 +11,67 @@ #include <errno.h> #include <log.h> #include <malloc.h> +#include <dm.h> +#include <fdtdec.h> #include <part.h> #include <mmc.h> -#include <asm/global_data.h> #include <asm/io.h> #include <asm/arch/cpu.h> #include <asm/arch/soc.h> #include <mvebu_mmc.h>
-DECLARE_GLOBAL_DATA_PTR;
-#define DRIVER_NAME "MVEBU_MMC" +#include <dm/device_compat.h>
#define MVEBU_TARGET_DRAM 0
#define TIMEOUT_DELAY 5*CONFIG_SYS_HZ /* wait 5 seconds */
-static void mvebu_mmc_write(u32 offs, u32 val) +static inline void *get_regbase(const struct mmc *mmc) {
- writel(val, CONFIG_SYS_MMC_BASE + (offs));
- struct mvebu_mmc_plat *pdata = mmc->priv;
- return pdata->iobase;
}
-static u32 mvebu_mmc_read(u32 offs) +static void mvebu_mmc_write(const struct mmc *mmc, u32 offs, u32 val) {
- return readl(CONFIG_SYS_MMC_BASE + (offs));
- writel(val, get_regbase(mmc) + (offs));
}
-static int mvebu_mmc_setup_data(struct mmc_data *data) +static u32 mvebu_mmc_read(const struct mmc *mmc, u32 offs) {
- return readl(get_regbase(mmc) + (offs));
+}
+static int mvebu_mmc_setup_data(struct udevice *dev, struct mmc_data *data) +{
- struct mvebu_mmc_plat *pdata = dev_get_plat(dev);
- struct mmc *mmc = &pdata->mmc; u32 ctrl_reg;
- debug("%s, data %s : blocks=%d blksz=%d\n", DRIVER_NAME,
(data->flags & MMC_DATA_READ) ? "read" : "write",
data->blocks, data->blocksize);
dev_dbg(dev, "data %s : blocks=%d blksz=%d\n",
(data->flags & MMC_DATA_READ) ? "read" : "write",
data->blocks, data->blocksize);
/* default to maximum timeout */
- ctrl_reg = mvebu_mmc_read(SDIO_HOST_CTRL);
- ctrl_reg = mvebu_mmc_read(mmc, SDIO_HOST_CTRL); ctrl_reg |= SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX);
- mvebu_mmc_write(SDIO_HOST_CTRL, ctrl_reg);
mvebu_mmc_write(mmc, SDIO_HOST_CTRL, ctrl_reg);
if (data->flags & MMC_DATA_READ) {
mvebu_mmc_write(SDIO_SYS_ADDR_LOW, (u32)data->dest & 0xffff);
mvebu_mmc_write(SDIO_SYS_ADDR_HI, (u32)data->dest >> 16);
mvebu_mmc_write(mmc, SDIO_SYS_ADDR_LOW, (u32)data->dest & 0xffff);
} else {mvebu_mmc_write(mmc, SDIO_SYS_ADDR_HI, (u32)data->dest >> 16);
mvebu_mmc_write(SDIO_SYS_ADDR_LOW, (u32)data->src & 0xffff);
mvebu_mmc_write(SDIO_SYS_ADDR_HI, (u32)data->src >> 16);
mvebu_mmc_write(mmc, SDIO_SYS_ADDR_LOW, (u32)data->src & 0xffff);
}mvebu_mmc_write(mmc, SDIO_SYS_ADDR_HI, (u32)data->src >> 16);
- mvebu_mmc_write(SDIO_BLK_COUNT, data->blocks);
- mvebu_mmc_write(SDIO_BLK_SIZE, data->blocksize);
mvebu_mmc_write(mmc, SDIO_BLK_COUNT, data->blocks);
mvebu_mmc_write(mmc, SDIO_BLK_SIZE, data->blocksize);
return 0;
}
-static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, +static int mvebu_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data *data) { ulong start; @@ -72,12 +79,14 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, ushort resptype = 0; ushort xfertype = 0; ushort resp_indx = 0;
- struct mvebu_mmc_plat *pdata = dev_get_plat(dev);
- struct mmc *mmc = &pdata->mmc;
- debug("%s: cmdidx [0x%x] resp_type[0x%x] cmdarg[0x%x]\n",
DRIVER_NAME, cmd->cmdidx, cmd->resp_type, cmd->cmdarg);
- dev_dbg(dev, "cmdidx [0x%x] resp_type[0x%x] cmdarg[0x%x]\n",
cmd->cmdidx, cmd->resp_type, cmd->cmdarg);
- debug("%s: cmd %d (hw state 0x%04x)\n", DRIVER_NAME,
cmd->cmdidx, mvebu_mmc_read(SDIO_HW_STATE));
dev_dbg(dev, "cmd %d (hw state 0x%04x)\n",
cmd->cmdidx, mvebu_mmc_read(mmc, SDIO_HW_STATE));
/*
- Hardware weirdness. The FIFO_EMPTY bit of the HW_STATE
@@ -88,26 +97,26 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, * this bit comes to good sense (which eventually happens by * itself) then the new transfer simply fails with a timeout. */
- if (!(mvebu_mmc_read(SDIO_HW_STATE) & CMD_FIFO_EMPTY)) {
if (!(mvebu_mmc_read(mmc, SDIO_HW_STATE) & CMD_FIFO_EMPTY)) { ushort hw_state, count = 0;
start = get_timer(0); do {
hw_state = mvebu_mmc_read(SDIO_HW_STATE);
hw_state = mvebu_mmc_read(mmc, SDIO_HW_STATE); if ((get_timer(0) - start) > TIMEOUT_DELAY) { printf("%s : FIFO_EMPTY bit missing\n",
DRIVER_NAME);
} while (!(hw_state & CMD_FIFO_EMPTY));dev->name); break; } count++;
debug("%s *** wait for FIFO_EMPTY bit (hw=0x%04x, count=%d, jiffies=%ld)\n",
DRIVER_NAME, hw_state, count, (get_timer(0) - (start)));
dev_dbg(dev, "*** wait for FIFO_EMPTY bit (hw=0x%04x, count=%d, jiffies=%ld)\n",
hw_state, count, (get_timer(0) - (start)));
}
/* Clear status */
- mvebu_mmc_write(SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK);
- mvebu_mmc_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK);
mvebu_mmc_write(mmc, SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK);
mvebu_mmc_write(mmc, SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK);
resptype = SDIO_CMD_INDEX(cmd->cmdidx);
@@ -133,11 +142,10 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, }
if (data) {
int err = mvebu_mmc_setup_data(data);
int err = mvebu_mmc_setup_data(dev, data);
if (err) {
debug("%s: command DATA error :%x\n",
DRIVER_NAME, err);
}dev_dbg(dev, "command DATA error :%x\n", err); return err;
@@ -154,34 +162,33 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, }
/* Setting cmd arguments */
- mvebu_mmc_write(SDIO_ARG_LOW, cmd->cmdarg & 0xffff);
- mvebu_mmc_write(SDIO_ARG_HI, cmd->cmdarg >> 16);
mvebu_mmc_write(mmc, SDIO_ARG_LOW, cmd->cmdarg & 0xffff);
mvebu_mmc_write(mmc, SDIO_ARG_HI, cmd->cmdarg >> 16);
/* Setting Xfer mode */
- mvebu_mmc_write(SDIO_XFER_MODE, xfertype);
mvebu_mmc_write(mmc, SDIO_XFER_MODE, xfertype);
/* Sending command */
- mvebu_mmc_write(SDIO_CMD, resptype);
mvebu_mmc_write(mmc, SDIO_CMD, resptype);
start = get_timer(0);
- while (!((mvebu_mmc_read(SDIO_NOR_INTR_STATUS)) & waittype)) {
if (mvebu_mmc_read(SDIO_NOR_INTR_STATUS) & SDIO_NOR_ERROR) {
debug("%s: error! cmdidx : %d, err reg: %04x\n",
DRIVER_NAME, cmd->cmdidx,
mvebu_mmc_read(SDIO_ERR_INTR_STATUS));
if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) &
- while (!((mvebu_mmc_read(mmc, SDIO_NOR_INTR_STATUS)) & waittype)) {
if (mvebu_mmc_read(mmc, SDIO_NOR_INTR_STATUS) & SDIO_NOR_ERROR) {
dev_dbg(dev, "error! cmdidx : %d, err reg: %04x\n",
cmd->cmdidx,
mvebu_mmc_read(mmc, SDIO_ERR_INTR_STATUS));
if (mvebu_mmc_read(mmc, SDIO_ERR_INTR_STATUS) & (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT)) {
debug("%s: command READ timed out\n",
DRIVER_NAME);
dev_dbg(dev, "command READ timed out\n"); return -ETIMEDOUT; }
debug("%s: command READ error\n", DRIVER_NAME);
dev_dbg(dev, "command READ error\n"); return -ECOMM;
}
if ((get_timer(0) - start) > TIMEOUT_DELAY) {
debug("%s: command timed out\n", DRIVER_NAME);
} }dev_dbg(dev, "command timed out\n"); return -ETIMEDOUT;
@@ -191,8 +198,7 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, uint response[8];
for (resp_indx = 0; resp_indx < 8; resp_indx++)
response[resp_indx]
= mvebu_mmc_read(SDIO_RSP(resp_indx));
response[resp_indx] = mvebu_mmc_read(mmc, SDIO_RSP(resp_indx));
cmd->response[0] = ((response[0] & 0x03ff) << 22) | ((response[1] & 0xffff) << 6) |
@@ -209,8 +215,7 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, uint response[3];
for (resp_indx = 0; resp_indx < 3; resp_indx++)
response[resp_indx]
= mvebu_mmc_read(SDIO_RSP(resp_indx));
response[resp_indx] = mvebu_mmc_read(mmc, SDIO_RSP(resp_indx));
cmd->response[0] = ((response[2] & 0x003f) << (8 - 8)) | ((response[1] & 0xffff) << (14 - 8)) |
@@ -225,64 +230,71 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, cmd->response[3] = 0; }
- debug("%s: resp[0x%x] ", DRIVER_NAME, cmd->resp_type);
- dev_dbg(dev, "resp[0x%x] ", cmd->resp_type); debug("[0x%x] ", cmd->response[0]); debug("[0x%x] ", cmd->response[1]); debug("[0x%x] ", cmd->response[2]); debug("[0x%x] ", cmd->response[3]); debug("\n");
- if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) &
if (mvebu_mmc_read(mmc, SDIO_ERR_INTR_STATUS) & (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT)) return -ETIMEDOUT;
return 0;
}
-static void mvebu_mmc_power_up(void) +static void mvebu_mmc_power_up(struct udevice *dev) {
- debug("%s: power up\n", DRIVER_NAME);
struct mvebu_mmc_plat *pdata = dev_get_plat(dev);
struct mmc *mmc = &pdata->mmc;
dev_dbg(dev, "power up\n");
/* disable interrupts */
- mvebu_mmc_write(SDIO_NOR_INTR_EN, 0);
- mvebu_mmc_write(SDIO_ERR_INTR_EN, 0);
mvebu_mmc_write(mmc, SDIO_NOR_INTR_EN, 0);
mvebu_mmc_write(mmc, SDIO_ERR_INTR_EN, 0);
/* SW reset */
- mvebu_mmc_write(SDIO_SW_RESET, SDIO_SW_RESET_NOW);
- mvebu_mmc_write(mmc, SDIO_SW_RESET, SDIO_SW_RESET_NOW);
- mvebu_mmc_write(SDIO_XFER_MODE, 0);
mvebu_mmc_write(mmc, SDIO_XFER_MODE, 0);
/* enable status */
- mvebu_mmc_write(SDIO_NOR_STATUS_EN, SDIO_POLL_MASK);
- mvebu_mmc_write(SDIO_ERR_STATUS_EN, SDIO_POLL_MASK);
mvebu_mmc_write(mmc, SDIO_NOR_STATUS_EN, SDIO_POLL_MASK);
mvebu_mmc_write(mmc, SDIO_ERR_STATUS_EN, SDIO_POLL_MASK);
/* enable interrupts status */
- mvebu_mmc_write(SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK);
- mvebu_mmc_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK);
- mvebu_mmc_write(mmc, SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK);
- mvebu_mmc_write(mmc, SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK);
}
-static void mvebu_mmc_set_clk(unsigned int clock) +static void mvebu_mmc_set_clk(struct udevice *dev, unsigned int clock) { unsigned int m;
struct mvebu_mmc_plat *pdata = dev_get_plat(dev);
struct mmc *mmc = &pdata->mmc;
if (clock == 0) {
debug("%s: clock off\n", DRIVER_NAME);
mvebu_mmc_write(SDIO_XFER_MODE, SDIO_XFER_MODE_STOP_CLK);
mvebu_mmc_write(SDIO_CLK_DIV, MVEBU_MMC_BASE_DIV_MAX);
dev_dbg(dev, "clock off\n");
mvebu_mmc_write(mmc, SDIO_XFER_MODE, SDIO_XFER_MODE_STOP_CLK);
} else { m = MVEBU_MMC_BASE_FAST_CLOCK/(2*clock) - 1; if (m > MVEBU_MMC_BASE_DIV_MAX) m = MVEBU_MMC_BASE_DIV_MAX;mvebu_mmc_write(mmc, SDIO_CLK_DIV, MVEBU_MMC_BASE_DIV_MAX);
mvebu_mmc_write(SDIO_CLK_DIV, m & MVEBU_MMC_BASE_DIV_MAX);
debug("%s: clock (%d) div : %d\n", DRIVER_NAME, clock, m);
mvebu_mmc_write(mmc, SDIO_CLK_DIV, m & MVEBU_MMC_BASE_DIV_MAX);
}dev_dbg(dev, "clock (%d) div : %d\n", clock, m);
}
-static void mvebu_mmc_set_bus(unsigned int bus) +static void mvebu_mmc_set_bus(struct udevice *dev, unsigned int bus) {
- struct mvebu_mmc_plat *pdata = dev_get_plat(dev);
- struct mmc *mmc = &pdata->mmc; u32 ctrl_reg = 0;
- ctrl_reg = mvebu_mmc_read(SDIO_HOST_CTRL);
ctrl_reg = mvebu_mmc_read(mmc, SDIO_HOST_CTRL); ctrl_reg &= ~SDIO_HOST_CTRL_DATA_WIDTH_4_BITS;
switch (bus) {
@@ -306,23 +318,26 @@ static void mvebu_mmc_set_bus(unsigned int bus)
ctrl_reg |= SDIO_HOST_CTRL_CARD_TYPE_MEM_ONLY;
- debug("%s: ctrl 0x%04x: %s %s %s\n", DRIVER_NAME, ctrl_reg,
(ctrl_reg & SDIO_HOST_CTRL_PUSH_PULL_EN) ?
"push-pull" : "open-drain",
(ctrl_reg & SDIO_HOST_CTRL_DATA_WIDTH_4_BITS) ?
"4bit-width" : "1bit-width",
(ctrl_reg & SDIO_HOST_CTRL_HI_SPEED_EN) ?
"high-speed" : "");
- dev_dbg(dev, "ctrl 0x%04x: %s %s %s\n", ctrl_reg,
(ctrl_reg & SDIO_HOST_CTRL_PUSH_PULL_EN) ?
"push-pull" : "open-drain",
(ctrl_reg & SDIO_HOST_CTRL_DATA_WIDTH_4_BITS) ?
"4bit-width" : "1bit-width",
(ctrl_reg & SDIO_HOST_CTRL_HI_SPEED_EN) ?
"high-speed" : "");
- mvebu_mmc_write(SDIO_HOST_CTRL, ctrl_reg);
- mvebu_mmc_write(mmc, SDIO_HOST_CTRL, ctrl_reg);
}
-static int mvebu_mmc_set_ios(struct mmc *mmc) +static int mvebu_mmc_set_ios(struct udevice *dev) {
- debug("%s: bus[%d] clock[%d]\n", DRIVER_NAME,
mmc->bus_width, mmc->clock);
- mvebu_mmc_set_bus(mmc->bus_width);
- mvebu_mmc_set_clk(mmc->clock);
struct mvebu_mmc_plat *pdata = dev_get_plat(dev);
struct mmc *mmc = &pdata->mmc;
dev_dbg(dev, "bus[%d] clock[%d]\n",
mmc->bus_width, mmc->clock);
mvebu_mmc_set_bus(dev, mmc->bus_width);
mvebu_mmc_set_clk(dev, mmc->clock);
return 0;
} @@ -330,13 +345,13 @@ static int mvebu_mmc_set_ios(struct mmc *mmc) /*
- Set window register.
*/ -static void mvebu_window_setup(void) +static void mvebu_window_setup(const struct mmc *mmc) { int i;
for (i = 0; i < 4; i++) {
mvebu_mmc_write(WINDOW_CTRL(i), 0);
mvebu_mmc_write(WINDOW_BASE(i), 0);
mvebu_mmc_write(mmc, WINDOW_CTRL(i), 0);
} for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { u32 size, base, attrib;mvebu_mmc_write(mmc, WINDOW_BASE(i), 0);
@@ -364,79 +379,119 @@ static void mvebu_window_setup(void) size = gd->bd->bi_dram[i].size; base = gd->bd->bi_dram[i].start; if (size && attrib) {
mvebu_mmc_write(WINDOW_CTRL(i),
} else {mvebu_mmc_write(mmc, WINDOW_CTRL(i), MVCPU_WIN_CTRL_DATA(size, MVEBU_TARGET_DRAM, attrib, MVCPU_WIN_ENABLE));
mvebu_mmc_write(WINDOW_CTRL(i), MVCPU_WIN_DISABLE);
}mvebu_mmc_write(mmc, WINDOW_CTRL(i), MVCPU_WIN_DISABLE);
mvebu_mmc_write(WINDOW_BASE(i), base);
}mvebu_mmc_write(mmc, WINDOW_BASE(i), base);
}
-static int mvebu_mmc_initialize(struct mmc *mmc) +static int mvebu_mmc_initialize(struct udevice *dev) {
- debug("%s: mvebu_mmc_initialize\n", DRIVER_NAME);
struct mvebu_mmc_plat *pdata = dev_get_plat(dev);
struct mmc *mmc = &pdata->mmc;
dev_dbg(dev, "%s\n", __func__);
/*
- Setting host parameters
- Initial Host Ctrl : Timeout : max , Normal Speed mode,
- 4-bit data mode, Big Endian, SD memory Card, Push_pull CMD Line
*/
- mvebu_mmc_write(SDIO_HOST_CTRL,
- mvebu_mmc_write(mmc, SDIO_HOST_CTRL, SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX) | SDIO_HOST_CTRL_DATA_WIDTH_4_BITS | SDIO_HOST_CTRL_BIG_ENDIAN | SDIO_HOST_CTRL_PUSH_PULL_EN | SDIO_HOST_CTRL_CARD_TYPE_MEM_ONLY);
- mvebu_mmc_write(SDIO_CLK_CTRL, 0);
mvebu_mmc_write(mmc, SDIO_CLK_CTRL, 0);
/* enable status */
- mvebu_mmc_write(SDIO_NOR_STATUS_EN, SDIO_POLL_MASK);
- mvebu_mmc_write(SDIO_ERR_STATUS_EN, SDIO_POLL_MASK);
mvebu_mmc_write(mmc, SDIO_NOR_STATUS_EN, SDIO_POLL_MASK);
mvebu_mmc_write(mmc, SDIO_ERR_STATUS_EN, SDIO_POLL_MASK);
/* disable interrupts */
- mvebu_mmc_write(SDIO_NOR_INTR_EN, 0);
- mvebu_mmc_write(SDIO_ERR_INTR_EN, 0);
- mvebu_mmc_write(mmc, SDIO_NOR_INTR_EN, 0);
- mvebu_mmc_write(mmc, SDIO_ERR_INTR_EN, 0);
- mvebu_window_setup();
mvebu_window_setup(mmc);
/* SW reset */
- mvebu_mmc_write(SDIO_SW_RESET, SDIO_SW_RESET_NOW);
mvebu_mmc_write(mmc, SDIO_SW_RESET, SDIO_SW_RESET_NOW);
return 0;
}
-static const struct mmc_ops mvebu_mmc_ops = {
- .send_cmd = mvebu_mmc_send_cmd,
- .set_ios = mvebu_mmc_set_ios,
- .init = mvebu_mmc_initialize,
-};
-static struct mmc_config mvebu_mmc_cfg = {
- .name = DRIVER_NAME,
- .ops = &mvebu_mmc_ops,
- .f_min = MVEBU_MMC_BASE_FAST_CLOCK / MVEBU_MMC_BASE_DIV_MAX,
- .f_max = MVEBU_MMC_CLOCKRATE_MAX,
- .voltages = MMC_VDD_32_33 | MMC_VDD_33_34,
- .host_caps = MMC_MODE_4BIT | MMC_MODE_HS |
MMC_MODE_HS_52MHz,
- .part_type = PART_TYPE_DOS,
- .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
-};
-int mvebu_mmc_init(struct bd_info *bis) +static int mvebu_mmc_of_to_plat(struct udevice *dev) {
- struct mmc *mmc;
- struct mvebu_mmc_plat *pdata = dev_get_plat(dev);
- fdt_addr_t addr;
- mvebu_mmc_power_up();
- addr = dev_read_addr(dev);
- if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
- mmc = mmc_create(&mvebu_mmc_cfg, bis);
- if (mmc == NULL)
return -1;
pdata->iobase = (void *)addr;
return 0;
}
+static int mvebu_mmc_probe(struct udevice *dev) +{
- struct mvebu_mmc_plat *pdata = dev_get_plat(dev);
- struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
- struct mmc *mmc = &pdata->mmc;
- struct mmc_config *cfg = &pdata->cfg;
- cfg->name = dev->name;
- cfg->f_min = MVEBU_MMC_BASE_FAST_CLOCK / MVEBU_MMC_BASE_DIV_MAX;
- cfg->f_max = MVEBU_MMC_CLOCKRATE_MAX;
- cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
- cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_HS | MMC_MODE_HS_52MHz;
- cfg->part_type = PART_TYPE_DOS;
- cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
- mmc->cfg = cfg;
- mmc->priv = pdata;
- mmc->dev = dev;
- upriv->mmc = mmc;
- mvebu_mmc_power_up(dev);
- mvebu_mmc_initialize(dev);
- return 0;
+}
+static const struct dm_mmc_ops mvebu_dm_mmc_ops = {
- .send_cmd = mvebu_mmc_send_cmd,
- .set_ios = mvebu_mmc_set_ios,
+};
+static int mvebu_mmc_bind(struct udevice *dev) +{
- struct mvebu_mmc_plat *pdata = dev_get_plat(dev);
- return mmc_bind(dev, &pdata->mmc, &pdata->cfg);
+}
+static const struct udevice_id mvebu_mmc_match[] = {
- { .compatible = "marvell,orion-sdio" },
- { /* sentinel */ }
+};
+U_BOOT_DRIVER(mvebu_mmc) = {
- .name = "mvebu_mmc",
- .id = UCLASS_MMC,
- .of_match = mvebu_mmc_match,
- .ops = &mvebu_dm_mmc_ops,
- .probe = mvebu_mmc_probe,
- .bind = mvebu_mmc_bind,
- .of_to_plat = mvebu_mmc_of_to_plat,
- .plat_auto = sizeof(struct mvebu_mmc_plat),
+}; diff --git a/include/mvebu_mmc.h b/include/mvebu_mmc.h index a35e5a12ce..e75c3fa328 100644 --- a/include/mvebu_mmc.h +++ b/include/mvebu_mmc.h @@ -258,17 +258,10 @@ /* Hardware reset */ #define MMC_CAP_HW_RESET (1 << 31)
-struct mvebu_mmc_cfg {
- u32 mvebu_mmc_base;
- u32 mvebu_mmc_clk;
- u8 max_bus_width;
+struct mvebu_mmc_plat {
- void *iobase; struct mmc_config cfg;
- struct mmc mmc;
};
-/*
- Functions prototypes
- */
-int mvebu_mmc_init(struct bd_info *bis);
#endif /* __MVEBU_MMC_H__ */

The non-dm MMC driver has been converted to the driver model. The sheevaplug was using the non-dm driver and this commit enables the new driver.
Signed-off-by: Harm Berntsen harm.berntsen@nedap.com Reviewed-by: Stefan Roese sr@denx.de CC: Prafulla Wadaskar prafulla@marvell.com CC: Stefan Roese sr@denx.de CC: Tom Rini trini@konsulko.com ---
Changes in v2: - Add commit text
configs/sheevaplug_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/sheevaplug_defconfig b/configs/sheevaplug_defconfig index 34da356b8e..65d8dff7ff 100644 --- a/configs/sheevaplug_defconfig +++ b/configs/sheevaplug_defconfig @@ -40,6 +40,8 @@ CONFIG_ENV_IS_IN_NAND=y CONFIG_NETCONSOLE=y CONFIG_DM=y CONFIG_MVSATA_IDE=y +CONFIG_DM_MMC=y +CONFIG_MVEBU_MMC=y CONFIG_MTD=y CONFIG_MTD_RAW_NAND=y CONFIG_MVGBE=y

On 30.03.21 10:19, Harm Berntsen wrote:
This series converts the existing mvebu_mmc driver to the driver model. Only two boards in the u-boot tree were using this: openrd and sheevaplug. The openrd board does currently not support driver model at all. Given the deadlines for conversion, this patch series drops MMC support for that board. The sheevaplug should still work but I don't have hardware to test it on. I've tested the driver on an out of tree Kirkwood board.
CC: Rick Thomas rick.thomas@pobox.com CC: Chris Packham judge.packham@gmail.com CC: Vagrant Cascadian vagrant@debian.org
Thanks for the feedback :)! Changes in v2:
- Fixed patch style by sending patch through patman + git send-email
- Add commit text
Harm Berntsen (8): configs: remove unused CONFIG_SYS_MMC_BASE defs configs: openrd: remove non-dm MMC driver configs: sheevaplug: remove non-dm MMC driver arm: kirkwood: remove non-dm MMC driver init configs: remove obsolete CONFIG_SYS_MMC_BASE configs: remove obsolete CONFIG_MVEBU_MMC mmc: mvebu: convert to driver model configs: sheevaplug: enable driver-model based MMC
arch/arm/mach-kirkwood/cpu.c | 7 - configs/sheevaplug_defconfig | 2 + drivers/mmc/Kconfig | 9 + drivers/mmc/mvebu_mmc.c | 309 ++++++++++++++++++------------ include/configs/clearfog.h | 5 - include/configs/controlcenterdc.h | 5 - include/configs/db-88f6820-gp.h | 5 - include/configs/helios4.h | 5 - include/configs/openrd.h | 5 - include/configs/sheevaplug.h | 8 - include/mvebu_mmc.h | 13 +- scripts/config_whitelist.txt | 2 - 12 files changed, 196 insertions(+), 179 deletions(-)
Applied to u-boot-marvell/master (whole series)
Thanks, Stefan
participants (3)
-
Harm Berntsen
-
Jaehoon Chung
-
Stefan Roese