Add a minimal non-DM MMC driver for use in size-constrained environments. Signed-off-by: Ferass El Hafidi <fundersc...@postmarketos.org> --- arch/arm/include/asm/arch-meson/gx.h | 5 +++ drivers/mmc/meson_gx_mmc.c | 75 +++++++++++++++++++++++++++++++++++- 2 files changed, 79 insertions(+), 1 deletion(-)
diff --git a/arch/arm/include/asm/arch-meson/gx.h b/arch/arm/include/asm/arch-meson/gx.h index 26ec5d0bc340bc03587047d68a88042779e64536..8cfc6b00329f252bbf452dba00f8ad56b480c707 100644 --- a/arch/arm/include/asm/arch-meson/gx.h +++ b/arch/arm/include/asm/arch-meson/gx.h @@ -41,4 +41,9 @@ #define GX_GPIO_IN(n) GX_PERIPHS_ADDR(_GX_GPIO_OFF(n) + 1) #define GX_GPIO_OUT(n) GX_PERIPHS_ADDR(_GX_GPIO_OFF(n) + 2) +/* Non-DM MMC init */ +#if CONFIG_IS_ENABLED(MMC) && !CONFIG_IS_ENABLED(DM_MMC) +struct mmc *meson_mmc_init(int mmc_no); +#endif + #endif /* __GX_H__ */ diff --git a/drivers/mmc/meson_gx_mmc.c b/drivers/mmc/meson_gx_mmc.c index 5852b24c6d2a5a9d1b1e8a62f8c0ec325b339182..a4338f1e29c1da07acb0333be9b75a318cba1334 100644 --- a/drivers/mmc/meson_gx_mmc.c +++ b/drivers/mmc/meson_gx_mmc.c @@ -16,6 +16,7 @@ #include <linux/log2.h> #include "meson_gx_mmc.h" +#if CONFIG_IS_ENABLED(DM_MMC) bool meson_gx_mmc_is_compatible(struct udevice *dev, enum meson_gx_mmc_compatible family) { @@ -23,6 +24,7 @@ bool meson_gx_mmc_is_compatible(struct udevice *dev, return compat == family; } +#endif static inline void *get_regbase(const struct mmc *mmc) { @@ -67,7 +69,7 @@ static void meson_mmc_config_clock(struct mmc *mmc) * Other SoCs use CLK_CO_PHASE_180 by default. * It needs to find what is a proper value about each SoCs. */ - if (meson_gx_mmc_is_compatible(mmc->dev, MMC_COMPATIBLE_SM1)) + if (IS_ENABLED(CONFIG_MESON_SM)) meson_mmc_clk |= CLK_CO_PHASE_270; else meson_mmc_clk |= CLK_CO_PHASE_180; @@ -82,9 +84,14 @@ static void meson_mmc_config_clock(struct mmc *mmc) meson_write(mmc, meson_mmc_clk, MESON_SD_EMMC_CLOCK); } +#if CONFIG_IS_ENABLED(DM_MMC) static int meson_dm_mmc_set_ios(struct udevice *dev) { struct mmc *mmc = mmc_get_mmc_dev(dev); +#else +static int meson_legacy_mmc_set_ios(struct mmc *mmc) +{ +#endif uint32_t meson_mmc_cfg; meson_mmc_config_clock(mmc); @@ -193,10 +200,16 @@ static void meson_mmc_read_response(struct mmc *mmc, struct mmc_cmd *cmd) } } +#if CONFIG_IS_ENABLED(DM_MMC) static int meson_dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data *data) { struct mmc *mmc = mmc_get_mmc_dev(dev); +#else +static int meson_legacy_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, + struct mmc_data *data) +{ +#endif struct meson_mmc_plat *pdata = mmc->priv; uint32_t status; ulong start; @@ -235,6 +248,59 @@ static int meson_dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, return ret; } +#if !CONFIG_IS_ENABLED(DM_MMC) +struct meson_mmc_plat mmc_plat[2]; + +static int meson_legacy_mmc_init(struct mmc *mmc) +{ + /* reset all status bits */ + meson_write(mmc, STATUS_MASK, MESON_SD_EMMC_STATUS); + + /* disable interrupts */ + meson_write(mmc, 0, MESON_SD_EMMC_IRQ_EN); + + return 0; +} + +static const struct mmc_ops meson_mmc_ops = { + .send_cmd = meson_legacy_mmc_send_cmd, + .set_ios = meson_legacy_mmc_set_ios, + .init = meson_legacy_mmc_init, +}; + +struct mmc *meson_mmc_init(int mmc_no) +{ + struct meson_mmc_plat *pdata = &mmc_plat[mmc_no]; + struct mmc_config *cfg = &pdata->cfg; + + cfg->voltages = MMC_VDD_33_34 | MMC_VDD_32_33 | + MMC_VDD_31_32 | MMC_VDD_165_195; + cfg->host_caps = MMC_MODE_8BIT | MMC_MODE_4BIT; + cfg->f_min = DIV_ROUND_UP(SD_EMMC_CLKSRC_24M, CLK_MAX_DIV); + cfg->f_max = 6000000; /* 6 MHz */ + cfg->b_max = 127; /* max 128 - 1 block */ + cfg->name = "Meson SD/eMMC"; + cfg->ops = &meson_mmc_ops; + + if (mmc_no == 0) /* MMC1: SD card */ + pdata->regbase = (void *)0xd0072000; + else if (mmc_no == 1) /* MMC2: eMMC */ + pdata->regbase = (void *)0xd0074000; + +#if CONFIG_IS_ENABLED(MMC_PWRSEQ) + /* Enable power if needed */ + ret = mmc_pwrseq_get_power(dev, cfg); + if (!ret) { + ret = pwrseq_set_power(cfg->pwr_dev, true); + if (ret) + return ret; + } +#endif + + return mmc_create(cfg, pdata); +} + +#else static const struct dm_mmc_ops meson_dm_mmc_ops = { .send_cmd = meson_dm_mmc_send_cmd, .set_ios = meson_dm_mmc_set_ios, @@ -282,6 +348,12 @@ static int meson_mmc_probe(struct udevice *dev) cfg->b_max = 511; /* max 512 - 1 blocks */ cfg->name = dev->name; + if (IS_ENABLED(CONFIG_SPL_BUILD)) { + cfg->host_caps &= ~(MMC_MODE_HS_52MHz | MMC_MODE_HS); + cfg->f_max = 6000000; /* 6 MHz */ + cfg->b_max = 127; /* max 128 - 1 block */ + } + mmc->priv = pdata; upriv->mmc = mmc; @@ -336,3 +408,4 @@ U_BOOT_DRIVER(meson_mmc) = { .of_to_plat = meson_mmc_of_to_plat, .plat_auto = sizeof(struct meson_mmc_plat), }; +#endif -- 2.51.0