xref: /arm-trusted-firmware/plat/hisilicon/hikey960/hikey960_bl2_setup.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <assert.h>
8*91f16700Schasinglulu #include <errno.h>
9*91f16700Schasinglulu #include <string.h>
10*91f16700Schasinglulu 
11*91f16700Schasinglulu #include <platform_def.h>
12*91f16700Schasinglulu 
13*91f16700Schasinglulu #include <arch_helpers.h>
14*91f16700Schasinglulu #include <common/bl_common.h>
15*91f16700Schasinglulu #include <common/debug.h>
16*91f16700Schasinglulu #include <common/desc_image_load.h>
17*91f16700Schasinglulu #include <drivers/arm/pl011.h>
18*91f16700Schasinglulu #include <drivers/delay_timer.h>
19*91f16700Schasinglulu #include <drivers/dw_ufs.h>
20*91f16700Schasinglulu #include <drivers/generic_delay_timer.h>
21*91f16700Schasinglulu #include <drivers/partition/partition.h>
22*91f16700Schasinglulu #include <drivers/ufs.h>
23*91f16700Schasinglulu #include <lib/mmio.h>
24*91f16700Schasinglulu #ifdef SPD_opteed
25*91f16700Schasinglulu #include <lib/optee_utils.h>
26*91f16700Schasinglulu #endif
27*91f16700Schasinglulu 
28*91f16700Schasinglulu #include <hi3660.h>
29*91f16700Schasinglulu #include "hikey960_def.h"
30*91f16700Schasinglulu #include "hikey960_private.h"
31*91f16700Schasinglulu 
32*91f16700Schasinglulu #define BL2_RW_BASE		(BL_CODE_END)
33*91f16700Schasinglulu 
34*91f16700Schasinglulu /* BL2 platform parameters passed to BL31 */
35*91f16700Schasinglulu static plat_params_from_bl2_t plat_params_from_bl2;
36*91f16700Schasinglulu 
37*91f16700Schasinglulu static meminfo_t bl2_el3_tzram_layout;
38*91f16700Schasinglulu static console_t console;
39*91f16700Schasinglulu extern int load_lpm3(void);
40*91f16700Schasinglulu 
41*91f16700Schasinglulu enum {
42*91f16700Schasinglulu 	BOOT_MODE_RECOVERY = 0,
43*91f16700Schasinglulu 	BOOT_MODE_NORMAL,
44*91f16700Schasinglulu 	BOOT_MODE_MASK = 1,
45*91f16700Schasinglulu };
46*91f16700Schasinglulu 
47*91f16700Schasinglulu /*******************************************************************************
48*91f16700Schasinglulu  * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol.
49*91f16700Schasinglulu  * Return 0 on success, -1 otherwise.
50*91f16700Schasinglulu  ******************************************************************************/
51*91f16700Schasinglulu int plat_hikey960_bl2_handle_scp_bl2(image_info_t *scp_bl2_image_info)
52*91f16700Schasinglulu {
53*91f16700Schasinglulu 	int i;
54*91f16700Schasinglulu 	int *buf;
55*91f16700Schasinglulu 
56*91f16700Schasinglulu 	assert(scp_bl2_image_info->image_size < SCP_BL2_SIZE);
57*91f16700Schasinglulu 
58*91f16700Schasinglulu 	INFO("BL2: Initiating SCP_BL2 transfer to SCP\n");
59*91f16700Schasinglulu 
60*91f16700Schasinglulu 	INFO("BL2: SCP_BL2: 0x%lx@0x%x\n",
61*91f16700Schasinglulu 	     scp_bl2_image_info->image_base,
62*91f16700Schasinglulu 	     scp_bl2_image_info->image_size);
63*91f16700Schasinglulu 
64*91f16700Schasinglulu 	buf = (int *)scp_bl2_image_info->image_base;
65*91f16700Schasinglulu 
66*91f16700Schasinglulu 	INFO("BL2: SCP_BL2 HEAD:\n");
67*91f16700Schasinglulu 	for (i = 0; i < 64; i += 4)
68*91f16700Schasinglulu 		INFO("BL2: SCP_BL2 0x%x 0x%x 0x%x 0x%x\n",
69*91f16700Schasinglulu 			buf[i], buf[i+1], buf[i+2], buf[i+3]);
70*91f16700Schasinglulu 
71*91f16700Schasinglulu 	buf = (int *)(scp_bl2_image_info->image_base +
72*91f16700Schasinglulu 		      scp_bl2_image_info->image_size - 256);
73*91f16700Schasinglulu 
74*91f16700Schasinglulu 	INFO("BL2: SCP_BL2 TAIL:\n");
75*91f16700Schasinglulu 	for (i = 0; i < 64; i += 4)
76*91f16700Schasinglulu 		INFO("BL2: SCP_BL2 0x%x 0x%x 0x%x 0x%x\n",
77*91f16700Schasinglulu 			buf[i], buf[i+1], buf[i+2], buf[i+3]);
78*91f16700Schasinglulu 
79*91f16700Schasinglulu 	INFO("BL2: SCP_BL2 transferred to SCP\n");
80*91f16700Schasinglulu 
81*91f16700Schasinglulu 	load_lpm3();
82*91f16700Schasinglulu 	(void)buf;
83*91f16700Schasinglulu 
84*91f16700Schasinglulu 	return 0;
85*91f16700Schasinglulu }
86*91f16700Schasinglulu 
87*91f16700Schasinglulu static void hikey960_ufs_reset(void)
88*91f16700Schasinglulu {
89*91f16700Schasinglulu 	unsigned int data, mask;
90*91f16700Schasinglulu 
91*91f16700Schasinglulu 	mmio_write_32(CRG_PERDIS7_REG, 1 << 14);
92*91f16700Schasinglulu 	mmio_clrbits_32(UFS_SYS_PHY_CLK_CTRL_REG, BIT_SYSCTRL_REF_CLOCK_EN);
93*91f16700Schasinglulu 	do {
94*91f16700Schasinglulu 		data = mmio_read_32(UFS_SYS_PHY_CLK_CTRL_REG);
95*91f16700Schasinglulu 	} while (data & BIT_SYSCTRL_REF_CLOCK_EN);
96*91f16700Schasinglulu 	/* use abb clk */
97*91f16700Schasinglulu 	mmio_clrbits_32(UFS_SYS_UFS_SYSCTRL_REG, BIT_UFS_REFCLK_SRC_SE1);
98*91f16700Schasinglulu 	mmio_clrbits_32(UFS_SYS_PHY_ISO_EN_REG, BIT_UFS_REFCLK_ISO_EN);
99*91f16700Schasinglulu 	mmio_write_32(PCTRL_PERI_CTRL3_REG, (1 << 0) | (1 << 16));
100*91f16700Schasinglulu 	mdelay(1);
101*91f16700Schasinglulu 	mmio_write_32(CRG_PEREN7_REG, 1 << 14);
102*91f16700Schasinglulu 	mmio_setbits_32(UFS_SYS_PHY_CLK_CTRL_REG, BIT_SYSCTRL_REF_CLOCK_EN);
103*91f16700Schasinglulu 
104*91f16700Schasinglulu 	mmio_write_32(CRG_PERRSTEN3_REG, PERI_UFS_BIT);
105*91f16700Schasinglulu 	do {
106*91f16700Schasinglulu 		data = mmio_read_32(CRG_PERRSTSTAT3_REG);
107*91f16700Schasinglulu 	} while ((data & PERI_UFS_BIT) == 0);
108*91f16700Schasinglulu 	mmio_setbits_32(UFS_SYS_PSW_POWER_CTRL_REG, BIT_UFS_PSW_MTCMOS_EN);
109*91f16700Schasinglulu 	mdelay(1);
110*91f16700Schasinglulu 	mmio_setbits_32(UFS_SYS_HC_LP_CTRL_REG, BIT_SYSCTRL_PWR_READY);
111*91f16700Schasinglulu 	mmio_write_32(UFS_SYS_UFS_DEVICE_RESET_CTRL_REG,
112*91f16700Schasinglulu 		      MASK_UFS_DEVICE_RESET);
113*91f16700Schasinglulu 	/* clear SC_DIV_UFS_PERIBUS */
114*91f16700Schasinglulu 	mask = SC_DIV_UFS_PERIBUS << 16;
115*91f16700Schasinglulu 	mmio_write_32(CRG_CLKDIV17_REG, mask);
116*91f16700Schasinglulu 	/* set SC_DIV_UFSPHY_CFG(3) */
117*91f16700Schasinglulu 	mask = SC_DIV_UFSPHY_CFG_MASK << 16;
118*91f16700Schasinglulu 	data = SC_DIV_UFSPHY_CFG(3);
119*91f16700Schasinglulu 	mmio_write_32(CRG_CLKDIV16_REG, mask | data);
120*91f16700Schasinglulu 	data = mmio_read_32(UFS_SYS_PHY_CLK_CTRL_REG);
121*91f16700Schasinglulu 	data &= ~MASK_SYSCTRL_CFG_CLOCK_FREQ;
122*91f16700Schasinglulu 	data |= 0x39;
123*91f16700Schasinglulu 	mmio_write_32(UFS_SYS_PHY_CLK_CTRL_REG, data);
124*91f16700Schasinglulu 	mmio_clrbits_32(UFS_SYS_PHY_CLK_CTRL_REG, MASK_SYSCTRL_REF_CLOCK_SEL);
125*91f16700Schasinglulu 	mmio_setbits_32(UFS_SYS_CLOCK_GATE_BYPASS_REG,
126*91f16700Schasinglulu 			MASK_UFS_CLK_GATE_BYPASS);
127*91f16700Schasinglulu 	mmio_setbits_32(UFS_SYS_UFS_SYSCTRL_REG, MASK_UFS_SYSCTRL_BYPASS);
128*91f16700Schasinglulu 
129*91f16700Schasinglulu 	mmio_setbits_32(UFS_SYS_PSW_CLK_CTRL_REG, BIT_SYSCTRL_PSW_CLK_EN);
130*91f16700Schasinglulu 	mmio_clrbits_32(UFS_SYS_PSW_POWER_CTRL_REG, BIT_UFS_PSW_ISO_CTRL);
131*91f16700Schasinglulu 	mmio_clrbits_32(UFS_SYS_PHY_ISO_EN_REG, BIT_UFS_PHY_ISO_CTRL);
132*91f16700Schasinglulu 	mmio_clrbits_32(UFS_SYS_HC_LP_CTRL_REG, BIT_SYSCTRL_LP_ISOL_EN);
133*91f16700Schasinglulu 	mmio_write_32(CRG_PERRSTDIS3_REG, PERI_ARST_UFS_BIT);
134*91f16700Schasinglulu 	mmio_setbits_32(UFS_SYS_RESET_CTRL_EN_REG, BIT_SYSCTRL_LP_RESET_N);
135*91f16700Schasinglulu 	mdelay(1);
136*91f16700Schasinglulu 	mmio_write_32(UFS_SYS_UFS_DEVICE_RESET_CTRL_REG,
137*91f16700Schasinglulu 		      MASK_UFS_DEVICE_RESET | BIT_UFS_DEVICE_RESET);
138*91f16700Schasinglulu 	mdelay(20);
139*91f16700Schasinglulu 	mmio_write_32(UFS_SYS_UFS_DEVICE_RESET_CTRL_REG,
140*91f16700Schasinglulu 		      0x03300330);
141*91f16700Schasinglulu 
142*91f16700Schasinglulu 	mmio_write_32(CRG_PERRSTDIS3_REG, PERI_UFS_BIT);
143*91f16700Schasinglulu 	do {
144*91f16700Schasinglulu 		data = mmio_read_32(CRG_PERRSTSTAT3_REG);
145*91f16700Schasinglulu 	} while (data & PERI_UFS_BIT);
146*91f16700Schasinglulu }
147*91f16700Schasinglulu 
148*91f16700Schasinglulu static void hikey960_init_ufs(void)
149*91f16700Schasinglulu {
150*91f16700Schasinglulu 	dw_ufs_params_t ufs_params;
151*91f16700Schasinglulu 
152*91f16700Schasinglulu 	memset(&ufs_params, 0, sizeof(ufs_params_t));
153*91f16700Schasinglulu 	ufs_params.reg_base = UFS_REG_BASE;
154*91f16700Schasinglulu 	ufs_params.desc_base = HIKEY960_UFS_DESC_BASE;
155*91f16700Schasinglulu 	ufs_params.desc_size = HIKEY960_UFS_DESC_SIZE;
156*91f16700Schasinglulu 	hikey960_ufs_reset();
157*91f16700Schasinglulu 	dw_ufs_init(&ufs_params);
158*91f16700Schasinglulu }
159*91f16700Schasinglulu 
160*91f16700Schasinglulu /*******************************************************************************
161*91f16700Schasinglulu  * Gets SPSR for BL32 entry
162*91f16700Schasinglulu  ******************************************************************************/
163*91f16700Schasinglulu uint32_t hikey960_get_spsr_for_bl32_entry(void)
164*91f16700Schasinglulu {
165*91f16700Schasinglulu 	/*
166*91f16700Schasinglulu 	 * The Secure Payload Dispatcher service is responsible for
167*91f16700Schasinglulu 	 * setting the SPSR prior to entry into the BL3-2 image.
168*91f16700Schasinglulu 	 */
169*91f16700Schasinglulu 	return 0;
170*91f16700Schasinglulu }
171*91f16700Schasinglulu 
172*91f16700Schasinglulu /*******************************************************************************
173*91f16700Schasinglulu  * Gets SPSR for BL33 entry
174*91f16700Schasinglulu  ******************************************************************************/
175*91f16700Schasinglulu #ifdef __aarch64__
176*91f16700Schasinglulu uint32_t hikey960_get_spsr_for_bl33_entry(void)
177*91f16700Schasinglulu {
178*91f16700Schasinglulu 	unsigned int mode;
179*91f16700Schasinglulu 	uint32_t spsr;
180*91f16700Schasinglulu 
181*91f16700Schasinglulu 	/* Figure out what mode we enter the non-secure world in */
182*91f16700Schasinglulu 	mode = (el_implemented(2) != EL_IMPL_NONE) ? MODE_EL2 : MODE_EL1;
183*91f16700Schasinglulu 
184*91f16700Schasinglulu 	/*
185*91f16700Schasinglulu 	 * TODO: Consider the possibility of specifying the SPSR in
186*91f16700Schasinglulu 	 * the FIP ToC and allowing the platform to have a say as
187*91f16700Schasinglulu 	 * well.
188*91f16700Schasinglulu 	 */
189*91f16700Schasinglulu 	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
190*91f16700Schasinglulu 	return spsr;
191*91f16700Schasinglulu }
192*91f16700Schasinglulu #else
193*91f16700Schasinglulu uint32_t hikey960_get_spsr_for_bl33_entry(void)
194*91f16700Schasinglulu {
195*91f16700Schasinglulu 	unsigned int hyp_status, mode, spsr;
196*91f16700Schasinglulu 
197*91f16700Schasinglulu 	hyp_status = GET_VIRT_EXT(read_id_pfr1());
198*91f16700Schasinglulu 
199*91f16700Schasinglulu 	mode = (hyp_status) ? MODE32_hyp : MODE32_svc;
200*91f16700Schasinglulu 
201*91f16700Schasinglulu 	/*
202*91f16700Schasinglulu 	 * TODO: Consider the possibility of specifying the SPSR in
203*91f16700Schasinglulu 	 * the FIP ToC and allowing the platform to have a say as
204*91f16700Schasinglulu 	 * well.
205*91f16700Schasinglulu 	 */
206*91f16700Schasinglulu 	spsr = SPSR_MODE32(mode, plat_get_ns_image_entrypoint() & 0x1,
207*91f16700Schasinglulu 			SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS);
208*91f16700Schasinglulu 	return spsr;
209*91f16700Schasinglulu }
210*91f16700Schasinglulu #endif /* __aarch64__ */
211*91f16700Schasinglulu 
212*91f16700Schasinglulu int hikey960_bl2_handle_post_image_load(unsigned int image_id)
213*91f16700Schasinglulu {
214*91f16700Schasinglulu 	int err = 0;
215*91f16700Schasinglulu 	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
216*91f16700Schasinglulu #ifdef SPD_opteed
217*91f16700Schasinglulu 	bl_mem_params_node_t *pager_mem_params = NULL;
218*91f16700Schasinglulu 	bl_mem_params_node_t *paged_mem_params = NULL;
219*91f16700Schasinglulu #endif
220*91f16700Schasinglulu 	assert(bl_mem_params);
221*91f16700Schasinglulu 
222*91f16700Schasinglulu 	switch (image_id) {
223*91f16700Schasinglulu 	case BL31_IMAGE_ID:
224*91f16700Schasinglulu 		/* Pass BL2 platform parameter to BL31 */
225*91f16700Schasinglulu 		bl_mem_params->ep_info.args.arg1 = (uint64_t) &plat_params_from_bl2;
226*91f16700Schasinglulu 		break;
227*91f16700Schasinglulu 
228*91f16700Schasinglulu #ifdef __aarch64__
229*91f16700Schasinglulu 	case BL32_IMAGE_ID:
230*91f16700Schasinglulu #ifdef SPD_opteed
231*91f16700Schasinglulu 		pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
232*91f16700Schasinglulu 		assert(pager_mem_params);
233*91f16700Schasinglulu 
234*91f16700Schasinglulu 		paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
235*91f16700Schasinglulu 		assert(paged_mem_params);
236*91f16700Schasinglulu 
237*91f16700Schasinglulu 		err = parse_optee_header(&bl_mem_params->ep_info,
238*91f16700Schasinglulu 				&pager_mem_params->image_info,
239*91f16700Schasinglulu 				&paged_mem_params->image_info);
240*91f16700Schasinglulu 		if (err != 0) {
241*91f16700Schasinglulu 			WARN("OPTEE header parse error.\n");
242*91f16700Schasinglulu 		}
243*91f16700Schasinglulu #endif
244*91f16700Schasinglulu 		bl_mem_params->ep_info.spsr = hikey960_get_spsr_for_bl32_entry();
245*91f16700Schasinglulu 		break;
246*91f16700Schasinglulu #endif
247*91f16700Schasinglulu 
248*91f16700Schasinglulu 	case BL33_IMAGE_ID:
249*91f16700Schasinglulu 		/* BL33 expects to receive the primary CPU MPID (through r0) */
250*91f16700Schasinglulu 		bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
251*91f16700Schasinglulu 		bl_mem_params->ep_info.spsr = hikey960_get_spsr_for_bl33_entry();
252*91f16700Schasinglulu 		break;
253*91f16700Schasinglulu 
254*91f16700Schasinglulu #ifdef SCP_BL2_BASE
255*91f16700Schasinglulu 	case SCP_BL2_IMAGE_ID:
256*91f16700Schasinglulu 		/* The subsequent handling of SCP_BL2 is platform specific */
257*91f16700Schasinglulu 		err = plat_hikey960_bl2_handle_scp_bl2(&bl_mem_params->image_info);
258*91f16700Schasinglulu 		if (err) {
259*91f16700Schasinglulu 			WARN("Failure in platform-specific handling of SCP_BL2 image.\n");
260*91f16700Schasinglulu 		}
261*91f16700Schasinglulu 		break;
262*91f16700Schasinglulu #endif
263*91f16700Schasinglulu 	default:
264*91f16700Schasinglulu 		/* Do nothing in default case */
265*91f16700Schasinglulu 		break;
266*91f16700Schasinglulu 	}
267*91f16700Schasinglulu 
268*91f16700Schasinglulu 	return err;
269*91f16700Schasinglulu }
270*91f16700Schasinglulu 
271*91f16700Schasinglulu /*******************************************************************************
272*91f16700Schasinglulu  * This function can be used by the platforms to update/use image
273*91f16700Schasinglulu  * information for given `image_id`.
274*91f16700Schasinglulu  ******************************************************************************/
275*91f16700Schasinglulu int bl2_plat_handle_pre_image_load(unsigned int image_id)
276*91f16700Schasinglulu {
277*91f16700Schasinglulu 	return hikey960_set_fip_addr(image_id, "fip");
278*91f16700Schasinglulu }
279*91f16700Schasinglulu 
280*91f16700Schasinglulu int bl2_plat_handle_post_image_load(unsigned int image_id)
281*91f16700Schasinglulu {
282*91f16700Schasinglulu 	return hikey960_bl2_handle_post_image_load(image_id);
283*91f16700Schasinglulu }
284*91f16700Schasinglulu 
285*91f16700Schasinglulu void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2,
286*91f16700Schasinglulu 				  u_register_t arg3, u_register_t arg4)
287*91f16700Schasinglulu {
288*91f16700Schasinglulu 	unsigned int id, uart_base;
289*91f16700Schasinglulu 
290*91f16700Schasinglulu 	generic_delay_timer_init();
291*91f16700Schasinglulu 	hikey960_read_boardid(&id);
292*91f16700Schasinglulu 	if (id == 5300)
293*91f16700Schasinglulu 		uart_base = PL011_UART5_BASE;
294*91f16700Schasinglulu 	else
295*91f16700Schasinglulu 		uart_base = PL011_UART6_BASE;
296*91f16700Schasinglulu 	/* Initialize the console to provide early debug support */
297*91f16700Schasinglulu 	console_pl011_register(uart_base, PL011_UART_CLK_IN_HZ,
298*91f16700Schasinglulu 			       PL011_BAUDRATE, &console);
299*91f16700Schasinglulu 	/*
300*91f16700Schasinglulu 	 * Allow BL2 to see the whole Trusted RAM.
301*91f16700Schasinglulu 	 */
302*91f16700Schasinglulu 	bl2_el3_tzram_layout.total_base = BL2_RW_BASE;
303*91f16700Schasinglulu 	bl2_el3_tzram_layout.total_size = BL31_LIMIT - BL2_RW_BASE;
304*91f16700Schasinglulu }
305*91f16700Schasinglulu 
306*91f16700Schasinglulu void bl2_el3_plat_arch_setup(void)
307*91f16700Schasinglulu {
308*91f16700Schasinglulu 	hikey960_init_mmu_el3(bl2_el3_tzram_layout.total_base,
309*91f16700Schasinglulu 			      bl2_el3_tzram_layout.total_size,
310*91f16700Schasinglulu 			      BL_CODE_BASE,
311*91f16700Schasinglulu 			      BL_CODE_END,
312*91f16700Schasinglulu 			      BL_COHERENT_RAM_BASE,
313*91f16700Schasinglulu 			      BL_COHERENT_RAM_END);
314*91f16700Schasinglulu }
315*91f16700Schasinglulu 
316*91f16700Schasinglulu void bl2_platform_setup(void)
317*91f16700Schasinglulu {
318*91f16700Schasinglulu 	int ret;
319*91f16700Schasinglulu 
320*91f16700Schasinglulu 	/* disable WDT0 */
321*91f16700Schasinglulu 	if (mmio_read_32(WDT0_REG_BASE + WDT_LOCK_OFFSET) == WDT_LOCKED) {
322*91f16700Schasinglulu 		mmio_write_32(WDT0_REG_BASE + WDT_LOCK_OFFSET, WDT_UNLOCK);
323*91f16700Schasinglulu 		mmio_write_32(WDT0_REG_BASE + WDT_CONTROL_OFFSET, 0);
324*91f16700Schasinglulu 		mmio_write_32(WDT0_REG_BASE + WDT_LOCK_OFFSET, 0);
325*91f16700Schasinglulu 	}
326*91f16700Schasinglulu 	hikey960_clk_init();
327*91f16700Schasinglulu 	hikey960_pmu_init();
328*91f16700Schasinglulu 	hikey960_regulator_enable();
329*91f16700Schasinglulu 	hikey960_tzc_init();
330*91f16700Schasinglulu 	hikey960_peri_init();
331*91f16700Schasinglulu 	hikey960_pinmux_init();
332*91f16700Schasinglulu 	hikey960_gpio_init();
333*91f16700Schasinglulu 	hikey960_init_ufs();
334*91f16700Schasinglulu 	hikey960_io_setup();
335*91f16700Schasinglulu 
336*91f16700Schasinglulu 	/* Read serial number from storage */
337*91f16700Schasinglulu 	plat_params_from_bl2.fastboot_serno = 0;
338*91f16700Schasinglulu 	ret = hikey960_load_serialno(&plat_params_from_bl2.fastboot_serno);
339*91f16700Schasinglulu 	if (ret != 0) {
340*91f16700Schasinglulu 		ERROR("BL2: could not read serial number\n");
341*91f16700Schasinglulu 	}
342*91f16700Schasinglulu 	INFO("BL2: fastboot_serno %lx\n", plat_params_from_bl2.fastboot_serno);
343*91f16700Schasinglulu 	flush_dcache_range((uintptr_t)&plat_params_from_bl2, sizeof(plat_params_from_bl2_t));
344*91f16700Schasinglulu }
345