[U-Boot] [PATCH 2/4] nds32: ftsdc010: Support ftsdc010 DM.

Andes uboot at andestech.com
Thu Jun 1 07:46:13 UTC 2017


From: rick <rick at andestech.com>

ftsdc010 support device tree flow.

Signed-off-by: rick <rick at andestech.com>
---
 drivers/mmc/ftsdc010_mci.c |  139 ++++++++++++++++++++++++++++++++++----------
 drivers/mmc/ftsdc010_mci.h |   53 +++++++++++++++++
 2 files changed, 161 insertions(+), 31 deletions(-)
 create mode 100644 drivers/mmc/ftsdc010_mci.h

diff --git a/drivers/mmc/ftsdc010_mci.c b/drivers/mmc/ftsdc010_mci.c
index 652a718..87855b6 100644
--- a/drivers/mmc/ftsdc010_mci.c
+++ b/drivers/mmc/ftsdc010_mci.c
@@ -12,24 +12,15 @@
 #include <part.h>
 #include <mmc.h>
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/errno.h>
 #include <asm/byteorder.h>
 #include <faraday/ftsdc010.h>
+#include "ftsdc010_mci.h"
 
 #define CFG_CMD_TIMEOUT (CONFIG_SYS_HZ >> 4) /* 250 ms */
 #define CFG_RST_TIMEOUT CONFIG_SYS_HZ /* 1 sec reset timeout */
 
