On 07/22/2017 06:22 AM, Marek Vasut wrote: > Add MMC DM and DT probing support into the SH SDHI driver. > This patch abstracts out the common bits of the send command > and set ios functions, so they can be used both by DM and non > DM setups and adds the DM probe support. > > Signed-off-by: Marek Vasut <marek.vasut+rene...@gmail.com> > Cc: Hiroyuki Yokoyama <hiroyuki.yokoyama...@renesas.com> > Cc: Nobuhiro Iwamatsu <iwama...@nigauri.org> > Cc: Jaehoon Chung <jh80.ch...@samsung.com> > Reviewed-by: Nobuhiro Iwamatsu <iwama...@nigauri.org>
Applied to u-boot-mmc. Sorry for late! Best Regards, Jaehoon Chung > --- > drivers/mmc/sh_sdhi.c | 165 > ++++++++++++++++++++++++++++++++++++++++++++------ > 1 file changed, 145 insertions(+), 20 deletions(-) > > diff --git a/drivers/mmc/sh_sdhi.c b/drivers/mmc/sh_sdhi.c > index d181b63905..fd710399b6 100644 > --- a/drivers/mmc/sh_sdhi.c > +++ b/drivers/mmc/sh_sdhi.c > @@ -13,15 +13,18 @@ > #include <common.h> > #include <malloc.h> > #include <mmc.h> > +#include <dm.h> > #include <linux/errno.h> > -#include <asm/io.h> > +#include <linux/compat.h> > +#include <linux/io.h> > +#include <linux/sizes.h> > #include <asm/arch/rmobile.h> > #include <asm/arch/sh_sdhi.h> > > #define DRIVER_NAME "sh-sdhi" > > struct sh_sdhi_host { > - unsigned long addr; > + void __iomem *addr; > int ch; > int bus_shift; > unsigned long quirks; > @@ -50,11 +53,6 @@ static inline u16 sh_sdhi_readw(struct sh_sdhi_host *host, > int reg) > return readw(host->addr + (reg << host->bus_shift)); > } > > -static void *mmc_priv(struct mmc *mmc) > -{ > - return (void *)mmc->priv; > -} > - > static void sh_sdhi_detect(struct sh_sdhi_host *host) > { > sh_sdhi_writew(host, SDHI_OPTION, > @@ -634,23 +632,17 @@ static int sh_sdhi_start_cmd(struct sh_sdhi_host *host, > return ret; > } > > -static int sh_sdhi_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, > - struct mmc_data *data) > +static int sh_sdhi_send_cmd_common(struct sh_sdhi_host *host, > + struct mmc_cmd *cmd, struct mmc_data *data) > { > - struct sh_sdhi_host *host = mmc_priv(mmc); > - int ret; > - > host->sd_error = 0; > > - ret = sh_sdhi_start_cmd(host, data, cmd); > - > - return ret; > + return sh_sdhi_start_cmd(host, data, cmd); > } > > -static int sh_sdhi_set_ios(struct mmc *mmc) > +static int sh_sdhi_set_ios_common(struct sh_sdhi_host *host, struct mmc *mmc) > { > int ret; > - struct sh_sdhi_host *host = mmc_priv(mmc); > > ret = sh_sdhi_clock_control(host, mmc->clock); > if (ret) > @@ -674,9 +666,8 @@ static int sh_sdhi_set_ios(struct mmc *mmc) > return 0; > } > > -static int sh_sdhi_initialize(struct mmc *mmc) > +static int sh_sdhi_initialize_common(struct sh_sdhi_host *host) > { > - struct sh_sdhi_host *host = mmc_priv(mmc); > int ret = sh_sdhi_sync_reset(host); > > sh_sdhi_writew(host, SDHI_PORTSEL, USE_1PORT); > @@ -692,6 +683,34 @@ static int sh_sdhi_initialize(struct mmc *mmc) > return ret; > } > > +#ifndef CONFIG_DM_MMC > +static void *mmc_priv(struct mmc *mmc) > +{ > + return (void *)mmc->priv; > +} > + > +static int sh_sdhi_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, > + struct mmc_data *data) > +{ > + struct sh_sdhi_host *host = mmc_priv(mmc); > + > + return sh_sdhi_send_cmd_common(host, cmd, data); > +} > + > +static int sh_sdhi_set_ios(struct mmc *mmc) > +{ > + struct sh_sdhi_host *host = mmc_priv(mmc); > + > + return sh_sdhi_set_ios_common(host, mmc); > +} > + > +static int sh_sdhi_initialize(struct mmc *mmc) > +{ > + struct sh_sdhi_host *host = mmc_priv(mmc); > + > + return sh_sdhi_initialize_common(host); > +} > + > static const struct mmc_ops sh_sdhi_ops = { > .send_cmd = sh_sdhi_send_cmd, > .set_ios = sh_sdhi_set_ios, > @@ -743,7 +762,7 @@ int sh_sdhi_init(unsigned long addr, int ch, unsigned > long quirks) > } > > host->ch = ch; > - host->addr = addr; > + host->addr = (void __iomem *)addr; > host->quirks = quirks; > > if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF) > @@ -757,3 +776,109 @@ error: > free(host); > return ret; > } > + > +#else > + > +struct sh_sdhi_plat { > + struct mmc_config cfg; > + struct mmc mmc; > +}; > + > +int sh_sdhi_dm_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, > + struct mmc_data *data) > +{ > + struct sh_sdhi_host *host = dev_get_priv(dev); > + > + return sh_sdhi_send_cmd_common(host, cmd, data); > +} > + > +int sh_sdhi_dm_set_ios(struct udevice *dev) > +{ > + struct sh_sdhi_host *host = dev_get_priv(dev); > + struct mmc *mmc = mmc_get_mmc_dev(dev); > + > + return sh_sdhi_set_ios_common(host, mmc); > +} > + > +static const struct dm_mmc_ops sh_sdhi_dm_ops = { > + .send_cmd = sh_sdhi_dm_send_cmd, > + .set_ios = sh_sdhi_dm_set_ios, > +}; > + > +static int sh_sdhi_dm_bind(struct udevice *dev) > +{ > + struct sh_sdhi_plat *plat = dev_get_platdata(dev); > + > + return mmc_bind(dev, &plat->mmc, &plat->cfg); > +} > + > +static int sh_sdhi_dm_probe(struct udevice *dev) > +{ > + struct sh_sdhi_plat *plat = dev_get_platdata(dev); > + struct sh_sdhi_host *host = dev_get_priv(dev); > + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); > + const u32 quirks = dev_get_driver_data(dev); > + fdt_addr_t base; > + > + base = devfdt_get_addr(dev); > + if (base == FDT_ADDR_T_NONE) > + return -EINVAL; > + > + host->addr = devm_ioremap(dev, base, SZ_2K); > + if (!host->addr) > + return -ENOMEM; > + > + host->quirks = quirks; > + > + if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF) > + host->bus_shift = 2; > + else if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF) > + host->bus_shift = 1; > + > + plat->cfg.name = dev->name; > + plat->cfg.host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS; > + > + switch (fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "bus-width", > + 1)) { > + case 8: > + plat->cfg.host_caps |= MMC_MODE_8BIT; > + break; > + case 4: > + plat->cfg.host_caps |= MMC_MODE_4BIT; > + break; > + case 1: > + break; > + default: > + dev_err(dev, "Invalid \"bus-width\" value\n"); > + return -EINVAL; > + } > + > + sh_sdhi_initialize_common(host); > + > + plat->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34; > + plat->cfg.f_min = CLKDEV_INIT; > + plat->cfg.f_max = CLKDEV_HS_DATA; > + plat->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; > + > + upriv->mmc = &plat->mmc; > + > + return 0; > +} > + > +static const struct udevice_id sh_sdhi_sd_match[] = { > + { .compatible = "renesas,sdhi-r8a7795", .data = SH_SDHI_QUIRK_64BIT_BUF > }, > + { .compatible = "renesas,sdhi-r8a7796", .data = SH_SDHI_QUIRK_64BIT_BUF > }, > + { /* sentinel */ } > +}; > + > +U_BOOT_DRIVER(sh_sdhi_mmc) = { > + .name = "sh-sdhi-mmc", > + .id = UCLASS_MMC, > + .of_match = sh_sdhi_sd_match, > + .bind = sh_sdhi_dm_bind, > + .probe = sh_sdhi_dm_probe, > + .priv_auto_alloc_size = sizeof(struct sh_sdhi_host), > + .platdata_auto_alloc_size = sizeof(struct sh_sdhi_plat), > + .ops = &sh_sdhi_dm_ops, > +}; > +#endif > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot