[U-Boot] [PATCH 00/27] dm: mmc: Add driver-model support for MMC operations

At present MMC does not use driver model for its operations. It uses its own structure and passes a struct mmc instead of a struct udevice.
This series addresses this by adding driver-model operations for MMC. The conversion process is also started, with patches for rockchip, zynq and qualcomm.
The zynq patches are a starting point only and need more work.
Simon Glass (27): dm: mmc: dwmmc: Add comments to the dwmmc setup functions rockchip: Use 'select' instead of defaults in Kconfig mmc: Add function declarations for mmc_bread() and mmc_switch_part() dm: mmc: Move CONFIG_BLK code into the mmc uclass dm: mmc: Move non-CONFIG_BLK code into mmc_legacy.c mmc: Move MMC boot code into its own file dm: mmc: rockchip: Support only CONFIG_BLK mmc: Move tracing code into separate functions rockchip: Disable CONFIG_SDHCI dm: mmc: Add a way to use driver model for MMC operations dm: mmc: dwmmc: Support CONFIG_DM_MMC_OPS dm: mmc: rockchip: Enable CONFIG_DM_MMC_OPS for all boards rockchip: Add MAINTAINER files for kylin_rk3036, evb_rk3036 dm: sandbox: Convert to use CONFIG_CMD_MMC_OPS dm: mmc: sdhci: Refactor configuration setup to support DM dm: mmc: sdhci: Support CONFIG_BLK and CONFIG_DM_MMC_OPS dm: mmc: msm_sdhci: Support CONFIG_BLK and CONFIG_DM_MMC_OPS dm: mmc: Move dragonboard410c to use CONFIG_BLK and CONFIG_DM_MMC_OPS dm: mmc: msmsdhic: Drop old MMC code dm: spl: mmc: Support CONFIG_BLK in SPL MMC dm: dfu: mmc: Support CONFIG_BLK in DFU for MMC net: phy: marvell: Add a missing errno.h header zynq: Increase the early malloc() size dm: zynq: usb: Convert to CONFIG_DM_USB dm: mmc: zynq: Convert zynq to use driver model for MMC dm: mmc: Enable DM_MMC_OPS by default with DM_MMC dm: blk: Enable CONFIG_BLK if DM_MMC is enabled
arch/Kconfig | 1 + arch/arm/Kconfig | 18 ++ arch/arm/cpu/armv8/zynqmp/Kconfig | 4 + arch/arm/mach-rockchip/Kconfig | 27 --- arch/arm/mach-zynq/Kconfig | 3 + board/evb_rk3036/evb_rk3036/MAINTAINERS | 6 + board/kylin/kylin_rk3036/MAINTAINERS | 6 + common/spl/spl_mmc.c | 6 +- configs/dragonboard410c_defconfig | 2 + configs/sandbox_defconfig | 4 +- drivers/block/Kconfig | 1 + drivers/dfu/dfu_mmc.c | 11 +- drivers/mmc/Kconfig | 12 +- drivers/mmc/Makefile | 3 + drivers/mmc/dw_mmc.c | 33 +++ drivers/mmc/mmc-uclass.c | 146 +++++++++++++ drivers/mmc/mmc.c | 371 +++++--------------------------- drivers/mmc/mmc_boot.c | 131 +++++++++++ drivers/mmc/mmc_legacy.c | 91 ++++++++ drivers/mmc/mmc_private.h | 47 ++++ drivers/mmc/msm_sdhci.c | 38 +++- drivers/mmc/rockchip_dw_mmc.c | 14 +- drivers/mmc/sandbox_mmc.c | 17 +- drivers/mmc/sdhci.c | 147 ++++++++----- drivers/mmc/zynq_sdhci.c | 39 +++- drivers/net/phy/marvell.c | 1 + drivers/usb/host/ehci-zynq.c | 102 +++++---- include/configs/rk3036_common.h | 1 - include/configs/rk3288_common.h | 1 - include/dwmmc.h | 73 +++++++ include/mmc.h | 66 +++++- include/sdhci.h | 80 +++++++ 32 files changed, 1006 insertions(+), 496 deletions(-) create mode 100644 drivers/mmc/mmc_boot.c

These comments were missed when the original code was written. Add them to help people port their drivers over.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/dwmmc.h | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+)
diff --git a/include/dwmmc.h b/include/dwmmc.h index 335af51..0199def 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -224,9 +224,73 @@ static inline u8 dwmci_readb(struct dwmci_host *host, int reg) return readb(host->ioaddr + reg); }
+#ifdef CONFIG_BLK +/** + * dwmci_setup_cfg() - Set up the configuration for DWMMC + * + * This is used to set up a DWMMC device when you are using CONFIG_BLK. + * + * This should be called from your MMC driver's probe() method once you have + * the information required. + * + * Generally your driver will have a platform data structure which holds both + * the configuration (struct mmc_config) and the MMC device info (struct mmc). + * For example: + * + * struct rockchip_mmc_plat { + * struct mmc_config cfg; + * struct mmc mmc; + * }; + * + * ... + * + * Inside U_BOOT_DRIVER(): + * .platdata_auto_alloc_size = sizeof(struct rockchip_mmc_plat), + * + * To access platform data: + * struct rockchip_mmc_plat *plat = dev_get_platdata(dev); + * + * See rockchip_dw_mmc.c for an example. + * + * @cfg: Configuration structure to fill in (generally &plat->mmc) + * @name: Device name (normally dev->name) + * @buswidth: Bus width (in bits, such as 4 or 8) + * @caps: Host capabilities (MMC_MODE_...) + * @max_clk: Maximum supported clock speed in HZ (e.g. 400000) + * @min_clk: Minimum supported clock speed in HZ (e.g. 150000000) + */ void dwmci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth, uint caps, u32 max_clk, u32 min_clk); + +/** + * dwmci_bind() - Set up a new MMC block device + * + * This is used to set up a DWMMC block device when you are using CONFIG_BLK. + * It should be called from your driver's bind() method. + * + * See rockchip_dw_mmc.c for an example. + * + * @dev: Device to set up + * @mmc: Pointer to mmc structure (normally &plat->mmc) + * @cfg: Empty configuration structure (generally &plat->cfg). This is + * normally all zeroes at this point. The only purpose of passing + * this in is to set mmc->cfg to it. + * @return 0 if OK, -ve if the block device could not be created + */ int dwmci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg);
+#else +/** + * add_dwmci() - Add a new DWMMC interface + * + * This is used when you are not using CONFIG_BLK. Convert your driver over! + * + * @host: DWMMC host structure + * @max_clk: Maximum supported clock speed in HZ (e.g. 400000) + * @min_clk: Minimum supported clock speed in HZ (e.g. 150000000) + * @return 0 if OK, -ve on error + */ int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk); +#endif /* !CONFIG_BLK */ + #endif /* __DWMMC_HW_H */

Hi Simon,
On 06/13/2016 02:30 PM, Simon Glass wrote:
These comments were missed when the original code was written. Add them to help people port their drivers over.
Signed-off-by: Simon Glass sjg@chromium.org
include/dwmmc.h | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+)
diff --git a/include/dwmmc.h b/include/dwmmc.h index 335af51..0199def 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -224,9 +224,73 @@ static inline u8 dwmci_readb(struct dwmci_host *host, int reg) return readb(host->ioaddr + reg); }
+#ifdef CONFIG_BLK +/**
- dwmci_setup_cfg() - Set up the configuration for DWMMC
- This is used to set up a DWMMC device when you are using CONFIG_BLK.
- This should be called from your MMC driver's probe() method once you have
- the information required.
- Generally your driver will have a platform data structure which holds both
- the configuration (struct mmc_config) and the MMC device info (struct mmc).
- For example:
- struct rockchip_mmc_plat {
- struct mmc_config cfg;
- struct mmc mmc;
- };
- ...
- Inside U_BOOT_DRIVER():
- .platdata_auto_alloc_size = sizeof(struct rockchip_mmc_plat),
- To access platform data:
- struct rockchip_mmc_plat *plat = dev_get_platdata(dev);
- See rockchip_dw_mmc.c for an example.
- @cfg: Configuration structure to fill in (generally &plat->mmc)
- @name: Device name (normally dev->name)
- @buswidth: Bus width (in bits, such as 4 or 8)
- @caps: Host capabilities (MMC_MODE_...)
- @max_clk: Maximum supported clock speed in HZ (e.g. 400000)
- @min_clk: Minimum supported clock speed in HZ (e.g. 150000000)
e,g is need to swap max_clk <-> min_clk?
- */
void dwmci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth, uint caps, u32 max_clk, u32 min_clk);
+/**
- dwmci_bind() - Set up a new MMC block device
- This is used to set up a DWMMC block device when you are using CONFIG_BLK.
- It should be called from your driver's bind() method.
- See rockchip_dw_mmc.c for an example.
- @dev: Device to set up
- @mmc: Pointer to mmc structure (normally &plat->mmc)
- @cfg: Empty configuration structure (generally &plat->cfg). This is
normally all zeroes at this point. The only purpose of passing
this in is to set mmc->cfg to it.
- @return 0 if OK, -ve if the block device could not be created
- */
int dwmci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg);
+#else +/**
- add_dwmci() - Add a new DWMMC interface
- This is used when you are not using CONFIG_BLK. Convert your driver over!
- @host: DWMMC host structure
- @max_clk: Maximum supported clock speed in HZ (e.g. 400000)
- @min_clk: Minimum supported clock speed in HZ (e.g. 150000000)
- @return 0 if OK, -ve on error
- */
Ditto.
I'm starting to covert to DM for dwmmc exynos... After finishing convert for dwmmc_exynos, I will check in more detail on dwmmc core side.
Sorry for checking too late.
Best Regards, Jaehoon Chung
int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk); +#endif /* !CONFIG_BLK */
#endif /* __DWMMC_HW_H */

Hi Jaehoon,
On 27 June 2016 at 04:54, Jaehoon Chung jh80.chung@samsung.com wrote:
Hi Simon,
On 06/13/2016 02:30 PM, Simon Glass wrote:
These comments were missed when the original code was written. Add them to help people port their drivers over.
Signed-off-by: Simon Glass sjg@chromium.org
include/dwmmc.h | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+)
diff --git a/include/dwmmc.h b/include/dwmmc.h index 335af51..0199def 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -224,9 +224,73 @@ static inline u8 dwmci_readb(struct dwmci_host *host, int reg) return readb(host->ioaddr + reg); }
+#ifdef CONFIG_BLK +/**
- dwmci_setup_cfg() - Set up the configuration for DWMMC
- This is used to set up a DWMMC device when you are using CONFIG_BLK.
- This should be called from your MMC driver's probe() method once you have
- the information required.
- Generally your driver will have a platform data structure which holds both
- the configuration (struct mmc_config) and the MMC device info (struct mmc).
- For example:
- struct rockchip_mmc_plat {
- struct mmc_config cfg;
- struct mmc mmc;
- };
- ...
- Inside U_BOOT_DRIVER():
- .platdata_auto_alloc_size = sizeof(struct rockchip_mmc_plat),
- To access platform data:
- struct rockchip_mmc_plat *plat = dev_get_platdata(dev);
- See rockchip_dw_mmc.c for an example.
- @cfg: Configuration structure to fill in (generally &plat->mmc)
- @name: Device name (normally dev->name)
- @buswidth: Bus width (in bits, such as 4 or 8)
- @caps: Host capabilities (MMC_MODE_...)
- @max_clk: Maximum supported clock speed in HZ (e.g. 400000)
- @min_clk: Minimum supported clock speed in HZ (e.g. 150000000)
e,g is need to swap max_clk <-> min_clk?
- */
void dwmci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth, uint caps, u32 max_clk, u32 min_clk);
+/**
- dwmci_bind() - Set up a new MMC block device
- This is used to set up a DWMMC block device when you are using CONFIG_BLK.
- It should be called from your driver's bind() method.
- See rockchip_dw_mmc.c for an example.
- @dev: Device to set up
- @mmc: Pointer to mmc structure (normally &plat->mmc)
- @cfg: Empty configuration structure (generally &plat->cfg). This is
normally all zeroes at this point. The only purpose of passing
this in is to set mmc->cfg to it.
- @return 0 if OK, -ve if the block device could not be created
- */
int dwmci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg);
+#else +/**
- add_dwmci() - Add a new DWMMC interface
- This is used when you are not using CONFIG_BLK. Convert your driver over!
- @host: DWMMC host structure
- @max_clk: Maximum supported clock speed in HZ (e.g. 400000)
- @min_clk: Minimum supported clock speed in HZ (e.g. 150000000)
- @return 0 if OK, -ve on error
- */
Ditto.
I'm starting to covert to DM for dwmmc exynos... After finishing convert for dwmmc_exynos, I will check in more detail on dwmmc core side.
OK I see your patches so I'll apply this as is. Your patches are assigned to Minkyu, so I'll leave them to him.
Sorry for checking too late.
Best Regards, Jaehoon Chung
int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk); +#endif /* !CONFIG_BLK */
#endif /* __DWMMC_HW_H */
Regards, Simon

On 3 July 2016 at 16:28, Simon Glass sjg@chromium.org wrote:
Hi Jaehoon,
On 27 June 2016 at 04:54, Jaehoon Chung jh80.chung@samsung.com wrote:
Hi Simon,
On 06/13/2016 02:30 PM, Simon Glass wrote:
These comments were missed when the original code was written. Add them to help people port their drivers over.
Signed-off-by: Simon Glass sjg@chromium.org
include/dwmmc.h | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+)
diff --git a/include/dwmmc.h b/include/dwmmc.h index 335af51..0199def 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -224,9 +224,73 @@ static inline u8 dwmci_readb(struct dwmci_host *host, int reg) return readb(host->ioaddr + reg); }
+#ifdef CONFIG_BLK +/**
- dwmci_setup_cfg() - Set up the configuration for DWMMC
- This is used to set up a DWMMC device when you are using CONFIG_BLK.
- This should be called from your MMC driver's probe() method once you have
- the information required.
- Generally your driver will have a platform data structure which holds both
- the configuration (struct mmc_config) and the MMC device info (struct mmc).
- For example:
- struct rockchip_mmc_plat {
- struct mmc_config cfg;
- struct mmc mmc;
- };
- ...
- Inside U_BOOT_DRIVER():
- .platdata_auto_alloc_size = sizeof(struct rockchip_mmc_plat),
- To access platform data:
- struct rockchip_mmc_plat *plat = dev_get_platdata(dev);
- See rockchip_dw_mmc.c for an example.
- @cfg: Configuration structure to fill in (generally &plat->mmc)
- @name: Device name (normally dev->name)
- @buswidth: Bus width (in bits, such as 4 or 8)
- @caps: Host capabilities (MMC_MODE_...)
- @max_clk: Maximum supported clock speed in HZ (e.g. 400000)
- @min_clk: Minimum supported clock speed in HZ (e.g. 150000000)
e,g is need to swap max_clk <-> min_clk?
- */
void dwmci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth, uint caps, u32 max_clk, u32 min_clk);
+/**
- dwmci_bind() - Set up a new MMC block device
- This is used to set up a DWMMC block device when you are using CONFIG_BLK.
- It should be called from your driver's bind() method.
- See rockchip_dw_mmc.c for an example.
- @dev: Device to set up
- @mmc: Pointer to mmc structure (normally &plat->mmc)
- @cfg: Empty configuration structure (generally &plat->cfg). This is
normally all zeroes at this point. The only purpose of passing
this in is to set mmc->cfg to it.
- @return 0 if OK, -ve if the block device could not be created
- */
int dwmci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg);
+#else +/**
- add_dwmci() - Add a new DWMMC interface
- This is used when you are not using CONFIG_BLK. Convert your driver over!
- @host: DWMMC host structure
- @max_clk: Maximum supported clock speed in HZ (e.g. 400000)
- @min_clk: Minimum supported clock speed in HZ (e.g. 150000000)
- @return 0 if OK, -ve on error
- */
Ditto.
I'm starting to covert to DM for dwmmc exynos... After finishing convert for dwmmc_exynos, I will check in more detail on dwmmc core side.
OK I see your patches so I'll apply this as is. Your patches are assigned to Minkyu, so I'll leave them to him.
Sorry for checking too late.
Best Regards, Jaehoon Chung
int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk); +#endif /* !CONFIG_BLK */
#endif /* __DWMMC_HW_H */
Regards, Simon
Applied to u-boot-dm/next.

Rockchip uses driver model for all subsystems. Specify this in the arm Kconfig rather than as defaults in the Rockchip Kconfig. This means that boards cannot turn these options off, which seems correct.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/arm/Kconfig | 10 ++++++++++ arch/arm/mach-rockchip/Kconfig | 27 --------------------------- 2 files changed, 10 insertions(+), 27 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e75c4c0..85b4d31 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -823,7 +823,17 @@ config ARCH_ROCKCHIP select SPL select OF_CONTROL select CPU_V7 + select BLK select DM + select SPL_DM + select SYS_MALLOC_F + select SPL_SYS_MALLOC_SIMPLE + select DM_GPIO + select DM_I2C + select DM_MMC + select DM_SERIAL + select DM_SPI + select DM_SPI_FLASH
config TARGET_THUNDERX_88XX bool "Support ThunderX 88xx" diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index 2a8afac..c49cc19 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -17,33 +17,6 @@ config ROCKCHIP_RK3036 and video codec support. Peripherals include Gigabit Ethernet, USB2 host and OTG, SDIO, I2S, UART, SPI, I2C and PWMs.
-config SYS_MALLOC_F - default y - -config SPL_SYS_MALLOC_SIMPLE - default y - -config SPL_DM - default y - -config DM_SERIAL - default y - -config DM_SPI - default y - -config DM_SPI_FLASH - default y - -config DM_I2C - default y - -config DM_GPIO - default y - -config BLK - default y - source "arch/arm/mach-rockchip/rk3288/Kconfig" source "arch/arm/mach-rockchip/rk3036/Kconfig" endif

On 12 June 2016 at 23:30, Simon Glass sjg@chromium.org wrote:
Rockchip uses driver model for all subsystems. Specify this in the arm Kconfig rather than as defaults in the Rockchip Kconfig. This means that boards cannot turn these options off, which seems correct.
Signed-off-by: Simon Glass sjg@chromium.org
arch/arm/Kconfig | 10 ++++++++++ arch/arm/mach-rockchip/Kconfig | 27 --------------------------- 2 files changed, 10 insertions(+), 27 deletions(-)
Applied to u-boot-dm/next.

These private functions are used both in the driver-model implementation and in the legacy code. Add them to the header.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/mmc/mmc.c | 9 ++++----- drivers/mmc/mmc_private.h | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 7586558..c0a97e4 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -215,11 +215,10 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start, }
#ifdef CONFIG_BLK -static ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, - void *dst) +ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst) #else -static ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, - lbaint_t blkcnt, void *dst) +ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, + void *dst) #endif { #ifdef CONFIG_BLK @@ -566,7 +565,7 @@ static int mmc_set_capacity(struct mmc *mmc, int part_num) return 0; }
-static int mmc_switch_part(struct mmc *mmc, unsigned int part_num) +int mmc_switch_part(struct mmc *mmc, unsigned int part_num) { int ret;
diff --git a/drivers/mmc/mmc_private.h b/drivers/mmc/mmc_private.h index 9f0d5c2..cfc4aca 100644 --- a/drivers/mmc/mmc_private.h +++ b/drivers/mmc/mmc_private.h @@ -20,6 +20,14 @@ extern int mmc_set_blocklen(struct mmc *mmc, int len); void mmc_adapter_card_type_ident(void); #endif
+#ifdef CONFIG_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 + #ifndef CONFIG_SPL_BUILD
unsigned long mmc_berase(struct blk_desc *block_dev, lbaint_t start, @@ -89,4 +97,13 @@ void mmc_list_init(void); */ void mmc_list_add(struct mmc *mmc);
+/** + * mmc_switch_part() - Switch to a new MMC hardware partition + * + * @mmc: MMC device + * @part_num: Hardware partition number + * @return 0 if OK, -ve on error + */ +int mmc_switch_part(struct mmc *mmc, unsigned int part_num); + #endif /* _MMC_PRIVATE_H_ */

On 12 June 2016 at 23:30, Simon Glass sjg@chromium.org wrote:
These private functions are used both in the driver-model implementation and in the legacy code. Add them to the header.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/mmc/mmc.c | 9 ++++----- drivers/mmc/mmc_private.h | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-)
Applied to u-boot-dm/next.

Rather than having #ifdef in mmc.c, move this code into the uclass file.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/mmc/mmc-uclass.c | 80 +++++++++++++++++++++++++++++++++++++++++++++ drivers/mmc/mmc.c | 85 ++---------------------------------------------- 2 files changed, 83 insertions(+), 82 deletions(-)
diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index 1b967d9..530276a 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -8,8 +8,10 @@ #include <common.h> #include <mmc.h> #include <dm.h> +#include <dm/device-internal.h> #include <dm/lists.h> #include <dm/root.h> +#include "mmc_private.h"
struct mmc *mmc_get_mmc_dev(struct udevice *dev) { @@ -125,6 +127,84 @@ void print_mmc_devices(char separator) #else void print_mmc_devices(char separator) { } #endif + +int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg) +{ + struct blk_desc *bdesc; + struct udevice *bdev; + int ret; + + ret = blk_create_devicef(dev, "mmc_blk", "blk", IF_TYPE_MMC, -1, 512, + 0, &bdev); + if (ret) { + debug("Cannot create block device\n"); + return ret; + } + bdesc = dev_get_uclass_platdata(bdev); + mmc->cfg = cfg; + mmc->priv = dev; + + /* the following chunk was from mmc_register() */ + + /* Setup dsr related values */ + mmc->dsr_imp = 0; + mmc->dsr = 0xffffffff; + /* Setup the universal parts of the block interface just once */ + bdesc->removable = 1; + + /* setup initial part type */ + bdesc->part_type = cfg->part_type; + mmc->dev = dev; + + return 0; +} + +int mmc_unbind(struct udevice *dev) +{ + struct udevice *bdev; + + device_find_first_child(dev, &bdev); + if (bdev) { + device_remove(bdev); + device_unbind(bdev); + } + + return 0; +} + +static int mmc_select_hwpart(struct udevice *bdev, int hwpart) +{ + struct udevice *mmc_dev = dev_get_parent(bdev); + struct mmc *mmc = mmc_get_mmc_dev(mmc_dev); + struct blk_desc *desc = dev_get_uclass_platdata(bdev); + int ret; + + if (desc->hwpart == hwpart) + return 0; + + if (mmc->part_config == MMCPART_NOAVAILABLE) + return -EMEDIUMTYPE; + + ret = mmc_switch_part(mmc, hwpart); + if (ret) + return ret; + + return 0; +} + +static const struct blk_ops mmc_blk_ops = { + .read = mmc_bread, +#ifndef CONFIG_SPL_BUILD + .write = mmc_bwrite, +#endif + .select_hwpart = mmc_select_hwpart, +}; + +U_BOOT_DRIVER(mmc_blk) = { + .name = "mmc_blk", + .id = UCLASS_BLK, + .ops = &mmc_blk_ops, +}; #endif /* CONFIG_BLK */
U_BOOT_DRIVER(mmc) = { diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index c0a97e4..52e7be5 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -585,27 +585,7 @@ int mmc_switch_part(struct mmc *mmc, unsigned int part_num) return ret; }
-#ifdef CONFIG_BLK -static int mmc_select_hwpart(struct udevice *bdev, int hwpart) -{ - struct udevice *mmc_dev = dev_get_parent(bdev); - struct mmc *mmc = mmc_get_mmc_dev(mmc_dev); - struct blk_desc *desc = dev_get_uclass_platdata(bdev); - int ret; - - if (desc->hwpart == hwpart) - return 0; - - if (mmc->part_config == MMCPART_NOAVAILABLE) - return -EMEDIUMTYPE; - - ret = mmc_switch_part(mmc, hwpart); - if (ret) - return ret; - - return 0; -} -#else +#ifndef CONFIG_BLK static int mmc_select_hwpartp(struct blk_desc *desc, int hwpart) { struct mmc *mmc = find_mmc_device(desc->devnum); @@ -1528,52 +1508,7 @@ static int mmc_send_if_cond(struct mmc *mmc) return 0; }
-#ifdef CONFIG_BLK -int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg) -{ - struct blk_desc *bdesc; - struct udevice *bdev; - int ret; - - ret = blk_create_devicef(dev, "mmc_blk", "blk", IF_TYPE_MMC, -1, 512, - 0, &bdev); - if (ret) { - debug("Cannot create block device\n"); - return ret; - } - bdesc = dev_get_uclass_platdata(bdev); - mmc->cfg = cfg; - mmc->priv = dev; - - /* the following chunk was from mmc_register() */ - - /* Setup dsr related values */ - mmc->dsr_imp = 0; - mmc->dsr = 0xffffffff; - /* Setup the universal parts of the block interface just once */ - bdesc->removable = 1; - - /* setup initial part type */ - bdesc->part_type = cfg->part_type; - mmc->dev = dev; - - return 0; -} - -int mmc_unbind(struct udevice *dev) -{ - struct udevice *bdev; - - device_find_first_child(dev, &bdev); - if (bdev) { - device_remove(bdev); - device_unbind(bdev); - } - - return 0; -} - -#else +#ifndef CONFIG_BLK struct mmc *mmc_create(const struct mmc_config *cfg, void *priv) { struct blk_desc *bdesc; @@ -1617,9 +1552,7 @@ void mmc_destroy(struct mmc *mmc) /* only freeing memory for now */ free(mmc); } -#endif
-#ifndef CONFIG_BLK static int mmc_get_dev(int dev, struct blk_desc **descp) { struct mmc *mmc = find_mmc_device(dev); @@ -1959,19 +1892,7 @@ int mmc_set_rst_n_function(struct mmc *mmc, u8 enable) } #endif
-#ifdef CONFIG_BLK -static const struct blk_ops mmc_blk_ops = { - .read = mmc_bread, - .write = mmc_bwrite, - .select_hwpart = mmc_select_hwpart, -}; - -U_BOOT_DRIVER(mmc_blk) = { - .name = "mmc_blk", - .id = UCLASS_BLK, - .ops = &mmc_blk_ops, -}; -#else +#ifndef CONFIG_BLK U_BOOT_LEGACY_BLK(mmc) = { .if_typename = "mmc", .if_type = IF_TYPE_MMC,

On 12 June 2016 at 23:30, Simon Glass sjg@chromium.org wrote:
Rather than having #ifdef in mmc.c, move this code into the uclass file.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/mmc/mmc-uclass.c | 80 +++++++++++++++++++++++++++++++++++++++++++++ drivers/mmc/mmc.c | 85 ++---------------------------------------------- 2 files changed, 83 insertions(+), 82 deletions(-)
Applied to u-boot-dm/next.

Rather than having #ifdef in mmc.c, move this code into the legacy file.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/mmc/mmc.c | 95 ------------------------------------------------ drivers/mmc/mmc_legacy.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 95 deletions(-)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 52e7be5..40ab506 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -585,29 +585,6 @@ int mmc_switch_part(struct mmc *mmc, unsigned int part_num) return ret; }
-#ifndef CONFIG_BLK -static int mmc_select_hwpartp(struct blk_desc *desc, int hwpart) -{ - struct mmc *mmc = find_mmc_device(desc->devnum); - int ret; - - if (!mmc) - return -ENODEV; - - if (mmc->block_dev.hwpart == hwpart) - return 0; - - if (mmc->part_config == MMCPART_NOAVAILABLE) - return -EMEDIUMTYPE; - - ret = mmc_switch_part(mmc, hwpart); - if (ret) - return ret; - - return 0; -} -#endif - int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf, enum mmc_hwpart_conf_mode mode) @@ -1508,68 +1485,6 @@ static int mmc_send_if_cond(struct mmc *mmc) return 0; }
-#ifndef CONFIG_BLK -struct mmc *mmc_create(const struct mmc_config *cfg, void *priv) -{ - struct blk_desc *bdesc; - struct mmc *mmc; - - /* quick validation */ - if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL || - cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0) - return NULL; - - mmc = calloc(1, sizeof(*mmc)); - if (mmc == NULL) - return NULL; - - mmc->cfg = cfg; - mmc->priv = priv; - - /* the following chunk was mmc_register() */ - - /* Setup dsr related values */ - mmc->dsr_imp = 0; - mmc->dsr = 0xffffffff; - /* Setup the universal parts of the block interface just once */ - bdesc = mmc_get_blk_desc(mmc); - bdesc->if_type = IF_TYPE_MMC; - bdesc->removable = 1; - bdesc->devnum = mmc_get_next_devnum(); - bdesc->block_read = mmc_bread; - bdesc->block_write = mmc_bwrite; - bdesc->block_erase = mmc_berase; - - /* setup initial part type */ - bdesc->part_type = mmc->cfg->part_type; - mmc_list_add(mmc); - - return mmc; -} - -void mmc_destroy(struct mmc *mmc) -{ - /* only freeing memory for now */ - free(mmc); -} - -static int mmc_get_dev(int dev, struct blk_desc **descp) -{ - struct mmc *mmc = find_mmc_device(dev); - int ret; - - if (!mmc) - return -ENODEV; - ret = mmc_init(mmc); - if (ret) - return ret; - - *descp = &mmc->block_dev; - - return 0; -} -#endif - /* board-specific MMC power initializations. */ __weak void board_mmc_power_init(void) { @@ -1891,13 +1806,3 @@ int mmc_set_rst_n_function(struct mmc *mmc, u8 enable) enable); } #endif - -#ifndef CONFIG_BLK -U_BOOT_LEGACY_BLK(mmc) = { - .if_typename = "mmc", - .if_type = IF_TYPE_MMC, - .max_devs = -1, - .get_dev = mmc_get_dev, - .select_hwpart = mmc_select_hwpartp, -}; -#endif diff --git a/drivers/mmc/mmc_legacy.c b/drivers/mmc/mmc_legacy.c index 3ec649f..040728b 100644 --- a/drivers/mmc/mmc_legacy.c +++ b/drivers/mmc/mmc_legacy.c @@ -6,7 +6,9 @@ */
#include <common.h> +#include <malloc.h> #include <mmc.h> +#include "mmc_private.h"
static struct list_head mmc_devices; static int cur_dev_num = -1; @@ -106,3 +108,92 @@ void print_mmc_devices(char separator) #else void print_mmc_devices(char separator) { } #endif + +struct mmc *mmc_create(const struct mmc_config *cfg, void *priv) +{ + struct blk_desc *bdesc; + struct mmc *mmc; + + /* quick validation */ + if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL || + cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0) + return NULL; + + mmc = calloc(1, sizeof(*mmc)); + if (mmc == NULL) + return NULL; + + mmc->cfg = cfg; + mmc->priv = priv; + + /* the following chunk was mmc_register() */ + + /* Setup dsr related values */ + mmc->dsr_imp = 0; + mmc->dsr = 0xffffffff; + /* Setup the universal parts of the block interface just once */ + bdesc = mmc_get_blk_desc(mmc); + bdesc->if_type = IF_TYPE_MMC; + bdesc->removable = 1; + bdesc->devnum = mmc_get_next_devnum(); + bdesc->block_read = mmc_bread; + bdesc->block_write = mmc_bwrite; + bdesc->block_erase = mmc_berase; + + /* setup initial part type */ + bdesc->part_type = mmc->cfg->part_type; + mmc_list_add(mmc); + + return mmc; +} + +void mmc_destroy(struct mmc *mmc) +{ + /* only freeing memory for now */ + free(mmc); +} + +static int mmc_select_hwpartp(struct blk_desc *desc, int hwpart) +{ + struct mmc *mmc = find_mmc_device(desc->devnum); + int ret; + + if (!mmc) + return -ENODEV; + + if (mmc->block_dev.hwpart == hwpart) + return 0; + + if (mmc->part_config == MMCPART_NOAVAILABLE) + return -EMEDIUMTYPE; + + ret = mmc_switch_part(mmc, hwpart); + if (ret) + return ret; + + return 0; +} + +static int mmc_get_dev(int dev, struct blk_desc **descp) +{ + struct mmc *mmc = find_mmc_device(dev); + int ret; + + if (!mmc) + return -ENODEV; + ret = mmc_init(mmc); + if (ret) + return ret; + + *descp = &mmc->block_dev; + + return 0; +} + +U_BOOT_LEGACY_BLK(mmc) = { + .if_typename = "mmc", + .if_type = IF_TYPE_MMC, + .max_devs = -1, + .get_dev = mmc_get_dev, + .select_hwpart = mmc_select_hwpartp, +};

On 12 June 2016 at 23:30, Simon Glass sjg@chromium.org wrote:
Rather than having #ifdef in mmc.c, move this code into the legacy file.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/mmc/mmc.c | 95 ------------------------------------------------ drivers/mmc/mmc_legacy.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 95 deletions(-)
Applied to u-boot-dm/next.

Rather than having an #ifdef in the main mmc.c file, control this feature from the Makefile by moving the code into its own file.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/mmc/Makefile | 3 ++ drivers/mmc/mmc.c | 126 +------------------------------------------- drivers/mmc/mmc_boot.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/mmc/mmc_private.h | 11 ++++ 4 files changed, 146 insertions(+), 125 deletions(-) create mode 100644 drivers/mmc/mmc_boot.c
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 3da4817..b44a12e 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -25,6 +25,9 @@ obj-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o obj-$(CONFIG_FTSDC010) += ftsdc010_mci.o obj-$(CONFIG_FTSDC021) += ftsdc021_sdhci.o obj-$(CONFIG_GENERIC_MMC) += mmc.o +ifdef CONFIG_SUPPORT_EMMC_BOOT +obj-$(CONFIG_GENERIC_MMC) += mmc_boot.o +endif obj-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o obj-$(CONFIG_KONA_SDHCI) += kona_sdhci.o obj-$(CONFIG_MMC_SPI) += mmc_spi.o diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 40ab506..6593f25 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -463,8 +463,7 @@ static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd) return err; }
- -static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value) +int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value) { struct mmc_cmd cmd; int timeout = 1000; @@ -1683,126 +1682,3 @@ int mmc_initialize(bd_t *bis) mmc_do_preinit(); return 0; } - -#ifdef CONFIG_SUPPORT_EMMC_BOOT -/* - * This function changes the size of boot partition and the size of rpmb - * partition present on EMMC devices. - * - * Input Parameters: - * struct *mmc: pointer for the mmc device strcuture - * bootsize: size of boot partition - * rpmbsize: size of rpmb partition - * - * Returns 0 on success. - */ - -int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize, - unsigned long rpmbsize) -{ - int err; - struct mmc_cmd cmd; - - /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */ - cmd.cmdidx = MMC_CMD_RES_MAN; - cmd.resp_type = MMC_RSP_R1b; - cmd.cmdarg = MMC_CMD62_ARG1; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) { - debug("mmc_boot_partition_size_change: Error1 = %d\n", err); - return err; - } - - /* Boot partition changing mode */ - cmd.cmdidx = MMC_CMD_RES_MAN; - cmd.resp_type = MMC_RSP_R1b; - cmd.cmdarg = MMC_CMD62_ARG2; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) { - debug("mmc_boot_partition_size_change: Error2 = %d\n", err); - return err; - } - /* boot partition size is multiple of 128KB */ - bootsize = (bootsize * 1024) / 128; - - /* Arg: boot partition size */ - cmd.cmdidx = MMC_CMD_RES_MAN; - cmd.resp_type = MMC_RSP_R1b; - cmd.cmdarg = bootsize; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) { - debug("mmc_boot_partition_size_change: Error3 = %d\n", err); - return err; - } - /* RPMB partition size is multiple of 128KB */ - rpmbsize = (rpmbsize * 1024) / 128; - /* Arg: RPMB partition size */ - cmd.cmdidx = MMC_CMD_RES_MAN; - cmd.resp_type = MMC_RSP_R1b; - cmd.cmdarg = rpmbsize; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) { - debug("mmc_boot_partition_size_change: Error4 = %d\n", err); - return err; - } - return 0; -} - -/* - * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH - * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH - * and BOOT_MODE. - * - * Returns 0 on success. - */ -int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode) -{ - int err; - - err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH, - EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) | - EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) | - EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width)); - - if (err) - return err; - return 0; -} - -/* - * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG) - * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and - * PARTITION_ACCESS. - * - * Returns 0 on success. - */ -int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access) -{ - int err; - - err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF, - EXT_CSD_BOOT_ACK(ack) | - EXT_CSD_BOOT_PART_NUM(part_num) | - EXT_CSD_PARTITION_ACCESS(access)); - - if (err) - return err; - return 0; -} - -/* - * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value - * for enable. Note that this is a write-once field for non-zero values. - * - * Returns 0 on success. - */ -int mmc_set_rst_n_function(struct mmc *mmc, u8 enable) -{ - return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION, - enable); -} -#endif diff --git a/drivers/mmc/mmc_boot.c b/drivers/mmc/mmc_boot.c new file mode 100644 index 0000000..756a982 --- /dev/null +++ b/drivers/mmc/mmc_boot.c @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2016 Google, Inc + * Written by Amar amarendra.xt@samsung.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <mmc.h> +#include "mmc_private.h" + +/* + * This function changes the size of boot partition and the size of rpmb + * partition present on EMMC devices. + * + * Input Parameters: + * struct *mmc: pointer for the mmc device strcuture + * bootsize: size of boot partition + * rpmbsize: size of rpmb partition + * + * Returns 0 on success. + */ + +int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize, + unsigned long rpmbsize) +{ + int err; + struct mmc_cmd cmd; + + /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */ + cmd.cmdidx = MMC_CMD_RES_MAN; + cmd.resp_type = MMC_RSP_R1b; + cmd.cmdarg = MMC_CMD62_ARG1; + + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) { + debug("mmc_boot_partition_size_change: Error1 = %d\n", err); + return err; + } + + /* Boot partition changing mode */ + cmd.cmdidx = MMC_CMD_RES_MAN; + cmd.resp_type = MMC_RSP_R1b; + cmd.cmdarg = MMC_CMD62_ARG2; + + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) { + debug("mmc_boot_partition_size_change: Error2 = %d\n", err); + return err; + } + /* boot partition size is multiple of 128KB */ + bootsize = (bootsize * 1024) / 128; + + /* Arg: boot partition size */ + cmd.cmdidx = MMC_CMD_RES_MAN; + cmd.resp_type = MMC_RSP_R1b; + cmd.cmdarg = bootsize; + + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) { + debug("mmc_boot_partition_size_change: Error3 = %d\n", err); + return err; + } + /* RPMB partition size is multiple of 128KB */ + rpmbsize = (rpmbsize * 1024) / 128; + /* Arg: RPMB partition size */ + cmd.cmdidx = MMC_CMD_RES_MAN; + cmd.resp_type = MMC_RSP_R1b; + cmd.cmdarg = rpmbsize; + + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) { + debug("mmc_boot_partition_size_change: Error4 = %d\n", err); + return err; + } + return 0; +} + +/* + * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH + * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH + * and BOOT_MODE. + * + * Returns 0 on success. + */ +int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode) +{ + int err; + + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH, + EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) | + EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) | + EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width)); + + if (err) + return err; + return 0; +} + +/* + * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG) + * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and + * PARTITION_ACCESS. + * + * Returns 0 on success. + */ +int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access) +{ + int err; + + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF, + EXT_CSD_BOOT_ACK(ack) | + EXT_CSD_BOOT_PART_NUM(part_num) | + EXT_CSD_PARTITION_ACCESS(access)); + + if (err) + return err; + return 0; +} + +/* + * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value + * for enable. Note that this is a write-once field for non-zero values. + * + * Returns 0 on success. + */ +int mmc_set_rst_n_function(struct mmc *mmc, u8 enable) +{ + return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION, + enable); +} diff --git a/drivers/mmc/mmc_private.h b/drivers/mmc/mmc_private.h index cfc4aca..3d189ba 100644 --- a/drivers/mmc/mmc_private.h +++ b/drivers/mmc/mmc_private.h @@ -106,4 +106,15 @@ void mmc_list_add(struct mmc *mmc); */ int mmc_switch_part(struct mmc *mmc, unsigned int part_num);
+/** + * mmc_switch() - Issue and MMC switch mode command + * + * @mmc: MMC device + * @set: Unused + * @index: Cmdarg index + * @value: Cmdarg value + * @return 0 if OK, -ve on error + */ +int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value); + #endif /* _MMC_PRIVATE_H_ */

