]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
ARM: hisilicon: hikey: Fix eMMC with latest ATF & U-Boot
authorPeter Griffin <peter.griffin@linaro.org>
Tue, 15 Aug 2017 16:18:16 +0000 (17:18 +0100)
committerTom Rini <trini@konsulko.com>
Sun, 20 Aug 2017 13:54:31 +0000 (09:54 -0400)
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>
board/hisilicon/hikey/hikey.c

index c513d0af10a6059b9256b5f44ad82bdaa031a3a9..5357f870a99134615db28b0c6302f15e6eaba800 100644 (file)
@@ -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"