diff options
author | Peter Griffin <peter.griffin@linaro.org> | 2017-08-15 17:18:16 +0100 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2017-08-20 09:54:31 -0400 |
commit | fb53e7eb60567dae2181a3d55f51e72e03a2aac6 (patch) | |
tree | 746c4d0590b7c4b5ad3a72095423c5ddfabb7e19 | |
parent | 42a9f147d87b6e4442d6c3074c34b08854f36ef5 (diff) |
ARM: hisilicon: hikey: Fix eMMC with latest ATF & U-Boot
ATF can leave the MMC IP in a state where U-Boot mmc driver
can't enumerate the eMMC.
This patch provides a mmc0_reset_clk() function like we
already so do sd card controller which resets the IP
when entering U-Boot.
With this patch applied eMMC partitions are successfully
enumerated again.
=> mmc dev 0
switch to partitions #0, OK
mmc0(part 0) is current device
=> mmc part
Partition Map for MMC device 0 -- Partition Type: EFI
Part Start LBA End LBA Name
Attributes
Type GUID
Partition GUID
1 0x00000800 0x00000fff "vrl"
attrs: 0x0000000000000000
type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
guid: 496847ab-56a1-4cd5-a1ad-47f4acf055c9
2 0x00001000 0x000017ff "vrl_backup"
attrs: 0x0000000000000000
type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
guid: 61a36fc1-8efb-4899-84d8-b61642efa723
3 0x00001800 0x00001fff "mcuimage"
<snip>
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
-rw-r--r-- | board/hisilicon/hikey/hikey.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/board/hisilicon/hikey/hikey.c b/board/hisilicon/hikey/hikey.c index c513d0af10a..5357f870a99 100644 --- a/board/hisilicon/hikey/hikey.c +++ b/board/hisilicon/hikey/hikey.c @@ -295,13 +295,47 @@ static void mmc1_reset_clk(void) data = readl(&peri_sc->rst0_stat); } while (!(data & PERI_RST0_MMC1)); - /* unreset mmc0 clock domain */ + /* unreset mmc1 clock domain */ writel(PERI_RST0_MMC1, &peri_sc->rst0_dis); do { data = readl(&peri_sc->rst0_stat); } while (data & PERI_RST0_MMC1); } +static void mmc0_reset_clk(void) +{ + unsigned int data; + + /* disable mmc0 bus clock */ + hi6220_clk_disable(PERI_CLK0_MMC0, &peri_sc->clk0_dis); + + /* enable mmc0 bus clock */ + hi6220_clk_enable(PERI_CLK0_MMC0, &peri_sc->clk0_en); + + /* reset mmc0 clock domain */ + writel(PERI_RST0_MMC0, &peri_sc->rst0_en); + + /* bypass mmc0 clock phase */ + data = readl(&peri_sc->ctrl2); + data |= 3; + writel(data, &peri_sc->ctrl2); + + /* disable low power */ + data = readl(&peri_sc->ctrl13); + data |= 1 << 3; + writel(data, &peri_sc->ctrl13); + do { + data = readl(&peri_sc->rst0_stat); + } while (!(data & PERI_RST0_MMC0)); + + /* unreset mmc0 clock domain */ + writel(PERI_RST0_MMC0, &peri_sc->rst0_dis); + do { + data = readl(&peri_sc->rst0_stat); + } while (data & PERI_RST0_MMC0); +} + + /* PMU SSI is the IP that maps the external PMU hi6553 registers as IO */ static void hi6220_pmussi_init(void) { @@ -349,7 +383,8 @@ static int init_dwmmc(void) #ifdef CONFIG_MMC_DW - /* mmc0 clocks are already configured by ATF */ + /* mmc0 pll is already configured by ATF */ + mmc0_reset_clk(); ret = hi6220_pinmux_config(PERIPH_ID_SDMMC0); if (ret) printf("%s: Error configuring pinmux for eMMC (%d)\n" |