diff options
author | Tom Rini <trini@konsulko.com> | 2025-03-27 08:10:06 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2025-03-27 08:10:06 -0600 |
commit | 02d95aaee01a2faf53bba8f1417b55cd02b6a743 (patch) | |
tree | 91ad26d87939e3e0887e1d6c44a0c0a948e472f3 /drivers/mmc | |
parent | 4adbf64ff8d8c730223fd8ae299d770bebb6fe86 (diff) | |
parent | 6d6d58be25dd0b8e1955b15cf197f418be58bfd9 (diff) |
Merge branch 'next' of https://source.denx.de/u-boot/custodians/u-boot-sunxi into next
Assorted fixes, refactorings and additions that are ready, and shave
off some load from upcoming series'.
Improves MMC performance on D1/T113 (missed clock divider), enables
eMMC access on the H616 family (never worked, many thanks to Jernej for
the fix!), DRAM detection fixes for the H616 (now reportedly stable).
Some patches for the upcoming Allwinner A133 SoC support: a few
refactorings, plus the DM clock and pinctrl driver. The DRAM init
routines work, but need some more polishing, that also holds back the
actual enablement patch, which will hopefully follow for v2025.07 still.
Also some preparatory patches for the Allwinner A523 SoC support, for
now just to improve the FEL save/restore code. There will be more patches
coming up for this, ideally also in the coming cycle still.
Gitlab CI passed, and I booted that briefly on some boards.
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/sunxi_mmc.c | 35 | ||||
-rw-r--r-- | drivers/mmc/sunxi_mmc.h | 18 |
2 files changed, 45 insertions, 8 deletions
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 0b56d1405be..951e6acd34d 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -92,6 +92,13 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz) pll = CCM_MMC_CTRL_PLL6; pll_hz = clock_get_pll6(); #endif + /* + * On the D1/R528/T113 mux source 1 refers to PLL_PERIPH0(1x), + * like for the older SoCs. However we still have the hidden + * divider of 2x, so compensate for that here. + */ + if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) + pll_hz /= 2; } div = pll_hz / hz; @@ -442,6 +449,26 @@ out: return error; } +static void sunxi_mmc_reset(void *regs) +{ + /* Reset controller */ + writel(SUNXI_MMC_GCTRL_RESET, regs + SUNXI_MMC_GCTRL); + udelay(1000); + + if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) || IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) { + /* Reset card */ + writel(SUNXI_MMC_HWRST_ASSERT, regs + SUNXI_MMC_HWRST); + udelay(10); + writel(SUNXI_MMC_HWRST_DEASSERT, regs + SUNXI_MMC_HWRST); + udelay(300); + + /* Setup FIFO R/W threshold. Needed on H616. */ + writel(SUNXI_MMC_THLDC_READ_THLD(512) | + SUNXI_MMC_THLDC_WRITE_EN | + SUNXI_MMC_THLDC_READ_EN, regs + SUNXI_MMC_THLDC); + } +} + /* non-DM code here is used by the (ARM) SPL only */ #if !CONFIG_IS_ENABLED(DM_MMC) @@ -489,9 +516,7 @@ static int sunxi_mmc_core_init(struct mmc *mmc) { struct sunxi_mmc_priv *priv = mmc->priv; - /* Reset controller */ - writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl); - udelay(1000); + sunxi_mmc_reset(priv->reg); return 0; } @@ -684,9 +709,7 @@ static int sunxi_mmc_probe(struct udevice *dev) upriv->mmc = &plat->mmc; - /* Reset controller */ - writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl); - udelay(1000); + sunxi_mmc_reset(priv->reg); return 0; } diff --git a/drivers/mmc/sunxi_mmc.h b/drivers/mmc/sunxi_mmc.h index f4ae5a790c8..71865160319 100644 --- a/drivers/mmc/sunxi_mmc.h +++ b/drivers/mmc/sunxi_mmc.h @@ -37,7 +37,9 @@ struct sunxi_mmc { u32 res0; /* 0x54 reserved */ u32 a12a; /* 0x58 Auto command 12 argument */ u32 ntsr; /* 0x5c New timing set register */ - u32 res1[8]; + u32 res1[6]; + u32 hwrst; /* 0x78 Hardware Reset */ + u32 res5; u32 dmac; /* 0x80 internal DMA control */ u32 dlba; /* 0x84 internal DMA descr list base address */ u32 idst; /* 0x88 internal DMA status */ @@ -46,7 +48,8 @@ struct sunxi_mmc { u32 cbda; /* 0x94 */ u32 res2[26]; #if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2) - u32 res3[17]; + u32 thldc; /* 0x100 Threshold control */ + u32 res3[16]; u32 samp_dl; u32 res4[46]; #endif @@ -57,6 +60,7 @@ struct sunxi_mmc { #define SUNXI_MMC_CLK_ENABLE (0x1 << 16) #define SUNXI_MMC_CLK_DIVIDER_MASK (0xff) +#define SUNXI_MMC_GCTRL 0x000 #define SUNXI_MMC_GCTRL_SOFT_RESET (0x1 << 0) #define SUNXI_MMC_GCTRL_FIFO_RESET (0x1 << 1) #define SUNXI_MMC_GCTRL_DMA_RESET (0x1 << 2) @@ -123,6 +127,10 @@ struct sunxi_mmc { #define SUNXI_MMC_NTSR_MODE_SEL_NEW (0x1 << 31) +#define SUNXI_MMC_HWRST 0x078 +#define SUNXI_MMC_HWRST_ASSERT (0x0 << 0) +#define SUNXI_MMC_HWRST_DEASSERT (0x1 << 0) + #define SUNXI_MMC_IDMAC_RESET (0x1 << 0) #define SUNXI_MMC_IDMAC_FIXBURST (0x1 << 1) #define SUNXI_MMC_IDMAC_ENABLE (0x1 << 7) @@ -133,6 +141,12 @@ struct sunxi_mmc { #define SUNXI_MMC_COMMON_CLK_GATE (1 << 16) #define SUNXI_MMC_COMMON_RESET (1 << 18) +#define SUNXI_MMC_THLDC 0x100 +#define SUNXI_MMC_THLDC_READ_EN (0x1 << 0) +#define SUNXI_MMC_THLDC_BSY_CLR_INT_EN (0x1 << 1) +#define SUNXI_MMC_THLDC_WRITE_EN (0x1 << 2) +#define SUNXI_MMC_THLDC_READ_THLD(x) (((x) & 0xfff) << 16) + #define SUNXI_MMC_CAL_DL_SW_EN (0x1 << 7) #endif /* _SUNXI_MMC_H */ |