diff mbox series

[U-Boot,v1,07/10] arm: pxa: mmc: add driver model support

Message ID 20190520004502.8924-8-marcel@ziswiler.com
State Awaiting Upstream
Delegated to: Peng Fan
Headers show
Series arm: pxa: mmc: add driver model support | expand

Commit Message

Marcel Ziswiler May 20, 2019, 12:44 a.m. UTC
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

Comments

Marek Vasut May 20, 2019, 1:04 a.m. UTC | #1
On 5/20/19 2:44 AM, Marcel Ziswiler wrote:
> 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)

u32 just like you do in the next hunk ?

I think you might want to split the cleanup from DM conversion.

>  {
>  	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(&regs->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))

BIT(31)

[...]

> +#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 */

We no longer support PXA3xx (Monahans) , just drop this.

And if you're really eager, feel free to pluck out all the
#if.*CPU_MONAHANS all over the codebase.

> +	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,

Are you sure about this one ? I vaguely remember that Colibri PXA board
I have has card detect signal ...

> +	.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 */
>
Tom Rini June 30, 2020, 3:21 p.m. UTC | #2
On Mon, May 20, 2019 at 02:44:59AM +0200, Marcel Ziswiler wrote:

> Add driver model (DM) support.
> 
> Signed-off-by: Marcel Ziswiler <marcel@ziswiler.com>

Applied to u-boot/next, thanks!
diff mbox series

Patch

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(&regs->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(&regs->rxfifo);
-
 		}
 
 		if (readl(&regs->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),
-		&regs->i_mask);
+	       &regs->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 */