Skip to contentSkip to conversation

Extend ARM_PL180_MMCI

PATCH New patrice.chotard at st.com 2 participants 11 messages Oct 23, 2017 – Nov 17, 2017

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

v2 cover Extend ARM_PL180_MMCI

From: Patrice Chotard <[email protected]>

Currently this driver is used by VEXPRESS platform which doesn't support Driver Model.
ARM_PL180_MMCI IP is embedded on STM32F4 and F7 platforms. In order to add SD support on these 2 STM32 family SoCs, the following reworks are needed:
_ update arm_pl180_mmci_init() prototype to make this driver working with
DM and none DM platforms
_ addapt driver to driver model
_ add bus_width device tree support
_ add clock support
_ add .get_cd callback support

This series has been tested internally on both STM32F4 and STM32F7 SoCs family. Future SD support for these 2 platforms will be added soon.

v2: _ add defines for clock min and max value in patch 2
_ remove useless return in bus_width switch case in patch 3

Patrice Chotard (5):
mmc: arm_pl180_mmci: update arm_pl180_mmci_init() prototype
mmc: arm_pl180_mmci: adapt driver to DM usage
mmc: arm_pl180_mmci: add bus_width DT property support
mmc: arm_pl180_mmci: add clock support
mmc: arm_pl180_mmci: add .getcd callback

 board/armltd/vexpress/vexpress_common.c |   3 +-
 drivers/mmc/Kconfig                     |   9 ++
 drivers/mmc/arm_pl180_mmci.c            | 187 +++++++++++++++++++++++++++++---
 drivers/mmc/arm_pl180_mmci.h            |   9 +-
 4 files changed, 189 insertions(+), 19 deletions(-)
Signature · 1 line
1.9.1
#1 lore raw

PATCH v2 1/5 mmc: arm_pl180_mmci: update arm_pl180_mmci_init() prototype

From: Patrice Chotard <[email protected]>

Update arm_pl180_mmci_init() prototype by adding struct mmc** param. This is needed before converting this driver to driver model in order to use arm_pl180_mmci_init() in driver model and in none driver model implementation

---
 board/armltd/vexpress/vexpress_common.c |  3 ++-
 drivers/mmc/arm_pl180_mmci.c            | 10 +++++-----
 drivers/mmc/arm_pl180_mmci.h            |  2 +-
 3 files changed, 8 insertions(+), 7 deletions(-)
board/armltd/vexpress/vexpress_common.c +2 -1
index 89ab8f7..37b8d7f 100644
@@ -76,6 +76,7 @@ int cpu_mmc_init(bd_t *bis)
 	(void) bis;
 #ifdef CONFIG_ARM_PL180_MMCI
 	struct pl180_mmc_host *host;
+	struct mmc *mmc;
 
 	host = malloc(sizeof(struct pl180_mmc_host));
 	if (!host)
@@ -91,7 +92,7 @@ int cpu_mmc_init(bd_t *bis)
 	host->clock_in = ARM_MCLK;
 	host->clock_min = ARM_MCLK / (2 * (SDI_CLKCR_CLKDIV_INIT_V1 + 1));
 	host->clock_max = CONFIG_ARM_PL180_MMCI_CLOCK_FREQ;
-	rc = arm_pl180_mmci_init(host);
+	rc = arm_pl180_mmci_init(host, &mmc);
 #endif
 	return rc;
 }