On 12 June 2016 at 23:30, Simon Glass sjg@chromium.org wrote:
Rather than having an #ifdef in the main mmc.c file, control this feature from the Makefile by moving the code into its own file.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/mmc/Makefile | 3 ++ drivers/mmc/mmc.c | 126 +------------------------------------------- drivers/mmc/mmc_boot.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/mmc/mmc_private.h | 11 ++++ 4 files changed, 146 insertions(+), 125 deletions(-) create mode 100644 drivers/mmc/mmc_boot.c
Applied to u-boot-dm/next.

Since all Rockchip boards use CONFIG_BLK, we can remove this old code.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/mmc/rockchip_dw_mmc.c | 11 ----------- 1 file changed, 11 deletions(-)
diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c index 750ab9f..d928b0b 100644 --- a/drivers/mmc/rockchip_dw_mmc.c +++ b/drivers/mmc/rockchip_dw_mmc.c @@ -67,9 +67,7 @@ static int rockchip_dwmmc_ofdata_to_platdata(struct udevice *dev)
static int rockchip_dwmmc_probe(struct udevice *dev) { -#ifdef CONFIG_BLK struct rockchip_mmc_plat *plat = dev_get_platdata(dev); -#endif struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct rockchip_dwmmc_priv *priv = dev_get_priv(dev); struct dwmci_host *host = &priv->host; @@ -108,16 +106,9 @@ static int rockchip_dwmmc_probe(struct udevice *dev) return ret; } #endif -#ifdef CONFIG_BLK dwmci_setup_cfg(&plat->cfg, dev->name, host->buswidth, host->caps, minmax[1], minmax[0]); host->mmc = &plat->mmc; -#else - ret = add_dwmci(host, minmax[1], minmax[0]); - if (ret) - return ret; - -#endif host->mmc->priv = &priv->host; host->mmc->dev = dev; upriv->mmc = host->mmc; @@ -127,14 +118,12 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
static int rockchip_dwmmc_bind(struct udevice *dev) { -#ifdef CONFIG_BLK struct rockchip_mmc_plat *plat = dev_get_platdata(dev); int ret;
ret = dwmci_bind(dev, &plat->mmc, &plat->cfg); if (ret) return ret; -#endif
return 0; }

On 12 June 2016 at 23:30, Simon Glass sjg@chromium.org wrote:
Since all Rockchip boards use CONFIG_BLK, we can remove this old code.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/mmc/rockchip_dw_mmc.c | 11 ----------- 1 file changed, 11 deletions(-)
Applied to u-boot-dm/next.

Move this code into separate functions so that it can be used from the uclass also. Add static inline versions for when the option is disabled.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/mmc/mmc.c | 41 ++++++++++++++++++++++++++--------------- drivers/mmc/mmc_private.h | 19 +++++++++++++++++++ 2 files changed, 45 insertions(+), 15 deletions(-)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 6593f25..66aaca7 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -47,17 +47,18 @@ __weak int board_mmc_getcd(struct mmc *mmc) return -1; }
-int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) +#ifdef CONFIG_MMC_TRACE +void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd) { - int ret; + printf("CMD_SEND:%d\n", cmd->cmdidx); + printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg); +}
-#ifdef CONFIG_MMC_TRACE +void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd, int ret) +{ int i; u8 *ptr;
- printf("CMD_SEND:%d\n", cmd->cmdidx); - printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg); - ret = mmc->cfg->ops->send_cmd(mmc, cmd, data); if (ret) { printf("\t\tRET\t\t\t %d\n", ret); } else { @@ -103,9 +104,25 @@ int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) break; } } -#else - ret = mmc->cfg->ops->send_cmd(mmc, cmd, data); +} + +void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd) +{ + int status; + + status = (cmd->response[0] & MMC_STATUS_CURR_STATE) >> 9; + printf("CURR STATE:%d\n", status); +} #endif + +int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) +{ + int ret; + + mmmc_trace_before_send(mmc, cmd); + ret = mmc->cfg->ops->send_cmd(mmc, cmd, data); + mmmc_trace_after_send(mmc, cmd, ret); + return ret; }
@@ -113,9 +130,6 @@ int mmc_send_status(struct mmc *mmc, int timeout) { struct mmc_cmd cmd; int err, retries = 5; -#ifdef CONFIG_MMC_TRACE - int status; -#endif
cmd.cmdidx = MMC_CMD_SEND_STATUS; cmd.resp_type = MMC_RSP_R1; @@ -145,10 +159,7 @@ int mmc_send_status(struct mmc *mmc, int timeout) udelay(1000); }
-#ifdef CONFIG_MMC_TRACE - status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9; - printf("CURR STATE:%d\n", status); -#endif + mmc_trace_state(mmc, &cmd); if (timeout <= 0) { #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) printf("Timeout waiting card ready\n"); diff --git a/drivers/mmc/mmc_private.h b/drivers/mmc/mmc_private.h index 3d189ba..49ec022 100644 --- a/drivers/mmc/mmc_private.h +++ b/drivers/mmc/mmc_private.h @@ -73,6 +73,25 @@ static inline ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start,
#endif /* CONFIG_SPL_BUILD */
+#ifdef CONFIG_MMC_TRACE +void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd); +void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd, int ret); +void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd); +#else +static inline void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd) +{ +} + +static inline void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd, + int ret) +{ +} + +static inline void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd) +{ +} +#endif + /** * mmc_get_next_devnum() - Get the next available MMC device number *

On 12 June 2016 at 23:30, Simon Glass sjg@chromium.org wrote:
Move this code into separate functions so that it can be used from the uclass also. Add static inline versions for when the option is disabled.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/mmc/mmc.c | 41 ++++++++++++++++++++++++++--------------- drivers/mmc/mmc_private.h | 19 +++++++++++++++++++ 2 files changed, 45 insertions(+), 15 deletions(-)
Applied to u-boot-dm/next.

