xref: /rk3399_ARM-atf/plat/hisilicon/hikey/hikey_bl2_setup.c (revision 3b6e88a2b364d136acd28cdd1dea166a3a12a94e)
132e9fc1aSHaojian Zhuang /*
232e9fc1aSHaojian Zhuang  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
332e9fc1aSHaojian Zhuang  *
432e9fc1aSHaojian Zhuang  * SPDX-License-Identifier: BSD-3-Clause
532e9fc1aSHaojian Zhuang  */
632e9fc1aSHaojian Zhuang 
732e9fc1aSHaojian Zhuang #include <arch_helpers.h>
832e9fc1aSHaojian Zhuang #include <assert.h>
932e9fc1aSHaojian Zhuang #include <bl_common.h>
1032e9fc1aSHaojian Zhuang #include <console.h>
1132e9fc1aSHaojian Zhuang #include <debug.h>
1232e9fc1aSHaojian Zhuang #include <dw_mmc.h>
1332e9fc1aSHaojian Zhuang #include <emmc.h>
1432e9fc1aSHaojian Zhuang #include <errno.h>
1532e9fc1aSHaojian Zhuang #include <hi6220.h>
1632e9fc1aSHaojian Zhuang #include <hisi_mcu.h>
1732e9fc1aSHaojian Zhuang #include <hisi_sram_map.h>
1832e9fc1aSHaojian Zhuang #include <mmio.h>
1932e9fc1aSHaojian Zhuang #include <platform_def.h>
2032e9fc1aSHaojian Zhuang #include <sp804_delay_timer.h>
2132e9fc1aSHaojian Zhuang #include <string.h>
2232e9fc1aSHaojian Zhuang 
2332e9fc1aSHaojian Zhuang #include "hikey_def.h"
2432e9fc1aSHaojian Zhuang #include "hikey_private.h"
2532e9fc1aSHaojian Zhuang 
2632e9fc1aSHaojian Zhuang /*
2732e9fc1aSHaojian Zhuang  * The next 2 constants identify the extents of the code & RO data region.
2832e9fc1aSHaojian Zhuang  * These addresses are used by the MMU setup code and therefore they must be
2932e9fc1aSHaojian Zhuang  * page-aligned.  It is the responsibility of the linker script to ensure that
3032e9fc1aSHaojian Zhuang  * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
3132e9fc1aSHaojian Zhuang  */
3232e9fc1aSHaojian Zhuang #define BL2_RO_BASE (unsigned long)(&__RO_START__)
3332e9fc1aSHaojian Zhuang #define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
3432e9fc1aSHaojian Zhuang 
3532e9fc1aSHaojian Zhuang /*
3632e9fc1aSHaojian Zhuang  * The next 2 constants identify the extents of the coherent memory region.
3732e9fc1aSHaojian Zhuang  * These addresses are used by the MMU setup code and therefore they must be
3832e9fc1aSHaojian Zhuang  * page-aligned.  It is the responsibility of the linker script to ensure that
3932e9fc1aSHaojian Zhuang  * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
4032e9fc1aSHaojian Zhuang  * page-aligned addresses.
4132e9fc1aSHaojian Zhuang  */
4232e9fc1aSHaojian Zhuang #define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
4332e9fc1aSHaojian Zhuang #define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
4432e9fc1aSHaojian Zhuang 
4532e9fc1aSHaojian Zhuang static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
4632e9fc1aSHaojian Zhuang 
4732e9fc1aSHaojian Zhuang typedef struct bl2_to_bl31_params_mem {
4832e9fc1aSHaojian Zhuang 	bl31_params_t		bl31_params;
4932e9fc1aSHaojian Zhuang 	image_info_t		bl31_image_info;
5032e9fc1aSHaojian Zhuang 	image_info_t		bl32_image_info;
5132e9fc1aSHaojian Zhuang 	image_info_t		bl33_image_info;
5232e9fc1aSHaojian Zhuang 	entry_point_info_t	bl33_ep_info;
5332e9fc1aSHaojian Zhuang 	entry_point_info_t	bl32_ep_info;
5432e9fc1aSHaojian Zhuang 	entry_point_info_t	bl31_ep_info;
5532e9fc1aSHaojian Zhuang } bl2_to_bl31_params_mem_t;
5632e9fc1aSHaojian Zhuang 
5732e9fc1aSHaojian Zhuang static bl2_to_bl31_params_mem_t bl31_params_mem;
5832e9fc1aSHaojian Zhuang 
5932e9fc1aSHaojian Zhuang meminfo_t *bl2_plat_sec_mem_layout(void)
6032e9fc1aSHaojian Zhuang {
6132e9fc1aSHaojian Zhuang 	return &bl2_tzram_layout;
6232e9fc1aSHaojian Zhuang }
6332e9fc1aSHaojian Zhuang 
6432e9fc1aSHaojian Zhuang void bl2_plat_get_scp_bl2_meminfo(meminfo_t *scp_bl2_meminfo)
6532e9fc1aSHaojian Zhuang {
6632e9fc1aSHaojian Zhuang 	scp_bl2_meminfo->total_base = SCP_BL2_BASE;
6732e9fc1aSHaojian Zhuang 	scp_bl2_meminfo->total_size = SCP_BL2_SIZE;
6832e9fc1aSHaojian Zhuang 	scp_bl2_meminfo->free_base = SCP_BL2_BASE;
6932e9fc1aSHaojian Zhuang 	scp_bl2_meminfo->free_size = SCP_BL2_SIZE;
7032e9fc1aSHaojian Zhuang }
7132e9fc1aSHaojian Zhuang 
7232e9fc1aSHaojian Zhuang int bl2_plat_handle_scp_bl2(struct image_info *scp_bl2_image_info)
7332e9fc1aSHaojian Zhuang {
7432e9fc1aSHaojian Zhuang 	/* Enable MCU SRAM */
7532e9fc1aSHaojian Zhuang 	hisi_mcu_enable_sram();
7632e9fc1aSHaojian Zhuang 
7732e9fc1aSHaojian Zhuang 	/* Load MCU binary into SRAM */
7832e9fc1aSHaojian Zhuang 	hisi_mcu_load_image(scp_bl2_image_info->image_base,
7932e9fc1aSHaojian Zhuang 			    scp_bl2_image_info->image_size);
8032e9fc1aSHaojian Zhuang 	/* Let MCU running */
8132e9fc1aSHaojian Zhuang 	hisi_mcu_start_run();
8232e9fc1aSHaojian Zhuang 
8332e9fc1aSHaojian Zhuang 	INFO("%s: MCU PC is at 0x%x\n",
8432e9fc1aSHaojian Zhuang 	     __func__, mmio_read_32(AO_SC_MCU_SUBSYS_STAT2));
8532e9fc1aSHaojian Zhuang 	INFO("%s: AO_SC_PERIPH_CLKSTAT4 is 0x%x\n",
8632e9fc1aSHaojian Zhuang 	     __func__, mmio_read_32(AO_SC_PERIPH_CLKSTAT4));
8732e9fc1aSHaojian Zhuang 	return 0;
8832e9fc1aSHaojian Zhuang }
8932e9fc1aSHaojian Zhuang 
9032e9fc1aSHaojian Zhuang bl31_params_t *bl2_plat_get_bl31_params(void)
9132e9fc1aSHaojian Zhuang {
9232e9fc1aSHaojian Zhuang 	bl31_params_t *bl2_to_bl31_params = NULL;
9332e9fc1aSHaojian Zhuang 
9432e9fc1aSHaojian Zhuang 	/*
9532e9fc1aSHaojian Zhuang 	 * Initialise the memory for all the arguments that needs to
9632e9fc1aSHaojian Zhuang 	 * be passed to BL3-1
9732e9fc1aSHaojian Zhuang 	 */
9832e9fc1aSHaojian Zhuang 	memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
9932e9fc1aSHaojian Zhuang 
10032e9fc1aSHaojian Zhuang 	/* Assign memory for TF related information */
10132e9fc1aSHaojian Zhuang 	bl2_to_bl31_params = &bl31_params_mem.bl31_params;
10232e9fc1aSHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
10332e9fc1aSHaojian Zhuang 
10432e9fc1aSHaojian Zhuang 	/* Fill BL3-1 related information */
10532e9fc1aSHaojian Zhuang 	bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
10632e9fc1aSHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY,
10732e9fc1aSHaojian Zhuang 		VERSION_1, 0);
10832e9fc1aSHaojian Zhuang 
10932e9fc1aSHaojian Zhuang 	/* Fill BL3-2 related information if it exists */
11032e9fc1aSHaojian Zhuang #if BL32_BASE
11132e9fc1aSHaojian Zhuang 	bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
11232e9fc1aSHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP,
11332e9fc1aSHaojian Zhuang 		VERSION_1, 0);
11432e9fc1aSHaojian Zhuang 	bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
11532e9fc1aSHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY,
11632e9fc1aSHaojian Zhuang 		VERSION_1, 0);
11732e9fc1aSHaojian Zhuang #endif
11832e9fc1aSHaojian Zhuang 
11932e9fc1aSHaojian Zhuang 	/* Fill BL3-3 related information */
12032e9fc1aSHaojian Zhuang 	bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
12132e9fc1aSHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
12232e9fc1aSHaojian Zhuang 		PARAM_EP, VERSION_1, 0);
12332e9fc1aSHaojian Zhuang 
12432e9fc1aSHaojian Zhuang 	/* BL3-3 expects to receive the primary CPU MPID (through x0) */
12532e9fc1aSHaojian Zhuang 	bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
12632e9fc1aSHaojian Zhuang 
12732e9fc1aSHaojian Zhuang 	bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
12832e9fc1aSHaojian Zhuang 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY,
12932e9fc1aSHaojian Zhuang 		VERSION_1, 0);
13032e9fc1aSHaojian Zhuang 
13132e9fc1aSHaojian Zhuang 	return bl2_to_bl31_params;
13232e9fc1aSHaojian Zhuang }
13332e9fc1aSHaojian Zhuang 
13432e9fc1aSHaojian Zhuang struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
13532e9fc1aSHaojian Zhuang {
13632e9fc1aSHaojian Zhuang 	return &bl31_params_mem.bl31_ep_info;
13732e9fc1aSHaojian Zhuang }
13832e9fc1aSHaojian Zhuang 
13932e9fc1aSHaojian Zhuang void bl2_plat_set_bl31_ep_info(image_info_t *image,
14032e9fc1aSHaojian Zhuang 			       entry_point_info_t *bl31_ep_info)
14132e9fc1aSHaojian Zhuang {
14232e9fc1aSHaojian Zhuang 	SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
14332e9fc1aSHaojian Zhuang 	bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
14432e9fc1aSHaojian Zhuang 				       DISABLE_ALL_EXCEPTIONS);
14532e9fc1aSHaojian Zhuang }
14632e9fc1aSHaojian Zhuang 
147*3b6e88a2SVictor Chong /*******************************************************************************
148*3b6e88a2SVictor Chong  * Before calling this function BL32 is loaded in memory and its entrypoint
149*3b6e88a2SVictor Chong  * is set by load_image. This is a placeholder for the platform to change
150*3b6e88a2SVictor Chong  * the entrypoint of BL32 and set SPSR and security state.
151*3b6e88a2SVictor Chong  * On Hikey we only set the security state of the entrypoint
152*3b6e88a2SVictor Chong  ******************************************************************************/
153*3b6e88a2SVictor Chong #ifdef BL32_BASE
154*3b6e88a2SVictor Chong void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
155*3b6e88a2SVictor Chong 					entry_point_info_t *bl32_ep_info)
156*3b6e88a2SVictor Chong {
157*3b6e88a2SVictor Chong 	SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
158*3b6e88a2SVictor Chong 	/*
159*3b6e88a2SVictor Chong 	 * The Secure Payload Dispatcher service is responsible for
160*3b6e88a2SVictor Chong 	 * setting the SPSR prior to entry into the BL32 image.
161*3b6e88a2SVictor Chong 	 */
162*3b6e88a2SVictor Chong 	bl32_ep_info->spsr = 0;
163*3b6e88a2SVictor Chong }
164*3b6e88a2SVictor Chong 
165*3b6e88a2SVictor Chong /*******************************************************************************
166*3b6e88a2SVictor Chong  * Populate the extents of memory available for loading BL32
167*3b6e88a2SVictor Chong  ******************************************************************************/
168*3b6e88a2SVictor Chong void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
169*3b6e88a2SVictor Chong {
170*3b6e88a2SVictor Chong 	/*
171*3b6e88a2SVictor Chong 	 * Populate the extents of memory available for loading BL32.
172*3b6e88a2SVictor Chong 	 */
173*3b6e88a2SVictor Chong 	bl32_meminfo->total_base = BL32_BASE;
174*3b6e88a2SVictor Chong 	bl32_meminfo->free_base = BL32_BASE;
175*3b6e88a2SVictor Chong 	bl32_meminfo->total_size =
176*3b6e88a2SVictor Chong 			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
177*3b6e88a2SVictor Chong 	bl32_meminfo->free_size =
178*3b6e88a2SVictor Chong 			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
179*3b6e88a2SVictor Chong }
180*3b6e88a2SVictor Chong #endif /* BL32_BASE */
181*3b6e88a2SVictor Chong 
18232e9fc1aSHaojian Zhuang void bl2_plat_set_bl33_ep_info(image_info_t *image,
18332e9fc1aSHaojian Zhuang 			       entry_point_info_t *bl33_ep_info)
18432e9fc1aSHaojian Zhuang {
18532e9fc1aSHaojian Zhuang 	unsigned long el_status;
18632e9fc1aSHaojian Zhuang 	unsigned int mode;
18732e9fc1aSHaojian Zhuang 
18832e9fc1aSHaojian Zhuang 	/* Figure out what mode we enter the non-secure world in */
18932e9fc1aSHaojian Zhuang 	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
19032e9fc1aSHaojian Zhuang 	el_status &= ID_AA64PFR0_ELX_MASK;
19132e9fc1aSHaojian Zhuang 
19232e9fc1aSHaojian Zhuang 	if (el_status)
19332e9fc1aSHaojian Zhuang 		mode = MODE_EL2;
19432e9fc1aSHaojian Zhuang 	else
19532e9fc1aSHaojian Zhuang 		mode = MODE_EL1;
19632e9fc1aSHaojian Zhuang 
19732e9fc1aSHaojian Zhuang 	/*
19832e9fc1aSHaojian Zhuang 	 * TODO: Consider the possibility of specifying the SPSR in
19932e9fc1aSHaojian Zhuang 	 * the FIP ToC and allowing the platform to have a say as
20032e9fc1aSHaojian Zhuang 	 * well.
20132e9fc1aSHaojian Zhuang 	 */
20232e9fc1aSHaojian Zhuang 	bl33_ep_info->spsr = SPSR_64(mode, MODE_SP_ELX,
20332e9fc1aSHaojian Zhuang 				       DISABLE_ALL_EXCEPTIONS);
20432e9fc1aSHaojian Zhuang 	SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
20532e9fc1aSHaojian Zhuang }
20632e9fc1aSHaojian Zhuang 
20732e9fc1aSHaojian Zhuang void bl2_plat_flush_bl31_params(void)
20832e9fc1aSHaojian Zhuang {
20932e9fc1aSHaojian Zhuang 	flush_dcache_range((unsigned long)&bl31_params_mem,
21032e9fc1aSHaojian Zhuang 			   sizeof(bl2_to_bl31_params_mem_t));
21132e9fc1aSHaojian Zhuang }
21232e9fc1aSHaojian Zhuang 
21332e9fc1aSHaojian Zhuang void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
21432e9fc1aSHaojian Zhuang {
21532e9fc1aSHaojian Zhuang 	bl33_meminfo->total_base = DDR_BASE;
21632e9fc1aSHaojian Zhuang 	bl33_meminfo->total_size = DDR_SIZE;
21732e9fc1aSHaojian Zhuang 	bl33_meminfo->free_base = DDR_BASE;
21832e9fc1aSHaojian Zhuang 	bl33_meminfo->free_size = DDR_SIZE;
21932e9fc1aSHaojian Zhuang }
22032e9fc1aSHaojian Zhuang 
22132e9fc1aSHaojian Zhuang static void reset_dwmmc_clk(void)
22232e9fc1aSHaojian Zhuang {
22332e9fc1aSHaojian Zhuang 	unsigned int data;
22432e9fc1aSHaojian Zhuang 
22532e9fc1aSHaojian Zhuang 	/* disable mmc0 bus clock */
22632e9fc1aSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CLKDIS0, PERI_CLK0_MMC0);
22732e9fc1aSHaojian Zhuang 	do {
22832e9fc1aSHaojian Zhuang 		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
22932e9fc1aSHaojian Zhuang 	} while (data & PERI_CLK0_MMC0);
23032e9fc1aSHaojian Zhuang 	/* enable mmc0 bus clock */
23132e9fc1aSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_MMC0);
23232e9fc1aSHaojian Zhuang 	do {
23332e9fc1aSHaojian Zhuang 		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
23432e9fc1aSHaojian Zhuang 	} while (!(data & PERI_CLK0_MMC0));
23532e9fc1aSHaojian Zhuang 	/* reset mmc0 clock domain */
23632e9fc1aSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_RSTEN0, PERI_RST0_MMC0);
23732e9fc1aSHaojian Zhuang 
23832e9fc1aSHaojian Zhuang 	/* bypass mmc0 clock phase */
23932e9fc1aSHaojian Zhuang 	data = mmio_read_32(PERI_SC_PERIPH_CTRL2);
24032e9fc1aSHaojian Zhuang 	data |= 3;
24132e9fc1aSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CTRL2, data);
24232e9fc1aSHaojian Zhuang 
24332e9fc1aSHaojian Zhuang 	/* disable low power */
24432e9fc1aSHaojian Zhuang 	data = mmio_read_32(PERI_SC_PERIPH_CTRL13);
24532e9fc1aSHaojian Zhuang 	data |= 1 << 3;
24632e9fc1aSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CTRL13, data);
24732e9fc1aSHaojian Zhuang 	do {
24832e9fc1aSHaojian Zhuang 		data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
24932e9fc1aSHaojian Zhuang 	} while (!(data & PERI_RST0_MMC0));
25032e9fc1aSHaojian Zhuang 
25132e9fc1aSHaojian Zhuang 	/* unreset mmc0 clock domain */
25232e9fc1aSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_RSTDIS0, PERI_RST0_MMC0);
25332e9fc1aSHaojian Zhuang 	do {
25432e9fc1aSHaojian Zhuang 		data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
25532e9fc1aSHaojian Zhuang 	} while (data & PERI_RST0_MMC0);
25632e9fc1aSHaojian Zhuang }
25732e9fc1aSHaojian Zhuang 
25832e9fc1aSHaojian Zhuang static void hikey_boardid_init(void)
25932e9fc1aSHaojian Zhuang {
26032e9fc1aSHaojian Zhuang 	u_register_t midr;
26132e9fc1aSHaojian Zhuang 
26232e9fc1aSHaojian Zhuang 	midr = read_midr();
26332e9fc1aSHaojian Zhuang 	mmio_write_32(MEMORY_AXI_CHIP_ADDR, midr);
26432e9fc1aSHaojian Zhuang 	INFO("[BDID] [%x] midr: 0x%x\n", MEMORY_AXI_CHIP_ADDR,
26532e9fc1aSHaojian Zhuang 	     (unsigned int)midr);
26632e9fc1aSHaojian Zhuang 
26732e9fc1aSHaojian Zhuang 	mmio_write_32(MEMORY_AXI_BOARD_TYPE_ADDR, 0);
26832e9fc1aSHaojian Zhuang 	mmio_write_32(MEMORY_AXI_BOARD_ID_ADDR, 0x2b);
26932e9fc1aSHaojian Zhuang 
27032e9fc1aSHaojian Zhuang 	mmio_write_32(ACPU_ARM64_FLAGA, 0x1234);
27132e9fc1aSHaojian Zhuang 	mmio_write_32(ACPU_ARM64_FLAGB, 0x5678);
27232e9fc1aSHaojian Zhuang }
27332e9fc1aSHaojian Zhuang 
27432e9fc1aSHaojian Zhuang static void hikey_sd_init(void)
27532e9fc1aSHaojian Zhuang {
27632e9fc1aSHaojian Zhuang 	/* switch pinmux to SD */
27732e9fc1aSHaojian Zhuang 	mmio_write_32(IOMG_SD_CLK, IOMG_MUX_FUNC0);
27832e9fc1aSHaojian Zhuang 	mmio_write_32(IOMG_SD_CMD, IOMG_MUX_FUNC0);
27932e9fc1aSHaojian Zhuang 	mmio_write_32(IOMG_SD_DATA0, IOMG_MUX_FUNC0);
28032e9fc1aSHaojian Zhuang 	mmio_write_32(IOMG_SD_DATA1, IOMG_MUX_FUNC0);
28132e9fc1aSHaojian Zhuang 	mmio_write_32(IOMG_SD_DATA2, IOMG_MUX_FUNC0);
28232e9fc1aSHaojian Zhuang 	mmio_write_32(IOMG_SD_DATA3, IOMG_MUX_FUNC0);
28332e9fc1aSHaojian Zhuang 
28432e9fc1aSHaojian Zhuang 	mmio_write_32(IOCG_SD_CLK, IOCG_INPUT_16MA);
28532e9fc1aSHaojian Zhuang 	mmio_write_32(IOCG_SD_CMD, IOCG_INPUT_12MA);
28632e9fc1aSHaojian Zhuang 	mmio_write_32(IOCG_SD_DATA0, IOCG_INPUT_12MA);
28732e9fc1aSHaojian Zhuang 	mmio_write_32(IOCG_SD_DATA1, IOCG_INPUT_12MA);
28832e9fc1aSHaojian Zhuang 	mmio_write_32(IOCG_SD_DATA2, IOCG_INPUT_12MA);
28932e9fc1aSHaojian Zhuang 	mmio_write_32(IOCG_SD_DATA3, IOCG_INPUT_12MA);
29032e9fc1aSHaojian Zhuang 
29132e9fc1aSHaojian Zhuang 	/* set SD Card detect as nopull */
29232e9fc1aSHaojian Zhuang 	mmio_write_32(IOCG_GPIO8, 0);
29332e9fc1aSHaojian Zhuang }
29432e9fc1aSHaojian Zhuang 
29532e9fc1aSHaojian Zhuang static void hikey_jumper_init(void)
29632e9fc1aSHaojian Zhuang {
29732e9fc1aSHaojian Zhuang 	/* set jumper detect as nopull */
29832e9fc1aSHaojian Zhuang 	mmio_write_32(IOCG_GPIO24, 0);
29932e9fc1aSHaojian Zhuang 	/* set jumper detect as GPIO */
30032e9fc1aSHaojian Zhuang 	mmio_write_32(IOMG_GPIO24, IOMG_MUX_FUNC0);
30132e9fc1aSHaojian Zhuang }
30232e9fc1aSHaojian Zhuang 
30332e9fc1aSHaojian Zhuang void bl2_early_platform_setup(meminfo_t *mem_layout)
30432e9fc1aSHaojian Zhuang {
30532e9fc1aSHaojian Zhuang 	dw_mmc_params_t params;
30632e9fc1aSHaojian Zhuang 
30732e9fc1aSHaojian Zhuang 	/* Initialize the console to provide early debug support */
30832e9fc1aSHaojian Zhuang 	console_init(CONSOLE_BASE, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE);
30932e9fc1aSHaojian Zhuang 
31032e9fc1aSHaojian Zhuang 	/* Setup the BL2 memory layout */
31132e9fc1aSHaojian Zhuang 	bl2_tzram_layout = *mem_layout;
31232e9fc1aSHaojian Zhuang 
31332e9fc1aSHaojian Zhuang 	/* Clear SRAM since it'll be used by MCU right now. */
31432e9fc1aSHaojian Zhuang 	memset((void *)SRAM_BASE, 0, SRAM_SIZE);
31532e9fc1aSHaojian Zhuang 
31632e9fc1aSHaojian Zhuang 	sp804_timer_init(SP804_TIMER0_BASE, 10, 192);
31732e9fc1aSHaojian Zhuang 	dsb();
31832e9fc1aSHaojian Zhuang 	hikey_ddr_init();
31932e9fc1aSHaojian Zhuang 
32032e9fc1aSHaojian Zhuang 	hikey_boardid_init();
32132e9fc1aSHaojian Zhuang 	init_acpu_dvfs();
32232e9fc1aSHaojian Zhuang 	hikey_sd_init();
32332e9fc1aSHaojian Zhuang 	hikey_jumper_init();
32432e9fc1aSHaojian Zhuang 
32532e9fc1aSHaojian Zhuang 	reset_dwmmc_clk();
32632e9fc1aSHaojian Zhuang 	memset(&params, 0, sizeof(dw_mmc_params_t));
32732e9fc1aSHaojian Zhuang 	params.reg_base = DWMMC0_BASE;
32832e9fc1aSHaojian Zhuang 	params.desc_base = HIKEY_MMC_DESC_BASE;
32932e9fc1aSHaojian Zhuang 	params.desc_size = 1 << 20;
33032e9fc1aSHaojian Zhuang 	params.clk_rate = 24 * 1000 * 1000;
33132e9fc1aSHaojian Zhuang 	params.bus_width = EMMC_BUS_WIDTH_8;
33232e9fc1aSHaojian Zhuang 	params.flags = EMMC_FLAG_CMD23;
33332e9fc1aSHaojian Zhuang 	dw_mmc_init(&params);
33432e9fc1aSHaojian Zhuang 
33532e9fc1aSHaojian Zhuang 	hikey_io_setup();
33632e9fc1aSHaojian Zhuang }
33732e9fc1aSHaojian Zhuang 
33832e9fc1aSHaojian Zhuang void bl2_plat_arch_setup(void)
33932e9fc1aSHaojian Zhuang {
34032e9fc1aSHaojian Zhuang 	hikey_init_mmu_el1(bl2_tzram_layout.total_base,
34132e9fc1aSHaojian Zhuang 			   bl2_tzram_layout.total_size,
34232e9fc1aSHaojian Zhuang 			   BL2_RO_BASE,
34332e9fc1aSHaojian Zhuang 			   BL2_RO_LIMIT,
34432e9fc1aSHaojian Zhuang 			   BL2_COHERENT_RAM_BASE,
34532e9fc1aSHaojian Zhuang 			   BL2_COHERENT_RAM_LIMIT);
34632e9fc1aSHaojian Zhuang }
34732e9fc1aSHaojian Zhuang 
34832e9fc1aSHaojian Zhuang void bl2_platform_setup(void)
34932e9fc1aSHaojian Zhuang {
35032e9fc1aSHaojian Zhuang }
351