uboot-tools/sunxi-dm-mmc-sata.patch

2020 lines
60 KiB
Diff

From 745a94f352b8f6f05e038110d3ce44d211bf31f3 Mon Sep 17 00:00:00 2001
From: Simon Glass <sjg@chromium.org>
Date: Tue, 4 Jul 2017 13:31:18 -0600
Subject: [PATCH 01/52] ahci: Support non-PCI controllers
At present the AHCI SCSI driver only supports PCI with driver model.
Rename the existing function to indicate this and add support for adding
a non-PCI controller .
Signed-off-by: Simon Glass <sjg@chromium.org>
---
arch/x86/cpu/ivybridge/sata.c | 2 +-
drivers/ata/ahci.c | 26 +++++++++++++++++---------
include/ahci.h | 14 +++++++++++++-
3 files changed, 31 insertions(+), 11 deletions(-)
diff --git a/arch/x86/cpu/ivybridge/sata.c b/arch/x86/cpu/ivybridge/sata.c
index 462b7c09dd..7febb8cf88 100644
--- a/arch/x86/cpu/ivybridge/sata.c
+++ b/arch/x86/cpu/ivybridge/sata.c
@@ -236,7 +236,7 @@ static int bd82x6x_sata_probe(struct udevice *dev)
bd82x6x_sata_enable(dev);
else {
bd82x6x_sata_init(dev, pch);
- ret = ahci_probe_scsi(dev);
+ ret = ahci_probe_scsi_pci(dev);
if (ret)
return ret;
}
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 606347faac..7c56f57bfd 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -431,7 +431,7 @@ static void ahci_print_info(struct ahci_uc_priv *uc_priv)
cap2 & (1 << 0) ? "boh " : "");
}
-#ifndef CONFIG_SCSI_AHCI_PLAT
+#if defined(CONFIG_DM_SCSI) || !defined(CONFIG_SCSI_AHCI_PLAT)
# if defined(CONFIG_DM_PCI) || defined(CONFIG_DM_SCSI)
static int ahci_init_one(struct ahci_uc_priv *uc_priv, struct udevice *dev)
# else
@@ -1158,11 +1158,8 @@ int ahci_bind_scsi(struct udevice *ahci_dev, struct udevice **devp)
return 0;
}
-int ahci_probe_scsi(struct udevice *ahci_dev)
+int ahci_probe_scsi(struct udevice *ahci_dev, ulong base)
{
-#ifdef CONFIG_SCSI_AHCI_PLAT
- return -ENOSYS; /* TODO(sjg@chromium.org): Support non-PCI AHCI */
-#else
struct ahci_uc_priv *uc_priv;
struct scsi_platdata *uc_plat;
struct udevice *dev;
@@ -1172,22 +1169,33 @@ int ahci_probe_scsi(struct udevice *ahci_dev)
if (!dev)
return -ENODEV;
uc_plat = dev_get_uclass_platdata(dev);
- uc_plat->base = (ulong)dm_pci_map_bar(ahci_dev, PCI_BASE_ADDRESS_5,
- PCI_REGION_MEM);
+ uc_plat->base = base;
uc_plat->max_lun = 1;
uc_plat->max_id = 2;
- uc_priv = dev_get_uclass_priv(dev);
+
+ uc_priv = dev_get_uclass_priv(ahci_dev);
ret = ahci_init_one(uc_priv, dev);
if (ret)
return ret;
ret = ahci_start_ports(uc_priv);
if (ret)
return ret;
-#endif
return 0;
}
+#ifdef CONFIG_DM_PCI
+int ahci_probe_scsi_pci(struct udevice *ahci_dev)
+{
+ ulong base;
+
+ base = (ulong)dm_pci_map_bar(ahci_dev, PCI_BASE_ADDRESS_5,
+ PCI_REGION_MEM);
+
+ return ahci_probe_scsi(ahci_dev, base);
+}
+#endif
+
struct scsi_ops scsi_ops = {
.exec = ahci_scsi_exec,
.bus_reset = ahci_scsi_bus_reset,
diff --git a/include/ahci.h b/include/ahci.h
index 818f34464e..29f4ba1d13 100644
--- a/include/ahci.h
+++ b/include/ahci.h
@@ -218,8 +218,20 @@ int ahci_bind_scsi(struct udevice *ahci_dev, struct udevice **devp);
* devices it finds.
*
* @ahci_dev: AHCI parent device
+ * @base: Base address of AHCI port
* @return 0 if OK, -ve on error
*/
-int ahci_probe_scsi(struct udevice *ahci_dev);
+int ahci_probe_scsi(struct udevice *ahci_dev, ulong base);
+
+/**
+ * ahci_probe_scsi_pci() - probe and scan the attached SCSI bus on PCI
+ *
+ * Note that the SCSI device will itself bind block devices for any storage
+ * devices it finds.
+ *
+ * @ahci_dev: AHCI parent device
+ * @return 0 if OK, -ve on error
+ */
+int ahci_probe_scsi_pci(struct udevice *ahci_dev);
#endif
--
2.13.3
From c4d660d4d0abcde0fdbcee8401b215fc2b56d7aa Mon Sep 17 00:00:00 2001
From: Simon Glass <sjg@chromium.org>
Date: Tue, 4 Jul 2017 13:31:19 -0600
Subject: [PATCH 02/52] dm: mmc: Allow disabling driver model in SPL
At present if U-Boot proper uses driver model for MMC, then SPL has to
also. While this is desirable, it places a significant barrier to moving
to driver model in some cases. For example, with a space-constrained SPL
it may be necessary to enable CONFIG_SPL_OF_PLATDATA which involves
adjusting some drivers.
Add new SPL versions of the options for DM_MMC, DM_MMC_OPS and BLK. By
default these follow their non-SPL versions, but this can be changed by
boards which need it.
Signed-off-by: Simon Glass <sjg@chromium.org>
---
common/spl/spl_mmc.c | 4 ++--
drivers/block/Kconfig | 12 ++++++++++++
drivers/block/Makefile | 4 ++--
drivers/mmc/Kconfig | 21 +++++++++++++++++++++
drivers/mmc/Makefile | 4 ++--
drivers/mmc/mmc-uclass.c | 6 +++---
drivers/mmc/mmc.c | 28 ++++++++++++++--------------
drivers/mmc/mmc_legacy.c | 2 +-
drivers/mmc/mmc_private.h | 6 +++---
drivers/mmc/omap_hsmmc.c | 20 ++++++++++----------
drivers/scsi/scsi.c | 2 +-
include/blk.h | 4 ++--
include/mmc.h | 12 ++++++------
13 files changed, 79 insertions(+), 46 deletions(-)
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index bb48cac1ef..d95f94ca15 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -115,7 +115,7 @@ static int spl_mmc_get_device_index(u32 boot_device)
static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device)
{
-#ifdef CONFIG_DM_MMC
+#if CONFIG_IS_ENABLED(DM_MMC)
struct udevice *dev;
#endif
int err, mmc_dev;
@@ -132,7 +132,7 @@ static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device)
return err;
}
-#ifdef CONFIG_DM_MMC
+#if CONFIG_IS_ENABLED(DM_MMC)
err = uclass_get_device(UCLASS_MMC, mmc_dev, &dev);
if (!err)
*mmcp = mmc_get_mmc_dev(dev);
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index ca7692d8a5..26760895f9 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -10,6 +10,18 @@ config BLK
be partitioned into several areas, called 'partitions' in U-Boot.
A filesystem can be placed in each partition.
+config SPL_BLK
+ bool "Support block devices in SPL"
+ depends on SPL_DM && BLK
+ default y
+ help
+ Enable support for block devices, such as SCSI, MMC and USB
+ flash sticks. These provide a block-level interface which permits
+ reading, writing and (in some cases) erasing blocks. Block
+ devices often have a partition table which allows the device to
+ be partitioned into several areas, called 'partitions' in U-Boot.
+ A filesystem can be placed in each partition.
+
config BLOCK_CACHE
bool "Use block device cache"
default n
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index a5e7307c97..dea2c15c14 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -5,9 +5,9 @@
# SPDX-License-Identifier: GPL-2.0+
#
-obj-$(CONFIG_BLK) += blk-uclass.o
+obj-$(CONFIG_$(SPL_)BLK) += blk-uclass.o
-ifndef CONFIG_BLK
+ifndef CONFIG_$(SPL_)BLK
obj-y += blk_legacy.o
endif
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 82b8d75686..51a87cdd77 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -30,6 +30,27 @@ config DM_MMC_OPS
option will be removed as soon as all DM_MMC drivers use it, as it
will the only supported behaviour.
+config SPL_DM_MMC
+ bool "Enable MMC controllers using Driver Model in SPL"
+ depends on SPL_DM && DM_MMC
+ default y
+ help
+ This enables the MultiMediaCard (MMC) uclass which supports MMC and
+ Secure Digital I/O (SDIO) cards. Both removable (SD, micro-SD, etc.)
+ and non-removable (e.g. eMMC chip) devices are supported. These
+ appear as block devices in U-Boot and can support filesystems such
+ as EXT4 and FAT.
+
+config SPL_DM_MMC_OPS
+ bool "Support MMC controller operations using Driver Model in SPL"
+ depends on SPL_DM && DM_MMC_OPS
+ default y
+ help
+ Driver model provides a means of supporting device operations. This
+ option moves MMC operations under the control of driver model. The
+ option will be removed as soon as all DM_MMC drivers use it, as it
+ will the only supported behaviour.
+
if MMC
config SPL_MMC_TINY
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 2d781c38a6..a6becb2309 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -6,9 +6,9 @@
#
obj-y += mmc.o
-obj-$(CONFIG_DM_MMC) += mmc-uclass.o
+obj-$(CONFIG_$(SPL_)DM_MMC) += mmc-uclass.o
-ifndef CONFIG_BLK
+ifndef CONFIG_$(SPL_)BLK
obj-y += mmc_legacy.o
endif
diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index 994d2686f4..3e907253ea 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -15,7 +15,7 @@
DECLARE_GLOBAL_DATA_PTR;
-#ifdef CONFIG_DM_MMC_OPS
+#if CONFIG_IS_ENABLED(DM_MMC_OPS)
int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
struct mmc_data *data)
{
@@ -91,7 +91,7 @@ struct mmc *mmc_get_mmc_dev(struct udevice *dev)
return upriv->mmc;
}
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
struct mmc *find_mmc_device(int dev_num)
{
struct udevice *dev, *mmc_dev;
@@ -198,7 +198,7 @@ int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg)
struct udevice *bdev;
int ret, devnum = -1;
-#ifdef CONFIG_DM_MMC_OPS
+#if CONFIG_IS_ENABLED(DM_MMC_OPS)
if (!mmc_get_ops(dev))
return -ENOSYS;
#endif
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 3cdf6a4f3b..38e1c800e1 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -53,7 +53,7 @@ struct blk_desc *mmc_get_blk_desc(struct mmc *mmc)
}
#endif
-#ifndef CONFIG_DM_MMC_OPS
+#if !CONFIG_IS_ENABLED(DM_MMC_OPS)
__weak int board_mmc_getwp(struct mmc *mmc)
{
return -1;
@@ -149,7 +149,7 @@ void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd)
}
#endif
-#ifndef CONFIG_DM_MMC_OPS
+#if !CONFIG_IS_ENABLED(DM_MMC_OPS)
int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
{
int ret;
@@ -261,14 +261,14 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
return blkcnt;
}
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst)
#else
ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
void *dst)
#endif
{
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
#endif
int dev_num = block_dev->devnum;
@@ -839,7 +839,7 @@ int mmc_hwpart_config(struct mmc *mmc,
return 0;
}
-#ifndef CONFIG_DM_MMC_OPS
+#if !CONFIG_IS_ENABLED(DM_MMC_OPS)
int mmc_getcd(struct mmc *mmc)
{
int cd;
@@ -1075,7 +1075,7 @@ static const u8 multipliers[] = {
80,
};
-#ifndef CONFIG_DM_MMC_OPS
+#if !CONFIG_IS_ENABLED(DM_MMC_OPS)
static void mmc_set_ios(struct mmc *mmc)
{
if (mmc->cfg->ops->set_ios)
@@ -1608,7 +1608,7 @@ static int mmc_send_if_cond(struct mmc *mmc)
return 0;
}
-#ifndef CONFIG_DM_MMC
+#if !CONFIG_IS_ENABLED(DM_MMC)
/* board-specific MMC power initializations. */
__weak void board_mmc_power_init(void)
{
@@ -1617,7 +1617,7 @@ __weak void board_mmc_power_init(void)
static int mmc_power_init(struct mmc *mmc)
{
-#if defined(CONFIG_DM_MMC)
+#if CONFIG_IS_ENABLED(DM_MMC)
#if defined(CONFIG_DM_REGULATOR) && !defined(CONFIG_SPL_BUILD)
struct udevice *vmmc_supply;
int ret;
@@ -1652,7 +1652,7 @@ int mmc_start_init(struct mmc *mmc)
/* we pretend there's no card when init is NULL */
no_card = mmc_getcd(mmc) == 0;
-#ifndef CONFIG_DM_MMC_OPS
+#if !CONFIG_IS_ENABLED(DM_MMC_OPS)
no_card = no_card || (mmc->cfg->ops->init == NULL);
#endif
if (no_card) {
@@ -1673,7 +1673,7 @@ int mmc_start_init(struct mmc *mmc)
if (err)
return err;
-#ifdef CONFIG_DM_MMC_OPS
+#if CONFIG_IS_ENABLED(DM_MMC_OPS)
/* The device has already been probed ready for use */
#else
/* made sure it's not NULL earlier */
@@ -1739,7 +1739,7 @@ int mmc_init(struct mmc *mmc)
{
int err = 0;
__maybe_unused unsigned start;
-#ifdef CONFIG_DM_MMC
+#if CONFIG_IS_ENABLED(DM_MMC)
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
upriv->mmc = mmc;
@@ -1783,12 +1783,12 @@ void mmc_set_preinit(struct mmc *mmc, int preinit)
mmc->preinit = preinit;
}
-#if defined(CONFIG_DM_MMC) && defined(CONFIG_SPL_BUILD)
+#if CONFIG_IS_ENABLED(DM_MMC) && defined(CONFIG_SPL_BUILD)
static int mmc_probe(bd_t *bis)
{
return 0;
}
-#elif defined(CONFIG_DM_MMC)
+#elif CONFIG_IS_ENABLED(DM_MMC)
static int mmc_probe(bd_t *bis)
{
int ret, i;
@@ -1835,7 +1835,7 @@ int mmc_initialize(bd_t *bis)
return 0;
initialized = 1;
-#ifndef CONFIG_BLK
+#if !CONFIG_IS_ENABLED(BLK)
#if !CONFIG_IS_ENABLED(MMC_TINY)
mmc_list_init();
#endif
diff --git a/drivers/mmc/mmc_legacy.c b/drivers/mmc/mmc_legacy.c
index bdf9d984dd..59dc3df35f 100644
--- a/drivers/mmc/mmc_legacy.c
+++ b/drivers/mmc/mmc_legacy.c
@@ -150,7 +150,7 @@ struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
cfg->f_max == 0 || cfg->b_max == 0)
return NULL;
-#ifndef CONFIG_DM_MMC_OPS
+#if !CONFIG_IS_ENABLED(DM_MMC_OPS)
if (cfg->ops == NULL || cfg->ops->send_cmd == NULL)
return NULL;
#endif
diff --git a/drivers/mmc/mmc_private.h b/drivers/mmc/mmc_private.h
index 03bf24d5fe..1290eed590 100644
--- a/drivers/mmc/mmc_private.h
+++ b/drivers/mmc/mmc_private.h
@@ -20,7 +20,7 @@ extern int mmc_set_blocklen(struct mmc *mmc, int len);
void mmc_adapter_card_type_ident(void);
#endif
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
void *dst);
#else
@@ -30,7 +30,7 @@ ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
#if !(defined(CONFIG_SPL_BUILD) && !defined(CONFIG_SPL_SAVEENV))
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
ulong mmc_bwrite(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
const void *src);
ulong mmc_berase(struct udevice *dev, lbaint_t start, lbaint_t blkcnt);
@@ -44,7 +44,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt);
/* declare dummies to reduce code size. */
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
static inline unsigned long mmc_berase(struct udevice *dev,
lbaint_t start, lbaint_t blkcnt)
{
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index bb10caaf32..efa43896fc 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -62,11 +62,11 @@ struct omap2_mmc_platform_config {
struct omap_hsmmc_data {
struct hsmmc *base_addr;
-#ifndef CONFIG_DM_MMC
+#if !CONFIG_IS_ENABLED(DM_MMC)
struct mmc_config cfg;
#endif
#ifdef OMAP_HSMMC_USE_GPIO
-#ifdef CONFIG_DM_MMC
+#if CONFIG_IS_ENABLED(DM_MMC)
struct gpio_desc cd_gpio; /* Change Detect GPIO */
struct gpio_desc wp_gpio; /* Write Protect GPIO */
bool cd_inverted;
@@ -86,7 +86,7 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
static inline struct omap_hsmmc_data *omap_hsmmc_get_data(struct mmc *mmc)
{
-#ifdef CONFIG_DM_MMC
+#if CONFIG_IS_ENABLED(DM_MMC)
return dev_get_priv(mmc->dev);
#else
return (struct omap_hsmmc_data *)mmc->priv;
@@ -94,7 +94,7 @@ static inline struct omap_hsmmc_data *omap_hsmmc_get_data(struct mmc *mmc)
}
static inline struct mmc_config *omap_hsmmc_get_cfg(struct mmc *mmc)
{
-#ifdef CONFIG_DM_MMC
+#if CONFIG_IS_ENABLED(DM_MMC)
struct omap_hsmmc_plat *plat = dev_get_platdata(mmc->dev);
return &plat->cfg;
#else
@@ -102,7 +102,7 @@ static inline struct mmc_config *omap_hsmmc_get_cfg(struct mmc *mmc)
#endif
}
- #if defined(OMAP_HSMMC_USE_GPIO) && !defined(CONFIG_DM_MMC)
+#if defined(OMAP_HSMMC_USE_GPIO) && !CONFIG_IS_ENABLED(DM_MMC)
static int omap_mmc_setup_gpio_in(int gpio, const char *label)
{
int ret;
@@ -326,7 +326,7 @@ static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit)
}
}
}
-#ifndef CONFIG_DM_MMC
+#if !CONFIG_IS_ENABLED(DM_MMC)
static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
struct mmc_data *data)
{
@@ -564,7 +564,7 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
return 0;
}
-#ifndef CONFIG_DM_MMC
+#if !CONFIG_IS_ENABLED(DM_MMC)
static int omap_hsmmc_set_ios(struct mmc *mmc)
{
struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
@@ -630,7 +630,7 @@ static int omap_hsmmc_set_ios(struct udevice *dev)
}
#ifdef OMAP_HSMMC_USE_GPIO
-#ifdef CONFIG_DM_MMC
+#if CONFIG_IS_ENABLED(DM_MMC)
static int omap_hsmmc_getcd(struct udevice *dev)
{
struct omap_hsmmc_data *priv = dev_get_priv(dev);
@@ -688,7 +688,7 @@ static int omap_hsmmc_getwp(struct mmc *mmc)
#endif
#endif
-#ifdef CONFIG_DM_MMC
+#if CONFIG_IS_ENABLED(DM_MMC)
static const struct dm_mmc_ops omap_hsmmc_ops = {
.send_cmd = omap_hsmmc_send_cmd,
.set_ios = omap_hsmmc_set_ios,
@@ -709,7 +709,7 @@ static const struct mmc_ops omap_hsmmc_ops = {
};
#endif
-#ifndef CONFIG_DM_MMC
+#if !CONFIG_IS_ENABLED(DM_MMC)
int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
int wp_gpio)
{
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 7ec7ecc295..f192ca597c 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -451,7 +451,7 @@ static void scsi_init_dev_desc_priv(struct blk_desc *dev_desc)
dev_desc->product[0] = 0;
dev_desc->revision[0] = 0;
dev_desc->removable = false;
-#ifndef CONFIG_BLK
+#if !CONFIG_IS_ENABLED(BLK)
dev_desc->block_read = scsi_read;
dev_desc->block_write = scsi_write;
#endif
diff --git a/include/blk.h b/include/blk.h
index ef29a07ee2..1e6239ac9e 100644
--- a/include/blk.h
+++ b/include/blk.h
@@ -62,7 +62,7 @@ struct blk_desc {
char vendor[40+1]; /* IDE model, SCSI Vendor */
char product[20+1]; /* IDE Serial no, SCSI product */
char revision[8+1]; /* firmware revision */
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
/*
* For now we have a few functions which take struct blk_desc as a
* parameter. This field allows them to look up the associated
@@ -174,7 +174,7 @@ static inline void blkcache_invalidate(int iftype, int dev) {}
#endif
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
struct udevice;
/* Operations on block devices */
diff --git a/include/mmc.h b/include/mmc.h
index 00576fa3d0..ad9716c057 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -321,7 +321,7 @@ struct mmc_data {
/* forward decl. */
struct mmc;
-#ifdef CONFIG_DM_MMC_OPS
+#if CONFIG_IS_ENABLED(DM_MMC_OPS)
struct dm_mmc_ops {
/**
* send_cmd() - Send a command to the MMC device
@@ -385,7 +385,7 @@ struct mmc_ops {
struct mmc_config {
const char *name;
-#ifndef CONFIG_DM_MMC_OPS
+#if !CONFIG_IS_ENABLED(DM_MMC_OPS)
const struct mmc_ops *ops;
#endif
uint host_caps;
@@ -409,7 +409,7 @@ struct sd_ssr {
* TODO struct mmc should be in mmc_private but it's hard to fix right now
*/
struct mmc {
-#ifndef CONFIG_BLK
+#if !CONFIG_IS_ENABLED(BLK)
struct list_head link;
#endif
const struct mmc_config *cfg; /* provided configuration */
@@ -444,14 +444,14 @@ struct mmc {
u64 capacity_gp[4];
u64 enh_user_start;
u64 enh_user_size;
-#ifndef CONFIG_BLK
+#if !CONFIG_IS_ENABLED(BLK)
struct blk_desc block_dev;
#endif
char op_cond_pending; /* 1 if we are waiting on an op_cond command */
char init_in_progress; /* 1 if we have done mmc_start_init() */
char preinit; /* start init as early as possible */
int ddr_mode;
-#ifdef CONFIG_DM_MMC
+#if CONFIG_IS_ENABLED(DM_MMC)
struct udevice *dev; /* Device for this MMC controller */
#endif
};
@@ -519,7 +519,7 @@ int mmc_switch_part(struct mmc *mmc, unsigned int part_num);
int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf,
enum mmc_hwpart_conf_mode mode);
-#ifndef CONFIG_DM_MMC_OPS
+#if !CONFIG_IS_ENABLED(DM_MMC_OPS)
int mmc_getcd(struct mmc *mmc);
int board_mmc_getcd(struct mmc *mmc);
int mmc_getwp(struct mmc *mmc);
--
2.13.3
From 336a44877af84fc65e58a0759d9dc199e8c97036 Mon Sep 17 00:00:00 2001
From: Simon Glass <sjg@chromium.org>
Date: Tue, 4 Jul 2017 13:31:20 -0600
Subject: [PATCH 03/52] fdt: Correct fdt_get_base_address()
This function appears to obtain the value of the 'ranges' property rather
than 'reg'. As such it does not behave as documented or expected.
In addition it picks up the second field of the property which is the size
(with prop += naddr) rather than the first which is the address.
Fix it.
Signed-off-by: Simon Glass <sjg@chromium.org>
---
common/fdt_support.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/common/fdt_support.c b/common/fdt_support.c
index 5aa8e3422e..7ccf8b19fd 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -1464,14 +1464,11 @@ int fdt_verify_alias_address(void *fdt, int anode, const char *alias, u64 addr)
u64 fdt_get_base_address(const void *fdt, int node)
{
int size;
- u32 naddr;
const fdt32_t *prop;
- naddr = fdt_address_cells(fdt, node);
+ prop = fdt_getprop(fdt, node, "reg", &size);
- prop = fdt_getprop(fdt, node, "ranges", &size);
-
- return prop ? fdt_translate_address(fdt, node, prop + naddr) : 0;
+ return prop ? fdt_translate_address(fdt, node, prop) : 0;
}
/*
--
2.13.3
From 068a2fc1d500866e37f0ecc98806444c2996b25d Mon Sep 17 00:00:00 2001
From: Simon Glass <sjg@chromium.org>
Date: Tue, 4 Jul 2017 13:31:21 -0600
Subject: [PATCH 04/52] dm: scsi: Drop duplicate SCSI and DM_SCSI options
When the SATA code was moved into drivers/ata these Kconfig options were
added to that directory. They already exist in drivers/scsi. Remove them
from drivers/ata to fix the duplication.
Signed-off-by: Simon Glass <sjg@chromium.org>
Fixes: 7f2b5f4 (sata: Move drivers into new drivers/ata directory)
---
drivers/ata/Kconfig | 18 ------------------
1 file changed, 18 deletions(-)
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 6427f1b94a..a1bd12ebe9 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -20,24 +20,6 @@ config SATA
See also CMD_SATA which provides command-line support.
-config SCSI
- bool "Support SCSI controllers"
- help
- This enables support for SCSI (Small Computer System Interface),
- a parallel interface widely used with storage peripherals such as
- hard drives and optical drives. The SCSI standards define physical
- interfaces as well as protocols for controlling devices and
- tranferring data.
-
-config DM_SCSI
- bool "Support SCSI controllers with driver model"
- depends on BLK
- help
- This option enables the SCSI (Small Computer System Interface) uclass
- which supports SCSI and SATA HDDs. For every device configuration
- (IDs/LUNs) a block device is created with RAW read/write and
- filesystem support.
-
menu "SATA/SCSI device support"
config SATA_CEVA
--
2.13.3
From bfc1c6b4838501d10aa48c0e92eaf70976f4b2dd Mon Sep 17 00:00:00 2001
From: Simon Glass <sjg@chromium.org>
Date: Tue, 4 Jul 2017 13:31:22 -0600
Subject: [PATCH 05/52] dm: ahci: Correct uclass private data
This is expected to be attached to the uclass and the code operates that
way, but the uclass has not been updated. Fix it to avoid using memory at
address 0.
Signed-off-by: Simon Glass <sjg@chromium.org>
Fixes: 47fc61a (dm: ahci: Drop use of probe_ent)
---
drivers/ata/ahci-uclass.c | 2 ++
drivers/ata/ahci.c | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/ata/ahci-uclass.c b/drivers/ata/ahci-uclass.c
index 7b8c32699f..71600fed68 100644
--- a/drivers/ata/ahci-uclass.c
+++ b/drivers/ata/ahci-uclass.c
@@ -6,9 +6,11 @@
*/
#include <common.h>
+#include <ahci.h>
#include <dm.h>
UCLASS_DRIVER(ahci) = {
.id = UCLASS_AHCI,
.name = "ahci",
+ .per_device_auto_alloc_size = sizeof(struct ahci_uc_priv),
};
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 7c56f57bfd..5e4df19386 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -935,7 +935,7 @@ static int ahci_scsi_exec(struct udevice *dev, struct scsi_cmd *pccb)
{
struct ahci_uc_priv *uc_priv;
#ifdef CONFIG_DM_SCSI
- uc_priv = dev_get_uclass_priv(dev);
+ uc_priv = dev_get_uclass_priv(dev->parent);
#else
uc_priv = probe_ent;
#endif
--
2.13.3
From e3c794e2faf34a025a3975883440fcacf110ebb6 Mon Sep 17 00:00:00 2001
From: Simon Glass <sjg@chromium.org>
Date: Tue, 4 Jul 2017 13:31:23 -0600
Subject: [PATCH 06/52] dm: mmc: sunxi: Rename struct sunxi_mmc_host to
sunxi_mmc_priv
Use the driver-model naming convention for this structure. It is data
private to the driver.
Signed-off-by: Simon Glass <sjg@chromium.org>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
drivers/mmc/sunxi_mmc.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index fd3fc2af40..e30db015ef 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -19,7 +19,7 @@
#include <asm/arch/mmc.h>
#include <asm-generic/gpio.h>
-struct sunxi_mmc_host {
+struct sunxi_mmc_priv {
unsigned mmc_no;
uint32_t *mclkreg;
unsigned fatal_err;
@@ -28,7 +28,7 @@ struct sunxi_mmc_host {
};
/* support 4 mmc hosts */
-struct sunxi_mmc_host mmc_host[4];
+struct sunxi_mmc_priv mmc_host[4];
static int sunxi_mmc_getcd_gpio(int sdc_no)
{
@@ -43,7 +43,7 @@ static int sunxi_mmc_getcd_gpio(int sdc_no)
static int mmc_resource_init(int sdc_no)
{
- struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no];
+ struct sunxi_mmc_priv *mmchost = &mmc_host[sdc_no];
struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
int cd_pin, ret = 0;
@@ -84,7 +84,7 @@ static int mmc_resource_init(int sdc_no)
return ret;
}
-static int mmc_set_mod_clk(struct sunxi_mmc_host *mmchost, unsigned int hz)
+static int mmc_set_mod_clk(struct sunxi_mmc_priv *mmchost, unsigned int hz)
{
unsigned int pll, pll_hz, div, n, oclk_dly, sclk_dly;
@@ -156,7 +156,7 @@ static int mmc_set_mod_clk(struct sunxi_mmc_host *mmchost, unsigned int hz)
static int mmc_clk_io_on(int sdc_no)
{
- struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no];
+ struct sunxi_mmc_priv *mmchost = &mmc_host[sdc_no];
struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
debug("init mmc %d clock and io\n", sdc_no);
@@ -179,7 +179,7 @@ static int mmc_clk_io_on(int sdc_no)
static int mmc_update_clk(struct mmc *mmc)
{
- struct sunxi_mmc_host *mmchost = mmc->priv;
+ struct sunxi_mmc_priv *mmchost = mmc->priv;
unsigned int cmd;
unsigned timeout_msecs = 2000;
@@ -201,7 +201,7 @@ static int mmc_update_clk(struct mmc *mmc)
static int mmc_config_clock(struct mmc *mmc)
{
- struct sunxi_mmc_host *mmchost = mmc->priv;
+ struct sunxi_mmc_priv *mmchost = mmc->priv;
unsigned rval = readl(&mmchost->reg->clkcr);
/* Disable Clock */
@@ -229,7 +229,7 @@ static int mmc_config_clock(struct mmc *mmc)
static int sunxi_mmc_set_ios(struct mmc *mmc)
{
- struct sunxi_mmc_host *mmchost = mmc->priv;
+ struct sunxi_mmc_priv *mmchost = mmc->priv;
debug("set ios: bus_width: %x, clock: %d\n",
mmc->bus_width, mmc->clock);
@@ -253,7 +253,7 @@ static int sunxi_mmc_set_ios(struct mmc *mmc)
static int sunxi_mmc_core_init(struct mmc *mmc)
{
- struct sunxi_mmc_host *mmchost = mmc->priv;
+ struct sunxi_mmc_priv *mmchost = mmc->priv;
/* Reset controller */
writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl);
@@ -264,7 +264,7 @@ static int sunxi_mmc_core_init(struct mmc *mmc)
static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data)
{
- struct sunxi_mmc_host *mmchost = mmc->priv;
+ struct sunxi_mmc_priv *mmchost = mmc->priv;
const int reading = !!(data->flags & MMC_DATA_READ);
const uint32_t status_bit = reading ? SUNXI_MMC_STATUS_FIFO_EMPTY :
SUNXI_MMC_STATUS_FIFO_FULL;
@@ -297,7 +297,7 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data)
static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs,
unsigned int done_bit, const char *what)
{
- struct sunxi_mmc_host *mmchost = mmc->priv;
+ struct sunxi_mmc_priv *mmchost = mmc->priv;
unsigned int status;
do {
@@ -317,7 +317,7 @@ static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs,
static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
struct mmc_data *data)
{
- struct sunxi_mmc_host *mmchost = mmc->priv;
+ struct sunxi_mmc_priv *mmchost = mmc->priv;
unsigned int cmdval = SUNXI_MMC_CMD_START;
unsigned int timeout_msecs;
int error = 0;
@@ -437,7 +437,7 @@ out:
static int sunxi_mmc_getcd(struct mmc *mmc)
{
- struct sunxi_mmc_host *mmchost = mmc->priv;
+ struct sunxi_mmc_priv *mmchost = mmc->priv;
int cd_pin;
cd_pin = sunxi_mmc_getcd_gpio(mmchost->mmc_no);
@@ -458,7 +458,7 @@ struct mmc *sunxi_mmc_init(int sdc_no)
{
struct mmc_config *cfg = &mmc_host[sdc_no].cfg;
- memset(&mmc_host[sdc_no], 0, sizeof(struct sunxi_mmc_host));
+ memset(&mmc_host[sdc_no], 0, sizeof(struct sunxi_mmc_priv));
cfg->name = "SUNXI SD/MMC";
cfg->ops = &sunxi_mmc_ops;
--
2.13.3
From 3f5af12a5d24756dce661b0bc34c05f0fe1715aa Mon Sep 17 00:00:00 2001
From: Simon Glass <sjg@chromium.org>
Date: Tue, 4 Jul 2017 13:31:24 -0600
Subject: [PATCH 07/52] dm: mmc: sunxi: Rename mmchost to priv
Use the driver-model naming convention for this structure. It is data
private to the driver so the local variable should be called 'priv'.
Signed-off-by: Simon Glass <sjg@chromium.org>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
drivers/mmc/sunxi_mmc.c | 125 ++++++++++++++++++++++++------------------------
1 file changed, 62 insertions(+), 63 deletions(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index e30db015ef..9276a29d76 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -43,7 +43,7 @@ static int sunxi_mmc_getcd_gpio(int sdc_no)
static int mmc_resource_init(int sdc_no)
{
- struct sunxi_mmc_priv *mmchost = &mmc_host[sdc_no];
+ struct sunxi_mmc_priv *priv = &mmc_host[sdc_no];
struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
int cd_pin, ret = 0;
@@ -51,26 +51,26 @@ static int mmc_resource_init(int sdc_no)
switch (sdc_no) {
case 0:
- mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC0_BASE;
- mmchost->mclkreg = &ccm->sd0_clk_cfg;
+ priv->reg = (struct sunxi_mmc *)SUNXI_MMC0_BASE;
+ priv->mclkreg = &ccm->sd0_clk_cfg;
break;
case 1:
- mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC1_BASE;
- mmchost->mclkreg = &ccm->sd1_clk_cfg;
+ priv->reg = (struct sunxi_mmc *)SUNXI_MMC1_BASE;
+ priv->mclkreg = &ccm->sd1_clk_cfg;
break;
case 2:
- mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC2_BASE;
- mmchost->mclkreg = &ccm->sd2_clk_cfg;
+ priv->reg = (struct sunxi_mmc *)SUNXI_MMC2_BASE;
+ priv->mclkreg = &ccm->sd2_clk_cfg;
break;
case 3:
- mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC3_BASE;
- mmchost->mclkreg = &ccm->sd3_clk_cfg;
+ priv->reg = (struct sunxi_mmc *)SUNXI_MMC3_BASE;
+ priv->mclkreg = &ccm->sd3_clk_cfg;
break;
default:
printf("Wrong mmc number %d\n", sdc_no);
return -1;
}
- mmchost->mmc_no = sdc_no;
+ priv->mmc_no = sdc_no;
cd_pin = sunxi_mmc_getcd_gpio(sdc_no);
if (cd_pin >= 0) {
@@ -84,7 +84,7 @@ static int mmc_resource_init(int sdc_no)
return ret;
}
-static int mmc_set_mod_clk(struct sunxi_mmc_priv *mmchost, unsigned int hz)
+static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
{
unsigned int pll, pll_hz, div, n, oclk_dly, sclk_dly;
@@ -112,8 +112,8 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *mmchost, unsigned int hz)
}
if (n > 3) {
- printf("mmc %u error cannot set clock to %u\n",
- mmchost->mmc_no, hz);
+ printf("mmc %u error cannot set clock to %u\n", priv->mmc_no,
+ hz);
return -1;
}
@@ -145,18 +145,17 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *mmchost, unsigned int hz)
writel(CCM_MMC_CTRL_ENABLE | pll | CCM_MMC_CTRL_SCLK_DLY(sclk_dly) |
CCM_MMC_CTRL_N(n) | CCM_MMC_CTRL_OCLK_DLY(oclk_dly) |
- CCM_MMC_CTRL_M(div), mmchost->mclkreg);
+ CCM_MMC_CTRL_M(div), priv->mclkreg);
debug("mmc %u set mod-clk req %u parent %u n %u m %u rate %u\n",
- mmchost->mmc_no, hz, pll_hz, 1u << n, div,
- pll_hz / (1u << n) / div);
+ priv->mmc_no, hz, pll_hz, 1u << n, div, pll_hz / (1u << n) / div);
return 0;
}
static int mmc_clk_io_on(int sdc_no)
{
- struct sunxi_mmc_priv *mmchost = &mmc_host[sdc_no];
+ struct sunxi_mmc_priv *priv = &mmc_host[sdc_no];
struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
debug("init mmc %d clock and io\n", sdc_no);
@@ -174,53 +173,53 @@ static int mmc_clk_io_on(int sdc_no)
SUNXI_MMC_COMMON_BASE + 4 * sdc_no);
#endif
- return mmc_set_mod_clk(mmchost, 24000000);
+ return mmc_set_mod_clk(priv, 24000000);
}
static int mmc_update_clk(struct mmc *mmc)
{
- struct sunxi_mmc_priv *mmchost = mmc->priv;
+ struct sunxi_mmc_priv *priv = mmc->priv;
unsigned int cmd;
unsigned timeout_msecs = 2000;
cmd = SUNXI_MMC_CMD_START |
SUNXI_MMC_CMD_UPCLK_ONLY |
SUNXI_MMC_CMD_WAIT_PRE_OVER;
- writel(cmd, &mmchost->reg->cmd);
- while (readl(&mmchost->reg->cmd) & SUNXI_MMC_CMD_START) {
+ writel(cmd, &priv->reg->cmd);
+ while (readl(&priv->reg->cmd) & SUNXI_MMC_CMD_START) {
if (!timeout_msecs--)
return -1;
udelay(1000);
}
/* clock update sets various irq status bits, clear these */
- writel(readl(&mmchost->reg->rint), &mmchost->reg->rint);
+ writel(readl(&priv->reg->rint), &priv->reg->rint);
return 0;
}
static int mmc_config_clock(struct mmc *mmc)
{
- struct sunxi_mmc_priv *mmchost = mmc->priv;
- unsigned rval = readl(&mmchost->reg->clkcr);
+ struct sunxi_mmc_priv *priv = mmc->priv;
+ unsigned rval = readl(&priv->reg->clkcr);
/* Disable Clock */
rval &= ~SUNXI_MMC_CLK_ENABLE;
- writel(rval, &mmchost->reg->clkcr);
+ writel(rval, &priv->reg->clkcr);
if (mmc_update_clk(mmc))
return -1;
/* Set mod_clk to new rate */
- if (mmc_set_mod_clk(mmchost, mmc->clock))
+ if (mmc_set_mod_clk(priv, mmc->clock))
return -1;
/* Clear internal divider */
rval &= ~SUNXI_MMC_CLK_DIVIDER_MASK;
- writel(rval, &mmchost->reg->clkcr);
+ writel(rval, &priv->reg->clkcr);
/* Re-enable Clock */
rval |= SUNXI_MMC_CLK_ENABLE;
- writel(rval, &mmchost->reg->clkcr);
+ writel(rval, &priv->reg->clkcr);
if (mmc_update_clk(mmc))
return -1;
@@ -229,34 +228,34 @@ static int mmc_config_clock(struct mmc *mmc)
static int sunxi_mmc_set_ios(struct mmc *mmc)
{
- struct sunxi_mmc_priv *mmchost = mmc->priv;
+ struct sunxi_mmc_priv *priv = mmc->priv;
debug("set ios: bus_width: %x, clock: %d\n",
mmc->bus_width, mmc->clock);
/* Change clock first */
if (mmc->clock && mmc_config_clock(mmc) != 0) {
- mmchost->fatal_err = 1;
+ priv->fatal_err = 1;
return -EINVAL;
}
/* Change bus width */
if (mmc->bus_width == 8)
- writel(0x2, &mmchost->reg->width);
+ writel(0x2, &priv->reg->width);
else if (mmc->bus_width == 4)
- writel(0x1, &mmchost->reg->width);
+ writel(0x1, &priv->reg->width);
else
- writel(0x0, &mmchost->reg->width);
+ writel(0x0, &priv->reg->width);
return 0;
}
static int sunxi_mmc_core_init(struct mmc *mmc)
{
- struct sunxi_mmc_priv *mmchost = mmc->priv;
+ struct sunxi_mmc_priv *priv = mmc->priv;
/* Reset controller */
- writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl);
+ writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl);
udelay(1000);
return 0;
@@ -264,7 +263,7 @@ static int sunxi_mmc_core_init(struct mmc *mmc)
static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data)
{
- struct sunxi_mmc_priv *mmchost = mmc->priv;
+ struct sunxi_mmc_priv *priv = mmc->priv;
const int reading = !!(data->flags & MMC_DATA_READ);
const uint32_t status_bit = reading ? SUNXI_MMC_STATUS_FIFO_EMPTY :
SUNXI_MMC_STATUS_FIFO_FULL;
@@ -276,19 +275,19 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data)
timeout_usecs = 2000000;
/* Always read / write data through the CPU */
- setbits_le32(&mmchost->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB);
+ setbits_le32(&priv->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB);
for (i = 0; i < (byte_cnt >> 2); i++) {
- while (readl(&mmchost->reg->status) & status_bit) {
+ while (readl(&priv->reg->status) & status_bit) {
if (!timeout_usecs--)
return -1;
udelay(1);
}
if (reading)
- buff[i] = readl(&mmchost->reg->fifo);
+ buff[i] = readl(&priv->reg->fifo);
else
- writel(buff[i], &mmchost->reg->fifo);
+ writel(buff[i], &priv->reg->fifo);
}
return 0;
@@ -297,11 +296,11 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data)
static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs,
unsigned int done_bit, const char *what)
{
- struct sunxi_mmc_priv *mmchost = mmc->priv;
+ struct sunxi_mmc_priv *priv = mmc->priv;
unsigned int status;
do {
- status = readl(&mmchost->reg->rint);
+ status = readl(&priv->reg->rint);
if (!timeout_msecs-- ||
(status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT)) {
debug("%s timeout %x\n", what,
@@ -317,14 +316,14 @@ static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs,
static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
struct mmc_data *data)
{
- struct sunxi_mmc_priv *mmchost = mmc->priv;
+ struct sunxi_mmc_priv *priv = mmc->priv;
unsigned int cmdval = SUNXI_MMC_CMD_START;
unsigned int timeout_msecs;
int error = 0;
unsigned int status = 0;
unsigned int bytecnt = 0;
- if (mmchost->fatal_err)
+ if (priv->fatal_err)
return -1;
if (cmd->resp_type & MMC_RSP_BUSY)
debug("mmc cmd %d check rsp busy\n", cmd->cmdidx);
@@ -351,16 +350,16 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
cmdval |= SUNXI_MMC_CMD_WRITE;
if (data->blocks > 1)
cmdval |= SUNXI_MMC_CMD_AUTO_STOP;
- writel(data->blocksize, &mmchost->reg->blksz);
- writel(data->blocks * data->blocksize, &mmchost->reg->bytecnt);
+ writel(data->blocksize, &priv->reg->blksz);
+ writel(data->blocks * data->blocksize, &priv->reg->bytecnt);
}
- debug("mmc %d, cmd %d(0x%08x), arg 0x%08x\n", mmchost->mmc_no,
+ debug("mmc %d, cmd %d(0x%08x), arg 0x%08x\n", priv->mmc_no,
cmd->cmdidx, cmdval | cmd->cmdidx, cmd->cmdarg);
- writel(cmd->cmdarg, &mmchost->reg->arg);
+ writel(cmd->cmdarg, &priv->reg->arg);
if (!data)
- writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd);
+ writel(cmdval | cmd->cmdidx, &priv->reg->cmd);
/*
* transfer data and check status
@@ -372,10 +371,10 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
bytecnt = data->blocksize * data->blocks;
debug("trans data %d bytes\n", bytecnt);
- writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd);
+ writel(cmdval | cmd->cmdidx, &priv->reg->cmd);
ret = mmc_trans_data_by_cpu(mmc, data);
if (ret) {
- error = readl(&mmchost->reg->rint) & \
+ error = readl(&priv->reg->rint) &
SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT;
error = -ETIMEDOUT;
goto out;
@@ -401,7 +400,7 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
if (cmd->resp_type & MMC_RSP_BUSY) {
timeout_msecs = 2000;
do {
- status = readl(&mmchost->reg->status);
+ status = readl(&priv->reg->status);
if (!timeout_msecs--) {
debug("busy timeout\n");
error = -ETIMEDOUT;
@@ -412,35 +411,35 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
}
if (cmd->resp_type & MMC_RSP_136) {
- cmd->response[0] = readl(&mmchost->reg->resp3);
- cmd->response[1] = readl(&mmchost->reg->resp2);
- cmd->response[2] = readl(&mmchost->reg->resp1);
- cmd->response[3] = readl(&mmchost->reg->resp0);
+ cmd->response[0] = readl(&priv->reg->resp3);
+ cmd->response[1] = readl(&priv->reg->resp2);
+ cmd->response[2] = readl(&priv->reg->resp1);
+ cmd->response[3] = readl(&priv->reg->resp0);
debug("mmc resp 0x%08x 0x%08x 0x%08x 0x%08x\n",
cmd->response[3], cmd->response[2],
cmd->response[1], cmd->response[0]);
} else {
- cmd->response[0] = readl(&mmchost->reg->resp0);
+ cmd->response[0] = readl(&priv->reg->resp0);
debug("mmc resp 0x%08x\n", cmd->response[0]);
}
out:
if (error < 0) {
- writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl);
+ writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl);
mmc_update_clk(mmc);
}
- writel(0xffffffff, &mmchost->reg->rint);
- writel(readl(&mmchost->reg->gctrl) | SUNXI_MMC_GCTRL_FIFO_RESET,
- &mmchost->reg->gctrl);
+ writel(0xffffffff, &priv->reg->rint);
+ writel(readl(&priv->reg->gctrl) | SUNXI_MMC_GCTRL_FIFO_RESET,
+ &priv->reg->gctrl);
return error;
}
static int sunxi_mmc_getcd(struct mmc *mmc)
{
- struct sunxi_mmc_priv *mmchost = mmc->priv;
+ struct sunxi_mmc_priv *priv = mmc->priv;
int cd_pin;
- cd_pin = sunxi_mmc_getcd_gpio(mmchost->mmc_no);
+ cd_pin = sunxi_mmc_getcd_gpio(priv->mmc_no);
if (cd_pin < 0)
return 1;
--
2.13.3
From 034e226bc77e6b2137acaa5094d9886c8bc9a07e Mon Sep 17 00:00:00 2001
From: Simon Glass <sjg@chromium.org>
Date: Tue, 4 Jul 2017 13:31:25 -0600
Subject: [PATCH 08/52] dm: mmc: sunxi: Pass private data around explicitly
At present the driver-private data is obtained in various functions by
various means. With driver model this is provided automatically. Without
driver model it comes from a C array declared at the top of the file.
Adjust internal functions so that they are passed the private data as
a parameter, allowing the caller to obtain it using either means.
Signed-off-by: Simon Glass <sjg@chromium.org>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
drivers/mmc/sunxi_mmc.c | 71 +++++++++++++++++++++++++++++--------------------
1 file changed, 42 insertions(+), 29 deletions(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 9276a29d76..bd41fbb752 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -176,9 +176,8 @@ static int mmc_clk_io_on(int sdc_no)
return mmc_set_mod_clk(priv, 24000000);
}
-static int mmc_update_clk(struct mmc *mmc)
+static int mmc_update_clk(struct sunxi_mmc_priv *priv)
{
- struct sunxi_mmc_priv *priv = mmc->priv;
unsigned int cmd;
unsigned timeout_msecs = 2000;
@@ -198,15 +197,14 @@ static int mmc_update_clk(struct mmc *mmc)
return 0;
}
-static int mmc_config_clock(struct mmc *mmc)
+static int mmc_config_clock(struct sunxi_mmc_priv *priv, struct mmc *mmc)
{
- struct sunxi_mmc_priv *priv = mmc->priv;
unsigned rval = readl(&priv->reg->clkcr);
/* Disable Clock */
rval &= ~SUNXI_MMC_CLK_ENABLE;
writel(rval, &priv->reg->clkcr);
- if (mmc_update_clk(mmc))
+ if (mmc_update_clk(priv))
return -1;
/* Set mod_clk to new rate */
@@ -220,21 +218,20 @@ static int mmc_config_clock(struct mmc *mmc)
/* Re-enable Clock */
rval |= SUNXI_MMC_CLK_ENABLE;
writel(rval, &priv->reg->clkcr);
- if (mmc_update_clk(mmc))
+ if (mmc_update_clk(priv))
return -1;
return 0;
}
-static int sunxi_mmc_set_ios(struct mmc *mmc)
+static int sunxi_mmc_set_ios_common(struct sunxi_mmc_priv *priv,
+ struct mmc *mmc)
{
- struct sunxi_mmc_priv *priv = mmc->priv;
-
debug("set ios: bus_width: %x, clock: %d\n",
mmc->bus_width, mmc->clock);
/* Change clock first */
- if (mmc->clock && mmc_config_clock(mmc) != 0) {
+ if (mmc->clock && mmc_config_clock(priv, mmc) != 0) {
priv->fatal_err = 1;
return -EINVAL;
}
@@ -261,9 +258,9 @@ static int sunxi_mmc_core_init(struct mmc *mmc)
return 0;
}
-static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data)
+static int mmc_trans_data_by_cpu(struct sunxi_mmc_priv *priv, struct mmc *mmc,
+ struct mmc_data *data)
{
- struct sunxi_mmc_priv *priv = mmc->priv;
const int reading = !!(data->flags & MMC_DATA_READ);
const uint32_t status_bit = reading ? SUNXI_MMC_STATUS_FIFO_EMPTY :
SUNXI_MMC_STATUS_FIFO_FULL;
@@ -293,10 +290,9 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data)
return 0;
}
-static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs,
- unsigned int done_bit, const char *what)
+static int mmc_rint_wait(struct sunxi_mmc_priv *priv, struct mmc *mmc,
+ uint timeout_msecs, uint done_bit, const char *what)
{
- struct sunxi_mmc_priv *priv = mmc->priv;
unsigned int status;
do {
@@ -313,10 +309,10 @@ static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs,
return 0;
}
-static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
- struct mmc_data *data)
+static int sunxi_mmc_send_cmd_common(struct sunxi_mmc_priv *priv,
+ struct mmc *mmc, struct mmc_cmd *cmd,
+ struct mmc_data *data)
{
- struct sunxi_mmc_priv *priv = mmc->priv;
unsigned int cmdval = SUNXI_MMC_CMD_START;
unsigned int timeout_msecs;
int error = 0;
@@ -372,7 +368,7 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
bytecnt = data->blocksize * data->blocks;
debug("trans data %d bytes\n", bytecnt);
writel(cmdval | cmd->cmdidx, &priv->reg->cmd);
- ret = mmc_trans_data_by_cpu(mmc, data);
+ ret = mmc_trans_data_by_cpu(priv, mmc, data);
if (ret) {
error = readl(&priv->reg->rint) &
SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT;
@@ -381,14 +377,15 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
}
}
- error = mmc_rint_wait(mmc, 1000, SUNXI_MMC_RINT_COMMAND_DONE, "cmd");
+ error = mmc_rint_wait(priv, mmc, 1000, SUNXI_MMC_RINT_COMMAND_DONE,
+ "cmd");
if (error)
goto out;
if (data) {
timeout_msecs = 120;
debug("cacl timeout %x msec\n", timeout_msecs);
- error = mmc_rint_wait(mmc, timeout_msecs,
+ error = mmc_rint_wait(priv, mmc, timeout_msecs,
data->blocks > 1 ?
SUNXI_MMC_RINT_AUTO_COMMAND_DONE :
SUNXI_MMC_RINT_DATA_OVER,
@@ -425,7 +422,7 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
out:
if (error < 0) {
writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl);
- mmc_update_clk(mmc);
+ mmc_update_clk(priv);
}
writel(0xffffffff, &priv->reg->rint);
writel(readl(&priv->reg->gctrl) | SUNXI_MMC_GCTRL_FIFO_RESET,
@@ -434,7 +431,22 @@ out:
return error;
}
-static int sunxi_mmc_getcd(struct mmc *mmc)
+static int sunxi_mmc_set_ios_legacy(struct mmc *mmc)
+{
+ struct sunxi_mmc_priv *priv = mmc->priv;
+
+ return sunxi_mmc_set_ios_common(priv, mmc);
+}
+
+static int sunxi_mmc_send_cmd_legacy(struct mmc *mmc, struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ struct sunxi_mmc_priv *priv = mmc->priv;
+
+ return sunxi_mmc_send_cmd_common(priv, mmc, cmd, data);
+}
+
+static int sunxi_mmc_getcd_legacy(struct mmc *mmc)
{
struct sunxi_mmc_priv *priv = mmc->priv;
int cd_pin;
@@ -447,17 +459,18 @@ static int sunxi_mmc_getcd(struct mmc *mmc)
}
static const struct mmc_ops sunxi_mmc_ops = {
- .send_cmd = sunxi_mmc_send_cmd,
- .set_ios = sunxi_mmc_set_ios,
+ .send_cmd = sunxi_mmc_send_cmd_legacy,
+ .set_ios = sunxi_mmc_set_ios_legacy,
.init = sunxi_mmc_core_init,
- .getcd = sunxi_mmc_getcd,
+ .getcd = sunxi_mmc_getcd_legacy,
};
struct mmc *sunxi_mmc_init(int sdc_no)
{
- struct mmc_config *cfg = &mmc_host[sdc_no].cfg;
+ struct sunxi_mmc_priv *priv = &mmc_host[sdc_no];
+ struct mmc_config *cfg = &priv->cfg;
- memset(&mmc_host[sdc_no], 0, sizeof(struct sunxi_mmc_priv));
+ memset(priv, '\0', sizeof(struct sunxi_mmc_priv));
cfg->name = "SUNXI SD/MMC";
cfg->ops = &sunxi_mmc_ops;
@@ -479,5 +492,5 @@ struct mmc *sunxi_mmc_init(int sdc_no)
mmc_clk_io_on(sdc_no);
- return mmc_create(cfg, &mmc_host[sdc_no]);
+ return mmc_create(cfg, mmc_host);
}
--
2.13.3
From ec73d96090c4a513f1fe3a458987ed43480f29d4 Mon Sep 17 00:00:00 2001
From: Simon Glass <sjg@chromium.org>
Date: Tue, 4 Jul 2017 13:31:26 -0600
Subject: [PATCH 09/52] dm: mmc: sunxi: Drop mmc_clk_io_on()
This function has #ifdefs in it which we want to avoid for driver model.
Instead we should use different compatible strings and the .data field.
It also uses the MMC device number which is not available in driver
model except through aliases.
Move the function's into its caller so that the driver-model version can
do things its own way.
Signed-off-by: Simon Glass <sjg@chromium.org>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
drivers/mmc/sunxi_mmc.c | 42 ++++++++++++++++++------------------------
1 file changed, 18 insertions(+), 24 deletions(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index bd41fbb752..23bef94f24 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -153,29 +153,6 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
return 0;
}
-static int mmc_clk_io_on(int sdc_no)
-{
- struct sunxi_mmc_priv *priv = &mmc_host[sdc_no];
- struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
-
- debug("init mmc %d clock and io\n", sdc_no);
-
- /* config ahb clock */
- setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no));
-
-#ifdef CONFIG_SUNXI_GEN_SUN6I
- /* unassert reset */
- setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no));
-#endif
-#if defined(CONFIG_MACH_SUN9I)
- /* sun9i has a mmc-common module, also set the gate and reset there */
- writel(SUNXI_MMC_COMMON_CLK_GATE | SUNXI_MMC_COMMON_RESET,
- SUNXI_MMC_COMMON_BASE + 4 * sdc_no);
-#endif
-
- return mmc_set_mod_clk(priv, 24000000);
-}
-
static int mmc_update_clk(struct sunxi_mmc_priv *priv)
{
unsigned int cmd;
@@ -467,8 +444,10 @@ static const struct mmc_ops sunxi_mmc_ops = {
struct mmc *sunxi_mmc_init(int sdc_no)
{
+ struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
struct sunxi_mmc_priv *priv = &mmc_host[sdc_no];
struct mmc_config *cfg = &priv->cfg;
+ int ret;
memset(priv, '\0', sizeof(struct sunxi_mmc_priv));
@@ -490,7 +469,22 @@ struct mmc *sunxi_mmc_init(int sdc_no)
if (mmc_resource_init(sdc_no) != 0)
return NULL;
- mmc_clk_io_on(sdc_no);
+ /* config ahb clock */
+ debug("init mmc %d clock and io\n", sdc_no);
+ setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no));
+
+#ifdef CONFIG_SUNXI_GEN_SUN6I
+ /* unassert reset */
+ setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no));
+#endif
+#if defined(CONFIG_MACH_SUN9I)
+ /* sun9i has a mmc-common module, also set the gate and reset there */
+ writel(SUNXI_MMC_COMMON_CLK_GATE | SUNXI_MMC_COMMON_RESET,
+ SUNXI_MMC_COMMON_BASE + 4 * sdc_no);
+#endif
+ ret = mmc_set_mod_clk(priv, 24000000);
+ if (ret)
+ return NULL;
return mmc_create(cfg, mmc_host);
}
--
2.13.3
From dd27918c22521a4f1d33dc9aafe60ecf9975938b Mon Sep 17 00:00:00 2001
From: Simon Glass <sjg@chromium.org>
Date: Tue, 4 Jul 2017 13:31:27 -0600
Subject: [PATCH 10/52] dm: mmc: sunxi: Add support for driver model
Add a driver-model version of this driver which mostly uses the existing
code. The old code can be removed once all boards are switched over.
Signed-off-by: Simon Glass <sjg@chromium.org>
---
drivers/mmc/sunxi_mmc.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 133 insertions(+)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 23bef94f24..588574fab6 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -9,6 +9,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <errno.h>
#include <malloc.h>
#include <mmc.h>
@@ -19,14 +20,21 @@
#include <asm/arch/mmc.h>
#include <asm-generic/gpio.h>
+struct sunxi_mmc_plat {
+ struct mmc_config cfg;
+ struct mmc mmc;
+};
+
struct sunxi_mmc_priv {
unsigned mmc_no;
uint32_t *mclkreg;
unsigned fatal_err;
+ struct gpio_desc cd_gpio; /* Change Detect GPIO */
struct sunxi_mmc *reg;
struct mmc_config cfg;
};
+#if !CONFIG_IS_ENABLED(DM_MMC)
/* support 4 mmc hosts */
struct sunxi_mmc_priv mmc_host[4];
@@ -83,6 +91,7 @@ static int mmc_resource_init(int sdc_no)
return ret;
}
+#endif
static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
{
@@ -224,6 +233,7 @@ static int sunxi_mmc_set_ios_common(struct sunxi_mmc_priv *priv,
return 0;
}
+#if !CONFIG_IS_ENABLED(DM_MMC)
static int sunxi_mmc_core_init(struct mmc *mmc)
{
struct sunxi_mmc_priv *priv = mmc->priv;
@@ -234,6 +244,7 @@ static int sunxi_mmc_core_init(struct mmc *mmc)
return 0;
}
+#endif
static int mmc_trans_data_by_cpu(struct sunxi_mmc_priv *priv, struct mmc *mmc,
struct mmc_data *data)
@@ -408,6 +419,7 @@ out:
return error;
}
+#if !CONFIG_IS_ENABLED(DM_MMC)
static int sunxi_mmc_set_ios_legacy(struct mmc *mmc)
{
struct sunxi_mmc_priv *priv = mmc->priv;
@@ -488,3 +500,124 @@ struct mmc *sunxi_mmc_init(int sdc_no)
return mmc_create(cfg, mmc_host);
}
+#else
+
+static int sunxi_mmc_set_ios(struct udevice *dev)
+{
+ struct sunxi_mmc_plat *plat = dev_get_platdata(dev);
+ struct sunxi_mmc_priv *priv = dev_get_priv(dev);
+
+ return sunxi_mmc_set_ios_common(priv, &plat->mmc);
+}
+
+static int sunxi_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ struct sunxi_mmc_plat *plat = dev_get_platdata(dev);
+ struct sunxi_mmc_priv *priv = dev_get_priv(dev);
+
+ return sunxi_mmc_send_cmd_common(priv, &plat->mmc, cmd, data);
+}
+
+static int sunxi_mmc_getcd(struct udevice *dev)
+{
+ struct sunxi_mmc_priv *priv = dev_get_priv(dev);
+
+ if (dm_gpio_is_valid(&priv->cd_gpio))
+ return dm_gpio_get_value(&priv->cd_gpio);
+
+ return 1;
+}
+
+static const struct dm_mmc_ops sunxi_mmc_ops = {
+ .send_cmd = sunxi_mmc_send_cmd,
+ .set_ios = sunxi_mmc_set_ios,
+ .get_cd = sunxi_mmc_getcd,
+};
+
+static int sunxi_mmc_probe(struct udevice *dev)
+{
+ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+ struct sunxi_mmc_plat *plat = dev_get_platdata(dev);
+ struct sunxi_mmc_priv *priv = dev_get_priv(dev);
+ struct mmc_config *cfg = &plat->cfg;
+ struct ofnode_phandle_args args;
+ u32 *gate_reg;
+ int bus_width, ret;
+
+ cfg->name = dev->name;
+ bus_width = dev_read_u32_default(dev, "bus-width", 1);
+
+ cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
+ cfg->host_caps = 0;
+ if (bus_width == 8)
+ cfg->host_caps |= MMC_MODE_8BIT;
+ if (bus_width >= 4)
+ cfg->host_caps |= MMC_MODE_4BIT;
+ cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
+ cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+
+ cfg->f_min = 400000;
+ cfg->f_max = 52000000;
+
+ priv->reg = (void *)dev_read_addr(dev);
+
+ /* We don't have a sunxi clock driver so find the clock address here */
+ ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0,
+ 1, &args);
+ if (ret)
+ return ret;
+ priv->mclkreg = (u32 *)ofnode_get_addr(args.node);
+
+ ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0,
+ 0, &args);
+ if (ret)
+ return ret;
+ gate_reg = (u32 *)ofnode_get_addr(args.node);
+ setbits_le32(gate_reg, 1 << args.args[0]);
+ priv->mmc_no = args.args[0] - 8;
+
+ ret = mmc_set_mod_clk(priv, 24000000);
+ if (ret)
+ return ret;
+
+ /* This GPIO is optional */
+ if (!gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio,
+ GPIOD_IS_IN)) {
+ int cd_pin = gpio_get_number(&priv->cd_gpio);
+
+ sunxi_gpio_set_pull(cd_pin, SUNXI_GPIO_PULL_UP);
+ }
+
+ upriv->mmc = &plat->mmc;
+
+ /* Reset controller */
+ writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl);
+ udelay(1000);
+
+ return 0;
+}
+
+static int sunxi_mmc_bind(struct udevice *dev)
+{
+ struct sunxi_mmc_plat *plat = dev_get_platdata(dev);
+
+ return mmc_bind(dev, &plat->mmc, &plat->cfg);
+}
+
+static const struct udevice_id sunxi_mmc_ids[] = {
+ { .compatible = "allwinner,sun5i-a13-mmc" },
+ { }
+};
+
+U_BOOT_DRIVER(sunxi_mmc_drv) = {
+ .name = "sunxi_mmc",
+ .id = UCLASS_MMC,
+ .of_match = sunxi_mmc_ids,
+ .bind = sunxi_mmc_bind,
+ .probe = sunxi_mmc_probe,
+ .ops = &sunxi_mmc_ops,
+ .platdata_auto_alloc_size = sizeof(struct sunxi_mmc_plat),
+ .priv_auto_alloc_size = sizeof(struct sunxi_mmc_priv),
+};
+#endif
--
2.13.3
From 8620f384098bcc33bbde74b41f37c364552f30c4 Mon Sep 17 00:00:00 2001
From: Simon Glass <sjg@chromium.org>
Date: Tue, 4 Jul 2017 13:31:28 -0600
Subject: [PATCH 11/52] dm: sunxi: Linksprite_pcDuino3: Correct polarity of MMC
card detect
This is shown as active high in the schematics[1], so fix it.
[1] https://patchwork.ozlabs.org/patch/777890/
Signed-off-by: Simon Glass <sjg@chromium.org>
Reported-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
arch/arm/dts/sun7i-a20-pcduino3.dts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/dts/sun7i-a20-pcduino3.dts b/arch/arm/dts/sun7i-a20-pcduino3.dts
index 1a8b39be1d..37b1e0ee9b 100644
--- a/arch/arm/dts/sun7i-a20-pcduino3.dts
+++ b/arch/arm/dts/sun7i-a20-pcduino3.dts
@@ -164,7 +164,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
cd-inverted;
status = "okay";
};
--
2.13.3
From 74daf94a2305a7b70fc24511d2ca7dc3358e746d Mon Sep 17 00:00:00 2001
From: Simon Glass <sjg@chromium.org>
Date: Tue, 4 Jul 2017 13:31:30 -0600
Subject: [PATCH 12/52] dm: sunxi: sata: Don't build sata support into SPL
This is not used in SPL so we do not need to compile it. Make this change
before adding driver-model support to the driver, to avoid build errors.
With driver model we define a U_BOOT_DRIVER() which would otherwise be
present in SPL and not be garbage-collected when building.
Signed-off-by: Simon Glass <sjg@chromium.org>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
board/sunxi/Makefile | 2 ++
1 file changed, 2 insertions(+)
diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
index 43766e0ef4..f4411f01c3 100644
--- a/board/sunxi/Makefile
+++ b/board/sunxi/Makefile
@@ -10,7 +10,9 @@
#
obj-y += board.o
obj-$(CONFIG_SUNXI_GMAC) += gmac.o
+ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_SUNXI_AHCI) += ahci.o
+endif
obj-$(CONFIG_MACH_SUN4I) += dram_sun4i_auto.o
obj-$(CONFIG_MACH_SUN5I) += dram_sun5i_auto.o
obj-$(CONFIG_MACH_SUN7I) += dram_sun5i_auto.o
--
2.13.3
From cf7b2e10c90e09d6f290b7886722b20680b79731 Mon Sep 17 00:00:00 2001
From: Simon Glass <sjg@chromium.org>
Date: Tue, 4 Jul 2017 13:31:31 -0600
Subject: [PATCH 13/52] dm: sata: sunxi: Add support for driver model
Adjust SATA setup to support driver model.
Signed-off-by: Simon Glass <sjg@chromium.org>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
board/sunxi/ahci.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 58 insertions(+), 3 deletions(-)
diff --git a/board/sunxi/ahci.c b/board/sunxi/ahci.c
index 522e54ab16..a79b80ca1e 100644
--- a/board/sunxi/ahci.c
+++ b/board/sunxi/ahci.c
@@ -1,5 +1,6 @@
#include <common.h>
#include <ahci.h>
+#include <dm.h>
#include <scsi.h>
#include <errno.h>
#include <asm/io.h>
@@ -13,9 +14,8 @@
/* This magic PHY initialisation was taken from the Allwinner releases
* and Linux driver, but is completely undocumented.
*/
-static int sunxi_ahci_phy_init(u32 base)
+static int sunxi_ahci_phy_init(u8 *reg_base)
{
- u8 *reg_base = (u8 *)base;
u32 reg_val;
int timeout;
@@ -70,10 +70,65 @@ static int sunxi_ahci_phy_init(u32 base)
return 0;
}
+#ifndef CONFIG_DM_SCSI
void scsi_init(void)
{
- if (sunxi_ahci_phy_init(SUNXI_SATA_BASE) < 0)
+ if (sunxi_ahci_phy_init((u8 *)SUNXI_SATA_BASE) < 0)
return;
ahci_init((void __iomem *)SUNXI_SATA_BASE);
}
+#else
+static int sunxi_sata_probe(struct udevice *dev)
+{
+ ulong base;
+ u8 *reg;
+ int ret;
+
+ base = dev_read_addr(dev);
+ if (base == FDT_ADDR_T_NONE) {
+ debug("%s: Failed to find address (err=%d\n)", __func__, ret);
+ return -EINVAL;
+ }
+ reg = (u8 *)base;
+ ret = sunxi_ahci_phy_init(reg);
+ if (ret) {
+ debug("%s: Failed to init phy (err=%d\n)", __func__, ret);
+ return ret;
+ }
+ ret = ahci_probe_scsi(dev, base);
+ if (ret) {
+ debug("%s: Failed to probe (err=%d\n)", __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int sunxi_sata_bind(struct udevice *dev)
+{
+ struct udevice *scsi_dev;
+ int ret;
+
+ ret = ahci_bind_scsi(dev, &scsi_dev);
+ if (ret) {
+ debug("%s: Failed to bind (err=%d\n)", __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct udevice_id sunxi_ahci_ids[] = {
+ { .compatible = "allwinner,sun4i-a10-ahci" },
+ { }
+};
+
+U_BOOT_DRIVER(ahci_sunxi_drv) = {
+ .name = "ahci_sunxi",
+ .id = UCLASS_AHCI,
+ .of_match = sunxi_ahci_ids,
+ .bind = sunxi_sata_bind,
+ .probe = sunxi_sata_probe,
+};
+#endif
--
2.13.3
From 3936514b82e8a00115c56bf58e8745f73bfb119f Mon Sep 17 00:00:00 2001
From: Simon Glass <sjg@chromium.org>
Date: Tue, 4 Jul 2017 13:31:32 -0600
Subject: [PATCH 14/52] dm: sunxi: Move Linksprite_pcDuino3 to use DM for MMC,
SATA
Move this board over to driver model for MMC and SATA. This means that it
uses CONFIG_BLK as well. In SPL these options remain turned off since it
increases the code size. One option would be to use CONFIG_SPL_OF_PLATDATA
to avoid device-tree overhead.
Signed-off-by: Simon Glass <sjg@chromium.org>
---
configs/Linksprite_pcDuino3_defconfig | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/configs/Linksprite_pcDuino3_defconfig b/configs/Linksprite_pcDuino3_defconfig
index 6f4a02f8d4..f0d382c002 100644
--- a/configs/Linksprite_pcDuino3_defconfig
+++ b/configs/Linksprite_pcDuino3_defconfig
@@ -15,7 +15,12 @@ CONFIG_SPL_I2C_SUPPORT=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_ISO_PARTITION is not set
# CONFIG_SPL_EFI_PARTITION is not set
-CONFIG_SCSI=y
+# CONFIG_SPL_BLK is not set
+CONFIG_DM_MMC=y
+# CONFIG_SPL_DM_MMC is not set
+# CONFIG_SPL_DM_MMC_OPS is not set
CONFIG_ETH_DESIGNWARE=y
CONFIG_SUN7I_GMAC=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
CONFIG_USB_EHCI_HCD=y
--
2.13.3