This option is not actually needed for rockchip boards. Drop it, since it will not support driver-model MMC operation support.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/configs/rk3036_common.h | 1 - include/configs/rk3288_common.h | 1 - 2 files changed, 2 deletions(-)
diff --git a/include/configs/rk3036_common.h b/include/configs/rk3036_common.h index 1bdcf9d..ae4b101 100644 --- a/include/configs/rk3036_common.h +++ b/include/configs/rk3036_common.h @@ -45,7 +45,6 @@ /* MMC/SD IP block */ #define CONFIG_MMC #define CONFIG_GENERIC_MMC -#define CONFIG_SDHCI #define CONFIG_DWMMC #define CONFIG_BOUNCE_BUFFER
diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h index 9d50d83..8adc26f 100644 --- a/include/configs/rk3288_common.h +++ b/include/configs/rk3288_common.h @@ -51,7 +51,6 @@ /* MMC/SD IP block */ #define CONFIG_MMC #define CONFIG_GENERIC_MMC -#define CONFIG_SDHCI #define CONFIG_DWMMC #define CONFIG_BOUNCE_BUFFER

On 12 June 2016 at 23:30, Simon Glass sjg@chromium.org wrote:
This option is not actually needed for rockchip boards. Drop it, since it will not support driver-model MMC operation support.
Signed-off-by: Simon Glass sjg@chromium.org
include/configs/rk3036_common.h | 1 - include/configs/rk3288_common.h | 1 - 2 files changed, 2 deletions(-)
Applied to u-boot-dm/next.