drivers/mmc/arm_pl180_mmci.c +5 -5
index ddf8383..7898b0d 100644
@@ -348,9 +348,8 @@ static const struct mmc_ops arm_pl180_mmci_ops = {
  * Set initial clock and power for mmc slot.
  * Initialize mmc struct and register with mmc framework.
  */
-int arm_pl180_mmci_init(struct pl180_mmc_host *host)
+int arm_pl180_mmci_init(struct pl180_mmc_host *host, struct mmc **mmc)
 {
-	struct mmc *mmc;
 	u32 sdi_u32;
 
 	writel(host->pwr_init, &host->base->power);
@@ -373,11 +372,12 @@ int arm_pl180_mmci_init(struct pl180_mmc_host *host)
 	else
 		host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 
-	mmc = mmc_create(&host->cfg, host);
-	if (mmc == NULL)
+	*mmc = mmc_create(&host->cfg, host);
+	if (!*mmc)
 		return -1;
 
-	debug("registered mmc interface number is:%d\n", mmc->block_dev.devnum);
+	debug("registered mmc interface number is:%d\n",
+	      (*mmc)->block_dev.devnum);
 
 	return 0;
 }
drivers/mmc/arm_pl180_mmci.h +1 -1
index f23bd39..6e232f7 100644
@@ -190,6 +190,6 @@ struct pl180_mmc_host {
 	struct mmc_config cfg;
 };
 
-int arm_pl180_mmci_init(struct pl180_mmc_host *);
+int arm_pl180_mmci_init(struct pl180_mmc_host *host, struct mmc **mmc);
 
 #endif
Signature · 1 line
1.9.1
#2 lore raw

PATCH v2 1/5 mmc: arm_pl180_mmci: update arm_pl180_mmci_init() prototype

Quoted 8 lines · patrice.chotard at st.com

From: Patrice Chotard <[email protected]>

Update arm_pl180_mmci_init() prototype by adding struct mmc** param. This is needed before converting this driver to driver model in order to use arm_pl180_mmci_init() in driver model and in none driver model implementation

Applied to u-boot/master, thanks!

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171117/1de02634/attachment.sig>
#3 lore raw

PATCH v2 2/5 mmc: arm_pl180_mmci: adapt driver to DM usage

In reply to patrice.chotard at st.com

From: Patrice Chotard <[email protected]>

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.

---

v2: _ add defines for clock min and max value

 drivers/mmc/Kconfig          |   9 +++
 drivers/mmc/arm_pl180_mmci.c | 129 +++++++++++++++++++++++++++++++++++++++----
 drivers/mmc/arm_pl180_mmci.h |   3 +
 3 files changed, 129 insertions(+), 12 deletions(-)
drivers/mmc/Kconfig +9 -0
index 94050836..62ce0af 100644
@@ -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
drivers/mmc/arm_pl180_mmci.c +117 -12

166 lines not on this page · raw message

drivers/mmc/arm_pl180_mmci.h +3 -0
index 6e232f7..b935288 100644
@@ -142,6 +142,9 @@
 
 #define SDI_FIFO_BURST_SIZE	8
 
+#define VERSION1	false
+#define VERSION2	true
+
 struct sdi_registers {
 	u32 power;		/* 0x00*/
 	u32 clock;		/* 0x04*/
Signature · 1 line
1.9.1
#4 lore raw

PATCH v2 2/5 mmc: arm_pl180_mmci: adapt driver to DM usage

Quoted 10 lines · patrice.chotard at st.com

From: Patrice Chotard <[email protected]>

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.

Applied to u-boot/master, thanks!

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171117/3134330f/attachment.sig>
#5 lore raw

PATCH v2 3/5 mmc: arm_pl180_mmci: add bus_width DT property support

In reply to patrice.chotard at st.com

From: Patrice Chotard <[email protected]>

Allow to get "bus-width" property from device tree

---

v2: _ remove useless return in bus_width switch case

 drivers/mmc/arm_pl180_mmci.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
drivers/mmc/arm_pl180_mmci.c +16 -0
index b3c1f0d..fd57b55 100644
@@ -408,6 +408,7 @@ static int arm_pl180_mmc_probe(struct udevice *dev)
 	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
 	struct mmc *mmc = &pdata->mmc;
 	struct pl180_mmc_host *host = mmc->priv;
+	u32 bus_width;
 	int ret;
 
 	strcpy(host->name, "MMC");
@@ -421,6 +422,21 @@ static int arm_pl180_mmc_probe(struct udevice *dev)
 	host->clock_max = dev_read_u32_default(dev, "max-frequency",
 					       MMC_CLOCK_MAX);
 	host->version2 = dev_get_driver_data(dev);
+
+	bus_width = dev_read_u32_default(dev, "bus-width", 1);
+	switch (bus_width) {
+	case 8:
+		host->caps |= MMC_MODE_8BIT;
+		/* Hosts capable of 8-bit transfers can also do 4 bits */
+	case 4:
+		host->caps |= MMC_MODE_4BIT;
+		break;
+	case 1:
+		break;
+	default:
+		dev_err(dev, "Invalid bus-width value %u\n", bus_width);
+	}
+
 	ret = arm_pl180_mmci_init(host, &mmc);
 	if (ret) {
 		dev_err(dev, "arm_pl180_mmci init failed\n");
Signature · 1 line
1.9.1
#6 lore raw

PATCH v2 3/5 mmc: arm_pl180_mmci: add bus_width DT property support

Quoted 5 lines · patrice.chotard at st.com

From: Patrice Chotard <[email protected]>

Allow to get "bus-width" property from device tree

Applied to u-boot/master, thanks!

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171117/eb13968a/attachment.sig>
#7 lore raw

PATCH v2 4/5 mmc: arm_pl180_mmci: add clock support

In reply to patrice.chotard at st.com

From: Patrice Chotard <[email protected]>

Allow to get and enable MMC related clock

---
 drivers/mmc/arm_pl180_mmci.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)
drivers/mmc/arm_pl180_mmci.c +14 -2
index fd57b55..3de6b12 100644
@@ -13,6 +13,7 @@
 /* #define DEBUG */
 
 #include "common.h"
+#include <clk.h>
 #include <errno.h>
 #include <malloc.h>
 #include <mmc.h>
@@ -408,17 +409,28 @@ static int arm_pl180_mmc_probe(struct udevice *dev)
 	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
 	struct mmc *mmc = &pdata->mmc;
 	struct pl180_mmc_host *host = mmc->priv;
+	struct clk clk;
 	u32 bus_width;
 	int ret;
 
+	ret = clk_get_by_index(dev, 0, &clk);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_enable(&clk);
+	if (ret) {
+		dev_err(dev, "failed to enable clock\n");
+		return 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 = MMC_CLOCK_MAX;
-	host->clock_min = MMC_CLOCK_MIN;
+	host->clock_in = clk_get_rate(&clk);
+	host->clock_min = host->clock_in / (2 * (SDI_CLKCR_CLKDIV_INIT_V1 + 1));
 	host->clock_max = dev_read_u32_default(dev, "max-frequency",
 					       MMC_CLOCK_MAX);
 	host->version2 = dev_get_driver_data(dev);
Signature · 1 line
1.9.1
#8 lore raw

PATCH v2 4/5 mmc: arm_pl180_mmci: add clock support

Quoted 5 lines · patrice.chotard at st.com

From: Patrice Chotard <[email protected]>

Allow to get and enable MMC related clock

Applied to u-boot/master, thanks!

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171117/66459e23/attachment.sig>
#9 lore raw

PATCH v2 5/5 mmc: arm_pl180_mmci: add .getcd callback

In reply to patrice.chotard at st.com

From: Patrice Chotard <[email protected]>

Add .getcd callback to check is MMC card is present

---
 drivers/mmc/arm_pl180_mmci.c | 24 ++++++++++++++++++++++--
 drivers/mmc/arm_pl180_mmci.h |  4 ++++
 2 files changed, 26 insertions(+), 2 deletions(-)
drivers/mmc/arm_pl180_mmci.c +22 -2
index 3de6b12..89a7c19 100644
@@ -18,9 +18,10 @@
 #include <malloc.h>
 #include <mmc.h>
 
-#include "arm_pl180_mmci.h"
-
 #include <asm/io.h>
+#include <asm-generic/gpio.h>
+
+#include "arm_pl180_mmci.h"
 
 #ifdef CONFIG_DM_MMC
 #include <dm.h>
@@ -435,6 +436,8 @@ static int arm_pl180_mmc_probe(struct udevice *dev)
 					       MMC_CLOCK_MAX);
 	host->version2 = dev_get_driver_data(dev);
 
+	gpio_request_by_name(dev, "cd-gpios", 0, &host->cd_gpio, GPIOD_IS_IN);
+
 	bus_width = dev_read_u32_default(dev, "bus-width", 1);
 	switch (bus_width) {
 	case 8:
@@ -477,9 +480,26 @@ static int dm_host_set_ios(struct udevice *dev)
 	return host_set_ios(mmc);
 }
 
+static int dm_mmc_getcd(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;
+	int value = 1;
+
+	if (dm_gpio_is_valid(&host->cd_gpio)) {
+		value = dm_gpio_get_value(&host->cd_gpio);
+		if (host->cd_inverted)
+			return !value;
+	}
+
+	return value;
+}
+
 static const struct dm_mmc_ops arm_pl180_dm_mmc_ops = {
 	.send_cmd = dm_host_request,
 	.set_ios = dm_host_set_ios,
+	.get_cd = dm_mmc_getcd,
 };
 
 static int arm_pl180_mmc_ofdata_to_platdata(struct udevice *dev)
drivers/mmc/arm_pl180_mmci.h +4 -0
index b935288..9df4b75 100644
@@ -191,6 +191,10 @@ struct pl180_mmc_host {
 	unsigned int pwr_init;
 	int version2;
 	struct mmc_config cfg;
+#ifdef CONFIG_DM_MMC
+	struct gpio_desc cd_gpio;
+	bool cd_inverted;
+#endif
 };
 
 int arm_pl180_mmci_init(struct pl180_mmc_host *host, struct mmc **mmc);
Signature · 1 line
1.9.1
#10 lore raw

PATCH v2 5/5 mmc: arm_pl180_mmci: add .getcd callback

Quoted 5 lines · patrice.chotard at st.com

From: Patrice Chotard <[email protected]>

Add .getcd callback to check is MMC card is present

Applied to u-boot/master, thanks!

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171117/c462caa4/attachment.sig>