111ac2363SPeter Griffin /*
211ac2363SPeter Griffin * (C) Copyright 2015 Linaro
311ac2363SPeter Griffin * Peter Griffin <peter.griffin@linaro.org>
411ac2363SPeter Griffin *
511ac2363SPeter Griffin * SPDX-License-Identifier: GPL-2.0+
611ac2363SPeter Griffin */
711ac2363SPeter Griffin #include <common.h>
811ac2363SPeter Griffin #include <dm.h>
99c71bcdcSPeter Griffin #include <dm/platform_data/serial_pl01x.h>
1011ac2363SPeter Griffin #include <errno.h>
1111ac2363SPeter Griffin #include <malloc.h>
1211ac2363SPeter Griffin #include <netdev.h>
1311ac2363SPeter Griffin #include <asm/io.h>
1411ac2363SPeter Griffin #include <usb.h>
1511ac2363SPeter Griffin #include <power/hi6553_pmic.h>
1611ac2363SPeter Griffin #include <asm-generic/gpio.h>
1711ac2363SPeter Griffin #include <asm/arch/dwmmc.h>
1811ac2363SPeter Griffin #include <asm/arch/gpio.h>
1911ac2363SPeter Griffin #include <asm/arch/periph.h>
2011ac2363SPeter Griffin #include <asm/arch/pinmux.h>
2111ac2363SPeter Griffin #include <asm/arch/hi6220.h>
2221845825SAlexander Graf #include <asm/armv8/mmu.h>
2311ac2363SPeter Griffin
2411ac2363SPeter Griffin /*TODO drop this table in favour of device tree */
2511ac2363SPeter Griffin static const struct hikey_gpio_platdata hi6220_gpio[] = {
2611ac2363SPeter Griffin { 0, HI6220_GPIO_BASE(0)},
2711ac2363SPeter Griffin { 1, HI6220_GPIO_BASE(1)},
2811ac2363SPeter Griffin { 2, HI6220_GPIO_BASE(2)},
2911ac2363SPeter Griffin { 3, HI6220_GPIO_BASE(3)},
3011ac2363SPeter Griffin { 4, HI6220_GPIO_BASE(4)},
3111ac2363SPeter Griffin { 5, HI6220_GPIO_BASE(5)},
3211ac2363SPeter Griffin { 6, HI6220_GPIO_BASE(6)},
3311ac2363SPeter Griffin { 7, HI6220_GPIO_BASE(7)},
3411ac2363SPeter Griffin { 8, HI6220_GPIO_BASE(8)},
3511ac2363SPeter Griffin { 9, HI6220_GPIO_BASE(9)},
3611ac2363SPeter Griffin { 10, HI6220_GPIO_BASE(10)},
3711ac2363SPeter Griffin { 11, HI6220_GPIO_BASE(11)},
3811ac2363SPeter Griffin { 12, HI6220_GPIO_BASE(12)},
3911ac2363SPeter Griffin { 13, HI6220_GPIO_BASE(13)},
4011ac2363SPeter Griffin { 14, HI6220_GPIO_BASE(14)},
4111ac2363SPeter Griffin { 15, HI6220_GPIO_BASE(15)},
4211ac2363SPeter Griffin { 16, HI6220_GPIO_BASE(16)},
4311ac2363SPeter Griffin { 17, HI6220_GPIO_BASE(17)},
4411ac2363SPeter Griffin { 18, HI6220_GPIO_BASE(18)},
4511ac2363SPeter Griffin { 19, HI6220_GPIO_BASE(19)},
4611ac2363SPeter Griffin
4711ac2363SPeter Griffin };
4811ac2363SPeter Griffin
4911ac2363SPeter Griffin U_BOOT_DEVICES(hi6220_gpios) = {
5011ac2363SPeter Griffin { "gpio_hi6220", &hi6220_gpio[0] },
5111ac2363SPeter Griffin { "gpio_hi6220", &hi6220_gpio[1] },
5211ac2363SPeter Griffin { "gpio_hi6220", &hi6220_gpio[2] },
5311ac2363SPeter Griffin { "gpio_hi6220", &hi6220_gpio[3] },
5411ac2363SPeter Griffin { "gpio_hi6220", &hi6220_gpio[4] },
5511ac2363SPeter Griffin { "gpio_hi6220", &hi6220_gpio[5] },
5611ac2363SPeter Griffin { "gpio_hi6220", &hi6220_gpio[6] },
5711ac2363SPeter Griffin { "gpio_hi6220", &hi6220_gpio[7] },
5811ac2363SPeter Griffin { "gpio_hi6220", &hi6220_gpio[8] },
5911ac2363SPeter Griffin { "gpio_hi6220", &hi6220_gpio[9] },
6011ac2363SPeter Griffin { "gpio_hi6220", &hi6220_gpio[10] },
6111ac2363SPeter Griffin { "gpio_hi6220", &hi6220_gpio[11] },
6211ac2363SPeter Griffin { "gpio_hi6220", &hi6220_gpio[12] },
6311ac2363SPeter Griffin { "gpio_hi6220", &hi6220_gpio[13] },
6411ac2363SPeter Griffin { "gpio_hi6220", &hi6220_gpio[14] },
6511ac2363SPeter Griffin { "gpio_hi6220", &hi6220_gpio[15] },
6611ac2363SPeter Griffin { "gpio_hi6220", &hi6220_gpio[16] },
6711ac2363SPeter Griffin { "gpio_hi6220", &hi6220_gpio[17] },
6811ac2363SPeter Griffin { "gpio_hi6220", &hi6220_gpio[18] },
6911ac2363SPeter Griffin { "gpio_hi6220", &hi6220_gpio[19] },
7011ac2363SPeter Griffin };
7111ac2363SPeter Griffin
7211ac2363SPeter Griffin DECLARE_GLOBAL_DATA_PTR;
7311ac2363SPeter Griffin
74cd593ed6SPeter Griffin #if !CONFIG_IS_ENABLED(OF_CONTROL)
75cd593ed6SPeter Griffin
769c71bcdcSPeter Griffin static const struct pl01x_serial_platdata serial_platdata = {
779c71bcdcSPeter Griffin #if CONFIG_CONS_INDEX == 1
789c71bcdcSPeter Griffin .base = HI6220_UART0_BASE,
799c71bcdcSPeter Griffin #elif CONFIG_CONS_INDEX == 4
809c71bcdcSPeter Griffin .base = HI6220_UART3_BASE,
819c71bcdcSPeter Griffin #else
820af49b95SVagrant Cascadian #error "Unsupported console index value."
839c71bcdcSPeter Griffin #endif
849c71bcdcSPeter Griffin .type = TYPE_PL011,
859c71bcdcSPeter Griffin .clock = 19200000
869c71bcdcSPeter Griffin };
879c71bcdcSPeter Griffin
889c71bcdcSPeter Griffin U_BOOT_DEVICE(hikey_seriala) = {
899c71bcdcSPeter Griffin .name = "serial_pl01x",
909c71bcdcSPeter Griffin .platdata = &serial_platdata,
919c71bcdcSPeter Griffin };
92cd593ed6SPeter Griffin #endif
939c71bcdcSPeter Griffin
9421845825SAlexander Graf static struct mm_region hikey_mem_map[] = {
9521845825SAlexander Graf {
96cd4b0c5fSYork Sun .virt = 0x0UL,
97cd4b0c5fSYork Sun .phys = 0x0UL,
9821845825SAlexander Graf .size = 0x80000000UL,
9921845825SAlexander Graf .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
10021845825SAlexander Graf PTE_BLOCK_INNER_SHARE
10121845825SAlexander Graf }, {
102cd4b0c5fSYork Sun .virt = 0x80000000UL,
103cd4b0c5fSYork Sun .phys = 0x80000000UL,
10421845825SAlexander Graf .size = 0x80000000UL,
10521845825SAlexander Graf .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
10621845825SAlexander Graf PTE_BLOCK_NON_SHARE |
10721845825SAlexander Graf PTE_BLOCK_PXN | PTE_BLOCK_UXN
10821845825SAlexander Graf }, {
10921845825SAlexander Graf /* List terminator */
11021845825SAlexander Graf 0,
11121845825SAlexander Graf }
11221845825SAlexander Graf };
11321845825SAlexander Graf
11421845825SAlexander Graf struct mm_region *mem_map = hikey_mem_map;
11521845825SAlexander Graf
1169c71bcdcSPeter Griffin #ifdef CONFIG_BOARD_EARLY_INIT_F
board_uart_init(void)1179c71bcdcSPeter Griffin int board_uart_init(void)
1189c71bcdcSPeter Griffin {
1199c71bcdcSPeter Griffin switch (CONFIG_CONS_INDEX) {
1209c71bcdcSPeter Griffin case 1:
1219c71bcdcSPeter Griffin hi6220_pinmux_config(PERIPH_ID_UART0);
1229c71bcdcSPeter Griffin break;
1239c71bcdcSPeter Griffin case 4:
1249c71bcdcSPeter Griffin hi6220_pinmux_config(PERIPH_ID_UART3);
1259c71bcdcSPeter Griffin break;
1269c71bcdcSPeter Griffin default:
1279c71bcdcSPeter Griffin debug("%s: Unsupported UART selected\n", __func__);
1289c71bcdcSPeter Griffin return -1;
1299c71bcdcSPeter Griffin }
1309c71bcdcSPeter Griffin
1319c71bcdcSPeter Griffin return 0;
1329c71bcdcSPeter Griffin }
1339c71bcdcSPeter Griffin
board_early_init_f(void)1349c71bcdcSPeter Griffin int board_early_init_f(void)
1359c71bcdcSPeter Griffin {
1369c71bcdcSPeter Griffin board_uart_init();
1379c71bcdcSPeter Griffin return 0;
1389c71bcdcSPeter Griffin }
1399c71bcdcSPeter Griffin #endif
1409c71bcdcSPeter Griffin
14111ac2363SPeter Griffin struct peri_sc_periph_regs *peri_sc =
14211ac2363SPeter Griffin (struct peri_sc_periph_regs *)HI6220_PERI_BASE;
14311ac2363SPeter Griffin
14411ac2363SPeter Griffin struct alwayson_sc_regs *ao_sc =
14511ac2363SPeter Griffin (struct alwayson_sc_regs *)ALWAYSON_CTRL_BASE;
14611ac2363SPeter Griffin
14711ac2363SPeter Griffin /* status offset from enable reg */
14811ac2363SPeter Griffin #define STAT_EN_OFF 0x2
14911ac2363SPeter Griffin
hi6220_clk_enable(u32 bitfield,unsigned int * clk_base)15011ac2363SPeter Griffin void hi6220_clk_enable(u32 bitfield, unsigned int *clk_base)
15111ac2363SPeter Griffin {
15211ac2363SPeter Griffin uint32_t data;
15311ac2363SPeter Griffin
15411ac2363SPeter Griffin data = readl(clk_base);
15511ac2363SPeter Griffin data |= bitfield;
15611ac2363SPeter Griffin
15711ac2363SPeter Griffin writel(bitfield, clk_base);
15811ac2363SPeter Griffin do {
15911ac2363SPeter Griffin data = readl(clk_base + STAT_EN_OFF);
16011ac2363SPeter Griffin } while ((data & bitfield) == 0);
16111ac2363SPeter Griffin }
16211ac2363SPeter Griffin
16311ac2363SPeter Griffin /* status offset from disable reg */
16411ac2363SPeter Griffin #define STAT_DIS_OFF 0x1
16511ac2363SPeter Griffin
hi6220_clk_disable(u32 bitfield,unsigned int * clk_base)16611ac2363SPeter Griffin void hi6220_clk_disable(u32 bitfield, unsigned int *clk_base)
16711ac2363SPeter Griffin {
16811ac2363SPeter Griffin uint32_t data;
16911ac2363SPeter Griffin
17011ac2363SPeter Griffin data = readl(clk_base);
17111ac2363SPeter Griffin data |= bitfield;
17211ac2363SPeter Griffin
17311ac2363SPeter Griffin writel(data, clk_base);
17411ac2363SPeter Griffin do {
17511ac2363SPeter Griffin data = readl(clk_base + STAT_DIS_OFF);
17611ac2363SPeter Griffin } while (data & bitfield);
17711ac2363SPeter Griffin }
17811ac2363SPeter Griffin
17911ac2363SPeter Griffin #define EYE_PATTERN 0x70533483
18011ac2363SPeter Griffin
board_usb_init(int index,enum usb_init_type init)18111ac2363SPeter Griffin int board_usb_init(int index, enum usb_init_type init)
18211ac2363SPeter Griffin {
18311ac2363SPeter Griffin unsigned int data;
18411ac2363SPeter Griffin
18511ac2363SPeter Griffin /* enable USB clock */
18611ac2363SPeter Griffin hi6220_clk_enable(PERI_CLK0_USBOTG, &peri_sc->clk0_en);
18711ac2363SPeter Griffin
18811ac2363SPeter Griffin /* take usb IPs out of reset */
18911ac2363SPeter Griffin writel(PERI_RST0_USBOTG_BUS | PERI_RST0_POR_PICOPHY |
19011ac2363SPeter Griffin PERI_RST0_USBOTG | PERI_RST0_USBOTG_32K,
19111ac2363SPeter Griffin &peri_sc->rst0_dis);
19211ac2363SPeter Griffin do {
19311ac2363SPeter Griffin data = readl(&peri_sc->rst0_stat);
19411ac2363SPeter Griffin data &= PERI_RST0_USBOTG_BUS | PERI_RST0_POR_PICOPHY |
19511ac2363SPeter Griffin PERI_RST0_USBOTG | PERI_RST0_USBOTG_32K;
19611ac2363SPeter Griffin } while (data);
19711ac2363SPeter Griffin
19811ac2363SPeter Griffin /*CTRL 5*/
19911ac2363SPeter Griffin data = readl(&peri_sc->ctrl5);
20011ac2363SPeter Griffin data &= ~PERI_CTRL5_PICOPHY_BC_MODE;
20111ac2363SPeter Griffin data |= PERI_CTRL5_USBOTG_RES_SEL | PERI_CTRL5_PICOPHY_ACAENB;
20211ac2363SPeter Griffin data |= 0x300;
20311ac2363SPeter Griffin writel(data, &peri_sc->ctrl5);
20411ac2363SPeter Griffin
20511ac2363SPeter Griffin /*CTRL 4*/
20611ac2363SPeter Griffin
20711ac2363SPeter Griffin /* configure USB PHY */
20811ac2363SPeter Griffin data = readl(&peri_sc->ctrl4);
20911ac2363SPeter Griffin
21011ac2363SPeter Griffin /* make PHY out of low power mode */
21111ac2363SPeter Griffin data &= ~PERI_CTRL4_PICO_SIDDQ;
21211ac2363SPeter Griffin data &= ~PERI_CTRL4_PICO_OGDISABLE;
21311ac2363SPeter Griffin data |= PERI_CTRL4_PICO_VBUSVLDEXTSEL | PERI_CTRL4_PICO_VBUSVLDEXT;
21411ac2363SPeter Griffin writel(data, &peri_sc->ctrl4);
21511ac2363SPeter Griffin
21611ac2363SPeter Griffin writel(EYE_PATTERN, &peri_sc->ctrl8);
21711ac2363SPeter Griffin
21811ac2363SPeter Griffin mdelay(5);
21911ac2363SPeter Griffin return 0;
22011ac2363SPeter Griffin }
22111ac2363SPeter Griffin
config_sd_carddetect(void)22211ac2363SPeter Griffin static int config_sd_carddetect(void)
22311ac2363SPeter Griffin {
22411ac2363SPeter Griffin int ret;
22511ac2363SPeter Griffin
22611ac2363SPeter Griffin /* configure GPIO8 as nopull */
22711ac2363SPeter Griffin writel(0, 0xf8001830);
22811ac2363SPeter Griffin
22911ac2363SPeter Griffin gpio_request(8, "SD CD");
23011ac2363SPeter Griffin
23111ac2363SPeter Griffin gpio_direction_input(8);
23211ac2363SPeter Griffin ret = gpio_get_value(8);
23311ac2363SPeter Griffin
23411ac2363SPeter Griffin if (!ret) {
23511ac2363SPeter Griffin printf("%s: SD card present\n", __func__);
23611ac2363SPeter Griffin return 1;
23711ac2363SPeter Griffin }
23811ac2363SPeter Griffin
23911ac2363SPeter Griffin printf("%s: SD card not present\n", __func__);
24011ac2363SPeter Griffin return 0;
24111ac2363SPeter Griffin }
24211ac2363SPeter Griffin
24311ac2363SPeter Griffin
mmc1_init_pll(void)24411ac2363SPeter Griffin static void mmc1_init_pll(void)
24511ac2363SPeter Griffin {
24611ac2363SPeter Griffin uint32_t data;
24711ac2363SPeter Griffin
24811ac2363SPeter Griffin /* select SYSPLL as the source of MMC1 */
24911ac2363SPeter Griffin /* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */
25011ac2363SPeter Griffin writel(1 << 11 | 1 << 27, &peri_sc->clk0_sel);
25111ac2363SPeter Griffin do {
25211ac2363SPeter Griffin data = readl(&peri_sc->clk0_sel);
25311ac2363SPeter Griffin } while (!(data & (1 << 11)));
25411ac2363SPeter Griffin
25511ac2363SPeter Griffin /* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */
25611ac2363SPeter Griffin writel(1 << 30, &peri_sc->clk0_sel);
25711ac2363SPeter Griffin do {
25811ac2363SPeter Griffin data = readl(&peri_sc->clk0_sel);
25911ac2363SPeter Griffin } while (data & (1 << 14));
26011ac2363SPeter Griffin
26111ac2363SPeter Griffin hi6220_clk_enable(PERI_CLK0_MMC1, &peri_sc->clk0_en);
26211ac2363SPeter Griffin
26311ac2363SPeter Griffin hi6220_clk_enable(PERI_CLK12_MMC1_SRC, &peri_sc->clk12_en);
26411ac2363SPeter Griffin
26511ac2363SPeter Griffin do {
26611ac2363SPeter Griffin /* 1.2GHz / 50 = 24MHz */
26711ac2363SPeter Griffin writel(0x31 | (1 << 7), &peri_sc->clkcfg8bit2);
26811ac2363SPeter Griffin data = readl(&peri_sc->clkcfg8bit2);
26911ac2363SPeter Griffin } while ((data & 0x31) != 0x31);
27011ac2363SPeter Griffin }
27111ac2363SPeter Griffin
mmc1_reset_clk(void)27211ac2363SPeter Griffin static void mmc1_reset_clk(void)
27311ac2363SPeter Griffin {
27411ac2363SPeter Griffin unsigned int data;
27511ac2363SPeter Griffin
27611ac2363SPeter Griffin /* disable mmc1 bus clock */
27711ac2363SPeter Griffin hi6220_clk_disable(PERI_CLK0_MMC1, &peri_sc->clk0_dis);
27811ac2363SPeter Griffin
27911ac2363SPeter Griffin /* enable mmc1 bus clock */
28011ac2363SPeter Griffin hi6220_clk_enable(PERI_CLK0_MMC1, &peri_sc->clk0_en);
28111ac2363SPeter Griffin
28211ac2363SPeter Griffin /* reset mmc1 clock domain */
28311ac2363SPeter Griffin writel(PERI_RST0_MMC1, &peri_sc->rst0_en);
28411ac2363SPeter Griffin
28511ac2363SPeter Griffin /* bypass mmc1 clock phase */
28611ac2363SPeter Griffin data = readl(&peri_sc->ctrl2);
28711ac2363SPeter Griffin data |= 3 << 2;
28811ac2363SPeter Griffin writel(data, &peri_sc->ctrl2);
28911ac2363SPeter Griffin
29011ac2363SPeter Griffin /* disable low power */
29111ac2363SPeter Griffin data = readl(&peri_sc->ctrl13);
29211ac2363SPeter Griffin data |= 1 << 4;
29311ac2363SPeter Griffin writel(data, &peri_sc->ctrl13);
29411ac2363SPeter Griffin do {
29511ac2363SPeter Griffin data = readl(&peri_sc->rst0_stat);
29611ac2363SPeter Griffin } while (!(data & PERI_RST0_MMC1));
29711ac2363SPeter Griffin
298*fb53e7ebSPeter Griffin /* unreset mmc1 clock domain */
29911ac2363SPeter Griffin writel(PERI_RST0_MMC1, &peri_sc->rst0_dis);
30011ac2363SPeter Griffin do {
30111ac2363SPeter Griffin data = readl(&peri_sc->rst0_stat);
30211ac2363SPeter Griffin } while (data & PERI_RST0_MMC1);
30311ac2363SPeter Griffin }
30411ac2363SPeter Griffin
mmc0_reset_clk(void)305*fb53e7ebSPeter Griffin static void mmc0_reset_clk(void)
306*fb53e7ebSPeter Griffin {
307*fb53e7ebSPeter Griffin unsigned int data;
308*fb53e7ebSPeter Griffin
309*fb53e7ebSPeter Griffin /* disable mmc0 bus clock */
310*fb53e7ebSPeter Griffin hi6220_clk_disable(PERI_CLK0_MMC0, &peri_sc->clk0_dis);
311*fb53e7ebSPeter Griffin
312*fb53e7ebSPeter Griffin /* enable mmc0 bus clock */
313*fb53e7ebSPeter Griffin hi6220_clk_enable(PERI_CLK0_MMC0, &peri_sc->clk0_en);
314*fb53e7ebSPeter Griffin
315*fb53e7ebSPeter Griffin /* reset mmc0 clock domain */
316*fb53e7ebSPeter Griffin writel(PERI_RST0_MMC0, &peri_sc->rst0_en);
317*fb53e7ebSPeter Griffin
318*fb53e7ebSPeter Griffin /* bypass mmc0 clock phase */
319*fb53e7ebSPeter Griffin data = readl(&peri_sc->ctrl2);
320*fb53e7ebSPeter Griffin data |= 3;
321*fb53e7ebSPeter Griffin writel(data, &peri_sc->ctrl2);
322*fb53e7ebSPeter Griffin
323*fb53e7ebSPeter Griffin /* disable low power */
324*fb53e7ebSPeter Griffin data = readl(&peri_sc->ctrl13);
325*fb53e7ebSPeter Griffin data |= 1 << 3;
326*fb53e7ebSPeter Griffin writel(data, &peri_sc->ctrl13);
327*fb53e7ebSPeter Griffin do {
328*fb53e7ebSPeter Griffin data = readl(&peri_sc->rst0_stat);
329*fb53e7ebSPeter Griffin } while (!(data & PERI_RST0_MMC0));
330*fb53e7ebSPeter Griffin
331*fb53e7ebSPeter Griffin /* unreset mmc0 clock domain */
332*fb53e7ebSPeter Griffin writel(PERI_RST0_MMC0, &peri_sc->rst0_dis);
333*fb53e7ebSPeter Griffin do {
334*fb53e7ebSPeter Griffin data = readl(&peri_sc->rst0_stat);
335*fb53e7ebSPeter Griffin } while (data & PERI_RST0_MMC0);
336*fb53e7ebSPeter Griffin }
337*fb53e7ebSPeter Griffin
338*fb53e7ebSPeter Griffin
33911ac2363SPeter Griffin /* PMU SSI is the IP that maps the external PMU hi6553 registers as IO */
hi6220_pmussi_init(void)34011ac2363SPeter Griffin static void hi6220_pmussi_init(void)
34111ac2363SPeter Griffin {
34211ac2363SPeter Griffin uint32_t data;
34311ac2363SPeter Griffin
34411ac2363SPeter Griffin /* Take PMUSSI out of reset */
34511ac2363SPeter Griffin writel(ALWAYSON_SC_PERIPH_RST4_DIS_PRESET_PMUSSI_N,
34611ac2363SPeter Griffin &ao_sc->rst4_dis);
34711ac2363SPeter Griffin do {
34811ac2363SPeter Griffin data = readl(&ao_sc->rst4_stat);
34911ac2363SPeter Griffin } while (data & ALWAYSON_SC_PERIPH_RST4_DIS_PRESET_PMUSSI_N);
35011ac2363SPeter Griffin
35111ac2363SPeter Griffin /* set PMU SSI clock latency for read operation */
35211ac2363SPeter Griffin data = readl(&ao_sc->mcu_subsys_ctrl3);
35311ac2363SPeter Griffin data &= ~ALWAYSON_SC_MCU_SUBSYS_CTRL3_RCLK_MASK;
35411ac2363SPeter Griffin data |= ALWAYSON_SC_MCU_SUBSYS_CTRL3_RCLK_3;
35511ac2363SPeter Griffin writel(data, &ao_sc->mcu_subsys_ctrl3);
35611ac2363SPeter Griffin
35711ac2363SPeter Griffin /* enable PMUSSI clock */
35811ac2363SPeter Griffin data = ALWAYSON_SC_PERIPH_CLK5_EN_PCLK_PMUSSI_CCPU |
35911ac2363SPeter Griffin ALWAYSON_SC_PERIPH_CLK5_EN_PCLK_PMUSSI_MCU;
36011ac2363SPeter Griffin
36111ac2363SPeter Griffin hi6220_clk_enable(data, &ao_sc->clk5_en);
36211ac2363SPeter Griffin
36311ac2363SPeter Griffin /* Output high to PMIC on PWR_HOLD_GPIO0_0 */
36411ac2363SPeter Griffin gpio_request(0, "PWR_HOLD_GPIO0_0");
36511ac2363SPeter Griffin gpio_direction_output(0, 1);
36611ac2363SPeter Griffin }
36711ac2363SPeter Griffin
misc_init_r(void)36811ac2363SPeter Griffin int misc_init_r(void)
36911ac2363SPeter Griffin {
37011ac2363SPeter Griffin return 0;
37111ac2363SPeter Griffin }
37211ac2363SPeter Griffin
board_init(void)37311ac2363SPeter Griffin int board_init(void)
37411ac2363SPeter Griffin {
37511ac2363SPeter Griffin return 0;
37611ac2363SPeter Griffin }
37711ac2363SPeter Griffin
3784aa2ba3aSMasahiro Yamada #ifdef CONFIG_MMC
37911ac2363SPeter Griffin
init_dwmmc(void)38011ac2363SPeter Griffin static int init_dwmmc(void)
38111ac2363SPeter Griffin {
3822d5e86b1Sxypron.glpk@gmx.de int ret = 0;
38311ac2363SPeter Griffin
38455ed3b46SMasahiro Yamada #ifdef CONFIG_MMC_DW
38511ac2363SPeter Griffin
386*fb53e7ebSPeter Griffin /* mmc0 pll is already configured by ATF */
387*fb53e7ebSPeter Griffin mmc0_reset_clk();
38811ac2363SPeter Griffin ret = hi6220_pinmux_config(PERIPH_ID_SDMMC0);
38911ac2363SPeter Griffin if (ret)
39011ac2363SPeter Griffin printf("%s: Error configuring pinmux for eMMC (%d)\n"
39111ac2363SPeter Griffin , __func__, ret);
39211ac2363SPeter Griffin
39311ac2363SPeter Griffin ret |= hi6220_dwmci_add_port(0, HI6220_MMC0_BASE, 8);
39411ac2363SPeter Griffin if (ret)
39511ac2363SPeter Griffin printf("%s: Error adding eMMC port (%d)\n", __func__, ret);
39611ac2363SPeter Griffin
39711ac2363SPeter Griffin
39811ac2363SPeter Griffin /* take mmc1 (sd slot) out of reset, configure clocks and pinmuxing */
39911ac2363SPeter Griffin mmc1_init_pll();
40011ac2363SPeter Griffin mmc1_reset_clk();
40111ac2363SPeter Griffin
40211ac2363SPeter Griffin ret |= hi6220_pinmux_config(PERIPH_ID_SDMMC1);
40311ac2363SPeter Griffin if (ret)
40411ac2363SPeter Griffin printf("%s: Error configuring pinmux for eMMC (%d)\n"
40511ac2363SPeter Griffin , __func__, ret);
40611ac2363SPeter Griffin
40711ac2363SPeter Griffin config_sd_carddetect();
40811ac2363SPeter Griffin
40911ac2363SPeter Griffin ret |= hi6220_dwmci_add_port(1, HI6220_MMC1_BASE, 4);
41011ac2363SPeter Griffin if (ret)
41111ac2363SPeter Griffin printf("%s: Error adding SD port (%d)\n", __func__, ret);
41211ac2363SPeter Griffin
41311ac2363SPeter Griffin #endif
41411ac2363SPeter Griffin return ret;
41511ac2363SPeter Griffin }
41611ac2363SPeter Griffin
41711ac2363SPeter Griffin /* setup board specific PMIC */
power_init_board(void)41811ac2363SPeter Griffin int power_init_board(void)
41911ac2363SPeter Griffin {
42011ac2363SPeter Griffin /* init the hi6220 pmussi ip */
42111ac2363SPeter Griffin hi6220_pmussi_init();
42211ac2363SPeter Griffin
42311ac2363SPeter Griffin power_hi6553_init((u8 *)HI6220_PMUSSI_BASE);
42411ac2363SPeter Griffin
42511ac2363SPeter Griffin return 0;
42611ac2363SPeter Griffin }
42711ac2363SPeter Griffin
board_mmc_init(bd_t * bis)42811ac2363SPeter Griffin int board_mmc_init(bd_t *bis)
42911ac2363SPeter Griffin {
43011ac2363SPeter Griffin int ret;
43111ac2363SPeter Griffin
43211ac2363SPeter Griffin /* add the eMMC and sd ports */
43311ac2363SPeter Griffin ret = init_dwmmc();
43411ac2363SPeter Griffin
43511ac2363SPeter Griffin if (ret)
43611ac2363SPeter Griffin debug("init_dwmmc failed\n");
43711ac2363SPeter Griffin
43811ac2363SPeter Griffin return ret;
43911ac2363SPeter Griffin }
44011ac2363SPeter Griffin #endif
44111ac2363SPeter Griffin
dram_init(void)44211ac2363SPeter Griffin int dram_init(void)
44311ac2363SPeter Griffin {
44411ac2363SPeter Griffin gd->ram_size = PHYS_SDRAM_1_SIZE;
44511ac2363SPeter Griffin return 0;
44611ac2363SPeter Griffin }
44711ac2363SPeter Griffin
dram_init_banksize(void)44876b00acaSSimon Glass int dram_init_banksize(void)
44911ac2363SPeter Griffin {
450305b9091SPeter Griffin /*
451305b9091SPeter Griffin * Reserve regions below from DT memory node (which gets generated
452305b9091SPeter Griffin * by U-Boot from the dram banks in arch_fixup_fdt() before booting
453305b9091SPeter Griffin * the kernel. This will then match the kernel hikey dts memory node.
454305b9091SPeter Griffin *
455305b9091SPeter Griffin * 0x05e0,0000 - 0x05ef,ffff: MCU firmware runtime using
456305b9091SPeter Griffin * 0x05f0,1000 - 0x05f0,1fff: Reboot reason
457305b9091SPeter Griffin * 0x06df,f000 - 0x06df,ffff: Mailbox message data
458305b9091SPeter Griffin * 0x0740,f000 - 0x0740,ffff: MCU firmware section
459305b9091SPeter Griffin * 0x21f0,0000 - 0x21ff,ffff: pstore/ramoops buffer
460305b9091SPeter Griffin * 0x3e00,0000 - 0x3fff,ffff: OP-TEE
461305b9091SPeter Griffin */
462305b9091SPeter Griffin
46311ac2363SPeter Griffin gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
464305b9091SPeter Griffin gd->bd->bi_dram[0].size = 0x05e00000;
465305b9091SPeter Griffin
466305b9091SPeter Griffin gd->bd->bi_dram[1].start = 0x05f00000;
467305b9091SPeter Griffin gd->bd->bi_dram[1].size = 0x00001000;
468305b9091SPeter Griffin
469305b9091SPeter Griffin gd->bd->bi_dram[2].start = 0x05f02000;
470305b9091SPeter Griffin gd->bd->bi_dram[2].size = 0x00efd000;
471305b9091SPeter Griffin
472305b9091SPeter Griffin gd->bd->bi_dram[3].start = 0x06e00000;
473305b9091SPeter Griffin gd->bd->bi_dram[3].size = 0x0060f000;
474305b9091SPeter Griffin
475305b9091SPeter Griffin gd->bd->bi_dram[4].start = 0x07410000;
476305b9091SPeter Griffin gd->bd->bi_dram[4].size = 0x1aaf0000;
477305b9091SPeter Griffin
478305b9091SPeter Griffin gd->bd->bi_dram[5].start = 0x22000000;
479305b9091SPeter Griffin gd->bd->bi_dram[5].size = 0x1c000000;
48076b00acaSSimon Glass
48176b00acaSSimon Glass return 0;
48211ac2363SPeter Griffin }
48311ac2363SPeter Griffin
reset_cpu(ulong addr)48411ac2363SPeter Griffin void reset_cpu(ulong addr)
48511ac2363SPeter Griffin {
4869261f8b1SPeter Griffin writel(0x48698284, &ao_sc->stat0);
4879261f8b1SPeter Griffin wfi();
48811ac2363SPeter Griffin }
489