The driver model conversion for MMC has moved in small steps. The first step was to have an MMC device (CONFIG_DM_MMC). The second was to use a child block device (CONFIG_BLK). The final one is to use driver model for MMC operations (CONFIG_DM_MMC_OP). Add support for this.
The immediate priority is to make all boards that use DM_MMC also use those other two options. This will allow them to be removed.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/mmc/Kconfig | 9 +++++++ drivers/mmc/mmc-uclass.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/mmc/mmc.c | 21 ++++++++++++--- include/mmc.h | 66 +++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 158 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index c80efc3..b9662f9 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -16,6 +16,15 @@ config DM_MMC appear as block devices in U-Boot and can support filesystems such as EXT4 and FAT.
+config DM_MMC_OPS + bool "Support MMC controller operations using Driver Model" + depends on DM_MMC + 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. + config MSM_SDHCI bool "Qualcomm SDHCI controller" depends on DM_MMC diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index 530276a..38ced41 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -13,6 +13,72 @@ #include <dm/root.h> #include "mmc_private.h"
+#ifdef CONFIG_DM_MMC_OPS +int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct mmc *mmc = mmc_get_mmc_dev(dev); + struct dm_mmc_ops *ops = mmc_get_ops(dev); + int ret; + + mmmc_trace_before_send(mmc, cmd); + if (ops->send_cmd) + ret = ops->send_cmd(dev, cmd, data); + else + ret = -ENOSYS; + mmmc_trace_after_send(mmc, cmd, ret); + + return ret; +} + +int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) +{ + return dm_mmc_send_cmd(mmc->dev, cmd, data); +} + +int dm_mmc_set_ios(struct udevice *dev) +{ + struct dm_mmc_ops *ops = mmc_get_ops(dev); + + if (!ops->set_ios) + return -ENOSYS; + return ops->set_ios(dev); +} + +int mmc_set_ios(struct mmc *mmc) +{ + return dm_mmc_set_ios(mmc->dev); +} + +int dm_mmc_get_wp(struct udevice *dev) +{ + struct dm_mmc_ops *ops = mmc_get_ops(dev); + + if (!ops->get_wp) + return -ENOSYS; + return ops->get_wp(dev); +} + +int mmc_getwp(struct mmc *mmc) +{ + return dm_mmc_get_wp(mmc->dev); +} + +int dm_mmc_get_cd(struct udevice *dev) +{ + struct dm_mmc_ops *ops = mmc_get_ops(dev); + + if (!ops->get_cd) + return -ENOSYS; + return ops->get_cd(dev); +} + +int mmc_getcd(struct mmc *mmc) +{ + return dm_mmc_get_cd(mmc->dev); +} +#endif + struct mmc *mmc_get_mmc_dev(struct udevice *dev) { struct mmc_uclass_priv *upriv; diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 66aaca7..54324ce 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -21,6 +21,7 @@ #include <div64.h> #include "mmc_private.h"
+#ifndef CONFIG_DM_MMC_OPS __weak int board_mmc_getwp(struct mmc *mmc) { return -1; @@ -46,6 +47,7 @@ __weak int board_mmc_getcd(struct mmc *mmc) { return -1; } +#endif
#ifdef CONFIG_MMC_TRACE void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd) @@ -115,6 +117,7 @@ void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd) } #endif
+#ifndef CONFIG_DM_MMC_OPS int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { int ret; @@ -125,6 +128,7 @@ int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
return ret; } +#endif
int mmc_send_status(struct mmc *mmc, int timeout) { @@ -789,6 +793,7 @@ int mmc_hwpart_config(struct mmc *mmc, return 0; }
+#ifndef CONFIG_DM_MMC_OPS int mmc_getcd(struct mmc *mmc) { int cd; @@ -804,6 +809,7 @@ int mmc_getcd(struct mmc *mmc)
return cd; } +#endif
static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp) { @@ -967,11 +973,13 @@ static const u8 multipliers[] = { 80, };
+#ifndef CONFIG_DM_MMC_OPS static void mmc_set_ios(struct mmc *mmc) { if (mmc->cfg->ops->set_ios) mmc->cfg->ops->set_ios(mmc); } +#endif
void mmc_set_clock(struct mmc *mmc, uint clock) { @@ -1502,10 +1510,15 @@ __weak void board_mmc_power_init(void)
int mmc_start_init(struct mmc *mmc) { + bool no_card; int err;
/* we pretend there's no card when init is NULL */ - if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) { + no_card = mmc_getcd(mmc) == 0; +#ifndef CONFIG_DM_MMC_OPS + no_card = no_card || (mmc->cfg->ops->init == NULL); +#endif + if (no_card) { mmc->has_init = 0; #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) printf("MMC: no card present\n"); @@ -1521,12 +1534,14 @@ int mmc_start_init(struct mmc *mmc) #endif board_mmc_power_init();
+#ifdef CONFIG_DM_MMC_OPS + /* The device has already been probed ready for use */ +#else /* made sure it's not NULL earlier */ err = mmc->cfg->ops->init(mmc); - if (err) return err; - +#endif mmc->ddr_mode = 0; mmc_set_bus_width(mmc, 1); mmc_set_clock(mmc, 1); diff --git a/include/mmc.h b/include/mmc.h index 7fdfc32..7adba52 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -322,6 +322,58 @@ struct mmc_data { /* forward decl. */ struct mmc;
+#ifdef CONFIG_DM_MMC_OPS +struct dm_mmc_ops { + /** + * send_cmd() - Send a command to the MMC device + * + * @dev: Device to receive the command + * @cmd: Command to send + * @data: Additional data to send/receive + * @return 0 if OK, -ve on error + */ + int (*send_cmd)(struct udevice *dev, struct mmc_cmd *cmd, + struct mmc_data *data); + + /** + * set_ios() - Set the I/O speed/width for an MMC device + * + * @dev: Device to update + * @return 0 if OK, -ve on error + */ + int (*set_ios)(struct udevice *dev); + + /** + * get_cd() - See whether a card is present + * + * @dev: Device to check + * @return 0 if not present, 1 if present, -ve on error + */ + int (*get_cd)(struct udevice *dev); + + /** + * get_wp() - See whether a card has write-protect enabled + * + * @dev: Device to check + * @return 0 if write-enabled, 1 if write-protected, -ve on error + */ + int (*get_wp)(struct udevice *dev); +}; + +#define mmc_get_ops(dev) ((struct dm_mmc_ops *)(dev)->driver->ops) + +int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, + struct mmc_data *data); +int dm_mmc_set_ios(struct udevice *dev); +int dm_mmc_get_cd(struct udevice *dev); +int dm_mmc_get_wp(struct udevice *dev); + +/* Transition functions for compatibility */ +int mmc_set_ios(struct mmc *mmc); +int mmc_getcd(struct mmc *mmc); +int mmc_getwp(struct mmc *mmc); + +#else struct mmc_ops { int (*send_cmd)(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data); @@ -330,10 +382,13 @@ struct mmc_ops { int (*getcd)(struct mmc *mmc); int (*getwp)(struct mmc *mmc); }; +#endif
struct mmc_config { const char *name; +#ifndef CONFIG_DM_MMC_OPS const struct mmc_ops *ops; +#endif uint host_caps; uint voltages; uint f_min; @@ -342,7 +397,12 @@ struct mmc_config { unsigned char part_type; };
-/* TODO struct mmc should be in mmc_private but it's hard to fix right now */ +/* + * With CONFIG_DM_MMC enabled, struct mmc can be accessed from the MMC device + * with mmc_get_mmc_dev(). + * + * TODO struct mmc should be in mmc_private but it's hard to fix right now + */ struct mmc { #ifndef CONFIG_BLK struct list_head link; @@ -445,10 +505,14 @@ void print_mmc_devices(char separator); int get_mmc_num(void); int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf, enum mmc_hwpart_conf_mode mode); + +#ifndef CONFIG_DM_MMC_OPS int mmc_getcd(struct mmc *mmc); int board_mmc_getcd(struct mmc *mmc); int mmc_getwp(struct mmc *mmc); int board_mmc_getwp(struct mmc *mmc); +#endif + int mmc_set_dsr(struct mmc *mmc, u16 val); /* Function to change the size of boot partition and rpmb partitions */ int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,

On 12 June 2016 at 23:30, Simon Glass sjg@chromium.org wrote:
The driver model conversion for MMC has moved in small steps. The first step was to have an MMC device (CONFIG_DM_MMC). The second was to use a child block device (CONFIG_BLK). The final one is to use driver model for MMC operations (CONFIG_DM_MMC_OP). Add support for this.
The immediate priority is to make all boards that use DM_MMC also use those other two options. This will allow them to be removed.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/mmc/Kconfig | 9 +++++++ drivers/mmc/mmc-uclass.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/mmc/mmc.c | 21 ++++++++++++--- include/mmc.h | 66 +++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 158 insertions(+), 4 deletions(-)
Applied to u-boot-dm/next.

Add support to dwmmc for using driver model for MMC operations.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/mmc/dw_mmc.c | 33 +++++++++++++++++++++++++++++++++ include/dwmmc.h | 9 +++++++++ 2 files changed, 42 insertions(+)
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 74a2663..3411f95 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -181,9 +181,16 @@ static int dwmci_set_transfer_mode(struct dwmci_host *host, return mode; }
+#ifdef CONFIG_DM_MMC_OPS +int dwmci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct mmc *mmc = mmc_get_mmc_dev(dev); +#else static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { +#endif struct dwmci_host *host = mmc->priv; ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac, data ? DIV_ROUND_UP(data->blocks, 8) : 0); @@ -373,8 +380,14 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) return 0; }
+#ifdef CONFIG_DM_MMC_OPS +int dwmci_set_ios(struct udevice *dev) +{ + struct mmc *mmc = mmc_get_mmc_dev(dev); +#else static void dwmci_set_ios(struct mmc *mmc) { +#endif struct dwmci_host *host = (struct dwmci_host *)mmc->priv; u32 ctype, regs;
@@ -405,6 +418,9 @@ static void dwmci_set_ios(struct mmc *mmc)
if (host->clksel) host->clksel(host); +#ifdef CONFIG_DM_MMC_OPS + return 0; +#endif }
static int dwmci_init(struct mmc *mmc) @@ -448,17 +464,34 @@ static int dwmci_init(struct mmc *mmc) return 0; }
+#ifdef CONFIG_DM_MMC_OPS +int dwmci_probe(struct udevice *dev) +{ + struct mmc *mmc = mmc_get_mmc_dev(dev); + + return dwmci_init(mmc); +} + +const struct dm_mmc_ops dm_dwmci_ops = { + .send_cmd = dwmci_send_cmd, + .set_ios = dwmci_set_ios, +}; + +#else static const struct mmc_ops dwmci_ops = { .send_cmd = dwmci_send_cmd, .set_ios = dwmci_set_ios, .init = dwmci_init, }; +#endif
void dwmci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth, uint caps, u32 max_clk, u32 min_clk) { cfg->name = name; +#ifndef CONFIG_DM_MMC_OPS cfg->ops = &dwmci_ops; +#endif cfg->f_min = min_clk; cfg->f_max = max_clk;
diff --git a/include/dwmmc.h b/include/dwmmc.h index 0199def..6aebe96 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -293,4 +293,13 @@ int dwmci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg); int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk); #endif /* !CONFIG_BLK */
+#ifdef CONFIG_DM_MMC_OPS +/* Export the operations to drivers */ +int dwmci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, + struct mmc_data *data); +int dwmci_set_ios(struct udevice *dev); +int dwmci_probe(struct udevice *dev); +extern const struct dm_mmc_ops dm_dwmci_ops; +#endif + #endif /* __DWMMC_HW_H */

On 12 June 2016 at 23:30, Simon Glass sjg@chromium.org wrote:
Add support to dwmmc for using driver model for MMC operations.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/mmc/dw_mmc.c | 33 +++++++++++++++++++++++++++++++++ include/dwmmc.h | 9 +++++++++ 2 files changed, 42 insertions(+)
Applied to u-boot-dm/next.

Enable this option to move rockchip over to use driver model for MMC operations.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/arm/Kconfig | 1 + drivers/mmc/rockchip_dw_mmc.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 85b4d31..1af9c35 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -831,6 +831,7 @@ config ARCH_ROCKCHIP select DM_GPIO select DM_I2C select DM_MMC + select DM_MMC_OPS select DM_SERIAL select DM_SPI select DM_SPI_FLASH diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c index d928b0b..65b9aba 100644 --- a/drivers/mmc/rockchip_dw_mmc.c +++ b/drivers/mmc/rockchip_dw_mmc.c @@ -113,7 +113,7 @@ static int rockchip_dwmmc_probe(struct udevice *dev) host->mmc->dev = dev; upriv->mmc = host->mmc;
- return 0; + return dwmci_probe(dev); }
static int rockchip_dwmmc_bind(struct udevice *dev) @@ -138,6 +138,7 @@ U_BOOT_DRIVER(rockchip_dwmmc_drv) = { .id = UCLASS_MMC, .of_match = rockchip_dwmmc_ids, .ofdata_to_platdata = rockchip_dwmmc_ofdata_to_platdata, + .ops = &dm_dwmci_ops, .bind = rockchip_dwmmc_bind, .probe = rockchip_dwmmc_probe, .priv_auto_alloc_size = sizeof(struct rockchip_dwmmc_priv),

On 12 June 2016 at 23:30, Simon Glass sjg@chromium.org wrote:
Enable this option to move rockchip over to use driver model for MMC operations.
Signed-off-by: Simon Glass sjg@chromium.org
arch/arm/Kconfig | 1 + drivers/mmc/rockchip_dw_mmc.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-)
Applied to u-boot-dm/next.

These boards should have maintainer entries. Add them.
Signed-off-by: Simon Glass sjg@chromium.org ---
board/evb_rk3036/evb_rk3036/MAINTAINERS | 6 ++++++ board/kylin/kylin_rk3036/MAINTAINERS | 6 ++++++ 2 files changed, 12 insertions(+)
diff --git a/board/evb_rk3036/evb_rk3036/MAINTAINERS b/board/evb_rk3036/evb_rk3036/MAINTAINERS index e69de29..152d31c 100644 --- a/board/evb_rk3036/evb_rk3036/MAINTAINERS +++ b/board/evb_rk3036/evb_rk3036/MAINTAINERS @@ -0,0 +1,6 @@ +EVB-RK3036 +M: huang lin hl@rock-chips.com +S: Maintained +F: board/evb/evb-rk3036 +F: include/configs/evb-rk3036.h +F: configs/evb-rk3036_defconfig diff --git a/board/kylin/kylin_rk3036/MAINTAINERS b/board/kylin/kylin_rk3036/MAINTAINERS index e69de29..f8ee834 100644 --- a/board/kylin/kylin_rk3036/MAINTAINERS +++ b/board/kylin/kylin_rk3036/MAINTAINERS @@ -0,0 +1,6 @@ +KYLIN-RK3036 +M: huang lin hl@rock-chips.com +S: Maintained +F: board/kylin/kylin-rk3036 +F: include/configs/kylin-rk3036.h +F: configs/kylin-rk3036_defconfig

On 12 June 2016 at 23:30, Simon Glass sjg@chromium.org wrote:
These boards should have maintainer entries. Add them.
Signed-off-by: Simon Glass sjg@chromium.org
board/evb_rk3036/evb_rk3036/MAINTAINERS | 6 ++++++ board/kylin/kylin_rk3036/MAINTAINERS | 6 ++++++ 2 files changed, 12 insertions(+)
Applied to u-boot-dm/next.

Update the sandbox MMC emulation to use driver model for MMC operations.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/Kconfig | 1 + configs/sandbox_defconfig | 4 ++-- drivers/mmc/sandbox_mmc.c | 17 ++++++----------- 3 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/arch/Kconfig b/arch/Kconfig index 566f044..c43787c 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -63,6 +63,7 @@ config SANDBOX select DM_I2C select DM_SPI select DM_GPIO + select DM_MMC
config SH bool "SuperH architecture" diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 71f7130..8777bb8 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -1,5 +1,4 @@ CONFIG_SYS_MALLOC_F_LEN=0x2000 -CONFIG_BLK=y CONFIG_MMC=y CONFIG_PCI=y CONFIG_DEFAULT_DEVICE_TREE="sandbox" @@ -71,6 +70,7 @@ CONFIG_DEVRES=y CONFIG_DEBUG_DEVRES=y CONFIG_ADC=y CONFIG_ADC_SANDBOX=y +CONFIG_BLK=y CONFIG_CLK=y CONFIG_CPU=y CONFIG_DM_DEMO=y @@ -101,7 +101,7 @@ CONFIG_CROS_EC_SPI=y CONFIG_PWRSEQ=y CONFIG_SPL_PWRSEQ=y CONFIG_SYSRESET=y -CONFIG_DM_MMC=y +CONFIG_DM_MMC_OPS=y CONFIG_SANDBOX_MMC=y CONFIG_SPI_FLASH_SANDBOX=y CONFIG_SPI_FLASH=y diff --git a/drivers/mmc/sandbox_mmc.c b/drivers/mmc/sandbox_mmc.c index 7da059c..5f1333b 100644 --- a/drivers/mmc/sandbox_mmc.c +++ b/drivers/mmc/sandbox_mmc.c @@ -25,7 +25,7 @@ struct sandbox_mmc_plat { * This emulate an SD card version 2. Single-block reads result in zero data. * Multiple-block reads return a test string. */ -static int sandbox_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, +static int sandbox_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data *data) { switch (cmd->cmdidx) { @@ -85,25 +85,20 @@ static int sandbox_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, return 0; }
-static void sandbox_mmc_set_ios(struct mmc *mmc) -{ -} - -static int sandbox_mmc_init(struct mmc *mmc) +static int sandbox_mmc_set_ios(struct udevice *dev) { return 0; }
-static int sandbox_mmc_getcd(struct mmc *mmc) +static int sandbox_mmc_get_cd(struct udevice *dev) { return 1; }
-static const struct mmc_ops sandbox_mmc_ops = { +static const struct dm_mmc_ops sandbox_mmc_ops = { .send_cmd = sandbox_mmc_send_cmd, .set_ios = sandbox_mmc_set_ios, - .init = sandbox_mmc_init, - .getcd = sandbox_mmc_getcd, + .get_cd = sandbox_mmc_get_cd, };
int sandbox_mmc_probe(struct udevice *dev) @@ -120,7 +115,6 @@ int sandbox_mmc_bind(struct udevice *dev) int ret;
cfg->name = dev->name; - cfg->ops = &sandbox_mmc_ops; cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_8BIT; cfg->voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34; cfg->f_min = 1000000; @@ -150,6 +144,7 @@ U_BOOT_DRIVER(mmc_sandbox) = { .name = "mmc_sandbox", .id = UCLASS_MMC, .of_match = sandbox_mmc_ids, + .ops = &sandbox_mmc_ops, .bind = sandbox_mmc_bind, .unbind = sandbox_mmc_unbind, .probe = sandbox_mmc_probe,

On 12 June 2016 at 23:30, Simon Glass sjg@chromium.org wrote:
Update the sandbox MMC emulation to use driver model for MMC operations.
Signed-off-by: Simon Glass sjg@chromium.org
arch/Kconfig | 1 + configs/sandbox_defconfig | 4 ++-- drivers/mmc/sandbox_mmc.c | 17 ++++++----------- 3 files changed, 9 insertions(+), 13 deletions(-)
Applied to u-boot-dm/next.

Move the configuration setting into a separate function which can be used by the driver-model code.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/mmc/sdhci.c | 107 +++++++++++++++++++++++++++++----------------------- 1 file changed, 59 insertions(+), 48 deletions(-)
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 5c71ab8..6e786c8 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -9,6 +9,7 @@ */
#include <common.h> +#include <errno.h> #include <malloc.h> #include <mmc.h> #include <sdhci.h> @@ -478,73 +479,83 @@ static const struct mmc_ops sdhci_ops = { .init = sdhci_init, };
-int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) +int sdhci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth, + uint caps, u32 max_clk, u32 min_clk, uint version, + uint quirks, uint host_caps) { - unsigned int caps; - - host->cfg.name = host->name; - host->cfg.ops = &sdhci_ops; - - caps = sdhci_readl(host, SDHCI_CAPABILITIES); -#ifdef CONFIG_MMC_SDMA - if (!(caps & SDHCI_CAN_DO_SDMA)) { - printf("%s: Your controller doesn't support SDMA!!\n", - __func__); - return -1; - } + cfg->name = name; +#ifndef CONFIG_DM_MMC_OPS + cfg->ops = &sdhci_ops; #endif - if (max_clk) - host->cfg.f_max = max_clk; + cfg->f_max = max_clk; else { - if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) - host->cfg.f_max = (caps & SDHCI_CLOCK_V3_BASE_MASK) - >> SDHCI_CLOCK_BASE_SHIFT; + if (version >= SDHCI_SPEC_300) + cfg->f_max = (caps & SDHCI_CLOCK_V3_BASE_MASK) >> + SDHCI_CLOCK_BASE_SHIFT; else - host->cfg.f_max = (caps & SDHCI_CLOCK_BASE_MASK) - >> SDHCI_CLOCK_BASE_SHIFT; - host->cfg.f_max *= 1000000; - } - if (host->cfg.f_max == 0) { - printf("%s: Hardware doesn't specify base clock frequency\n", - __func__); - return -1; + cfg->f_max = (caps & SDHCI_CLOCK_BASE_MASK) >> + SDHCI_CLOCK_BASE_SHIFT; + cfg->f_max *= 1000000; } + if (cfg->f_max == 0) + return -EINVAL; if (min_clk) - host->cfg.f_min = min_clk; + cfg->f_min = min_clk; else { - if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) - host->cfg.f_min = host->cfg.f_max / - SDHCI_MAX_DIV_SPEC_300; + if (version >= SDHCI_SPEC_300) + cfg->f_min = cfg->f_max / SDHCI_MAX_DIV_SPEC_300; else - host->cfg.f_min = host->cfg.f_max / - SDHCI_MAX_DIV_SPEC_200; + cfg->f_min = cfg->f_max / SDHCI_MAX_DIV_SPEC_200; } - - host->cfg.voltages = 0; + cfg->voltages = 0; if (caps & SDHCI_CAN_VDD_330) - host->cfg.voltages |= MMC_VDD_32_33 | MMC_VDD_33_34; + cfg->voltages |= MMC_VDD_32_33 | MMC_VDD_33_34; if (caps & SDHCI_CAN_VDD_300) - host->cfg.voltages |= MMC_VDD_29_30 | MMC_VDD_30_31; + cfg->voltages |= MMC_VDD_29_30 | MMC_VDD_30_31; if (caps & SDHCI_CAN_VDD_180) - host->cfg.voltages |= MMC_VDD_165_195; + cfg->voltages |= MMC_VDD_165_195;
- if (host->quirks & SDHCI_QUIRK_BROKEN_VOLTAGE) - host->cfg.voltages |= host->voltages; - - host->cfg.host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT; - if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) { + cfg->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT; + if (version >= SDHCI_SPEC_300) { if (caps & SDHCI_CAN_DO_8BIT) - host->cfg.host_caps |= MMC_MODE_8BIT; + cfg->host_caps |= MMC_MODE_8BIT; }
- if (host->quirks & SDHCI_QUIRK_NO_HISPD_BIT) - host->cfg.host_caps &= ~(MMC_MODE_HS | MMC_MODE_HS_52MHz); + if (quirks & SDHCI_QUIRK_NO_HISPD_BIT) + cfg->host_caps &= ~(MMC_MODE_HS | MMC_MODE_HS_52MHz); + + if (host_caps) + cfg->host_caps |= host_caps;
- if (host->host_caps) - host->cfg.host_caps |= host->host_caps; + cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
- host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; + return 0; +} + +int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) +{ + unsigned int caps; + + caps = sdhci_readl(host, SDHCI_CAPABILITIES); +#ifdef CONFIG_MMC_SDMA + if (!(caps & SDHCI_CAN_DO_SDMA)) { + printf("%s: Your controller doesn't support SDMA!!\n", + __func__); + return -1; + } +#endif + + if (sdhci_setup_cfg(&host->cfg, host->name, host->bus_width, caps, + max_clk, min_clk, SDHCI_GET_VERSION(host), + host->quirks, host->host_caps)) { + printf("%s: Hardware doesn't specify base clock frequency\n", + __func__); + return -EINVAL; + } + + if (host->quirks & SDHCI_QUIRK_BROKEN_VOLTAGE) + host->cfg.voltages |= host->voltages;
sdhci_reset(host, SDHCI_RESET_ALL);

On 12 June 2016 at 23:30, Simon Glass sjg@chromium.org wrote:
Move the configuration setting into a separate function which can be used by the driver-model code.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/mmc/sdhci.c | 107 +++++++++++++++++++++++++++++----------------------- 1 file changed, 59 insertions(+), 48 deletions(-)
Applied to u-boot-dm/next.

Add support for using driver model for block devices and MMC operations in this driver.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/mmc/sdhci.c | 40 ++++++++++++++++++++++++++- include/sdhci.h | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 6e786c8..7d43f71 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -129,9 +129,17 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data, #endif #define CONFIG_SDHCI_CMD_DEFAULT_TIMEOUT 100
+#ifdef CONFIG_DM_MMC_OPS +static int sdhci_send_command(struct udevice *dev, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct mmc *mmc = mmc_get_mmc_dev(dev); + +#else static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) + struct mmc_data *data) { +#endif struct sdhci_host *host = mmc->priv; unsigned int stat = 0; int ret = 0; @@ -389,8 +397,14 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); }
+#ifdef CONFIG_DM_MMC_OPS +static int sdhci_set_ios(struct udevice *dev) +{ + struct mmc *mmc = mmc_get_mmc_dev(dev); +#else static void sdhci_set_ios(struct mmc *mmc) { +#endif u32 ctrl; struct sdhci_host *host = mmc->priv;
@@ -426,6 +440,9 @@ static void sdhci_set_ios(struct mmc *mmc) ctrl &= ~SDHCI_CTRL_HISPD;
sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); +#ifdef CONFIG_DM_MMC_OPS + return 0; +#endif }
static int sdhci_init(struct mmc *mmc) @@ -472,12 +489,25 @@ static int sdhci_init(struct mmc *mmc) return 0; }
+#ifdef CONFIG_DM_MMC_OPS +int sdhci_probe(struct udevice *dev) +{ + struct mmc *mmc = mmc_get_mmc_dev(dev); + + return sdhci_init(mmc); +}
+const struct dm_mmc_ops sdhci_ops = { + .send_cmd = sdhci_send_command, + .set_ios = sdhci_set_ios, +}; +#else static const struct mmc_ops sdhci_ops = { .send_cmd = sdhci_send_command, .set_ios = sdhci_set_ios, .init = sdhci_init, }; +#endif
int sdhci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth, uint caps, u32 max_clk, u32 min_clk, uint version, @@ -528,11 +558,18 @@ int sdhci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth, if (host_caps) cfg->host_caps |= host_caps;
+ cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
return 0; }
+#ifdef CONFIG_BLK +int sdhci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg) +{ + return mmc_bind(dev, mmc, cfg); +} +#else int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) { unsigned int caps; @@ -567,3 +604,4 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
return 0; } +#endif diff --git a/include/sdhci.h b/include/sdhci.h index e0f6667..c4d3b55 100644 --- a/include/sdhci.h +++ b/include/sdhci.h @@ -338,5 +338,85 @@ static inline u8 sdhci_readb(struct sdhci_host *host, int reg) } #endif
+#ifdef CONFIG_BLK +/** + * sdhci_setup_cfg() - Set up the configuration for DWMMC + * + * This is used to set up an SDHCI device when you are using CONFIG_BLK. + * + * This should be called from your MMC driver's probe() method once you have + * the information required. + * + * Generally your driver will have a platform data structure which holds both + * the configuration (struct mmc_config) and the MMC device info (struct mmc). + * For example: + * + * struct msm_sdhc_plat { + * struct mmc_config cfg; + * struct mmc mmc; + * }; + * + * ... + * + * Inside U_BOOT_DRIVER(): + * .platdata_auto_alloc_size = sizeof(struct msm_sdhc_plat), + * + * To access platform data: + * struct msm_sdhc_plat *plat = dev_get_platdata(dev); + * + * See msm_sdhci.c for an example. + * + * @cfg: Configuration structure to fill in (generally &plat->mmc) + * @name: Device name (normally dev->name) + * @buswidth: Bus width (in bits, such as 4 or 8) + * @caps: Host capabilities (MMC_MODE_...) + * @max_clk: Maximum supported clock speed in HZ (0 for default) + * @min_clk: Minimum supported clock speed in HZ (0 for default) + * @version: Host controller version (generally read from the + * SDHCI_HOST_VERSION register) + * @quirks: Quick flags (SDHCI_QUIRK_...) + * @host_caps: Additional host capabilities (0 if none) + */ +int sdhci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth, + uint caps, u32 max_clk, u32 min_clk, uint version, + uint quirks, uint host_caps); + +/** + * sdhci_bind() - Set up a new MMC block device + * + * This is used to set up an SDHCI block device when you are using CONFIG_BLK. + * It should be called from your driver's bind() method. + * + * See msm_sdhci.c for an example. + * + * @dev: Device to set up + * @mmc: Pointer to mmc structure (normally &plat->mmc) + * @cfg: Empty configuration structure (generally &plat->cfg). This is + * normally all zeroes at this point. The only purpose of passing + * this in is to set mmc->cfg to it. + * @return 0 if OK, -ve if the block device could not be created + */ +int sdhci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg); +#else + +/** + * add_sdhci() - Add a new SDHCI interface + * + * This is used when you are not using CONFIG_BLK. Convert your driver over! + * + * @host: SDHCI host structure + * @max_clk: Maximum supported clock speed in HZ (0 for default) + * @min_clk: Minimum supported clock speed in HZ (0 for default) + * @return 0 if OK, -ve on error + */ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk); +#endif /* !CONFIG_BLK */ + +#ifdef CONFIG_DM_MMC_OPS +/* Export the operations to drivers */ +int sdhci_probe(struct udevice *dev); +extern const struct dm_mmc_ops sdhci_ops; +#else +#endif + #endif /* __SDHCI_HW_H */

