Almost all of the newer Allwinner SoCs have a new operating mode for the eMMC clocks that needs to be enabled in both the clock and the MMC controller.
Add support for it through a Kconfig option Signed-off-by: Maxime Ripard <maxime.rip...@free-electrons.com> --- arch/arm/include/asm/arch-sunxi/mmc.h | 9 ++++++--- drivers/mmc/Kconfig | 3 +++ drivers/mmc/sunxi_mmc.c | 26 +++++++++++++++++++++++--- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h index cb52e648731c..0c2d496295ff 100644 --- a/arch/arm/include/asm/arch-sunxi/mmc.h +++ b/arch/arm/include/asm/arch-sunxi/mmc.h @@ -35,16 +35,19 @@ struct sunxi_mmc { u32 cbcr; /* 0x48 CIU byte count */ u32 bbcr; /* 0x4c BIU byte count */ u32 dbgc; /* 0x50 debug enable */ - u32 res0[11]; + u32 res0; /* 0x54 reserved */ + u32 a12a; /* 0x58 Auto command 12 argument */ + u32 ntsr; /* 0x5c New timing set register */ + u32 res1[8]; u32 dmac; /* 0x80 internal DMA control */ u32 dlba; /* 0x84 internal DMA descr list base address */ u32 idst; /* 0x88 internal DMA status */ u32 idie; /* 0x8c internal DMA interrupt enable */ u32 chda; /* 0x90 */ u32 cbda; /* 0x94 */ - u32 res1[26]; + u32 res2[26]; #ifdef CONFIG_SUNXI_GEN_SUN6I - u32 res2[64]; + u32 res3[64]; #endif u32 fifo; /* 0x100 / 0x200 FIFO access address */ }; diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 82b8d756867c..203f59547100 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -368,6 +368,9 @@ config MMC_SUNXI This selects support for the SD/MMC Host Controller on Allwinner sunxi SoCs. +config MMC_SUNXI_HAS_NEW_MODE + bool + config GENERIC_ATMEL_MCI bool "Atmel Multimedia Card Interface support" depends on DM_MMC && BLK && DM_MMC_OPS && ARCH_AT91 diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index fd3fc2af40a0..68750f3832b6 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -87,6 +87,20 @@ static int mmc_resource_init(int sdc_no) static int mmc_set_mod_clk(struct sunxi_mmc_host *mmchost, unsigned int hz) { unsigned int pll, pll_hz, div, n, oclk_dly, sclk_dly; + bool new_mode = false; + u32 val = 0; + +#ifdef CONFIG_MMC_SUNXI_HAS_NEW_MODE + if (mmchost->mmc_no == 2) + new_mode = true; +#endif + + /* + * The MMC clock has an extra /2 post-divider when operating in the new + * mode. + */ + if (new_mode) + hz = hz * 2; if (hz <= 24000000) { pll = CCM_MMC_CTRL_OSCM24; @@ -143,9 +157,15 @@ static int mmc_set_mod_clk(struct sunxi_mmc_host *mmchost, unsigned int hz) #endif } - writel(CCM_MMC_CTRL_ENABLE | pll | CCM_MMC_CTRL_SCLK_DLY(sclk_dly) | - CCM_MMC_CTRL_N(n) | CCM_MMC_CTRL_OCLK_DLY(oclk_dly) | - CCM_MMC_CTRL_M(div), mmchost->mclkreg); + if (new_mode) { + val = BIT(30); + writel(BIT(31), &mmchost->reg->ntsr); + } else { + val = CCM_MMC_CTRL_OCLK_DLY(oclk_dly) | CCM_MMC_CTRL_SCLK_DLY(sclk_dly); + } + + writel(CCM_MMC_CTRL_ENABLE| pll | CCM_MMC_CTRL_N(n) | CCM_MMC_CTRL_M(div) | val, + mmchost->mclkreg); debug("mmc %u set mod-clk req %u parent %u n %u m %u rate %u\n", mmchost->mmc_no, hz, pll_hz, 1u << n, div, -- 2.13.0 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot