summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2024-09-12 02:19:45 +0100
committerAndre Przywara <andre.przywara@arm.com>2025-07-27 22:57:35 +0100
commit869d396191ed226b66d9fe99e89230b359478d82 (patch)
tree6139394c179f737940ec1f59ae4a4981e0e760c9 /drivers/mmc
parent14c66b9e3510aa3a6c0f99ba1534c329e38dd94f (diff)
sunxi: mmc: add support for Allwinner A523 MMC mod clock
The Allwinner A523 SoC has a slightly changed mod clock, where the P factor, formerly a shift value, is now a second divider value. Also the input clock is not PLL_PERIPH0 (600MHz) anymore, but PLL_PERIPH0_400M (for MMC0/1), so adjust the input rate calculation accordingly. MMC2 has a different set of parents, so the input clock is 800 MHz there. Adjust for all of this. Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/sunxi_mmc.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 06c1e09bf26..e28c81afffe 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -99,6 +99,19 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
*/
if (IS_ENABLED(CONFIG_MACH_SUN8I_R528))
pll_hz /= 2;
+
+ /*
+ * The A523/T527 uses PERIPH0_400M as the MMC0/1 input clock,
+ * and PERIPH0_800M for MMC2. There is also the hidden divider
+ * of 2. The clock code reports 600 MHz for PERIPH0.
+ * Adjust the calculation accordingly: 600 * hidden2 / 3 for
+ * MMC0/1, and 600 * hidden2 / 3 * 2 for MMC2.
+ */
+ if (IS_ENABLED(CONFIG_MACH_SUN55I_A523)) {
+ pll_hz /= 3;
+ if (priv->mmc_no == 2)
+ pll_hz *= 2;
+ }
}
div = pll_hz / hz;
@@ -153,6 +166,10 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
CCM_MMC_CTRL_SCLK_DLY(sclk_dly);
}
+ /* The A523 has a second divider, not a shift. */
+ if (IS_ENABLED(CONFIG_MACH_SUN55I_A523))
+ n = (1U << n) - 1;
+
writel(CCM_MMC_CTRL_ENABLE| pll | CCM_MMC_CTRL_N(n) |
CCM_MMC_CTRL_M(div) | val, priv->mclkreg);
@@ -559,7 +576,8 @@ struct mmc *sunxi_mmc_init(int sdc_no)
cfg->host_caps = MMC_MODE_4BIT;
if ((IS_ENABLED(CONFIG_MACH_SUN50I) || IS_ENABLED(CONFIG_MACH_SUN8I) ||
- IS_ENABLED(CONFIG_SUN50I_GEN_H6)) && (sdc_no == 2))
+ IS_ENABLED(CONFIG_SUN50I_GEN_H6) || IS_ENABLED(CONFIG_MACH_SUN55I_A523)) &&
+ (sdc_no == 2))
cfg->host_caps = MMC_MODE_8BIT;
cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;