On 12 June 2016 at 23:30, Simon Glass sjg@chromium.org wrote:
Add support for using driver model for block devices and MMC operations in this driver.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/mmc/sdhci.c | 40 ++++++++++++++++++++++++++- include/sdhci.h | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+), 1 deletion(-)
Applied to u-boot-dm/next.

Add support for using driver model for block devices and MMC operations in this driver.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/mmc/msm_sdhci.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c index 1e2a29b..150adf0 100644 --- a/drivers/mmc/msm_sdhci.c +++ b/drivers/mmc/msm_sdhci.c @@ -36,6 +36,11 @@ /* Non standard (?) SDHCI register */ #define SDHCI_VENDOR_SPEC_CAPABILITIES0 0x11c
+struct msm_sdhc_plat { + struct mmc_config cfg; + struct mmc mmc; +}; + struct msm_sdhc { struct sdhci_host host; void *base; @@ -74,9 +79,14 @@ static int msm_sdc_clk_init(struct udevice *dev)
static int msm_sdc_probe(struct udevice *dev) { + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); +#ifdef CONFIG_BLK + struct msm_sdhc_plat *plat = dev_get_platdata(dev); +#endif struct msm_sdhc *prv = dev_get_priv(dev); struct sdhci_host *host = &prv->host; u32 core_version, core_minor, core_major; + u32 caps; int ret;
host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_BROKEN_R1B; @@ -120,7 +130,7 @@ static int msm_sdc_probe(struct udevice *dev) * controller versions and must be explicitly enabled. */ if (core_major >= 1 && core_minor != 0x11 && core_minor != 0x12) { - u32 caps = readl(host->ioaddr + SDHCI_CAPABILITIES); + caps = readl(host->ioaddr + SDHCI_CAPABILITIES); caps |= SDHCI_CAN_VDD_300 | SDHCI_CAN_DO_8BIT; writel(caps, host->ioaddr + SDHCI_VENDOR_SPEC_CAPABILITIES0); } @@ -128,8 +138,26 @@ static int msm_sdc_probe(struct udevice *dev) /* Set host controller version */ host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
+#ifdef CONFIG_BLK + caps = sdhci_readl(host, SDHCI_CAPABILITIES); + ret = sdhci_setup_cfg(&plat->cfg, dev->name, host->bus_width, + caps, 0, 0, host->version, host->quirks, 0); + host->mmc = &plat->mmc; +#else /* automatically detect max and min speed */ - return add_sdhci(host, 0, 0); + ret = add_sdhci(host, 0, 0); +#endif + if (ret) + return ret; + host->mmc->priv = &prv->host; + host->mmc->dev = dev; + upriv->mmc = host->mmc; + +#ifdef CONFIG_DM_MMC_OPS + return sdhci_probe(dev); +#else + return 0; +#endif }
static int msm_sdc_remove(struct udevice *dev) @@ -164,6 +192,20 @@ static int msm_ofdata_to_platdata(struct udevice *dev) return 0; }
+static int msm_sdc_bind(struct udevice *dev) +{ +#ifdef CONFIG_BLK + struct msm_sdhc_plat *plat = dev_get_platdata(dev); + int ret; + + ret = sdhci_bind(dev, &plat->mmc, &plat->cfg); + if (ret) + return ret; +#endif + + return 0; +} + static const struct udevice_id msm_mmc_ids[] = { { .compatible = "qcom,sdhci-msm-v4" }, { } @@ -174,7 +216,12 @@ U_BOOT_DRIVER(msm_sdc_drv) = { .id = UCLASS_MMC, .of_match = msm_mmc_ids, .ofdata_to_platdata = msm_ofdata_to_platdata, +#ifdef CONFIG_DM_MMC_OPS + .ops = &sdhci_ops, +#endif + .bind = msm_sdc_bind, .probe = msm_sdc_probe, .remove = msm_sdc_remove, .priv_auto_alloc_size = sizeof(struct msm_sdhc), + .platdata_auto_alloc_size = sizeof(struct msm_sdhc_plat), };

On 12 June 2016 at 23:30, Simon Glass sjg@chromium.org wrote:
Add support for using driver model for block devices and MMC operations in this driver.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/mmc/msm_sdhci.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-)
Applied to u-boot-dm/next.

Update this board to use driver model for block devices and MMC operations.
Signed-off-by: Simon Glass sjg@chromium.org ---
configs/dragonboard410c_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig index 37c5ea77..ad2e8b8 100644 --- a/configs/dragonboard410c_defconfig +++ b/configs/dragonboard410c_defconfig @@ -18,6 +18,7 @@ CONFIG_CMD_EXT2=y CONFIG_CMD_EXT4=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y +CONFIG_BLK=y CONFIG_CLK=y CONFIG_MSM_GPIO=y CONFIG_PM8916_GPIO=y @@ -25,6 +26,7 @@ CONFIG_LED=y CONFIG_LED_GPIO=y CONFIG_SYSRESET=y CONFIG_DM_MMC=y +CONFIG_DM_MMC_OPS=y CONFIG_MSM_SDHCI=y CONFIG_DM_PMIC=y CONFIG_PMIC_PM8916=y

On 12 June 2016 at 23:30, Simon Glass sjg@chromium.org wrote:
Update this board to use driver model for block devices and MMC operations.
Signed-off-by: Simon Glass sjg@chromium.org
configs/dragonboard410c_defconfig | 2 ++ 1 file changed, 2 insertions(+)
Applied to u-boot-dm/next.

