xref: /rk3399_ARM-atf/plat/hisilicon/hikey/hikey_bl_common.c (revision 054c3e0fa3d411795de4b8710d5e3e51cc88347a)
1*054c3e0fSHaojian Zhuang /*
2*054c3e0fSHaojian Zhuang  * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3*054c3e0fSHaojian Zhuang  *
4*054c3e0fSHaojian Zhuang  * SPDX-License-Identifier: BSD-3-Clause
5*054c3e0fSHaojian Zhuang  */
6*054c3e0fSHaojian Zhuang 
7*054c3e0fSHaojian Zhuang #include <arch_helpers.h>
8*054c3e0fSHaojian Zhuang #include <gpio.h>
9*054c3e0fSHaojian Zhuang #include <hi6220.h>
10*054c3e0fSHaojian Zhuang #include <hi6553.h>
11*054c3e0fSHaojian Zhuang #include <mmio.h>
12*054c3e0fSHaojian Zhuang #include <pl061_gpio.h>
13*054c3e0fSHaojian Zhuang #include <sp804_delay_timer.h>
14*054c3e0fSHaojian Zhuang 
15*054c3e0fSHaojian Zhuang #include "hikey_private.h"
16*054c3e0fSHaojian Zhuang 
17*054c3e0fSHaojian Zhuang void hikey_sp804_init(void)
18*054c3e0fSHaojian Zhuang {
19*054c3e0fSHaojian Zhuang 	uint32_t data;
20*054c3e0fSHaojian Zhuang 
21*054c3e0fSHaojian Zhuang 	/* select the clock of dual timer0 */
22*054c3e0fSHaojian Zhuang 	data = mmio_read_32(AO_SC_TIMER_EN0);
23*054c3e0fSHaojian Zhuang 	while (data & 3) {
24*054c3e0fSHaojian Zhuang 		data &= ~3;
25*054c3e0fSHaojian Zhuang 		data |= 3 << 16;
26*054c3e0fSHaojian Zhuang 		mmio_write_32(AO_SC_TIMER_EN0, data);
27*054c3e0fSHaojian Zhuang 		data = mmio_read_32(AO_SC_TIMER_EN0);
28*054c3e0fSHaojian Zhuang 	}
29*054c3e0fSHaojian Zhuang 	/* enable the pclk of dual timer0 */
30*054c3e0fSHaojian Zhuang 	data = mmio_read_32(AO_SC_PERIPH_CLKSTAT4);
31*054c3e0fSHaojian Zhuang 	while (!(data & PCLK_TIMER1) || !(data & PCLK_TIMER0)) {
32*054c3e0fSHaojian Zhuang 		mmio_write_32(AO_SC_PERIPH_CLKEN4, PCLK_TIMER1 | PCLK_TIMER0);
33*054c3e0fSHaojian Zhuang 		data = mmio_read_32(AO_SC_PERIPH_CLKSTAT4);
34*054c3e0fSHaojian Zhuang 	}
35*054c3e0fSHaojian Zhuang 	/* reset dual timer0 */
36*054c3e0fSHaojian Zhuang 	data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4);
37*054c3e0fSHaojian Zhuang 	mmio_write_32(AO_SC_PERIPH_RSTEN4, PCLK_TIMER1 | PCLK_TIMER0);
38*054c3e0fSHaojian Zhuang 	do {
39*054c3e0fSHaojian Zhuang 		data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4);
40*054c3e0fSHaojian Zhuang 	} while (!(data & PCLK_TIMER1) || !(data & PCLK_TIMER0));
41*054c3e0fSHaojian Zhuang 	/* unreset dual timer0 */
42*054c3e0fSHaojian Zhuang 	mmio_write_32(AO_SC_PERIPH_RSTDIS4, PCLK_TIMER1 | PCLK_TIMER0);
43*054c3e0fSHaojian Zhuang 	do {
44*054c3e0fSHaojian Zhuang 		data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4);
45*054c3e0fSHaojian Zhuang 	} while ((data & PCLK_TIMER1) || (data & PCLK_TIMER0));
46*054c3e0fSHaojian Zhuang 
47*054c3e0fSHaojian Zhuang 	sp804_timer_init(SP804_TIMER0_BASE, 10, 192);
48*054c3e0fSHaojian Zhuang }
49*054c3e0fSHaojian Zhuang 
50*054c3e0fSHaojian Zhuang void hikey_gpio_init(void)
51*054c3e0fSHaojian Zhuang {
52*054c3e0fSHaojian Zhuang 	pl061_gpio_init();
53*054c3e0fSHaojian Zhuang 	pl061_gpio_register(GPIO0_BASE, 0);
54*054c3e0fSHaojian Zhuang 	pl061_gpio_register(GPIO1_BASE, 1);
55*054c3e0fSHaojian Zhuang 	pl061_gpio_register(GPIO2_BASE, 2);
56*054c3e0fSHaojian Zhuang 	pl061_gpio_register(GPIO3_BASE, 3);
57*054c3e0fSHaojian Zhuang 	pl061_gpio_register(GPIO4_BASE, 4);
58*054c3e0fSHaojian Zhuang 	pl061_gpio_register(GPIO5_BASE, 5);
59*054c3e0fSHaojian Zhuang 	pl061_gpio_register(GPIO6_BASE, 6);
60*054c3e0fSHaojian Zhuang 	pl061_gpio_register(GPIO7_BASE, 7);
61*054c3e0fSHaojian Zhuang 	pl061_gpio_register(GPIO8_BASE, 8);
62*054c3e0fSHaojian Zhuang 	pl061_gpio_register(GPIO9_BASE, 9);
63*054c3e0fSHaojian Zhuang 	pl061_gpio_register(GPIO10_BASE, 10);
64*054c3e0fSHaojian Zhuang 	pl061_gpio_register(GPIO11_BASE, 11);
65*054c3e0fSHaojian Zhuang 	pl061_gpio_register(GPIO12_BASE, 12);
66*054c3e0fSHaojian Zhuang 	pl061_gpio_register(GPIO13_BASE, 13);
67*054c3e0fSHaojian Zhuang 	pl061_gpio_register(GPIO14_BASE, 14);
68*054c3e0fSHaojian Zhuang 	pl061_gpio_register(GPIO15_BASE, 15);
69*054c3e0fSHaojian Zhuang 	pl061_gpio_register(GPIO16_BASE, 16);
70*054c3e0fSHaojian Zhuang 	pl061_gpio_register(GPIO17_BASE, 17);
71*054c3e0fSHaojian Zhuang 	pl061_gpio_register(GPIO18_BASE, 18);
72*054c3e0fSHaojian Zhuang 	pl061_gpio_register(GPIO19_BASE, 19);
73*054c3e0fSHaojian Zhuang 
74*054c3e0fSHaojian Zhuang 	/* Power on indicator LED (USER_LED1). */
75*054c3e0fSHaojian Zhuang 	gpio_set_direction(32, GPIO_DIR_OUT);	/* LED1 */
76*054c3e0fSHaojian Zhuang 	gpio_set_value(32, GPIO_LEVEL_HIGH);
77*054c3e0fSHaojian Zhuang 	gpio_set_direction(33, GPIO_DIR_OUT);	/* LED2 */
78*054c3e0fSHaojian Zhuang 	gpio_set_value(33, GPIO_LEVEL_LOW);
79*054c3e0fSHaojian Zhuang 	gpio_set_direction(34, GPIO_DIR_OUT);	/* LED3 */
80*054c3e0fSHaojian Zhuang 	gpio_set_direction(35, GPIO_DIR_OUT);	/* LED4 */
81*054c3e0fSHaojian Zhuang }
82*054c3e0fSHaojian Zhuang 
83*054c3e0fSHaojian Zhuang void hikey_pmussi_init(void)
84*054c3e0fSHaojian Zhuang {
85*054c3e0fSHaojian Zhuang 	uint32_t data;
86*054c3e0fSHaojian Zhuang 
87*054c3e0fSHaojian Zhuang 	/* Initialize PWR_HOLD GPIO */
88*054c3e0fSHaojian Zhuang 	gpio_set_direction(0, GPIO_DIR_OUT);
89*054c3e0fSHaojian Zhuang 	gpio_set_value(0, GPIO_LEVEL_LOW);
90*054c3e0fSHaojian Zhuang 
91*054c3e0fSHaojian Zhuang 	/*
92*054c3e0fSHaojian Zhuang 	 * After reset, PMUSSI stays in reset mode.
93*054c3e0fSHaojian Zhuang 	 * Now make it out of reset.
94*054c3e0fSHaojian Zhuang 	 */
95*054c3e0fSHaojian Zhuang 	mmio_write_32(AO_SC_PERIPH_RSTDIS4,
96*054c3e0fSHaojian Zhuang 		      AO_SC_PERIPH_RSTDIS4_PRESET_PMUSSI_N);
97*054c3e0fSHaojian Zhuang 	do {
98*054c3e0fSHaojian Zhuang 		data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4);
99*054c3e0fSHaojian Zhuang 	} while (data & AO_SC_PERIPH_RSTDIS4_PRESET_PMUSSI_N);
100*054c3e0fSHaojian Zhuang 
101*054c3e0fSHaojian Zhuang 	/* Set PMUSSI clock latency for read operation. */
102*054c3e0fSHaojian Zhuang 	data = mmio_read_32(AO_SC_MCU_SUBSYS_CTRL3);
103*054c3e0fSHaojian Zhuang 	data &= ~AO_SC_MCU_SUBSYS_CTRL3_RCLK_MASK;
104*054c3e0fSHaojian Zhuang 	data |= AO_SC_MCU_SUBSYS_CTRL3_RCLK_3;
105*054c3e0fSHaojian Zhuang 	mmio_write_32(AO_SC_MCU_SUBSYS_CTRL3, data);
106*054c3e0fSHaojian Zhuang 
107*054c3e0fSHaojian Zhuang 	/* enable PMUSSI clock */
108*054c3e0fSHaojian Zhuang 	data = AO_SC_PERIPH_CLKEN5_PCLK_PMUSSI_CCPU |
109*054c3e0fSHaojian Zhuang 	       AO_SC_PERIPH_CLKEN5_PCLK_PMUSSI_MCU;
110*054c3e0fSHaojian Zhuang 	mmio_write_32(AO_SC_PERIPH_CLKEN5, data);
111*054c3e0fSHaojian Zhuang 	data = AO_SC_PERIPH_CLKEN4_PCLK_PMUSSI;
112*054c3e0fSHaojian Zhuang 	mmio_write_32(AO_SC_PERIPH_CLKEN4, data);
113*054c3e0fSHaojian Zhuang 
114*054c3e0fSHaojian Zhuang 	gpio_set_value(0, GPIO_LEVEL_HIGH);
115*054c3e0fSHaojian Zhuang }
116*054c3e0fSHaojian Zhuang 
117*054c3e0fSHaojian Zhuang void hikey_hi6553_init(void)
118*054c3e0fSHaojian Zhuang {
119*054c3e0fSHaojian Zhuang 	uint8_t data;
120*054c3e0fSHaojian Zhuang 
121*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_PERI_EN_MARK, 0x1e);
122*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_NP_REG_ADJ1, 0);
123*054c3e0fSHaojian Zhuang 	data = DISABLE6_XO_CLK_CONN | DISABLE6_XO_CLK_NFC |
124*054c3e0fSHaojian Zhuang 		DISABLE6_XO_CLK_RF1 | DISABLE6_XO_CLK_RF2;
125*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_DISABLE6_XO_CLK, data);
126*054c3e0fSHaojian Zhuang 
127*054c3e0fSHaojian Zhuang 	/* configure BUCK0 & BUCK1 */
128*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_BUCK01_CTRL2, 0x5e);
129*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_BUCK0_CTRL7, 0x10);
130*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_BUCK1_CTRL7, 0x10);
131*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_BUCK0_CTRL5, 0x1e);
132*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_BUCK1_CTRL5, 0x1e);
133*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_BUCK0_CTRL1, 0xfc);
134*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_BUCK1_CTRL1, 0xfc);
135*054c3e0fSHaojian Zhuang 
136*054c3e0fSHaojian Zhuang 	/* configure BUCK2 */
137*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_BUCK2_REG1, 0x4f);
138*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_BUCK2_REG5, 0x99);
139*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_BUCK2_REG6, 0x45);
140*054c3e0fSHaojian Zhuang 	mdelay(1);
141*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_VSET_BUCK2_ADJ, 0x22);
142*054c3e0fSHaojian Zhuang 	mdelay(1);
143*054c3e0fSHaojian Zhuang 
144*054c3e0fSHaojian Zhuang 	/* configure BUCK3 */
145*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_BUCK3_REG3, 0x02);
146*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_BUCK3_REG5, 0x99);
147*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_BUCK3_REG6, 0x41);
148*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_VSET_BUCK3_ADJ, 0x02);
149*054c3e0fSHaojian Zhuang 	mdelay(1);
150*054c3e0fSHaojian Zhuang 
151*054c3e0fSHaojian Zhuang 	/* configure BUCK4 */
152*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_BUCK4_REG2, 0x9a);
153*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_BUCK4_REG5, 0x99);
154*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_BUCK4_REG6, 0x45);
155*054c3e0fSHaojian Zhuang 
156*054c3e0fSHaojian Zhuang 	/* configure LDO20 */
157*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_LDO20_REG_ADJ, 0x50);
158*054c3e0fSHaojian Zhuang 
159*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_NP_REG_CHG, 0x0f);
160*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_CLK_TOP0, 0x06);
161*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_CLK_TOP3, 0xc0);
162*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_CLK_TOP4, 0x00);
163*054c3e0fSHaojian Zhuang 
164*054c3e0fSHaojian Zhuang 	/* configure LDO7 & LDO10 for SD slot */
165*054c3e0fSHaojian Zhuang 	/* enable LDO7 */
166*054c3e0fSHaojian Zhuang 	data = mmio_read_8(HI6553_LDO7_REG_ADJ);
167*054c3e0fSHaojian Zhuang 	data = (data & 0xf8) | 0x2;
168*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_LDO7_REG_ADJ, data);
169*054c3e0fSHaojian Zhuang 	mdelay(5);
170*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_ENABLE2_LDO1_8, 1 << 6);
171*054c3e0fSHaojian Zhuang 	mdelay(5);
172*054c3e0fSHaojian Zhuang 	/* enable LDO10 */
173*054c3e0fSHaojian Zhuang 	data = mmio_read_8(HI6553_LDO10_REG_ADJ);
174*054c3e0fSHaojian Zhuang 	data = (data & 0xf8) | 0x5;
175*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_LDO10_REG_ADJ, data);
176*054c3e0fSHaojian Zhuang 	mdelay(5);
177*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_ENABLE3_LDO9_16, 1 << 1);
178*054c3e0fSHaojian Zhuang 	mdelay(5);
179*054c3e0fSHaojian Zhuang 	/* enable LDO15 */
180*054c3e0fSHaojian Zhuang 	data = mmio_read_8(HI6553_LDO15_REG_ADJ);
181*054c3e0fSHaojian Zhuang 	data = (data & 0xf8) | 0x4;
182*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_LDO15_REG_ADJ, data);
183*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_ENABLE3_LDO9_16, 1 << 6);
184*054c3e0fSHaojian Zhuang 	mdelay(5);
185*054c3e0fSHaojian Zhuang 	/* enable LDO19 */
186*054c3e0fSHaojian Zhuang 	data = mmio_read_8(HI6553_LDO19_REG_ADJ);
187*054c3e0fSHaojian Zhuang 	data |= 0x7;
188*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_LDO19_REG_ADJ, data);
189*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 2);
190*054c3e0fSHaojian Zhuang 	mdelay(5);
191*054c3e0fSHaojian Zhuang 	/* enable LDO21 */
192*054c3e0fSHaojian Zhuang 	data = mmio_read_8(HI6553_LDO21_REG_ADJ);
193*054c3e0fSHaojian Zhuang 	data = (data & 0xf8) | 0x3;
194*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_LDO21_REG_ADJ, data);
195*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 4);
196*054c3e0fSHaojian Zhuang 	mdelay(5);
197*054c3e0fSHaojian Zhuang 	/* enable LDO22 */
198*054c3e0fSHaojian Zhuang 	data = mmio_read_8(HI6553_LDO22_REG_ADJ);
199*054c3e0fSHaojian Zhuang 	data = (data & 0xf8) | 0x7;
200*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_LDO22_REG_ADJ, data);
201*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 5);
202*054c3e0fSHaojian Zhuang 	mdelay(5);
203*054c3e0fSHaojian Zhuang 
204*054c3e0fSHaojian Zhuang 	/* select 32.764KHz */
205*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_CLK19M2_600_586_EN, 0x01);
206*054c3e0fSHaojian Zhuang 
207*054c3e0fSHaojian Zhuang 	/* Disable vbus_det interrupts */
208*054c3e0fSHaojian Zhuang 	data = mmio_read_8(HI6553_IRQ2_MASK);
209*054c3e0fSHaojian Zhuang 	data = data | 0x3;
210*054c3e0fSHaojian Zhuang 	mmio_write_8(HI6553_IRQ2_MASK, data);
211*054c3e0fSHaojian Zhuang }
212*054c3e0fSHaojian Zhuang 
213*054c3e0fSHaojian Zhuang void init_mmc0_pll(void)
214*054c3e0fSHaojian Zhuang {
215*054c3e0fSHaojian Zhuang 	unsigned int data;
216*054c3e0fSHaojian Zhuang 
217*054c3e0fSHaojian Zhuang 	/* select SYSPLL as the source of MMC0 */
218*054c3e0fSHaojian Zhuang 	/* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */
219*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_CLK_SEL0, 1 << 5 | 1 << 21);
220*054c3e0fSHaojian Zhuang 	do {
221*054c3e0fSHaojian Zhuang 		data = mmio_read_32(PERI_SC_CLK_SEL0);
222*054c3e0fSHaojian Zhuang 	} while (!(data & (1 << 5)));
223*054c3e0fSHaojian Zhuang 	/* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */
224*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_CLK_SEL0, 1 << 29);
225*054c3e0fSHaojian Zhuang 	do {
226*054c3e0fSHaojian Zhuang 		data = mmio_read_32(PERI_SC_CLK_SEL0);
227*054c3e0fSHaojian Zhuang 	} while (data & (1 << 13));
228*054c3e0fSHaojian Zhuang 
229*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CLKEN0, (1 << 0));
230*054c3e0fSHaojian Zhuang 	do {
231*054c3e0fSHaojian Zhuang 		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
232*054c3e0fSHaojian Zhuang 	} while (!(data & (1 << 0)));
233*054c3e0fSHaojian Zhuang 
234*054c3e0fSHaojian Zhuang 	data = mmio_read_32(PERI_SC_PERIPH_CLKEN12);
235*054c3e0fSHaojian Zhuang 	data |= 1 << 1;
236*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CLKEN12, data);
237*054c3e0fSHaojian Zhuang 
238*054c3e0fSHaojian Zhuang 	do {
239*054c3e0fSHaojian Zhuang 		mmio_write_32(PERI_SC_CLKCFG8BIT1, (1 << 7) | 0xb);
240*054c3e0fSHaojian Zhuang 		data = mmio_read_32(PERI_SC_CLKCFG8BIT1);
241*054c3e0fSHaojian Zhuang 	} while ((data & 0xb) != 0xb);
242*054c3e0fSHaojian Zhuang }
243*054c3e0fSHaojian Zhuang 
244*054c3e0fSHaojian Zhuang void reset_mmc0_clk(void)
245*054c3e0fSHaojian Zhuang {
246*054c3e0fSHaojian Zhuang 	unsigned int data;
247*054c3e0fSHaojian Zhuang 
248*054c3e0fSHaojian Zhuang 	/* disable mmc0 bus clock */
249*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CLKDIS0, PERI_CLK0_MMC0);
250*054c3e0fSHaojian Zhuang 	do {
251*054c3e0fSHaojian Zhuang 		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
252*054c3e0fSHaojian Zhuang 	} while (data & PERI_CLK0_MMC0);
253*054c3e0fSHaojian Zhuang 	/* enable mmc0 bus clock */
254*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_MMC0);
255*054c3e0fSHaojian Zhuang 	do {
256*054c3e0fSHaojian Zhuang 		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
257*054c3e0fSHaojian Zhuang 	} while (!(data & PERI_CLK0_MMC0));
258*054c3e0fSHaojian Zhuang 	/* reset mmc0 clock domain */
259*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_RSTEN0, PERI_RST0_MMC0);
260*054c3e0fSHaojian Zhuang 
261*054c3e0fSHaojian Zhuang 	/* bypass mmc0 clock phase */
262*054c3e0fSHaojian Zhuang 	data = mmio_read_32(PERI_SC_PERIPH_CTRL2);
263*054c3e0fSHaojian Zhuang 	data |= 3;
264*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CTRL2, data);
265*054c3e0fSHaojian Zhuang 
266*054c3e0fSHaojian Zhuang 	/* disable low power */
267*054c3e0fSHaojian Zhuang 	data = mmio_read_32(PERI_SC_PERIPH_CTRL13);
268*054c3e0fSHaojian Zhuang 	data |= 1 << 3;
269*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CTRL13, data);
270*054c3e0fSHaojian Zhuang 	do {
271*054c3e0fSHaojian Zhuang 		data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
272*054c3e0fSHaojian Zhuang 	} while (!(data & PERI_RST0_MMC0));
273*054c3e0fSHaojian Zhuang 
274*054c3e0fSHaojian Zhuang 	/* unreset mmc0 clock domain */
275*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_RSTDIS0, PERI_RST0_MMC0);
276*054c3e0fSHaojian Zhuang 	do {
277*054c3e0fSHaojian Zhuang 		data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
278*054c3e0fSHaojian Zhuang 	} while (data & PERI_RST0_MMC0);
279*054c3e0fSHaojian Zhuang }
280*054c3e0fSHaojian Zhuang 
281*054c3e0fSHaojian Zhuang void init_media_clk(void)
282*054c3e0fSHaojian Zhuang {
283*054c3e0fSHaojian Zhuang 	unsigned int data, value;
284*054c3e0fSHaojian Zhuang 
285*054c3e0fSHaojian Zhuang 	data = mmio_read_32(PMCTRL_MEDPLLCTRL);
286*054c3e0fSHaojian Zhuang 	data |= 1;
287*054c3e0fSHaojian Zhuang 	mmio_write_32(PMCTRL_MEDPLLCTRL, data);
288*054c3e0fSHaojian Zhuang 
289*054c3e0fSHaojian Zhuang 	for (;;) {
290*054c3e0fSHaojian Zhuang 		data = mmio_read_32(PMCTRL_MEDPLLCTRL);
291*054c3e0fSHaojian Zhuang 		value = 1 << 28;
292*054c3e0fSHaojian Zhuang 		if ((data & value) == value)
293*054c3e0fSHaojian Zhuang 			break;
294*054c3e0fSHaojian Zhuang 	}
295*054c3e0fSHaojian Zhuang 
296*054c3e0fSHaojian Zhuang 	data = mmio_read_32(PERI_SC_PERIPH_CLKEN12);
297*054c3e0fSHaojian Zhuang 	data = 1 << 10;
298*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CLKEN12, data);
299*054c3e0fSHaojian Zhuang }
300*054c3e0fSHaojian Zhuang 
301*054c3e0fSHaojian Zhuang void init_mmc1_pll(void)
302*054c3e0fSHaojian Zhuang {
303*054c3e0fSHaojian Zhuang 	uint32_t data;
304*054c3e0fSHaojian Zhuang 
305*054c3e0fSHaojian Zhuang 	/* select SYSPLL as the source of MMC1 */
306*054c3e0fSHaojian Zhuang 	/* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */
307*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_CLK_SEL0, 1 << 11 | 1 << 27);
308*054c3e0fSHaojian Zhuang 	do {
309*054c3e0fSHaojian Zhuang 		data = mmio_read_32(PERI_SC_CLK_SEL0);
310*054c3e0fSHaojian Zhuang 	} while (!(data & (1 << 11)));
311*054c3e0fSHaojian Zhuang 	/* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */
312*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_CLK_SEL0, 1 << 30);
313*054c3e0fSHaojian Zhuang 	do {
314*054c3e0fSHaojian Zhuang 		data = mmio_read_32(PERI_SC_CLK_SEL0);
315*054c3e0fSHaojian Zhuang 	} while (data & (1 << 14));
316*054c3e0fSHaojian Zhuang 
317*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CLKEN0, (1 << 1));
318*054c3e0fSHaojian Zhuang 	do {
319*054c3e0fSHaojian Zhuang 		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
320*054c3e0fSHaojian Zhuang 	} while (!(data & (1 << 1)));
321*054c3e0fSHaojian Zhuang 
322*054c3e0fSHaojian Zhuang 	data = mmio_read_32(PERI_SC_PERIPH_CLKEN12);
323*054c3e0fSHaojian Zhuang 	data |= 1 << 2;
324*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CLKEN12, data);
325*054c3e0fSHaojian Zhuang 
326*054c3e0fSHaojian Zhuang 	do {
327*054c3e0fSHaojian Zhuang 		/* 1.2GHz / 50 = 24MHz */
328*054c3e0fSHaojian Zhuang 		mmio_write_32(PERI_SC_CLKCFG8BIT2, 0x31 | (1 << 7));
329*054c3e0fSHaojian Zhuang 		data = mmio_read_32(PERI_SC_CLKCFG8BIT2);
330*054c3e0fSHaojian Zhuang 	} while ((data & 0x31) != 0x31);
331*054c3e0fSHaojian Zhuang }
332*054c3e0fSHaojian Zhuang 
333*054c3e0fSHaojian Zhuang void reset_mmc1_clk(void)
334*054c3e0fSHaojian Zhuang {
335*054c3e0fSHaojian Zhuang 	unsigned int data;
336*054c3e0fSHaojian Zhuang 
337*054c3e0fSHaojian Zhuang 	/* disable mmc1 bus clock */
338*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CLKDIS0, PERI_CLK0_MMC1);
339*054c3e0fSHaojian Zhuang 	do {
340*054c3e0fSHaojian Zhuang 		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
341*054c3e0fSHaojian Zhuang 	} while (data & PERI_CLK0_MMC1);
342*054c3e0fSHaojian Zhuang 	/* enable mmc1 bus clock */
343*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_MMC1);
344*054c3e0fSHaojian Zhuang 	do {
345*054c3e0fSHaojian Zhuang 		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
346*054c3e0fSHaojian Zhuang 	} while (!(data & PERI_CLK0_MMC1));
347*054c3e0fSHaojian Zhuang 	/* reset mmc1 clock domain */
348*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_RSTEN0, PERI_RST0_MMC1);
349*054c3e0fSHaojian Zhuang 
350*054c3e0fSHaojian Zhuang 	/* bypass mmc1 clock phase */
351*054c3e0fSHaojian Zhuang 	data = mmio_read_32(PERI_SC_PERIPH_CTRL2);
352*054c3e0fSHaojian Zhuang 	data |= 3 << 2;
353*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CTRL2, data);
354*054c3e0fSHaojian Zhuang 
355*054c3e0fSHaojian Zhuang 	/* disable low power */
356*054c3e0fSHaojian Zhuang 	data = mmio_read_32(PERI_SC_PERIPH_CTRL13);
357*054c3e0fSHaojian Zhuang 	data |= 1 << 4;
358*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CTRL13, data);
359*054c3e0fSHaojian Zhuang 	do {
360*054c3e0fSHaojian Zhuang 		data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
361*054c3e0fSHaojian Zhuang 	} while (!(data & PERI_RST0_MMC1));
362*054c3e0fSHaojian Zhuang 
363*054c3e0fSHaojian Zhuang 	/* unreset mmc0 clock domain */
364*054c3e0fSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_RSTDIS0, PERI_RST0_MMC1);
365*054c3e0fSHaojian Zhuang 	do {
366*054c3e0fSHaojian Zhuang 		data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
367*054c3e0fSHaojian Zhuang 	} while (data & PERI_RST0_MMC1);
368*054c3e0fSHaojian Zhuang }
369*054c3e0fSHaojian Zhuang 
370*054c3e0fSHaojian Zhuang /* Initialize PLL of both eMMC and SD controllers. */
371*054c3e0fSHaojian Zhuang void hikey_mmc_pll_init(void)
372*054c3e0fSHaojian Zhuang {
373*054c3e0fSHaojian Zhuang 	init_mmc0_pll();
374*054c3e0fSHaojian Zhuang 	reset_mmc0_clk();
375*054c3e0fSHaojian Zhuang 	init_media_clk();
376*054c3e0fSHaojian Zhuang 
377*054c3e0fSHaojian Zhuang 	dsb();
378*054c3e0fSHaojian Zhuang 
379*054c3e0fSHaojian Zhuang 	init_mmc1_pll();
380*054c3e0fSHaojian Zhuang 	reset_mmc1_clk();
381*054c3e0fSHaojian Zhuang }
382*054c3e0fSHaojian Zhuang 
383*054c3e0fSHaojian Zhuang void hikey_rtc_init(void)
384*054c3e0fSHaojian Zhuang {
385*054c3e0fSHaojian Zhuang 	uint32_t data;
386*054c3e0fSHaojian Zhuang 
387*054c3e0fSHaojian Zhuang 	data = mmio_read_32(AO_SC_PERIPH_CLKEN4);
388*054c3e0fSHaojian Zhuang 	data |= AO_SC_PERIPH_RSTDIS4_RESET_RTC0_N;
389*054c3e0fSHaojian Zhuang 	mmio_write_32(AO_SC_PERIPH_CLKEN4, data);
390*054c3e0fSHaojian Zhuang }
391