|
@@ -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(®s->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
|
|
|
+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
|
|
|
+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
|
|
|
+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(®s->status) & FTSDC010_STATUS_CARD_DETECT)
|
|
|
- return -ENOMEDIUM;
|
|
|
+ return !(readl(®s->status) & FTSDC010_STATUS_CARD_DETECT);
|
|
|
+}
|
|
|
|
|
|
+#ifdef CONFIG_DM_MMC
|
|
|
+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(®s->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(®s->feature) & 0xff) << 2;
|
|
|
|
|
|
/* 1. chip reset */
|
|
@@ -311,11 +336,70 @@ static int ftsdc010_init(struct mmc *mmc)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_DM_MMC
|
|
|
+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(®s->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
|
|
|
chip->cfg.ops = &ftsdc010_ops;
|
|
|
+#endif
|
|
|
chip->cfg.host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz;
|
|
|
- switch (readl(®s->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
|