xref: /rk3399_rockchip-uboot/board/hisilicon/hikey/hikey.c (revision fb53e7eb60567dae2181a3d55f51e72e03a2aac6)
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