-struct ftsdc010_chip {
-	void __iomem *regs;
-	uint32_t wprot;   /* write protected (locked) */
-	uint32_t rate;    /* actual SD clock in Hz */
-	uint32_t sclk;    /* FTSDC010 source clock in Hz */
-	uint32_t fifo;    /* fifo depth in bytes */
-	uint32_t acmd;
-	struct mmc_config cfg;	/* mmc configuration */
-};
-
 static inline int ftsdc010_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd)
 {
 	struct ftsdc010_chip *chip = mmc->priv;
@@ -127,9 +118,8 @@ static void ftsdc010_clkset(struct mmc *mmc, uint32_t rate)
 static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask)
 {
 	int ret = -ETIMEDOUT;
-	uint32_t st, ts;
-
-	for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
+	uint32_t st, timeout = 10000000;
+	while (timeout--) {
 		st = readl(&regs->status);
 		if (!(st & mask))
 			continue;
@@ -147,10 +137,16 @@ static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask)
 /*
  * u-boot mmc api
  */
-
+#ifdef CONFIG_DM_MMC_OPS
+static int ftsdc010_request(struct udevice *dev, struct mmc_cmd *cmd,
+	struct mmc_data *data)
+{
+	struct mmc *mmc = mmc_get_mmc_dev(dev);
+#else
 static int ftsdc010_request(struct mmc *mmc, struct mmc_cmd *cmd,
 	struct mmc_data *data)
 {
+#endif
 	int ret = -EOPNOTSUPP;
 	uint32_t len = 0;
 	struct ftsdc010_chip *chip = mmc->priv;
@@ -251,8 +247,14 @@ static int ftsdc010_request(struct mmc *mmc, struct mmc_cmd *cmd,
 	return ret;
 }
 
+#ifdef CONFIG_DM_MMC_OPS
+static int ftsdc010_set_ios(struct udevice *dev)
+{
+	struct mmc *mmc = mmc_get_mmc_dev(dev);
+#else
 static int ftsdc010_set_ios(struct mmc *mmc)
 {
+#endif
 	struct ftsdc010_chip *chip = mmc->priv;
 	struct ftsdc010_mmc __iomem *regs = chip->regs;
 
@@ -274,20 +276,43 @@ static int ftsdc010_set_ios(struct mmc *mmc)
 	return 0;
 }
 
-static int ftsdc010_init(struct mmc *mmc)
+#ifdef CONFIG_DM_MMC_OPS
+static int ftsdc010_get_cd(struct udevice *dev)
 {
+	struct mmc *mmc = mmc_get_mmc_dev(dev);
+#else
+static int ftsdc010_get_cd(struct mmc *mmc)
+{
+#endif
 	struct ftsdc010_chip *chip = mmc->priv;
 	struct ftsdc010_mmc __iomem *regs = chip->regs;
-	uint32_t ts;
-
-	if (readl(&regs->status) & FTSDC010_STATUS_CARD_DETECT)
-		return -ENOMEDIUM;
+	return !(readl(&regs->status) & FTSDC010_STATUS_CARD_DETECT);
+}
 
+#ifdef CONFIG_DM_MMC_OPS
+static int ftsdc010_get_wp(struct udevice *dev)
+{
+	struct mmc *mmc = mmc_get_mmc_dev(dev);
+#else
+static int ftsdc010_get_wp(struct mmc *mmc)
+{
+#endif
+	struct ftsdc010_chip *chip = mmc->priv;
+	struct ftsdc010_mmc __iomem *regs = chip->regs;
 	if (readl(&regs->status) & FTSDC010_STATUS_WRITE_PROT) {
 		printf("ftsdc010: write protected\n");
 		chip->wprot = 1;
 	}
 
+	return 0;
+}
+
+static int ftsdc010_init(struct mmc *mmc)
+{
+	struct ftsdc010_chip *chip = mmc->priv;
+	struct ftsdc010_mmc __iomem *regs = chip->regs;
+	uint32_t ts;
+
 	chip->fifo = (readl(&regs->feature) & 0xff) << 2;
 
 	/* 1. chip reset */
@@ -311,11 +336,70 @@ static int ftsdc010_init(struct mmc *mmc)
 	return 0;
 }
 
+#ifdef CONFIG_DM_MMC_OPS
+int ftsdc010_probe(struct udevice *dev)
+{
+	struct mmc *mmc = mmc_get_mmc_dev(dev);
+	return ftsdc010_init(mmc);
+}
+
+const struct dm_mmc_ops dm_ftsdc010_ops = {
+	.send_cmd	= ftsdc010_request,
+	.set_ios	= ftsdc010_set_ios,
+	.get_cd		= ftsdc010_get_cd,
+	.get_wp		= ftsdc010_get_wp,
+};
+
+#else
 static const struct mmc_ops ftsdc010_ops = {
 	.send_cmd	= ftsdc010_request,
 	.set_ios	= ftsdc010_set_ios,
+	.getcd		= ftsdc010_get_cd,
+	.getwp		= ftsdc010_get_wp,
 	.init		= ftsdc010_init,
 };
+#endif
+
+void ftsdc_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
+		     uint caps, u32 max_clk, u32 min_clk)
+{
+	cfg->name = name;
+	cfg->f_min = min_clk;
+	cfg->f_max = max_clk;
+	cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
+	cfg->host_caps = caps;
+	if (buswidth == 8) {
+		cfg->host_caps |= MMC_MODE_8BIT;
+		cfg->host_caps &= ~MMC_MODE_4BIT;
+	} else {
+		cfg->host_caps |= MMC_MODE_4BIT;
+		cfg->host_caps &= ~MMC_MODE_8BIT;
+	}
+	cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
+	cfg->part_type = PART_TYPE_DOS;
+	cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+}
+
+void set_bus_width(struct ftsdc010_mmc __iomem *regs, struct mmc_config *cfg)
+{
+	switch (readl(&regs->bwr) & FTSDC010_BWR_CAPS_MASK) {
+	case FTSDC010_BWR_CAPS_4BIT:
+		cfg->host_caps |= MMC_MODE_4BIT;
+		break;
+	case FTSDC010_BWR_CAPS_8BIT:
+		cfg->host_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
+		break;
+	default:
+		break;
+	}
+}
+
+#ifdef CONFIG_BLK
+int ftsdc010_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg)
+{
+	return mmc_bind(dev, mmc, cfg);
+}
+#else
 
 int ftsdc010_mmc_init(int devid)
 {
@@ -345,19 +429,11 @@ int ftsdc010_mmc_init(int devid)
 #endif
 
 	chip->cfg.name = "ftsdc010";
+#ifndef CONFIG_DM_MMC_OPS
 	chip->cfg.ops = &ftsdc010_ops;
+#endif
 	chip->cfg.host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz;
-	switch (readl(&regs->bwr) & FTSDC010_BWR_CAPS_MASK) {
-	case FTSDC010_BWR_CAPS_4BIT:
-		chip->cfg.host_caps |= MMC_MODE_4BIT;
-		break;
-	case FTSDC010_BWR_CAPS_8BIT:
-		chip->cfg.host_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
-		break;
-	default:
-		break;
-	}
-
+	set_bus_width(regs , &chip->cfg);
 	chip->cfg.voltages  = MMC_VDD_32_33 | MMC_VDD_33_34;
 	chip->cfg.f_max     = chip->sclk / 2;
 	chip->cfg.f_min     = chip->sclk / 0x100;
@@ -373,3 +449,4 @@ int ftsdc010_mmc_init(int devid)
 
 	return 0;
 }
+#endif
diff --git a/drivers/mmc/ftsdc010_mci.h b/drivers/mmc/ftsdc010_mci.h
new file mode 100644
index 0000000..63e85ee
--- /dev/null
+++ b/drivers/mmc/ftsdc010_mci.h
@@ -0,0 +1,53 @@
+/*
+ * Faraday FTSDC010 Secure Digital Memory Card Host Controller
+ *
+ * Copyright (C) 2011 Andes Technology Corporation
+ * Macpaul Lin, Andes Technology Corporation <macpaul at andestech.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <mmc.h>
+
+#ifndef __FTSDC010_MCI_H
+#define __FTSDC010_MCI_H
+
+struct ftsdc010_chip {
+	void __iomem *regs;
+	uint32_t wprot;   /* write protected (locked) */
+	uint32_t rate;    /* actual SD clock in Hz */
+	uint32_t sclk;    /* FTSDC010 source clock in Hz */
+	uint32_t fifo;    /* fifo depth in bytes */
+	uint32_t acmd;
+	struct mmc_config cfg;	/* mmc configuration */
+	const char *name;
+	void *ioaddr;
+	unsigned int caps;
+	unsigned int version;
+	unsigned int clock;
+	unsigned int bus_hz;
+	unsigned int div;
+	int dev_index;
+	int dev_id;
+	int buswidth;
+	u32 fifoth_val;
+	struct mmc *mmc;
+	void *priv;
+	bool fifo_mode;
+};
+
+
+#ifdef CONFIG_DM_MMC_OPS
+/* Export the operations to drivers */
+int ftsdc010_probe(struct udevice *dev);
+extern const struct dm_mmc_ops dm_ftsdc010_ops;
+#endif
+void ftsdc_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
+		     uint caps, u32 max_clk, u32 min_clk);
+void set_bus_width(struct ftsdc010_mmc __iomem *regs, struct mmc_config *cfg);
+
+#ifdef CONFIG_BLK
+int ftsdc010_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg);
+#endif
+
+
+#endif /* __FTSDC010_MCI_H */
-- 
1.7.9.5



More information about the U-Boot mailing list