* Remove obsolete comments * Set core phase to 180 regardless of the SoC like Linux * Enable always-on clock
AML mmc driver has been working okay(ish) for a few years The purpose of this patch is to bring u-boot closer to what Linux is doing Signed-off-by: Jerome Brunet <jbru...@baylibre.com> --- drivers/mmc/meson_gx_mmc.c | 45 ++++++++++++++++---------------------- drivers/mmc/meson_gx_mmc.h | 9 ++++++-- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/drivers/mmc/meson_gx_mmc.c b/drivers/mmc/meson_gx_mmc.c index fcf4f03d1e24..c6168792cbae 100644 --- a/drivers/mmc/meson_gx_mmc.c +++ b/drivers/mmc/meson_gx_mmc.c @@ -17,13 +17,14 @@ #include <linux/log2.h> #include "meson_gx_mmc.h" -bool meson_gx_mmc_is_compatible(struct udevice *dev, - enum meson_gx_mmc_compatible family) -{ - enum meson_gx_mmc_compatible compat = dev_get_driver_data(dev); - - return compat == family; -} +struct meson_gx_mmc_version_data meson_gx_mmc_version[] = { + [MMC_COMPATIBLE_V2] = { + .clk_always_on = BIT(24), + }, + [MMC_COMPATIBLE_V3] = { + .clk_always_on = BIT(28), + }, +}; static inline void *get_regbase(const struct mmc *mmc) { @@ -44,13 +45,17 @@ static inline void meson_write(struct mmc *mmc, uint32_t val, int offset) static void meson_mmc_config_clock(struct mmc *mmc) { + struct meson_mmc_plat *pdata = mmc->priv; uint32_t meson_mmc_clk = 0; unsigned int clk, clk_src, clk_div; if (!mmc->clock) return; - /* TOFIX This should use the proper clock taken from DT */ + /* Clk always on */ + meson_mmc_clk |= pdata->version->clk_always_on; + meson_mmc_clk |= CLK_CO_PHASE_180; + meson_mmc_clk |= CLK_TX_PHASE_000; /* 1GHz / CLK_MAX_DIV = 15,9 MHz */ if (mmc->clock > 16000000) { @@ -62,20 +67,6 @@ static void meson_mmc_config_clock(struct mmc *mmc) } clk_div = DIV_ROUND_UP(clk, mmc->clock); - /* - * SM1 SoCs doesn't work fine over 50MHz with CLK_CO_PHASE_180 - * If CLK_CO_PHASE_270 is used, it's more stable than other. - * 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)) - meson_mmc_clk |= CLK_CO_PHASE_270; - else - meson_mmc_clk |= CLK_CO_PHASE_180; - - /* 180 phase tx clock */ - meson_mmc_clk |= CLK_TX_PHASE_000; - /* clock settings */ meson_mmc_clk |= clk_src; meson_mmc_clk |= clk_div; @@ -243,6 +234,7 @@ static const struct dm_mmc_ops meson_dm_mmc_ops = { static int meson_mmc_of_to_plat(struct udevice *dev) { + enum meson_gx_mmc_compatible compat = dev_get_driver_data(dev); struct meson_mmc_plat *pdata = dev_get_plat(dev); fdt_addr_t addr; @@ -251,6 +243,7 @@ static int meson_mmc_of_to_plat(struct udevice *dev) return -EINVAL; pdata->regbase = (void *)addr; + pdata->version = &meson_gx_mmc_version[compat]; return 0; } @@ -277,7 +270,7 @@ static int meson_mmc_probe(struct udevice *dev) 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 | - MMC_MODE_HS_52MHz | MMC_MODE_HS; + SD_HS | MMC_MODE_HS_52MHz | MMC_MODE_HS; cfg->f_min = DIV_ROUND_UP(SD_EMMC_CLKSRC_24M, CLK_MAX_DIV); cfg->f_max = 100000000; /* 100 MHz */ cfg->b_max = 511; /* max 512 - 1 blocks */ @@ -321,9 +314,9 @@ int meson_mmc_bind(struct udevice *dev) } static const struct udevice_id meson_mmc_match[] = { - { .compatible = "amlogic,meson-gx-mmc", .data = MMC_COMPATIBLE_GX }, - { .compatible = "amlogic,meson-axg-mmc", .data = MMC_COMPATIBLE_GX }, - { .compatible = "amlogic,meson-sm1-mmc", .data = MMC_COMPATIBLE_SM1 }, + { .compatible = "amlogic,meson-gx-mmc", .data = MMC_COMPATIBLE_V2 }, + { .compatible = "amlogic,meson-axg-mmc", .data = MMC_COMPATIBLE_V3 }, + { .compatible = "amlogic,meson-sm1-mmc", .data = MMC_COMPATIBLE_V3 }, { /* sentinel */ } }; diff --git a/drivers/mmc/meson_gx_mmc.h b/drivers/mmc/meson_gx_mmc.h index 8974b78f559d..3ec913d1b5ef 100644 --- a/drivers/mmc/meson_gx_mmc.h +++ b/drivers/mmc/meson_gx_mmc.h @@ -10,8 +10,8 @@ #include <linux/bitops.h> enum meson_gx_mmc_compatible { - MMC_COMPATIBLE_GX, - MMC_COMPATIBLE_SM1, + MMC_COMPATIBLE_V2, + MMC_COMPATIBLE_V3, }; #define SDIO_PORT_A 0 @@ -84,7 +84,12 @@ enum meson_gx_mmc_compatible { #define MESON_SD_EMMC_CMD_RSP2 0x64 #define MESON_SD_EMMC_CMD_RSP3 0x68 +struct meson_gx_mmc_version_data { + uint32_t clk_always_on; +}; + struct meson_mmc_plat { + struct meson_gx_mmc_version_data *version; struct mmc_config cfg; struct mmc mmc; void *regbase; -- 2.40.1