From: rick <r...@andestech.com>

Add nds32_mmc to support ftsdc010 dm flow.

Signed-off-by: rick <r...@andestech.com>
---
 drivers/mmc/Kconfig     |   12 +++++
 drivers/mmc/Makefile    |    1 +
 drivers/mmc/nds32_mmc.c |  136 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 149 insertions(+)
 create mode 100644 drivers/mmc/nds32_mmc.c

diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 0dd4443..5a30a0f 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -377,6 +377,18 @@ config GENERIC_ATMEL_MCI
          the SD Memory Card Specification V2.0, the SDIO V2.0 specification
          and CE-ATA V1.1.
 
+config MMC_NDS32
+       bool "Andestech SD/MMC controller support"
+       depends on DM_MMC && OF_CONTROL && BLK && DM_MMC_OPS && FTSDC010
+       help
+         This enables support for the Andestech SD/MMM controller, which is
+         based on Faraday IP.
+
+config FTSDC010
+       bool "Ftsdc010 SD/MMC controller Support"
+       help
+         This SD/MMC controller is present in Andestech SoCs which is based on 
Faraday IP.
+
 endif
 
 config TEGRA124_MMC_DISABLE_EXT_LOOPBACK
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index a078649..08a552a 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_S3C_SDI) += s3c_sdi.o
 obj-$(CONFIG_MMC_SANDBOX)              += sandbox_mmc.o
 obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o
 obj-$(CONFIG_SH_SDHI) += sh_sdhi.o
+obj-$(CONFIG_MMC_NDS32) += nds32_mmc.o
 
 # SDHCI
 obj-$(CONFIG_MMC_SDHCI)                        += sdhci.o
diff --git a/drivers/mmc/nds32_mmc.c b/drivers/mmc/nds32_mmc.c
new file mode 100644
index 0000000..0101ace
--- /dev/null
+++ b/drivers/mmc/nds32_mmc.c
@@ -0,0 +1,136 @@
+/*
+ * Andestech ATFSDC010 SD/MMC driver
+ *
+ * (C) Copyright 2017
+ * Rick Chen, NDS32 Software Engineering, r...@andestech.com
+
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dt-structs.h>
+#include <errno.h>
+#include <mapmem.h>
+#include <mmc.h>
+#include <pwrseq.h>
+#include <syscon.h>
+#include <linux/err.h>
+#include <faraday/ftsdc010.h>
+#include "ftsdc010_mci.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+struct nds_mmc {
+       fdt32_t         bus_width;
+       bool            cap_mmc_highspeed;
+       bool            cap_sd_highspeed;
+       fdt32_t         clock_freq_min_max[2];
+       struct phandle_2_cell   clocks[4];
+       fdt32_t         fifo_depth;
+       fdt32_t         reg[2];
+};
+#endif
+
+struct nds_mmc_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+       struct nds_mmc dtplat;
+#endif
+       struct mmc_config cfg;
+       struct mmc mmc;
+};
+
+struct ftsdc_priv {
+       struct clk clk;
+       struct ftsdc010_chip chip;
+       int fifo_depth;
+       bool fifo_mode;
+       u32 minmax[2];
+};
+
+static int nds32_mmc_ofdata_to_platdata(struct udevice *dev)
+{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+       struct ftsdc_priv *priv = dev_get_priv(dev);
+       struct ftsdc010_chip *chip = &priv->chip;
+       chip->name = dev->name;
+       chip->ioaddr = (void *)dev_get_addr(dev);
+       chip->buswidth = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+                                       "bus-width", 4);
+       chip->priv = dev;
+       priv->fifo_depth = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+                                   "fifo-depth", 0);
+       priv->fifo_mode = fdtdec_get_bool(gd->fdt_blob, dev->of_offset,
+                                         "fifo-mode");
+       if (fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
+                        "clock-freq-min-max", priv->minmax, 2)) {
+               int val = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+                                 "max-frequency", -EINVAL);
+               if (val < 0)
+                       return val;
+
+               priv->minmax[0] = 400000;  /* 400 kHz */
+               priv->minmax[1] = val;
+       } else {
+               debug("%s: 'clock-freq-min-max' property was deprecated.\n",
+               __func__);
+       }
+#endif
+       chip->sclk = priv->minmax[1];
+       chip->regs = chip->ioaddr;
+       return 0;
+}
+
+static int nds32_mmc_probe(struct udevice *dev)
+{
+       struct nds_mmc_plat *plat = dev_get_platdata(dev);
+       struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+       struct ftsdc_priv *priv = dev_get_priv(dev);
+       struct ftsdc010_chip *chip = &priv->chip;
+       struct udevice *pwr_dev __maybe_unused;
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+       int ret;
+       struct nds_mmc *dtplat = &plat->dtplat;
+       chip->name = dev->name;
+       chip->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
+       chip->buswidth = dtplat->bus_width;
+       chip->priv = dev;
+       chip->dev_index = 1;
+       memcpy(priv->minmax, dtplat->clock_freq_min_max, sizeof(priv->minmax));
+       ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
+       if (ret < 0)
+               return ret;
+#endif
+       ftsdc_setup_cfg(&plat->cfg, dev->name, chip->buswidth, chip->caps,
+                       priv->minmax[1] , priv->minmax[0]);
+       chip->mmc = &plat->mmc;
+       chip->mmc->priv = &priv->chip;
+       chip->mmc->dev = dev;
+       upriv->mmc = chip->mmc;
+       return ftsdc010_probe(dev);
+}
+
+static int nds32_mmc_bind(struct udevice *dev)
+{
+       struct nds_mmc_plat *plat = dev_get_platdata(dev);
+       return ftsdc010_bind(dev, &plat->mmc, &plat->cfg);
+}
+
+static const struct udevice_id nds32_mmc_ids[] = {
+       { .compatible = "andestech,atsdc010" },
+       { }
+};
+
+U_BOOT_DRIVER(nds32_mmc_drv) = {
+       .name           = "nds32_mmc",
+       .id             = UCLASS_MMC,
+       .of_match       = nds32_mmc_ids,
+       .ofdata_to_platdata = nds32_mmc_ofdata_to_platdata,
+       .ops            = &dm_ftsdc010_ops,
+       .bind           = nds32_mmc_bind,
+       .probe          = nds32_mmc_probe,
+       .priv_auto_alloc_size = sizeof(struct ftsdc_priv),
+       .platdata_auto_alloc_size = sizeof(struct nds_mmc_plat),
+};
-- 
1.7.9.5

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to