[PATCH v2 1/4] mmc: pic32: Refresh PIC32 MMC driver

John Robertson john.robertson at simiatec.com
Mon Aug 31 20:04:24 CEST 2020


The existing driver is not compatible with the Driver Model.

This patch makes the necessary changes while also removing obsolescent
calls/properties as follows:

- fdtdec_* calls replaced with dev_read_* equivalents;
- 'clock-freq-min-max' property replaced by querying the frequency of
  the source clock 'base_clk';
- The card detect erratum workaround is applied during probe rather than
  overriding get_cd.

The card detect workaround (Microchip ref. DS80000736E, erratum #15) is
not needed if the SDCD signal is properly connected on the board and so
can be disabled using a vendor specific DT property.

Signed-off-by: John Robertson <john.robertson at simiatec.com>
---
Changes in v2:
- Split patch;
- Fix compilation failure after 'make pic32mzdask_defconfig'.

 drivers/mmc/pic32_sdhci.c | 77 ++++++++++++++++++++++++---------------
 1 file changed, 48 insertions(+), 29 deletions(-)

diff --git a/drivers/mmc/pic32_sdhci.c b/drivers/mmc/pic32_sdhci.c
index 029e0fbc2b..93f0532ad6 100644
--- a/drivers/mmc/pic32_sdhci.c
+++ b/drivers/mmc/pic32_sdhci.c
@@ -9,62 +9,78 @@
 #include <common.h>
 #include <dm.h>
 #include <sdhci.h>
-#include <linux/errno.h>
-#include <mach/pic32.h>
+#include <clk.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static int pic32_sdhci_get_cd(struct sdhci_host *host)
-{
-	/* PIC32 SDHCI CD errata:
-	 * - set CD_TEST and clear CD_TEST_INS bit
-	 */
-	sdhci_writeb(host, SDHCI_CTRL_CD_TEST, SDHCI_HOST_CONTROL);
-
-	return 0;
-}
-
-static const struct sdhci_ops pic32_sdhci_ops = {
-	.get_cd	= pic32_sdhci_get_cd,
+struct pic32_sdhci_plat {
+	struct mmc_config cfg;
+	struct mmc mmc;
 };
 
 static int pic32_sdhci_probe(struct udevice *dev)
 {
+	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+	struct pic32_sdhci_plat *plat = dev_get_platdata(dev);
 	struct sdhci_host *host = dev_get_priv(dev);
-	const void *fdt = gd->fdt_blob;
-	u32 f_min_max[2];
+
 	fdt_addr_t addr;
 	fdt_size_t size;
+	struct clk clk;
+	ulong clk_rate;
 	int ret;
 
-	addr = fdtdec_get_addr_size(fdt, dev_of_offset(dev), "reg", &size);
+	addr = dev_read_addr_size(dev, "reg", &size);
 	if (addr == FDT_ADDR_T_NONE)
 		return -EINVAL;
 
+	ret = clk_get_by_name(dev, "base_clk", &clk);
+	if (ret)
+		return ret;
+
+	clk_rate = clk_get_rate(&clk);
+	clk_free(&clk);
+
+	if (IS_ERR_VALUE(clk_rate))
+		return clk_rate;
+
 	host->ioaddr	= ioremap(addr, size);
 	host->name	= dev->name;
 	host->quirks	= SDHCI_QUIRK_NO_HISPD_BIT;
-	host->bus_width	= fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-					"bus-width", 4);
-	host->ops = &pic32_sdhci_ops;
-
-	ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
-				   "clock-freq-min-max", f_min_max, 2);
-	if (ret) {
-		printf("sdhci: clock-freq-min-max not found\n");
+	host->bus_width	= dev_read_u32_default(dev, "bus-width", 4);
+	host->max_clk   = clk_rate;
+
+	host->mmc = &plat->mmc;
+	host->mmc->dev = dev;
+
+	ret = sdhci_setup_cfg(&plat->cfg, host, 0, 0);
+	if (ret)
 		return ret;
-	}
 
-	host->max_clk   = f_min_max[1];
+	host->mmc->priv = host;
+	upriv->mmc = host->mmc;
 
-	ret = add_sdhci(host, 0, f_min_max[0]);
+	ret = sdhci_probe(dev);
 	if (ret)
 		return ret;
-	host->mmc->dev = dev;
+
+	if (!dev_read_bool(dev, "microchip,use-sdcd")) {
+		// Use workaround 1 for erratum #15 by default
+		u8 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+		ctrl = (ctrl & ~SDHCI_CTRL_CD_TEST_INS) | SDHCI_CTRL_CD_TEST;
+		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+	}
 
 	return 0;
 }
 
+static int pic32_sdhci_bind(struct udevice *dev)
+{
+	struct pic32_sdhci_plat *plat = dev_get_platdata(dev);
+
+	return sdhci_bind(dev, &plat->mmc, &plat->cfg);
+}
+
 static const struct udevice_id pic32_sdhci_ids[] = {
 	{ .compatible = "microchip,pic32mzda-sdhci" },
 	{ }
@@ -74,6 +90,9 @@ U_BOOT_DRIVER(pic32_sdhci_drv) = {
 	.name			= "pic32_sdhci",
 	.id			= UCLASS_MMC,
 	.of_match		= pic32_sdhci_ids,
+	.ops			= &sdhci_ops,
+	.bind			= pic32_sdhci_bind,
 	.probe			= pic32_sdhci_probe,
 	.priv_auto_alloc_size	= sizeof(struct sdhci_host),
+	.platdata_auto_alloc_size = sizeof(struct pic32_sdhci_plat)
 };
-- 
2.28.0



More information about the U-Boot mailing list