xref: /arm-trusted-firmware/plat/hisilicon/hikey/hikey_bl2_setup.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2017-2021, 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>	/* also includes hikey_def.h and hikey_layout.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/mmc.h>
20*91f16700Schasinglulu #include <drivers/synopsys/dw_mmc.h>
21*91f16700Schasinglulu #include <lib/mmio.h>
22*91f16700Schasinglulu #ifdef SPD_opteed
23*91f16700Schasinglulu #include <lib/optee_utils.h>
24*91f16700Schasinglulu #endif
25*91f16700Schasinglulu #include <plat/common/platform.h>
26*91f16700Schasinglulu 
27*91f16700Schasinglulu #include <hi6220.h>
28*91f16700Schasinglulu #include <hisi_mcu.h>
29*91f16700Schasinglulu #include <hisi_sram_map.h>
30*91f16700Schasinglulu #include "hikey_private.h"
31*91f16700Schasinglulu 
32*91f16700Schasinglulu #define BL2_RW_BASE		(BL_CODE_END)
33*91f16700Schasinglulu 
34*91f16700Schasinglulu static meminfo_t bl2_el3_tzram_layout;
35*91f16700Schasinglulu static console_t console;
36*91f16700Schasinglulu static struct mmc_device_info mmc_info;
37*91f16700Schasinglulu 
38*91f16700Schasinglulu enum {
39*91f16700Schasinglulu 	BOOT_MODE_RECOVERY = 0,
40*91f16700Schasinglulu 	BOOT_MODE_NORMAL,
41*91f16700Schasinglulu 	BOOT_MODE_MASK = 1,
42*91f16700Schasinglulu };
43*91f16700Schasinglulu 
44*91f16700Schasinglulu /*******************************************************************************
45*91f16700Schasinglulu  * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol.
46*91f16700Schasinglulu  * Return 0 on success, -1 otherwise.
47*91f16700Schasinglulu  ******************************************************************************/
48*91f16700Schasinglulu int plat_hikey_bl2_handle_scp_bl2(image_info_t *scp_bl2_image_info)
49*91f16700Schasinglulu {
50*91f16700Schasinglulu 	/* Enable MCU SRAM */
51*91f16700Schasinglulu 	hisi_mcu_enable_sram();
52*91f16700Schasinglulu 
53*91f16700Schasinglulu 	/* Load MCU binary into SRAM */
54*91f16700Schasinglulu 	hisi_mcu_load_image(scp_bl2_image_info->image_base,
55*91f16700Schasinglulu 			    scp_bl2_image_info->image_size);
56*91f16700Schasinglulu 	/* Let MCU running */
57*91f16700Schasinglulu 	hisi_mcu_start_run();
58*91f16700Schasinglulu 
59*91f16700Schasinglulu 	INFO("%s: MCU PC is at 0x%x\n",
60*91f16700Schasinglulu 	     __func__, mmio_read_32(AO_SC_MCU_SUBSYS_STAT2));
61*91f16700Schasinglulu 	INFO("%s: AO_SC_PERIPH_CLKSTAT4 is 0x%x\n",
62*91f16700Schasinglulu 	     __func__, mmio_read_32(AO_SC_PERIPH_CLKSTAT4));
63*91f16700Schasinglulu 	return 0;
64*91f16700Schasinglulu }
65*91f16700Schasinglulu 
66*91f16700Schasinglulu /*******************************************************************************
67*91f16700Schasinglulu  * Gets SPSR for BL32 entry
68*91f16700Schasinglulu  ******************************************************************************/
69*91f16700Schasinglulu uint32_t hikey_get_spsr_for_bl32_entry(void)
70*91f16700Schasinglulu {
71*91f16700Schasinglulu 	/*
72*91f16700Schasinglulu 	 * The Secure Payload Dispatcher service is responsible for
73*91f16700Schasinglulu 	 * setting the SPSR prior to entry into the BL3-2 image.
74*91f16700Schasinglulu 	 */
75*91f16700Schasinglulu 	return 0;
76*91f16700Schasinglulu }
77*91f16700Schasinglulu 
78*91f16700Schasinglulu /*******************************************************************************
79*91f16700Schasinglulu  * Gets SPSR for BL33 entry
80*91f16700Schasinglulu  ******************************************************************************/
81*91f16700Schasinglulu #ifdef __aarch64__
82*91f16700Schasinglulu uint32_t hikey_get_spsr_for_bl33_entry(void)
83*91f16700Schasinglulu {
84*91f16700Schasinglulu 	unsigned int mode;
85*91f16700Schasinglulu 	uint32_t spsr;
86*91f16700Schasinglulu 
87*91f16700Schasinglulu 	/* Figure out what mode we enter the non-secure world in */
88*91f16700Schasinglulu 	mode = (el_implemented(2) != EL_IMPL_NONE) ? MODE_EL2 : MODE_EL1;
89*91f16700Schasinglulu 
90*91f16700Schasinglulu 	/*
91*91f16700Schasinglulu 	 * TODO: Consider the possibility of specifying the SPSR in
92*91f16700Schasinglulu 	 * the FIP ToC and allowing the platform to have a say as
93*91f16700Schasinglulu 	 * well.
94*91f16700Schasinglulu 	 */
95*91f16700Schasinglulu 	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
96*91f16700Schasinglulu 	return spsr;
97*91f16700Schasinglulu }
98*91f16700Schasinglulu #else
99*91f16700Schasinglulu uint32_t hikey_get_spsr_for_bl33_entry(void)
100*91f16700Schasinglulu {
101*91f16700Schasinglulu 	unsigned int hyp_status, mode, spsr;
102*91f16700Schasinglulu 
103*91f16700Schasinglulu 	hyp_status = GET_VIRT_EXT(read_id_pfr1());
104*91f16700Schasinglulu 
105*91f16700Schasinglulu 	mode = (hyp_status) ? MODE32_hyp : MODE32_svc;
106*91f16700Schasinglulu 
107*91f16700Schasinglulu 	/*
108*91f16700Schasinglulu 	 * TODO: Consider the possibility of specifying the SPSR in
109*91f16700Schasinglulu 	 * the FIP ToC and allowing the platform to have a say as
110*91f16700Schasinglulu 	 * well.
111*91f16700Schasinglulu 	 */
112*91f16700Schasinglulu 	spsr = SPSR_MODE32(mode, plat_get_ns_image_entrypoint() & 0x1,
113*91f16700Schasinglulu 			SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS);
114*91f16700Schasinglulu 	return spsr;
115*91f16700Schasinglulu }
116*91f16700Schasinglulu #endif /* __aarch64__ */
117*91f16700Schasinglulu 
118*91f16700Schasinglulu int bl2_plat_handle_pre_image_load(unsigned int image_id)
119*91f16700Schasinglulu {
120*91f16700Schasinglulu 	return hikey_set_fip_addr(image_id, "fastboot");
121*91f16700Schasinglulu }
122*91f16700Schasinglulu 
123*91f16700Schasinglulu int hikey_bl2_handle_post_image_load(unsigned int image_id)
124*91f16700Schasinglulu {
125*91f16700Schasinglulu 	int err = 0;
126*91f16700Schasinglulu 	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
127*91f16700Schasinglulu #ifdef SPD_opteed
128*91f16700Schasinglulu 	bl_mem_params_node_t *pager_mem_params = NULL;
129*91f16700Schasinglulu 	bl_mem_params_node_t *paged_mem_params = NULL;
130*91f16700Schasinglulu #endif
131*91f16700Schasinglulu 	assert(bl_mem_params);
132*91f16700Schasinglulu 
133*91f16700Schasinglulu 	switch (image_id) {
134*91f16700Schasinglulu #ifdef __aarch64__
135*91f16700Schasinglulu 	case BL32_IMAGE_ID:
136*91f16700Schasinglulu #ifdef SPD_opteed
137*91f16700Schasinglulu 		pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
138*91f16700Schasinglulu 		assert(pager_mem_params);
139*91f16700Schasinglulu 
140*91f16700Schasinglulu 		paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
141*91f16700Schasinglulu 		assert(paged_mem_params);
142*91f16700Schasinglulu 
143*91f16700Schasinglulu 		err = parse_optee_header(&bl_mem_params->ep_info,
144*91f16700Schasinglulu 				&pager_mem_params->image_info,
145*91f16700Schasinglulu 				&paged_mem_params->image_info);
146*91f16700Schasinglulu 		if (err != 0) {
147*91f16700Schasinglulu 			WARN("OPTEE header parse error.\n");
148*91f16700Schasinglulu 		}
149*91f16700Schasinglulu #endif
150*91f16700Schasinglulu 		bl_mem_params->ep_info.spsr = hikey_get_spsr_for_bl32_entry();
151*91f16700Schasinglulu 		break;
152*91f16700Schasinglulu #endif
153*91f16700Schasinglulu 
154*91f16700Schasinglulu 	case BL33_IMAGE_ID:
155*91f16700Schasinglulu 		/* BL33 expects to receive the primary CPU MPID (through r0) */
156*91f16700Schasinglulu 		bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
157*91f16700Schasinglulu 		bl_mem_params->ep_info.spsr = hikey_get_spsr_for_bl33_entry();
158*91f16700Schasinglulu 		break;
159*91f16700Schasinglulu 
160*91f16700Schasinglulu #ifdef SCP_BL2_BASE
161*91f16700Schasinglulu 	case SCP_BL2_IMAGE_ID:
162*91f16700Schasinglulu 		/* The subsequent handling of SCP_BL2 is platform specific */
163*91f16700Schasinglulu 		err = plat_hikey_bl2_handle_scp_bl2(&bl_mem_params->image_info);
164*91f16700Schasinglulu 		if (err) {
165*91f16700Schasinglulu 			WARN("Failure in platform-specific handling of SCP_BL2 image.\n");
166*91f16700Schasinglulu 		}
167*91f16700Schasinglulu 		break;
168*91f16700Schasinglulu #endif
169*91f16700Schasinglulu 	default:
170*91f16700Schasinglulu 		/* Do nothing in default case */
171*91f16700Schasinglulu 		break;
172*91f16700Schasinglulu 	}
173*91f16700Schasinglulu 
174*91f16700Schasinglulu 	return err;
175*91f16700Schasinglulu }
176*91f16700Schasinglulu 
177*91f16700Schasinglulu /*******************************************************************************
178*91f16700Schasinglulu  * This function can be used by the platforms to update/use image
179*91f16700Schasinglulu  * information for given `image_id`.
180*91f16700Schasinglulu  ******************************************************************************/
181*91f16700Schasinglulu int bl2_plat_handle_post_image_load(unsigned int image_id)
182*91f16700Schasinglulu {
183*91f16700Schasinglulu 	return hikey_bl2_handle_post_image_load(image_id);
184*91f16700Schasinglulu }
185*91f16700Schasinglulu 
186*91f16700Schasinglulu static void reset_dwmmc_clk(void)
187*91f16700Schasinglulu {
188*91f16700Schasinglulu 	unsigned int data;
189*91f16700Schasinglulu 
190*91f16700Schasinglulu 	/* disable mmc0 bus clock */
191*91f16700Schasinglulu 	mmio_write_32(PERI_SC_PERIPH_CLKDIS0, PERI_CLK0_MMC0);
192*91f16700Schasinglulu 	do {
193*91f16700Schasinglulu 		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
194*91f16700Schasinglulu 	} while (data & PERI_CLK0_MMC0);
195*91f16700Schasinglulu 	/* enable mmc0 bus clock */
196*91f16700Schasinglulu 	mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_MMC0);
197*91f16700Schasinglulu 	do {
198*91f16700Schasinglulu 		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
199*91f16700Schasinglulu 	} while (!(data & PERI_CLK0_MMC0));
200*91f16700Schasinglulu 	/* reset mmc0 clock domain */
201*91f16700Schasinglulu 	mmio_write_32(PERI_SC_PERIPH_RSTEN0, PERI_RST0_MMC0);
202*91f16700Schasinglulu 
203*91f16700Schasinglulu 	/* bypass mmc0 clock phase */
204*91f16700Schasinglulu 	data = mmio_read_32(PERI_SC_PERIPH_CTRL2);
205*91f16700Schasinglulu 	data |= 3;
206*91f16700Schasinglulu 	mmio_write_32(PERI_SC_PERIPH_CTRL2, data);
207*91f16700Schasinglulu 
208*91f16700Schasinglulu 	/* disable low power */
209*91f16700Schasinglulu 	data = mmio_read_32(PERI_SC_PERIPH_CTRL13);
210*91f16700Schasinglulu 	data |= 1 << 3;
211*91f16700Schasinglulu 	mmio_write_32(PERI_SC_PERIPH_CTRL13, data);
212*91f16700Schasinglulu 	do {
213*91f16700Schasinglulu 		data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
214*91f16700Schasinglulu 	} while (!(data & PERI_RST0_MMC0));
215*91f16700Schasinglulu 
216*91f16700Schasinglulu 	/* unreset mmc0 clock domain */
217*91f16700Schasinglulu 	mmio_write_32(PERI_SC_PERIPH_RSTDIS0, PERI_RST0_MMC0);
218*91f16700Schasinglulu 	do {
219*91f16700Schasinglulu 		data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
220*91f16700Schasinglulu 	} while (data & PERI_RST0_MMC0);
221*91f16700Schasinglulu }
222*91f16700Schasinglulu 
223*91f16700Schasinglulu static void hikey_boardid_init(void)
224*91f16700Schasinglulu {
225*91f16700Schasinglulu 	u_register_t midr;
226*91f16700Schasinglulu 
227*91f16700Schasinglulu 	midr = read_midr();
228*91f16700Schasinglulu 	mmio_write_32(MEMORY_AXI_CHIP_ADDR, midr);
229*91f16700Schasinglulu 	INFO("[BDID] [%x] midr: 0x%x\n", MEMORY_AXI_CHIP_ADDR,
230*91f16700Schasinglulu 	     (unsigned int)midr);
231*91f16700Schasinglulu 
232*91f16700Schasinglulu 	mmio_write_32(MEMORY_AXI_BOARD_TYPE_ADDR, 0);
233*91f16700Schasinglulu 	mmio_write_32(MEMORY_AXI_BOARD_ID_ADDR, 0x2b);
234*91f16700Schasinglulu 
235*91f16700Schasinglulu 	mmio_write_32(ACPU_ARM64_FLAGA, 0x1234);
236*91f16700Schasinglulu 	mmio_write_32(ACPU_ARM64_FLAGB, 0x5678);
237*91f16700Schasinglulu }
238*91f16700Schasinglulu 
239*91f16700Schasinglulu static void hikey_sd_init(void)
240*91f16700Schasinglulu {
241*91f16700Schasinglulu 	/* switch pinmux to SD */
242*91f16700Schasinglulu 	mmio_write_32(IOMG_SD_CLK, IOMG_MUX_FUNC0);
243*91f16700Schasinglulu 	mmio_write_32(IOMG_SD_CMD, IOMG_MUX_FUNC0);
244*91f16700Schasinglulu 	mmio_write_32(IOMG_SD_DATA0, IOMG_MUX_FUNC0);
245*91f16700Schasinglulu 	mmio_write_32(IOMG_SD_DATA1, IOMG_MUX_FUNC0);
246*91f16700Schasinglulu 	mmio_write_32(IOMG_SD_DATA2, IOMG_MUX_FUNC0);
247*91f16700Schasinglulu 	mmio_write_32(IOMG_SD_DATA3, IOMG_MUX_FUNC0);
248*91f16700Schasinglulu 
249*91f16700Schasinglulu 	mmio_write_32(IOCG_SD_CLK, IOCG_INPUT_16MA);
250*91f16700Schasinglulu 	mmio_write_32(IOCG_SD_CMD, IOCG_INPUT_12MA);
251*91f16700Schasinglulu 	mmio_write_32(IOCG_SD_DATA0, IOCG_INPUT_12MA);
252*91f16700Schasinglulu 	mmio_write_32(IOCG_SD_DATA1, IOCG_INPUT_12MA);
253*91f16700Schasinglulu 	mmio_write_32(IOCG_SD_DATA2, IOCG_INPUT_12MA);
254*91f16700Schasinglulu 	mmio_write_32(IOCG_SD_DATA3, IOCG_INPUT_12MA);
255*91f16700Schasinglulu 
256*91f16700Schasinglulu 	/* set SD Card detect as nopull */
257*91f16700Schasinglulu 	mmio_write_32(IOCG_GPIO8, 0);
258*91f16700Schasinglulu }
259*91f16700Schasinglulu 
260*91f16700Schasinglulu static void hikey_jumper_init(void)
261*91f16700Schasinglulu {
262*91f16700Schasinglulu 	/* set jumper detect as nopull */
263*91f16700Schasinglulu 	mmio_write_32(IOCG_GPIO24, 0);
264*91f16700Schasinglulu 	/* set jumper detect as GPIO */
265*91f16700Schasinglulu 	mmio_write_32(IOMG_GPIO24, IOMG_MUX_FUNC0);
266*91f16700Schasinglulu }
267*91f16700Schasinglulu 
268*91f16700Schasinglulu void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2,
269*91f16700Schasinglulu 				  u_register_t arg3, u_register_t arg4)
270*91f16700Schasinglulu {
271*91f16700Schasinglulu 	/* Initialize the console to provide early debug support */
272*91f16700Schasinglulu 	console_pl011_register(CONSOLE_BASE, PL011_UART_CLK_IN_HZ,
273*91f16700Schasinglulu 			       PL011_BAUDRATE, &console);
274*91f16700Schasinglulu 	/*
275*91f16700Schasinglulu 	 * Allow BL2 to see the whole Trusted RAM.
276*91f16700Schasinglulu 	 */
277*91f16700Schasinglulu 	bl2_el3_tzram_layout.total_base = BL2_RW_BASE;
278*91f16700Schasinglulu 	bl2_el3_tzram_layout.total_size = BL31_LIMIT - BL2_RW_BASE;
279*91f16700Schasinglulu }
280*91f16700Schasinglulu 
281*91f16700Schasinglulu void bl2_el3_plat_arch_setup(void)
282*91f16700Schasinglulu {
283*91f16700Schasinglulu 	hikey_init_mmu_el3(bl2_el3_tzram_layout.total_base,
284*91f16700Schasinglulu 			   bl2_el3_tzram_layout.total_size,
285*91f16700Schasinglulu 			   BL_CODE_BASE,
286*91f16700Schasinglulu 			   BL_CODE_END,
287*91f16700Schasinglulu 			   BL_COHERENT_RAM_BASE,
288*91f16700Schasinglulu 			   BL_COHERENT_RAM_END);
289*91f16700Schasinglulu }
290*91f16700Schasinglulu 
291*91f16700Schasinglulu void bl2_platform_setup(void)
292*91f16700Schasinglulu {
293*91f16700Schasinglulu 	dw_mmc_params_t params;
294*91f16700Schasinglulu 
295*91f16700Schasinglulu 	hikey_sp804_init();
296*91f16700Schasinglulu 	hikey_gpio_init();
297*91f16700Schasinglulu 	hikey_pmussi_init();
298*91f16700Schasinglulu 	hikey_hi6553_init();
299*91f16700Schasinglulu 	/* Clear SRAM since it'll be used by MCU right now. */
300*91f16700Schasinglulu 	memset((void *)SRAM_BASE, 0, SRAM_SIZE);
301*91f16700Schasinglulu 
302*91f16700Schasinglulu 	dsb();
303*91f16700Schasinglulu 	hikey_ddr_init(DDR_FREQ_800M);
304*91f16700Schasinglulu 	hikey_security_setup();
305*91f16700Schasinglulu 
306*91f16700Schasinglulu 	hikey_boardid_init();
307*91f16700Schasinglulu 	init_acpu_dvfs();
308*91f16700Schasinglulu 	hikey_rtc_init();
309*91f16700Schasinglulu 	hikey_sd_init();
310*91f16700Schasinglulu 	hikey_jumper_init();
311*91f16700Schasinglulu 
312*91f16700Schasinglulu 	hikey_mmc_pll_init();
313*91f16700Schasinglulu 
314*91f16700Schasinglulu 	/* Clean SRAM before MCU used */
315*91f16700Schasinglulu 	clean_dcache_range(SRAM_BASE, SRAM_SIZE);
316*91f16700Schasinglulu 
317*91f16700Schasinglulu 	reset_dwmmc_clk();
318*91f16700Schasinglulu 	memset(&params, 0, sizeof(dw_mmc_params_t));
319*91f16700Schasinglulu 	params.reg_base = DWMMC0_BASE;
320*91f16700Schasinglulu 	params.desc_base = HIKEY_MMC_DESC_BASE;
321*91f16700Schasinglulu 	params.desc_size = 1 << 20;
322*91f16700Schasinglulu 	params.clk_rate = 24 * 1000 * 1000;
323*91f16700Schasinglulu 	params.bus_width = MMC_BUS_WIDTH_8;
324*91f16700Schasinglulu 	params.flags = MMC_FLAG_CMD23;
325*91f16700Schasinglulu 	mmc_info.mmc_dev_type = MMC_IS_EMMC;
326*91f16700Schasinglulu 	dw_mmc_init(&params, &mmc_info);
327*91f16700Schasinglulu 
328*91f16700Schasinglulu 	hikey_io_setup();
329*91f16700Schasinglulu }
330