Now that we have fully moved to driver model, drop the old code.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/mmc/Kconfig | 2 +- drivers/mmc/msm_sdhci.c | 15 --------------- 2 files changed, 1 insertion(+), 16 deletions(-)
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index b9662f9..79cf18f 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -27,7 +27,7 @@ config DM_MMC_OPS
config MSM_SDHCI bool "Qualcomm SDHCI controller" - depends on DM_MMC + depends on DM_MMC && BLK && DM_MMC_OPS help Enables support for SDHCI 2.0 controller present on some Qualcomm Snapdragon devices. This device is compatible with eMMC v4.5 and diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c index 150adf0..4bc402c 100644 --- a/drivers/mmc/msm_sdhci.c +++ b/drivers/mmc/msm_sdhci.c @@ -80,9 +80,7 @@ static int msm_sdc_clk_init(struct udevice *dev) static int msm_sdc_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); -#ifdef CONFIG_BLK struct msm_sdhc_plat *plat = dev_get_platdata(dev); -#endif struct msm_sdhc *prv = dev_get_priv(dev); struct sdhci_host *host = &prv->host; u32 core_version, core_minor, core_major; @@ -138,26 +136,17 @@ static int msm_sdc_probe(struct udevice *dev) /* Set host controller version */ host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
-#ifdef CONFIG_BLK caps = sdhci_readl(host, SDHCI_CAPABILITIES); ret = sdhci_setup_cfg(&plat->cfg, dev->name, host->bus_width, caps, 0, 0, host->version, host->quirks, 0); host->mmc = &plat->mmc; -#else - /* automatically detect max and min speed */ - ret = add_sdhci(host, 0, 0); -#endif if (ret) return ret; host->mmc->priv = &prv->host; host->mmc->dev = dev; upriv->mmc = host->mmc;
-#ifdef CONFIG_DM_MMC_OPS return sdhci_probe(dev); -#else - return 0; -#endif }
static int msm_sdc_remove(struct udevice *dev) @@ -194,14 +183,12 @@ static int msm_ofdata_to_platdata(struct udevice *dev)
static int msm_sdc_bind(struct udevice *dev) { -#ifdef CONFIG_BLK struct msm_sdhc_plat *plat = dev_get_platdata(dev); int ret;
ret = sdhci_bind(dev, &plat->mmc, &plat->cfg); if (ret) return ret; -#endif
return 0; } @@ -216,9 +203,7 @@ U_BOOT_DRIVER(msm_sdc_drv) = { .id = UCLASS_MMC, .of_match = msm_mmc_ids, .ofdata_to_platdata = msm_ofdata_to_platdata, -#ifdef CONFIG_DM_MMC_OPS .ops = &sdhci_ops, -#endif .bind = msm_sdc_bind, .probe = msm_sdc_probe, .remove = msm_sdc_remove,

On 12 June 2016 at 23:30, Simon Glass sjg@chromium.org wrote:
Now that we have fully moved to driver model, drop the old code.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/mmc/Kconfig | 2 +- drivers/mmc/msm_sdhci.c | 15 --------------- 2 files changed, 1 insertion(+), 16 deletions(-)
Applied to u-boot-dm/next.

Update the method of accessing the block device so that it works with CONFIG_BLK enabled.
Signed-off-by: Simon Glass sjg@chromium.org ---
common/spl/spl_mmc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index ef8583a..4c60bf6 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -184,7 +184,7 @@ static int mmc_load_image_raw_os(struct mmc *mmc) unsigned long count; int ret;
- count = mmc->block_dev.block_read(&mmc->block_dev, + count = blk_dread(mmc_get_blk_desc(mmc), CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR, CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS, (void *) CONFIG_SYS_SPL_ARGS_ADDR); @@ -225,13 +225,13 @@ int spl_mmc_do_fs_boot(struct mmc *mmc)
#ifdef CONFIG_SPL_FAT_SUPPORT if (!spl_start_uboot()) { - err = spl_load_image_fat_os(&mmc->block_dev, + err = spl_load_image_fat_os(mmc_get_blk_desc(mmc), CONFIG_SYS_MMCSD_FS_BOOT_PARTITION); if (!err) return err; } #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME - err = spl_load_image_fat(&mmc->block_dev, + err = spl_load_image_fat(mmc_get_blk_desc(mmc), CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); if (!err)

On 12 June 2016 at 23:30, Simon Glass sjg@chromium.org wrote:
Update the method of accessing the block device so that it works with CONFIG_BLK enabled.
Signed-off-by: Simon Glass sjg@chromium.org
common/spl/spl_mmc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
Applied to u-boot-dm/next.

Update the method of accessing the block device so that it works with CONFIG_BLK enabled.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/dfu/dfu_mmc.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c index 78724e4..926ccbd 100644 --- a/drivers/dfu/dfu_mmc.c +++ b/drivers/dfu/dfu_mmc.c @@ -49,7 +49,7 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu, }
if (dfu->data.mmc.hw_partition >= 0) { - part_num_bkp = mmc->block_dev.hwpart; + part_num_bkp = mmc_get_blk_desc(mmc)->hwpart; ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dfu->data.mmc.dev_num, dfu->data.mmc.hw_partition); @@ -62,12 +62,11 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu, dfu->data.mmc.dev_num, blk_start, blk_count, buf); switch (op) { case DFU_OP_READ: - n = mmc->block_dev.block_read(&mmc->block_dev, blk_start, - blk_count, buf); + n = blk_dread(mmc_get_blk_desc(mmc), blk_start, blk_count, buf); break; case DFU_OP_WRITE: - n = mmc->block_dev.block_write(&mmc->block_dev, blk_start, - blk_count, buf); + n = blk_dwrite(mmc_get_blk_desc(mmc), blk_start, blk_count, + buf); break; default: error("Operation not supported\n"); @@ -356,7 +355,7 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr, char *s)
} else if (!strcmp(entity_type, "part")) { disk_partition_t partinfo; - struct blk_desc *blk_dev = &mmc->block_dev; + struct blk_desc *blk_dev = mmc_get_blk_desc(mmc); int mmcdev = second_arg; int mmcpart = third_arg;

On 12 June 2016 at 23:30, Simon Glass sjg@chromium.org wrote:
Update the method of accessing the block device so that it works with CONFIG_BLK enabled.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/dfu/dfu_mmc.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
Applied to u-boot-dm/next.

This corrects a build error on zynqmp.
Signed-off-by: Simon Glass sjg@chromium.odrg Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/net/phy/marvell.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index d2e68d4..8de0574 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -8,6 +8,7 @@ */ #include <config.h> #include <common.h> +#include <errno.h> #include <phy.h>
#define PHY_AUTONEGOTIATE_TIMEOUT 5000

Hi Simon,
On Mon, Jun 13, 2016 at 12:30 AM, Simon Glass sjg@chromium.org wrote:
This corrects a build error on zynqmp.
Signed-off-by: Simon Glass sjg@chromium.odrg Signed-off-by: Simon Glass sjg@chromium.org
drivers/net/phy/marvell.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index d2e68d4..8de0574 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -8,6 +8,7 @@ */ #include <config.h> #include <common.h> +#include <errno.h> #include <phy.h>
Maybe we can go ahead and apply this:
https://patchwork.ozlabs.org/patch/605766/
Otherwise,
Acked-by: Joe Hershberger joe.hershberger@ni.com

On 13.6.2016 20:21, Joe Hershberger wrote:
Hi Simon,
On Mon, Jun 13, 2016 at 12:30 AM, Simon Glass sjg@chromium.org wrote:
This corrects a build error on zynqmp.
Signed-off-by: Simon Glass sjg@chromium.odrg
Maybe fix this address too.
Thanks, Michal

Hi Joe,
On 13 June 2016 at 12:21, Joe Hershberger joe.hershberger@gmail.com wrote:
Hi Simon,
On Mon, Jun 13, 2016 at 12:30 AM, Simon Glass sjg@chromium.org wrote:
This corrects a build error on zynqmp.
Signed-off-by: Simon Glass sjg@chromium.odrg Signed-off-by: Simon Glass sjg@chromium.org
drivers/net/phy/marvell.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index d2e68d4..8de0574 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -8,6 +8,7 @@ */ #include <config.h> #include <common.h> +#include <errno.h> #include <phy.h>
Maybe we can go ahead and apply this:
That seems reasonable to me. I like splitting headers up, but this one seems pretty fundamental.
Otherwise,
Acked-by: Joe Hershberger joe.hershberger@ni.com
Regards, Simon

This is needed to support driver-model conversion of USB and block devices.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/arm/cpu/armv8/zynqmp/Kconfig | 4 ++++ arch/arm/mach-zynq/Kconfig | 3 +++ 2 files changed, 7 insertions(+)
diff --git a/arch/arm/cpu/armv8/zynqmp/Kconfig b/arch/arm/cpu/armv8/zynqmp/Kconfig index 6c71d78..ed3305d 100644 --- a/arch/arm/cpu/armv8/zynqmp/Kconfig +++ b/arch/arm/cpu/armv8/zynqmp/Kconfig @@ -20,4 +20,8 @@ config SYS_CONFIG_NAME config ZYNQMP_USB bool "Configure ZynqMP USB"
+config SYS_MALLOC_F_LEN + default 0x600 + + endif diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig index db3c579..a982320 100644 --- a/arch/arm/mach-zynq/Kconfig +++ b/arch/arm/mach-zynq/Kconfig @@ -17,4 +17,7 @@ config SYS_CONFIG_NAME Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header will be used for board configuration.
+config SYS_MALLOC_F_LEN + default 0x600 + endif

Convert zynq USB to driver model. It does not actually work, but the error is similar.
Before:
Zynq> dm tree Class Probed Name ---------------------------------------- root [ + ] root_driver rsa_mod_exp [ ] |-- mod_exp_sw simple_bus [ + ] `-- amba gpio [ ] |-- gpio@e000a000 serial [ + ] |-- serial@e0001000 spi [ + ] |-- spi@e000d000 spi_flash [ ] | `-- spi_flash@0:0 eth [ + ] |-- ethernet@e000b000 mmc [ + ] |-- sdhci@e0100000 simple_bus [ ] `-- slcr@f8000000 Zynq> usb start starting USB... USB0: USB EHCI 1.00 scanning bus 0 for devices... 2 USB Device(s) found USB1: usb1 wrong num MIO: 0, Index 1 lowlevel init failed scanning usb for storage devices... 0 Storage Device(s) found Zynq>
After:
Zynq> dm tree Class Probed Name ---------------------------------------- root [ + ] root_driver rsa_mod_exp [ ] |-- mod_exp_sw simple_bus [ + ] `-- amba gpio [ ] |-- gpio@e000a000 serial [ + ] |-- serial@e0001000 spi [ + ] |-- spi@e000d000 spi_flash [ ] | `-- spi_flash@0:0 eth [ + ] |-- ethernet@e000b000 mmc [ + ] |-- sdhci@e0100000 blk [ + ] | `-- sdhci@e0100000.blk simple_bus [ ] |-- slcr@f8000000 usb [ + ] `-- usb@e0002000 Zynq> usb start starting USB... USB0: USB EHCI 1.00 scanning bus 0 for devices... Error: Cannot find high speed parent of usb-1 device EHCI timed out on TD - token=0x80008c80 unable to get device descriptor (error=-1) failed, error -1 Zynq>
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/arm/Kconfig | 2 + drivers/usb/host/ehci-zynq.c | 102 +++++++++++++++++++++---------------------- 2 files changed, 52 insertions(+), 52 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1af9c35..2b501eb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -643,6 +643,7 @@ config ARCH_ZYNQ select DM_SERIAL select DM_SPI_FLASH select SPL_SEPARATE_BSS if SPL + select DM_USB
config ARCH_ZYNQMP bool "Support Xilinx ZynqMP Platform" @@ -651,6 +652,7 @@ config ARCH_ZYNQMP select OF_CONTROL select DM_SERIAL select SUPPORT_SPL + select DM_USB
config TEGRA bool "NVIDIA Tegra" diff --git a/drivers/usb/host/ehci-zynq.c b/drivers/usb/host/ehci-zynq.c index 37a7935..b45c68d 100644 --- a/drivers/usb/host/ehci-zynq.c +++ b/drivers/usb/host/ehci-zynq.c @@ -7,55 +7,47 @@ */
#include <common.h> +#include <dm.h> +#include <usb.h> #include <asm/arch/hardware.h> #include <asm/arch/sys_proto.h> #include <asm/io.h> -#include <usb.h> #include <usb/ehci-ci.h> #include <usb/ulpi.h>
#include "ehci.h"
-#define ZYNQ_USB_USBCMD_RST 0x0000002 -#define ZYNQ_USB_USBCMD_STOP 0x0000000 -#define ZYNQ_USB_NUM_MIO 12 +struct zynq_ehci_priv { + struct usb_ehci *ehci; +};
-/* - * Create the appropriate control structures to manage - * a new EHCI host controller. - */ -int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, - struct ehci_hcor **hcor) +static int ehci_zynq_ofdata_to_platdata(struct udevice *dev) { - struct usb_ehci *ehci; + struct zynq_ehci_priv *priv = dev_get_priv(dev); + + priv->ehci = (struct usb_ehci *)dev_get_addr_ptr(dev); + if (!priv->ehci) + return -EINVAL; + + return 0; +} + +static int ehci_zynq_probe(struct udevice *dev) +{ + struct usb_platdata *plat = dev_get_platdata(dev); + struct zynq_ehci_priv *priv = dev_get_priv(dev); + struct ehci_hccr *hccr; + struct ehci_hcor *hcor; struct ulpi_viewport ulpi_vp; - int ret, mio_usb; /* Used for writing the ULPI data address */ struct ulpi_regs *ulpi = (struct ulpi_regs *)0; + int ret;
- if (!index) { - mio_usb = zynq_slcr_get_mio_pin_status("usb0"); - if (mio_usb != ZYNQ_USB_NUM_MIO) { - printf("usb0 wrong num MIO: %d, Index %d\n", mio_usb, - index); - return -1; - } - ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR0; - } else { - mio_usb = zynq_slcr_get_mio_pin_status("usb1"); - if (mio_usb != ZYNQ_USB_NUM_MIO) { - printf("usb1 wrong num MIO: %d, Index %d\n", mio_usb, - index); - return -1; - } - ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR1; - } - - *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength); - *hcor = (struct ehci_hcor *)((uint32_t) *hccr + - HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); + hccr = (struct ehci_hccr *)((uint32_t)&priv->ehci->caplength); + hcor = (struct ehci_hcor *)((uint32_t) hccr + + HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
- ulpi_vp.viewport_addr = (u32)&ehci->ulpi_viewpoint; + ulpi_vp.viewport_addr = (u32)&priv->ehci->ulpi_viewpoint; ulpi_vp.port_num = 0;
ret = ulpi_init(&ulpi_vp); @@ -77,28 +69,34 @@ int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, ulpi_write(&ulpi_vp, &ulpi->otg_ctrl_set, ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
- return 0; + return ehci_register(dev, hccr, hcor, NULL, 0, plat->init_type); }
-/* - * Destroy the appropriate control structures corresponding - * the the EHCI host controller. - */ -int ehci_hcd_stop(int index) +static int ehci_zynq_remove(struct udevice *dev) { - struct usb_ehci *ehci; - - if (!index) - ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR0; - else - ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR1; + int ret;
- /* Stop controller */ - writel(ZYNQ_USB_USBCMD_STOP, &ehci->usbcmd); - udelay(1000); - - /* Initiate controller reset */ - writel(ZYNQ_USB_USBCMD_RST, &ehci->usbcmd); + ret = ehci_deregister(dev); + if (ret) + return ret;
return 0; } + +static const struct udevice_id ehci_zynq_ids[] = { + { .compatible = "xlnx,zynq-usb-2.20a" }, + { } +}; + +U_BOOT_DRIVER(ehci_zynq) = { + .name = "ehci_zynq", + .id = UCLASS_USB, + .of_match = ehci_zynq_ids, + .ofdata_to_platdata = ehci_zynq_ofdata_to_platdata, + .probe = ehci_zynq_probe, + .remove = ehci_zynq_remove, + .ops = &ehci_usb_ops, + .platdata_auto_alloc_size = sizeof(struct usb_platdata), + .priv_auto_alloc_size = sizeof(struct zynq_ehci_priv), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +};

Hi Simon,
2016-06-13 7:30 GMT+02:00 Simon Glass sjg@chromium.org:
Convert zynq USB to driver model. It does not actually work, but the error is similar.
The first one is working. That low level init failed is there because there are two usb controllers and one is not wired. If you put usb stick to zybo you will see storage device there.
That's why this patch is breaking usb support.
Thanks, Michal

Hi Simon,
-----Original Message----- From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Simon Glass Sent: Monday, June 13, 2016 11:01 AM To: U-Boot Mailing List u-boot@lists.denx.de Cc: Marek Vasut marex@denx.de Subject: [U-Boot] [PATCH 24/27] dm: zynq: usb: Convert to CONFIG_DM_USB
Convert zynq USB to driver model. It does not actually work, but the error is similar.
Before:
Zynq> dm tree Class Probed Name
root [ + ] root_driver rsa_mod_exp [ ] |-- mod_exp_sw simple_bus [ + ] `-- amba gpio [ ] |-- gpio@e000a000 serial [ + ] |-- serial@e0001000 spi [ + ] |-- spi@e000d000 spi_flash [ ] | `-- spi_flash@0:0 eth [ + ] |-- ethernet@e000b000 mmc [ + ] |-- sdhci@e0100000 simple_bus [ ] `-- slcr@f8000000 Zynq> usb start starting USB... USB0: USB EHCI 1.00 scanning bus 0 for devices... 2 USB Device(s) found USB1: usb1 wrong num MIO: 0, Index 1 lowlevel init failed scanning usb for storage devices... 0 Storage Device(s) found Zynq>
After:
Zynq> dm tree Class Probed Name
root [ + ] root_driver rsa_mod_exp [ ] |-- mod_exp_sw simple_bus [ + ] `-- amba gpio [ ] |-- gpio@e000a000 serial [ + ] |-- serial@e0001000 spi [ + ] |-- spi@e000d000 spi_flash [ ] | `-- spi_flash@0:0 eth [ + ] |-- ethernet@e000b000 mmc [ + ] |-- sdhci@e0100000 blk [ + ] | `-- sdhci@e0100000.blk simple_bus [ ] |-- slcr@f8000000 usb [ + ] `-- usb@e0002000 Zynq> usb start starting USB... USB0: USB EHCI 1.00 scanning bus 0 for devices... Error: Cannot find high speed parent of usb-1 device EHCI timed out on TD - token=0x80008c80 unable to get device descriptor (error=-1) failed, error -1 Zynq>
Signed-off-by: Simon Glass sjg@chromium.org
arch/arm/Kconfig | 2 + drivers/usb/host/ehci-zynq.c | 102 +++++++++++++++++++++---------------------- 2 files changed, 52 insertions(+), 52 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1af9c35..2b501eb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -643,6 +643,7 @@ config ARCH_ZYNQ select DM_SERIAL select DM_SPI_FLASH select SPL_SEPARATE_BSS if SPL
- select DM_USB
config ARCH_ZYNQMP bool "Support Xilinx ZynqMP Platform" @@ -651,6 +652,7 @@ config ARCH_ZYNQMP select OF_CONTROL select DM_SERIAL select SUPPORT_SPL
- select DM_USB
config TEGRA bool "NVIDIA Tegra" diff --git a/drivers/usb/host/ehci-zynq.c b/drivers/usb/host/ehci-zynq.c index 37a7935..b45c68d 100644 --- a/drivers/usb/host/ehci-zynq.c +++ b/drivers/usb/host/ehci-zynq.c @@ -7,55 +7,47 @@ */
#include <common.h> +#include <dm.h> +#include <usb.h> #include <asm/arch/hardware.h> #include <asm/arch/sys_proto.h> #include <asm/io.h> -#include <usb.h> #include <usb/ehci-ci.h> #include <usb/ulpi.h>
#include "ehci.h"
-#define ZYNQ_USB_USBCMD_RST 0x0000002 -#define ZYNQ_USB_USBCMD_STOP 0x0000000 -#define ZYNQ_USB_NUM_MIO 12 +struct zynq_ehci_priv {
Please add below member to this structure as per my conversation with Hans de Goede. This solves the usb issue which you stated, Struct struct ehci_ctrl ehcictrl;
Thanks, Siva
- struct usb_ehci *ehci;
+};
-/*
- Create the appropriate control structures to manage
- a new EHCI host controller.
- */
-int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr,
struct ehci_hcor **hcor)
+static int ehci_zynq_ofdata_to_platdata(struct udevice *dev) {
- struct usb_ehci *ehci;
- struct zynq_ehci_priv *priv = dev_get_priv(dev);
- priv->ehci = (struct usb_ehci *)dev_get_addr_ptr(dev);
- if (!priv->ehci)
return -EINVAL;
- return 0;
+}
+static int ehci_zynq_probe(struct udevice *dev) {
- struct usb_platdata *plat = dev_get_platdata(dev);
- struct zynq_ehci_priv *priv = dev_get_priv(dev);
- struct ehci_hccr *hccr;
- struct ehci_hcor *hcor; struct ulpi_viewport ulpi_vp;
- int ret, mio_usb; /* Used for writing the ULPI data address */ struct ulpi_regs *ulpi = (struct ulpi_regs *)0;
- int ret;
- if (!index) {
mio_usb = zynq_slcr_get_mio_pin_status("usb0");
if (mio_usb != ZYNQ_USB_NUM_MIO) {
printf("usb0 wrong num MIO: %d, Index %d\n",
mio_usb,
index);
return -1;
}
ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR0;
- } else {
mio_usb = zynq_slcr_get_mio_pin_status("usb1");
if (mio_usb != ZYNQ_USB_NUM_MIO) {
printf("usb1 wrong num MIO: %d, Index %d\n",
mio_usb,
index);
return -1;
}
ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR1;
- }
- *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
- *hcor = (struct ehci_hcor *)((uint32_t) *hccr +
HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
- hccr = (struct ehci_hccr *)((uint32_t)&priv->ehci->caplength);
- hcor = (struct ehci_hcor *)((uint32_t) hccr +
HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
- ulpi_vp.viewport_addr = (u32)&ehci->ulpi_viewpoint;
ulpi_vp.viewport_addr = (u32)&priv->ehci->ulpi_viewpoint; ulpi_vp.port_num = 0;
ret = ulpi_init(&ulpi_vp);
@@ -77,28 +69,34 @@ int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, ulpi_write(&ulpi_vp, &ulpi->otg_ctrl_set, ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
- return 0;
- return ehci_register(dev, hccr, hcor, NULL, 0, plat->init_type);
}
-/*
- Destroy the appropriate control structures corresponding
- the the EHCI host controller.
- */
-int ehci_hcd_stop(int index) +static int ehci_zynq_remove(struct udevice *dev) {
- struct usb_ehci *ehci;
- if (!index)
ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR0;
- else
ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR1;
- int ret;
- /* Stop controller */
- writel(ZYNQ_USB_USBCMD_STOP, &ehci->usbcmd);
- udelay(1000);
- /* Initiate controller reset */
- writel(ZYNQ_USB_USBCMD_RST, &ehci->usbcmd);
ret = ehci_deregister(dev);
if (ret)
return ret;
return 0;
}
+static const struct udevice_id ehci_zynq_ids[] = {
- { .compatible = "xlnx,zynq-usb-2.20a" },
- { }
+};
+U_BOOT_DRIVER(ehci_zynq) = {
- .name = "ehci_zynq",
- .id = UCLASS_USB,
- .of_match = ehci_zynq_ids,
- .ofdata_to_platdata = ehci_zynq_ofdata_to_platdata,
- .probe = ehci_zynq_probe,
- .remove = ehci_zynq_remove,
- .ops = &ehci_usb_ops,
- .platdata_auto_alloc_size = sizeof(struct usb_platdata),
- .priv_auto_alloc_size = sizeof(struct zynq_ehci_priv),
- .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
2.8.0.rc3.226.g39d4020
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Hi Simon,
-----Original Message----- From: Siva Durga Prasad Paladugu Sent: Tuesday, June 28, 2016 11:38 AM To: 'Simon Glass' sjg@chromium.org; U-Boot Mailing List <u- boot@lists.denx.de> Cc: Marek Vasut marex@denx.de; 'Hans de Goede' hdegoede@redhat.com Subject: RE: [U-Boot] [PATCH 24/27] dm: zynq: usb: Convert to CONFIG_DM_USB
Hi Simon,
-----Original Message----- From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Simon Glass Sent: Monday, June 13, 2016 11:01 AM To: U-Boot Mailing List u-boot@lists.denx.de Cc: Marek Vasut marex@denx.de Subject: [U-Boot] [PATCH 24/27] dm: zynq: usb: Convert to CONFIG_DM_USB
Convert zynq USB to driver model. It does not actually work, but the error is similar.
Before:
Zynq> dm tree Class Probed Name
root [ + ] root_driver rsa_mod_exp [ ] |-- mod_exp_sw simple_bus [ + ] `-- amba gpio [ ] |-- gpio@e000a000 serial [ + ] |-- serial@e0001000 spi [ + ] |-- spi@e000d000 spi_flash [ ] | `-- spi_flash@0:0 eth [ + ] |-- ethernet@e000b000 mmc [ + ] |-- sdhci@e0100000 simple_bus [ ] `-- slcr@f8000000 Zynq> usb start starting USB... USB0: USB EHCI 1.00 scanning bus 0 for devices... 2 USB Device(s) found USB1: usb1 wrong num MIO: 0, Index 1 lowlevel init failed scanning usb for storage devices... 0 Storage Device(s) found Zynq>
After:
Zynq> dm tree Class Probed Name
root [ + ] root_driver rsa_mod_exp [ ] |-- mod_exp_sw simple_bus [ + ] `-- amba gpio [ ] |-- gpio@e000a000 serial [ + ] |-- serial@e0001000 spi [ + ] |-- spi@e000d000 spi_flash [ ] | `-- spi_flash@0:0 eth [ + ] |-- ethernet@e000b000 mmc [ + ] |-- sdhci@e0100000 blk [ + ] | `-- sdhci@e0100000.blk simple_bus [ ] |-- slcr@f8000000 usb [ + ] `-- usb@e0002000 Zynq> usb start starting USB... USB0: USB EHCI 1.00 scanning bus 0 for devices... Error: Cannot find high speed parent of usb-1 device EHCI timed out on TD - token=0x80008c80 unable to get device descriptor (error=-1) failed, error -1 Zynq>
Signed-off-by: Simon Glass sjg@chromium.org
arch/arm/Kconfig | 2 + drivers/usb/host/ehci-zynq.c | 102 +++++++++++++++++++++---------------------- 2 files changed, 52 insertions(+), 52 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1af9c35..2b501eb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -643,6 +643,7 @@ config ARCH_ZYNQ select DM_SERIAL select DM_SPI_FLASH select SPL_SEPARATE_BSS if SPL
- select DM_USB
config ARCH_ZYNQMP bool "Support Xilinx ZynqMP Platform" @@ -651,6 +652,7 @@ config ARCH_ZYNQMP select OF_CONTROL select DM_SERIAL select SUPPORT_SPL
- select DM_USB
config TEGRA bool "NVIDIA Tegra" diff --git a/drivers/usb/host/ehci-zynq.c b/drivers/usb/host/ehci-zynq.c index 37a7935..b45c68d 100644 --- a/drivers/usb/host/ehci-zynq.c +++ b/drivers/usb/host/ehci-zynq.c @@ -7,55 +7,47 @@ */
#include <common.h> +#include <dm.h> +#include <usb.h> #include <asm/arch/hardware.h> #include <asm/arch/sys_proto.h> #include <asm/io.h> -#include <usb.h> #include <usb/ehci-ci.h> #include <usb/ulpi.h>
#include "ehci.h"
-#define ZYNQ_USB_USBCMD_RST 0x0000002 -#define ZYNQ_USB_USBCMD_STOP 0x0000000 -#define ZYNQ_USB_NUM_MIO 12 +struct zynq_ehci_priv {
Please add below member to this structure as per my conversation with Hans de Goede. This solves the usb issue which you stated, Struct struct ehci_ctrl ehcictrl;
Can you add this element to structure (zynq_ehic_priv) as mentioned above in your patch?
Thanks, Siva
Thanks, Siva
- struct usb_ehci *ehci;
+};
-/*
- Create the appropriate control structures to manage
- a new EHCI host controller.
- */
-int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr,
struct ehci_hcor **hcor)
+static int ehci_zynq_ofdata_to_platdata(struct udevice *dev) {
- struct usb_ehci *ehci;
- struct zynq_ehci_priv *priv = dev_get_priv(dev);
- priv->ehci = (struct usb_ehci *)dev_get_addr_ptr(dev);
- if (!priv->ehci)
return -EINVAL;
- return 0;
+}
+static int ehci_zynq_probe(struct udevice *dev) {
- struct usb_platdata *plat = dev_get_platdata(dev);
- struct zynq_ehci_priv *priv = dev_get_priv(dev);
- struct ehci_hccr *hccr;
- struct ehci_hcor *hcor; struct ulpi_viewport ulpi_vp;
- int ret, mio_usb; /* Used for writing the ULPI data address */ struct ulpi_regs *ulpi = (struct ulpi_regs *)0;
- int ret;
- if (!index) {
mio_usb = zynq_slcr_get_mio_pin_status("usb0");
if (mio_usb != ZYNQ_USB_NUM_MIO) {
printf("usb0 wrong num MIO: %d, Index %d\n",
mio_usb,
index);
return -1;
}
ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR0;
- } else {
mio_usb = zynq_slcr_get_mio_pin_status("usb1");
if (mio_usb != ZYNQ_USB_NUM_MIO) {
printf("usb1 wrong num MIO: %d, Index %d\n",
mio_usb,
index);
return -1;
}
ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR1;
- }
- *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
- *hcor = (struct ehci_hcor *)((uint32_t) *hccr +
HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
- hccr = (struct ehci_hccr *)((uint32_t)&priv->ehci->caplength);
- hcor = (struct ehci_hcor *)((uint32_t) hccr +
HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
- ulpi_vp.viewport_addr = (u32)&ehci->ulpi_viewpoint;
ulpi_vp.viewport_addr = (u32)&priv->ehci->ulpi_viewpoint; ulpi_vp.port_num = 0;
ret = ulpi_init(&ulpi_vp);
@@ -77,28 +69,34 @@ int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, ulpi_write(&ulpi_vp, &ulpi->otg_ctrl_set, ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
- return 0;
- return ehci_register(dev, hccr, hcor, NULL, 0, plat->init_type);
}
-/*
- Destroy the appropriate control structures corresponding
- the the EHCI host controller.
- */
-int ehci_hcd_stop(int index) +static int ehci_zynq_remove(struct udevice *dev) {
- struct usb_ehci *ehci;
- if (!index)
ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR0;
- else
ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR1;
- int ret;
- /* Stop controller */
- writel(ZYNQ_USB_USBCMD_STOP, &ehci->usbcmd);
- udelay(1000);
- /* Initiate controller reset */
- writel(ZYNQ_USB_USBCMD_RST, &ehci->usbcmd);
ret = ehci_deregister(dev);
if (ret)
return ret;
return 0;
}
+static const struct udevice_id ehci_zynq_ids[] = {
- { .compatible = "xlnx,zynq-usb-2.20a" },
- { }
+};
+U_BOOT_DRIVER(ehci_zynq) = {
- .name = "ehci_zynq",
- .id = UCLASS_USB,
- .of_match = ehci_zynq_ids,
- .ofdata_to_platdata = ehci_zynq_ofdata_to_platdata,
- .probe = ehci_zynq_probe,
- .remove = ehci_zynq_remove,
- .ops = &ehci_usb_ops,
- .platdata_auto_alloc_size = sizeof(struct usb_platdata),
- .priv_auto_alloc_size = sizeof(struct zynq_ehci_priv),
- .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
2.8.0.rc3.226.g39d4020
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Hi Siva,
On 3 July 2016 at 22:49, Siva Durga Prasad Paladugu siva.durga.paladugu@xilinx.com wrote:
Hi Simon,
-----Original Message----- From: Siva Durga Prasad Paladugu Sent: Tuesday, June 28, 2016 11:38 AM To: 'Simon Glass' sjg@chromium.org; U-Boot Mailing List <u- boot@lists.denx.de> Cc: Marek Vasut marex@denx.de; 'Hans de Goede' hdegoede@redhat.com Subject: RE: [U-Boot] [PATCH 24/27] dm: zynq: usb: Convert to CONFIG_DM_USB
Hi Simon,
-----Original Message----- From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Simon Glass Sent: Monday, June 13, 2016 11:01 AM To: U-Boot Mailing List u-boot@lists.denx.de Cc: Marek Vasut marex@denx.de Subject: [U-Boot] [PATCH 24/27] dm: zynq: usb: Convert to CONFIG_DM_USB
Convert zynq USB to driver model. It does not actually work, but the error is similar.
Before:
Zynq> dm tree Class Probed Name
root [ + ] root_driver rsa_mod_exp [ ] |-- mod_exp_sw simple_bus [ + ] `-- amba gpio [ ] |-- gpio@e000a000 serial [ + ] |-- serial@e0001000 spi [ + ] |-- spi@e000d000 spi_flash [ ] | `-- spi_flash@0:0 eth [ + ] |-- ethernet@e000b000 mmc [ + ] |-- sdhci@e0100000 simple_bus [ ] `-- slcr@f8000000 Zynq> usb start starting USB... USB0: USB EHCI 1.00 scanning bus 0 for devices... 2 USB Device(s) found USB1: usb1 wrong num MIO: 0, Index 1 lowlevel init failed scanning usb for storage devices... 0 Storage Device(s) found Zynq>
After:
Zynq> dm tree Class Probed Name
root [ + ] root_driver rsa_mod_exp [ ] |-- mod_exp_sw simple_bus [ + ] `-- amba gpio [ ] |-- gpio@e000a000 serial [ + ] |-- serial@e0001000 spi [ + ] |-- spi@e000d000 spi_flash [ ] | `-- spi_flash@0:0 eth [ + ] |-- ethernet@e000b000 mmc [ + ] |-- sdhci@e0100000 blk [ + ] | `-- sdhci@e0100000.blk simple_bus [ ] |-- slcr@f8000000 usb [ + ] `-- usb@e0002000 Zynq> usb start starting USB... USB0: USB EHCI 1.00 scanning bus 0 for devices... Error: Cannot find high speed parent of usb-1 device EHCI timed out on TD - token=0x80008c80 unable to get device descriptor (error=-1) failed, error -1 Zynq>
Signed-off-by: Simon Glass sjg@chromium.org
arch/arm/Kconfig | 2 + drivers/usb/host/ehci-zynq.c | 102 +++++++++++++++++++++---------------------- 2 files changed, 52 insertions(+), 52 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1af9c35..2b501eb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -643,6 +643,7 @@ config ARCH_ZYNQ select DM_SERIAL select DM_SPI_FLASH select SPL_SEPARATE_BSS if SPL
- select DM_USB
config ARCH_ZYNQMP bool "Support Xilinx ZynqMP Platform" @@ -651,6 +652,7 @@ config ARCH_ZYNQMP select OF_CONTROL select DM_SERIAL select SUPPORT_SPL
- select DM_USB
config TEGRA bool "NVIDIA Tegra" diff --git a/drivers/usb/host/ehci-zynq.c b/drivers/usb/host/ehci-zynq.c index 37a7935..b45c68d 100644 --- a/drivers/usb/host/ehci-zynq.c +++ b/drivers/usb/host/ehci-zynq.c @@ -7,55 +7,47 @@ */
#include <common.h> +#include <dm.h> +#include <usb.h> #include <asm/arch/hardware.h> #include <asm/arch/sys_proto.h> #include <asm/io.h> -#include <usb.h> #include <usb/ehci-ci.h> #include <usb/ulpi.h>
#include "ehci.h"
-#define ZYNQ_USB_USBCMD_RST 0x0000002 -#define ZYNQ_USB_USBCMD_STOP 0x0000000 -#define ZYNQ_USB_NUM_MIO 12 +struct zynq_ehci_priv {
Please add below member to this structure as per my conversation with Hans de Goede. This solves the usb issue which you stated, Struct struct ehci_ctrl ehcictrl;
Can you add this element to structure (zynq_ehic_priv) as mentioned above in your patch?
Just to follow up - this was done and is now in mainline.
Thanks, Siva
Regards, Simon

Move zynq to the latest driver model support by enabling CONFIG_DM_MMC, CONFIG_DM_MMC_OPS and CONFIG_BLK.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/arm/Kconfig | 5 +++++ drivers/mmc/zynq_sdhci.c | 39 ++++++++++++++++++++++++++++++++++----- 2 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 2b501eb..42d0dd0 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -639,11 +639,13 @@ config ARCH_ZYNQ select DM_GPIO select SPL_DM if SPL select DM_MMC + select DM_MMC_OPS select DM_SPI select DM_SERIAL select DM_SPI_FLASH select SPL_SEPARATE_BSS if SPL select DM_USB + select BLK
config ARCH_ZYNQMP bool "Support Xilinx ZynqMP Platform" @@ -653,6 +655,9 @@ config ARCH_ZYNQMP select DM_SERIAL select SUPPORT_SPL select DM_USB + select DM_MMC + select DM_MMC_OPS + select BLK
config TEGRA bool "NVIDIA Tegra" diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index d405929..bcd154a 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -17,10 +17,18 @@ # define CONFIG_ZYNQ_SDHCI_MIN_FREQ 0 #endif
+struct arasan_sdhci_plat { + struct mmc_config cfg; + struct mmc mmc; +}; + static int arasan_sdhci_probe(struct udevice *dev) { + struct arasan_sdhci_plat *plat = dev_get_platdata(dev); struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct sdhci_host *host = dev_get_priv(dev); + u32 caps; + int ret;
host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_BROKEN_R1B; @@ -31,13 +39,19 @@ static int arasan_sdhci_probe(struct udevice *dev)
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
- add_sdhci(host, CONFIG_ZYNQ_SDHCI_MAX_FREQ, - CONFIG_ZYNQ_SDHCI_MIN_FREQ); - - upriv->mmc = host->mmc; + caps = sdhci_readl(host, SDHCI_CAPABILITIES); + ret = sdhci_setup_cfg(&plat->cfg, dev->name, host->bus_width, + caps, CONFIG_ZYNQ_SDHCI_MAX_FREQ, + CONFIG_ZYNQ_SDHCI_MIN_FREQ, host->version, + host->quirks, 0); + host->mmc = &plat->mmc; + if (ret) + return ret; + host->mmc->priv = host; host->mmc->dev = dev; + upriv->mmc = host->mmc;
- return 0; + return sdhci_probe(dev); }
static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev) @@ -50,6 +64,18 @@ static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev) return 0; }
+static int arasan_sdhci_bind(struct udevice *dev) +{ + struct arasan_sdhci_plat *plat = dev_get_platdata(dev); + int ret; + + ret = sdhci_bind(dev, &plat->mmc, &plat->cfg); + if (ret) + return ret; + + return 0; +} + static const struct udevice_id arasan_sdhci_ids[] = { { .compatible = "arasan,sdhci-8.9a" }, { } @@ -60,6 +86,9 @@ U_BOOT_DRIVER(arasan_sdhci_drv) = { .id = UCLASS_MMC, .of_match = arasan_sdhci_ids, .ofdata_to_platdata = arasan_sdhci_ofdata_to_platdata, + .ops = &sdhci_ops, + .bind = arasan_sdhci_bind, .probe = arasan_sdhci_probe, .priv_auto_alloc_size = sizeof(struct sdhci_host), + .platdata_auto_alloc_size = sizeof(struct arasan_sdhci_plat), };

These two options go together and it is best to do the conversion in one step. So enable DM_MMC_OPS by default if DM_MMC is enabled.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/mmc/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 79cf18f..b11725e 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -19,6 +19,7 @@ config DM_MMC config DM_MMC_OPS bool "Support MMC controller operations using Driver Model" depends on DM_MMC + default y if DM_MMC help Driver model provides a means of supporting device operations. This option moves MMC operations under the control of driver model. The

To speed up conversion to CONFIG_BLK, enable it by default when DM_MMC is enabled.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/block/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 80eea84..fe5aa07 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -1,6 +1,7 @@ config BLK bool "Support block devices" depends on DM + default y if DM_MMC help Enable support for block devices, such as SCSI, MMC and USB flash sticks. These provide a block-level interface which permits
participants (6)
-
Jaehoon Chung
-
Joe Hershberger
-
Michal Simek
-
Michal Simek
-
Simon Glass
-
Siva Durga Prasad Paladugu