
Add driver model (DM) support.
Signed-off-by: Marcel Ziswiler marcel@ziswiler.com
---
drivers/mmc/pxa_mmc_gen.c | 160 ++++++++++++++++++++----- include/dm/platform_data/pxa_mmc_gen.h | 22 ++++ 2 files changed, 154 insertions(+), 28 deletions(-) create mode 100644 include/dm/platform_data/pxa_mmc_gen.h
diff --git a/drivers/mmc/pxa_mmc_gen.c b/drivers/mmc/pxa_mmc_gen.c index a4dcdb5cff..08a5ca36a1 100644 --- a/drivers/mmc/pxa_mmc_gen.c +++ b/drivers/mmc/pxa_mmc_gen.c @@ -2,6 +2,9 @@ /* * Copyright (C) 2010 Marek Vasut marek.vasut@gmail.com * + * Modified to add driver model (DM) support + * Copyright (C) 2019 Marcel Ziswiler marcel@ziswiler.com + * * Loosely based on the old code and Linux's PXA MMC driver */
@@ -10,6 +13,8 @@ #include <asm/arch/regs-mmc.h> #include <linux/errno.h> #include <asm/io.h> +#include <dm.h> +#include <dm/platform_data/pxa_mmc_gen.h> #include <malloc.h> #include <mmc.h>
@@ -95,7 +100,7 @@ static int pxa_mmc_stop_clock(struct mmc *mmc) }
static int pxa_mmc_start_cmd(struct mmc *mmc, struct mmc_cmd *cmd, - uint32_t cmdat) + uint32_t cmdat) { struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; @@ -142,7 +147,7 @@ static int pxa_mmc_cmd_done(struct mmc *mmc, struct mmc_cmd *cmd) { struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; - uint32_t a, b, c; + u32 a, b, c; int i; int stat;
@@ -151,7 +156,7 @@ static int pxa_mmc_cmd_done(struct mmc *mmc, struct mmc_cmd *cmd)
/* * Linux says: - * Did I mention this is Sick. We always need to + * Did I mention this is Sick. We always need to * discard the upper 8 bits of the first 16-bit word. */ a = readl(®s->res) & 0xffff; @@ -163,13 +168,13 @@ static int pxa_mmc_cmd_done(struct mmc *mmc, struct mmc_cmd *cmd) }
/* The command response didn't arrive */ - if (stat & MMC_STAT_TIME_OUT_RESPONSE) + if (stat & MMC_STAT_TIME_OUT_RESPONSE) { return -ETIMEDOUT; - else if (stat & MMC_STAT_RES_CRC_ERROR - && cmd->resp_type & MMC_RSP_CRC) { -#ifdef PXAMMC_CRC_SKIP - if (cmd->resp_type & MMC_RSP_136 - && cmd->response[0] & (1 << 31)) + } else if (stat & MMC_STAT_RES_CRC_ERROR && + cmd->resp_type & MMC_RSP_CRC) { +#ifdef PXAMMC_CRC_SKIP + if (cmd->resp_type & MMC_RSP_136 && + cmd->response[0] & (1 << 31)) printf("Ignoring CRC, this may be dangerous!\n"); else #endif @@ -184,8 +189,8 @@ static int pxa_mmc_do_read_xfer(struct mmc *mmc, struct mmc_data *data) { struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; - uint32_t len; - uint32_t *buf = (uint32_t *)data->dest; + u32 len; + u32 *buf = (uint32_t *)data->dest; int size; int ret;
@@ -201,7 +206,6 @@ static int pxa_mmc_do_read_xfer(struct mmc *mmc, struct mmc_data *data) /* Read data into the buffer */ while (size--) *buf++ = readl(®s->rxfifo); - }
if (readl(®s->stat) & MMC_STAT_ERRORS) @@ -220,8 +224,8 @@ static int pxa_mmc_do_write_xfer(struct mmc *mmc, struct mmc_data *data) { struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; - uint32_t len; - uint32_t *buf = (uint32_t *)data->src; + u32 len; + u32 *buf = (uint32_t *)data->src; int size; int ret;
@@ -258,12 +262,11 @@ static int pxa_mmc_do_write_xfer(struct mmc *mmc, struct mmc_data *data) return 0; }
-static int pxa_mmc_request(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) +static int pxa_mmc_send_cmd_common(struct pxa_mmc_priv *priv, struct mmc *mmc, + struct mmc_cmd *cmd, struct mmc_data *data) { - struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; - uint32_t cmdat = 0; + u32 cmdat = 0; int ret;
/* Stop the controller */ @@ -312,12 +315,11 @@ static int pxa_mmc_request(struct mmc *mmc, struct mmc_cmd *cmd, return 0; }
-static int pxa_mmc_set_ios(struct mmc *mmc) +static int pxa_mmc_set_ios_common(struct pxa_mmc_priv *priv, struct mmc *mmc) { - struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; - uint32_t tmp; - uint32_t pxa_mmc_clock; + u32 tmp; + u32 pxa_mmc_clock;
if (!mmc->clock) { pxa_mmc_stop_clock(mmc); @@ -345,9 +347,8 @@ static int pxa_mmc_set_ios(struct mmc *mmc) return 0; }
-static int pxa_mmc_init(struct mmc *mmc) +static int pxa_mmc_init_common(struct pxa_mmc_priv *priv, struct mmc *mmc) { - struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs;
/* Make sure the clock are stopped */ @@ -361,10 +362,34 @@ static int pxa_mmc_init(struct mmc *mmc)
/* Mask all interrupts */ writel(~(MMC_I_MASK_TXFIFO_WR_REQ | MMC_I_MASK_RXFIFO_RD_REQ), - ®s->i_mask); + ®s->i_mask); + return 0; }
+#if !CONFIG_IS_ENABLED(DM_MMC) +static int pxa_mmc_init(struct mmc *mmc) +{ + struct pxa_mmc_priv *priv = mmc->priv; + + return pxa_mmc_init_common(priv, mmc); +} + +static int pxa_mmc_request(struct mmc *mmc, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct pxa_mmc_priv *priv = mmc->priv; + + return pxa_mmc_send_cmd_common(priv, mmc, cmd, data); +} + +static int pxa_mmc_set_ios(struct mmc *mmc) +{ + struct pxa_mmc_priv *priv = mmc->priv; + + return pxa_mmc_set_ios_common(priv, mmc); +} + static const struct mmc_ops pxa_mmc_ops = { .send_cmd = pxa_mmc_request, .set_ios = pxa_mmc_set_ios, @@ -385,7 +410,7 @@ int pxa_mmc_register(int card_index) { struct mmc *mmc; struct pxa_mmc_priv *priv; - uint32_t reg; + u32 reg; int ret = -ENOMEM;
priv = malloc(sizeof(struct pxa_mmc_priv)); @@ -404,7 +429,7 @@ int pxa_mmc_register(int card_index) default: ret = -EINVAL; printf("PXA MMC: Invalid MMC controller ID (card_index = %d)\n", - card_index); + card_index); goto err1; }
@@ -419,7 +444,7 @@ int pxa_mmc_register(int card_index) #endif
mmc = mmc_create(&pxa_mmc_cfg, priv); - if (mmc == NULL) + if (!mmc) goto err1;
return 0; @@ -429,3 +454,82 @@ err1: err0: return ret; } +#else /* !CONFIG_IS_ENABLED(DM_MMC) */ +static int pxa_mmc_probe(struct udevice *dev) +{ + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct pxa_mmc_plat *plat = dev_get_platdata(dev); + struct mmc_config *cfg = &plat->cfg; + struct mmc *mmc = &plat->mmc; + struct pxa_mmc_priv *priv = dev_get_priv(dev); + u32 reg; + + upriv->mmc = mmc; + + cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; + cfg->f_max = PXAMMC_MAX_SPEED; + cfg->f_min = PXAMMC_MIN_SPEED; + cfg->host_caps = PXAMMC_HOST_CAPS; + cfg->name = dev->name; + cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; + + mmc->priv = priv; + + priv->regs = plat->base; + +#ifndef CONFIG_CPU_MONAHANS /* PXA2xx */ + reg = readl(CKEN); + reg |= CKEN12_MMC; + writel(reg, CKEN); +#else /* PXA3xx */ + reg = readl(CKENA); + reg |= CKENA_12_MMC0 | CKENA_13_MMC1; + writel(reg, CKENA); +#endif + + return pxa_mmc_init_common(priv, mmc); +} + +static int pxa_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct pxa_mmc_plat *plat = dev_get_platdata(dev); + struct pxa_mmc_priv *priv = dev_get_priv(dev); + + return pxa_mmc_send_cmd_common(priv, &plat->mmc, cmd, data); +} + +static int pxa_mmc_set_ios(struct udevice *dev) +{ + struct pxa_mmc_plat *plat = dev_get_platdata(dev); + struct pxa_mmc_priv *priv = dev_get_priv(dev); + + return pxa_mmc_set_ios_common(priv, &plat->mmc); +} + +static const struct dm_mmc_ops pxa_mmc_ops = { + .get_cd = NULL, + .send_cmd = pxa_mmc_send_cmd, + .set_ios = pxa_mmc_set_ios, +}; + +#if CONFIG_IS_ENABLED(BLK) +static int pxa_mmc_bind(struct udevice *dev) +{ + struct pxa_mmc_plat *plat = dev_get_platdata(dev); + + return mmc_bind(dev, &plat->mmc, &plat->cfg); +} +#endif + +U_BOOT_DRIVER(pxa_mmc) = { +#if CONFIG_IS_ENABLED(BLK) + .bind = pxa_mmc_bind, +#endif + .id = UCLASS_MMC, + .name = "pxa_mmc", + .ops = &pxa_mmc_ops, + .priv_auto_alloc_size = sizeof(struct pxa_mmc_priv), + .probe = pxa_mmc_probe, +}; +#endif /* !CONFIG_IS_ENABLED(DM_MMC) */ diff --git a/include/dm/platform_data/pxa_mmc_gen.h b/include/dm/platform_data/pxa_mmc_gen.h new file mode 100644 index 0000000000..9875bab2cf --- /dev/null +++ b/include/dm/platform_data/pxa_mmc_gen.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2019 Marcel Ziswiler marcel.ziswiler@toradex.com + */ + +#ifndef __PXA_MMC_GEN_H +#define __PXA_MMC_GEN_H + +#include <mmc.h> + +/* + * struct pxa_mmc_platdata - information about a PXA MMC controller + * + * @base: MMC controller base register address + */ +struct pxa_mmc_plat { + struct mmc_config cfg; + struct mmc mmc; + struct pxa_mmc_regs *base; +}; + +#endif /* __PXA_MMC_GEN_H */