From cde9f4f41fd0fbdc740dbec91ed6848f0f6aa1b7 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Sun, 28 Jan 2018 23:00:15 +0800 Subject: [PATCH 01/11] hikey: fix memory overlapped in memory map MAP_TSP_MEM could be either in SRAM or DRAM. When MAP_TSP_MEM is in DRAM, it's overlapped with MAP_DDR. Since MAP_OPTEE_PAGEABLE isn't used in SRAM case, just remove it. Signed-off-by: Haojian Zhuang --- plat/hisilicon/hikey/aarch64/hikey_common.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/plat/hisilicon/hikey/aarch64/hikey_common.c b/plat/hisilicon/hikey/aarch64/hikey_common.c index d5b63cc6e..448857c28 100644 --- a/plat/hisilicon/hikey/aarch64/hikey_common.c +++ b/plat/hisilicon/hikey/aarch64/hikey_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,7 +17,7 @@ #include "../hikey_def.h" #define MAP_DDR MAP_REGION_FLAT(DDR_BASE, \ - DDR_SIZE, \ + DDR_SIZE - DDR_SEC_SIZE, \ MT_DEVICE | MT_RW | MT_NS) #define MAP_DEVICE MAP_REGION_FLAT(DEVICE_BASE, \ @@ -28,15 +28,6 @@ TSP_SEC_MEM_SIZE, \ MT_MEMORY | MT_RW | MT_SECURE) -#if LOAD_IMAGE_V2 -#ifdef SPD_opteed -#define MAP_OPTEE_PAGEABLE MAP_REGION_FLAT( \ - HIKEY_OPTEE_PAGEABLE_LOAD_BASE, \ - HIKEY_OPTEE_PAGEABLE_LOAD_SIZE, \ - MT_MEMORY | MT_RW | MT_SECURE) -#endif -#endif - #define MAP_ROM_PARAM MAP_REGION_FLAT(XG2RAM0_BASE, \ BL1_XG2RAM0_OFFSET, \ MT_DEVICE | MT_RO | MT_SECURE) @@ -73,11 +64,6 @@ static const mmap_region_t hikey_mmap[] = { MAP_DDR, MAP_DEVICE, MAP_TSP_MEM, -#if LOAD_IMAGE_V2 -#ifdef SPD_opteed - MAP_OPTEE_PAGEABLE, -#endif -#endif {0} }; #endif From 103c213c0d82f08cf72c3e4de435bab9683d4ed5 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Sun, 28 Jan 2018 23:33:02 +0800 Subject: [PATCH 02/11] hikey: drop LOAD_IMAGE v1 Since LOAD_IMAGE_V2 is always enabled in HiKey platform. Drop LOAD_IMAGE v1 to simplify code. Signed-off-by: Haojian Zhuang --- plat/hisilicon/hikey/hikey_bl1_setup.c | 12 -- plat/hisilicon/hikey/hikey_bl2_setup.c | 180 +------------------- plat/hisilicon/hikey/hikey_bl31_setup.c | 25 +-- plat/hisilicon/hikey/include/platform_def.h | 4 +- plat/hisilicon/hikey/platform.mk | 13 +- 5 files changed, 8 insertions(+), 226 deletions(-) diff --git a/plat/hisilicon/hikey/hikey_bl1_setup.c b/plat/hisilicon/hikey/hikey_bl1_setup.c index df0ad8e03..9e78a0da0 100644 --- a/plat/hisilicon/hikey/hikey_bl1_setup.c +++ b/plat/hisilicon/hikey/hikey_bl1_setup.c @@ -58,7 +58,6 @@ meminfo_t *bl1_plat_sec_mem_layout(void) return &bl1_tzram_layout; } -#if LOAD_IMAGE_V2 /******************************************************************************* * Function that takes a memory layout into which BL2 has been loaded and * populates a new memory layout for BL2 that ensures that BL1's data sections @@ -80,7 +79,6 @@ void bl1_init_bl2_mem_layout(const meminfo_t *bl1_mem_layout, flush_dcache_range((unsigned long)bl2_mem_layout, sizeof(meminfo_t)); } -#endif /* LOAD_IMAGE_V2 */ /* * Perform any BL1 specific platform actions. @@ -94,16 +92,6 @@ void bl1_early_platform_setup(void) bl1_tzram_layout.total_base = BL1_RW_BASE; bl1_tzram_layout.total_size = BL1_RW_SIZE; -#if !LOAD_IMAGE_V2 - /* Calculate how much RAM BL1 is using and how much remains free */ - bl1_tzram_layout.free_base = BL1_RW_BASE; - bl1_tzram_layout.free_size = BL1_RW_SIZE; - reserve_mem(&bl1_tzram_layout.free_base, - &bl1_tzram_layout.free_size, - BL1_RAM_BASE, - BL1_RAM_LIMIT - BL1_RAM_BASE); /* bl1_size */ -#endif - INFO("BL1: 0x%lx - 0x%lx [size = %lu]\n", BL1_RAM_BASE, BL1_RAM_LIMIT, BL1_RAM_LIMIT - BL1_RAM_BASE); /* bl1_size */ } diff --git a/plat/hisilicon/hikey/hikey_bl2_setup.c b/plat/hisilicon/hikey/hikey_bl2_setup.c index 3f5e48607..810f6aaa0 100644 --- a/plat/hisilicon/hikey/hikey_bl2_setup.c +++ b/plat/hisilicon/hikey/hikey_bl2_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,11 +17,9 @@ #include #include #include -#if LOAD_IMAGE_V2 #ifdef SPD_opteed #include #endif -#endif #include #include #include @@ -50,48 +48,11 @@ static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); -#if !LOAD_IMAGE_V2 - -/******************************************************************************* - * This structure represents the superset of information that is passed to - * BL31, e.g. while passing control to it from BL2, bl31_params - * and other platform specific params - ******************************************************************************/ -typedef struct bl2_to_bl31_params_mem { - bl31_params_t bl31_params; - image_info_t bl31_image_info; - image_info_t bl32_image_info; - image_info_t bl33_image_info; - entry_point_info_t bl33_ep_info; - entry_point_info_t bl32_ep_info; - entry_point_info_t bl31_ep_info; -} bl2_to_bl31_params_mem_t; - -static bl2_to_bl31_params_mem_t bl31_params_mem; - -meminfo_t *bl2_plat_sec_mem_layout(void) -{ - return &bl2_tzram_layout; -} - -void bl2_plat_get_scp_bl2_meminfo(meminfo_t *scp_bl2_meminfo) -{ - scp_bl2_meminfo->total_base = SCP_BL2_BASE; - scp_bl2_meminfo->total_size = SCP_BL2_SIZE; - scp_bl2_meminfo->free_base = SCP_BL2_BASE; - scp_bl2_meminfo->free_size = SCP_BL2_SIZE; -} -#endif /* LOAD_IMAGE_V2 */ - /******************************************************************************* * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol. * Return 0 on success, -1 otherwise. ******************************************************************************/ -#if LOAD_IMAGE_V2 int plat_hikey_bl2_handle_scp_bl2(image_info_t *scp_bl2_image_info) -#else -int bl2_plat_handle_scp_bl2(struct image_info *scp_bl2_image_info) -#endif { /* Enable MCU SRAM */ hisi_mcu_enable_sram(); @@ -161,7 +122,6 @@ uint32_t hikey_get_spsr_for_bl33_entry(void) } #endif /* AARCH32 */ -#if LOAD_IMAGE_V2 int hikey_bl2_handle_post_image_load(unsigned int image_id) { int err = 0; @@ -222,144 +182,6 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) return hikey_bl2_handle_post_image_load(image_id); } -#else /* LOAD_IMAGE_V2 */ - -bl31_params_t *bl2_plat_get_bl31_params(void) -{ - bl31_params_t *bl2_to_bl31_params = NULL; - - /* - * Initialise the memory for all the arguments that needs to - * be passed to BL3-1 - */ - memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t)); - - /* Assign memory for TF related information */ - bl2_to_bl31_params = &bl31_params_mem.bl31_params; - SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0); - - /* Fill BL3-1 related information */ - bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info; - SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY, - VERSION_1, 0); - - /* Fill BL3-2 related information if it exists */ -#ifdef BL32_BASE - bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info; - SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP, - VERSION_1, 0); - bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info; - SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY, - VERSION_1, 0); -#endif - - /* Fill BL3-3 related information */ - bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info; - SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info, - PARAM_EP, VERSION_1, 0); - - /* BL3-3 expects to receive the primary CPU MPID (through x0) */ - bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr(); - - bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info; - SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY, - VERSION_1, 0); - - return bl2_to_bl31_params; -} - -struct entry_point_info *bl2_plat_get_bl31_ep_info(void) -{ -#if DEBUG - bl31_params_mem.bl31_ep_info.args.arg1 = HIKEY_BL31_PLAT_PARAM_VAL; -#endif - - return &bl31_params_mem.bl31_ep_info; -} - -void bl2_plat_set_bl31_ep_info(image_info_t *image, - entry_point_info_t *bl31_ep_info) -{ - SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE); - bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, - DISABLE_ALL_EXCEPTIONS); -} - -/******************************************************************************* - * Before calling this function BL32 is loaded in memory and its entrypoint - * is set by load_image. This is a placeholder for the platform to change - * the entrypoint of BL32 and set SPSR and security state. - * On Hikey we only set the security state of the entrypoint - ******************************************************************************/ -#ifdef BL32_BASE -void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info, - entry_point_info_t *bl32_ep_info) -{ - SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE); - /* - * The Secure Payload Dispatcher service is responsible for - * setting the SPSR prior to entry into the BL32 image. - */ - bl32_ep_info->spsr = 0; -} - -/******************************************************************************* - * Populate the extents of memory available for loading BL32 - ******************************************************************************/ -void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo) -{ - /* - * Populate the extents of memory available for loading BL32. - */ - bl32_meminfo->total_base = BL32_BASE; - bl32_meminfo->free_base = BL32_BASE; - bl32_meminfo->total_size = - (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE; - bl32_meminfo->free_size = - (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE; -} -#endif /* BL32_BASE */ - -void bl2_plat_set_bl33_ep_info(image_info_t *image, - entry_point_info_t *bl33_ep_info) -{ - unsigned long el_status; - unsigned int mode; - - /* Figure out what mode we enter the non-secure world in */ - el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; - el_status &= ID_AA64PFR0_ELX_MASK; - - if (el_status) - mode = MODE_EL2; - else - mode = MODE_EL1; - - /* - * TODO: Consider the possibility of specifying the SPSR in - * the FIP ToC and allowing the platform to have a say as - * well. - */ - bl33_ep_info->spsr = SPSR_64(mode, MODE_SP_ELX, - DISABLE_ALL_EXCEPTIONS); - SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE); -} - -void bl2_plat_flush_bl31_params(void) -{ - flush_dcache_range((unsigned long)&bl31_params_mem, - sizeof(bl2_to_bl31_params_mem_t)); -} - -void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo) -{ - bl33_meminfo->total_base = DDR_BASE; - bl33_meminfo->total_size = DDR_SIZE; - bl33_meminfo->free_base = DDR_BASE; - bl33_meminfo->free_size = DDR_SIZE; -} -#endif /* LOAD_IMAGE_V2 */ - static void reset_dwmmc_clk(void) { unsigned int data; diff --git a/plat/hisilicon/hikey/hikey_bl31_setup.c b/plat/hisilicon/hikey/hikey_bl31_setup.c index 412b59355..e13ecf675 100644 --- a/plat/hisilicon/hikey/hikey_bl31_setup.c +++ b/plat/hisilicon/hikey/hikey_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -82,13 +82,8 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) return NULL; } -#if LOAD_IMAGE_V2 void bl31_early_platform_setup(void *from_bl2, void *plat_params_from_bl2) -#else -void bl31_early_platform_setup(bl31_params_t *from_bl2, - void *plat_params_from_bl2) -#endif { /* Initialize the console to provide early debug support */ console_init(CONSOLE_BASE, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE); @@ -97,7 +92,6 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2, cci_init(CCI400_BASE, cci_map, ARRAY_SIZE(cci_map)); cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1())); -#if LOAD_IMAGE_V2 /* * Check params passed from BL2 should not be NULL, */ @@ -124,23 +118,6 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2, if (bl33_ep_info.pc == 0) panic(); - -#else /* LOAD_IMAGE_V2 */ - - /* - * Check params passed from BL2 should not be NULL, - */ - assert(from_bl2 != NULL); - assert(from_bl2->h.type == PARAM_BL31); - assert(from_bl2->h.version >= VERSION_1); - - /* - * Copy BL3-2 and BL3-3 entry point information. - * They are stored in Secure RAM, in BL2's address space. - */ - bl32_ep_info = *from_bl2->bl32_ep_info; - bl33_ep_info = *from_bl2->bl33_ep_info; -#endif /* LOAD_IMAGE_V2 */ } void bl31_plat_arch_setup(void) diff --git a/plat/hisilicon/hikey/include/platform_def.h b/plat/hisilicon/hikey/include/platform_def.h index f4a3fd4e0..36418e174 100644 --- a/plat/hisilicon/hikey/include/platform_def.h +++ b/plat/hisilicon/hikey/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -113,13 +113,11 @@ #define BL32_DRAM_BASE DDR_SEC_BASE #define BL32_DRAM_LIMIT (DDR_SEC_BASE+DDR_SEC_SIZE) -#if LOAD_IMAGE_V2 #ifdef SPD_opteed /* Load pageable part of OP-TEE at end of allocated DRAM space for BL32 */ #define HIKEY_OPTEE_PAGEABLE_LOAD_BASE (BL32_DRAM_LIMIT - HIKEY_OPTEE_PAGEABLE_LOAD_SIZE) /* 0x3FC0_0000 */ #define HIKEY_OPTEE_PAGEABLE_LOAD_SIZE 0x400000 /* 4MB */ #endif -#endif #if (HIKEY_TSP_RAM_LOCATION_ID == HIKEY_DRAM_ID) #define TSP_SEC_MEM_BASE BL32_DRAM_BASE diff --git a/plat/hisilicon/hikey/platform.mk b/plat/hisilicon/hikey/platform.mk index c8a29924a..faaf88f36 100644 --- a/plat/hisilicon/hikey/platform.mk +++ b/plat/hisilicon/hikey/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -69,7 +69,8 @@ BL1_SOURCES += bl1/tbbr/tbbr_img_desc.c \ plat/hisilicon/hikey/hikey_bl1_setup.c \ plat/hisilicon/hikey/hikey_io_storage.c -BL2_SOURCES += drivers/arm/sp804/sp804_delay_timer.c \ +BL2_SOURCES += common/desc_image_load.c \ + drivers/arm/sp804/sp804_delay_timer.c \ drivers/delay_timer/delay_timer.c \ drivers/io/io_block.c \ drivers/io/io_fip.c \ @@ -77,22 +78,18 @@ BL2_SOURCES += drivers/arm/sp804/sp804_delay_timer.c \ drivers/emmc/emmc.c \ drivers/synopsys/emmc/dw_mmc.c \ plat/hisilicon/hikey/aarch64/hikey_helpers.S \ + plat/hisilicon/hikey/hikey_bl2_mem_params_desc.c \ plat/hisilicon/hikey/hikey_bl2_setup.c \ plat/hisilicon/hikey/hikey_security.c \ plat/hisilicon/hikey/hikey_ddr.c \ + plat/hisilicon/hikey/hikey_image_load.c \ plat/hisilicon/hikey/hikey_io_storage.c \ plat/hisilicon/hikey/hisi_dvfs.c \ plat/hisilicon/hikey/hisi_mcu.c -ifeq (${LOAD_IMAGE_V2},1) -BL2_SOURCES += plat/hisilicon/hikey/hikey_bl2_mem_params_desc.c \ - plat/hisilicon/hikey/hikey_image_load.c \ - common/desc_image_load.c - ifeq (${SPD},opteed) BL2_SOURCES += lib/optee/optee_utils.c endif -endif HIKEY_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v2/gicv2_main.c \ From a9b3021e145c7174f08465e88e6aba65a4099fdf Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Mon, 29 Jan 2018 11:42:42 +0800 Subject: [PATCH 03/11] hikey: clean dcache for SRAM after initialized Although SRAM is initialized, DCACHE should be cleaned too. Because MCU is a parrallel core to access SRAM. We need to make sure that initialized value is really written to SRAM before MCU using it. Signed-off-by: Haojian Zhuang --- plat/hisilicon/hikey/hikey_bl2_setup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/plat/hisilicon/hikey/hikey_bl2_setup.c b/plat/hisilicon/hikey/hikey_bl2_setup.c index 810f6aaa0..6080f84f2 100644 --- a/plat/hisilicon/hikey/hikey_bl2_setup.c +++ b/plat/hisilicon/hikey/hikey_bl2_setup.c @@ -276,6 +276,7 @@ void bl2_early_platform_setup(meminfo_t *mem_layout) /* Clear SRAM since it'll be used by MCU right now. */ memset((void *)SRAM_BASE, 0, SRAM_SIZE); + clean_dcache_range(SRAM_BASE, SRAM_SIZE); sp804_timer_init(SP804_TIMER0_BASE, 10, 192); dsb(); From a628b1ab2aa8fa7ca9ffe4e05d714c50e8d83792 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Thu, 25 Jan 2018 16:10:14 +0800 Subject: [PATCH 04/11] hikey: migrate to bl2_el3 Since non-TF ROM is used in HiKey platform (Hisilicon Hi6220 SoC), replace BL1 by BL2_EL3 in normal boot mode. When we recovery images in recovery mode, keep to use BL1. Signed-off-by: Haojian Zhuang --- docs/plat/hikey.rst | 6 +- plat/hisilicon/hikey/aarch64/hikey_common.c | 1 + plat/hisilicon/hikey/hikey_bl1_setup.c | 7 +- .../hikey/hikey_bl2_mem_params_desc.c | 4 +- plat/hisilicon/hikey/hikey_bl2_setup.c | 446 +++++++++++++++++- plat/hisilicon/hikey/hikey_io_storage.c | 11 +- plat/hisilicon/hikey/include/platform_def.h | 27 +- plat/hisilicon/hikey/platform.mk | 6 + 8 files changed, 451 insertions(+), 57 deletions(-) diff --git a/docs/plat/hikey.rst b/docs/plat/hikey.rst index 99259f3a7..33e6514f4 100644 --- a/docs/plat/hikey.rst +++ b/docs/plat/hikey.rst @@ -91,6 +91,7 @@ Build Procedure cd ${BUILD_PATH}/l-loader ln -sf ${EDK2_OUTPUT_DIR}/FV/bl1.bin + ln -sf ${EDK2_OUTPUT_DIR}/FV/bl2.bin ln -sf ${BUILD_PATH}/atf-fastboot/build/hikey/${FASTBOOT_BUILD_OPTION}/bl1.bin fastboot.bin make hikey PTABLE_LST=aosp-8g @@ -142,17 +143,18 @@ Flash images in recovery mode $sudo apt-get purge modemmanager -- Run the command to download l-loader.bin into HiKey. +- Run the command to download recovery.bin into HiKey. .. code:: shell - $sudo python hisi-idt.py -d /dev/ttyUSB1 --img1 l-loader.bin + $sudo python hisi-idt.py -d /dev/ttyUSB1 --img1 recovery.bin - Update images. All aosp or debian images could be fetched from `link `__. .. code:: shell $sudo fastboot flash ptable prm_ptable.img + $sudo fastboot flash loader l-loader.bin $sudo fastboot flash fastboot fip.bin $sudo fastboot flash boot boot.img $sudo fastboot flash cache cache.img diff --git a/plat/hisilicon/hikey/aarch64/hikey_common.c b/plat/hisilicon/hikey/aarch64/hikey_common.c index 448857c28..f95af5870 100644 --- a/plat/hisilicon/hikey/aarch64/hikey_common.c +++ b/plat/hisilicon/hikey/aarch64/hikey_common.c @@ -64,6 +64,7 @@ static const mmap_region_t hikey_mmap[] = { MAP_DDR, MAP_DEVICE, MAP_TSP_MEM, + MAP_SRAM, {0} }; #endif diff --git a/plat/hisilicon/hikey/hikey_bl1_setup.c b/plat/hisilicon/hikey/hikey_bl1_setup.c index 9e78a0da0..6fdfae558 100644 --- a/plat/hisilicon/hikey/hikey_bl1_setup.c +++ b/plat/hisilicon/hikey/hikey_bl1_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -529,9 +529,6 @@ unsigned int bl1_plat_get_next_image_id(void) boot_mode = mmio_read_32(ONCHIPROM_PARAM_BASE); switch (boot_mode) { - case BOOT_NORMAL: - ret = BL2_IMAGE_ID; - break; case BOOT_USB_DOWNLOAD: case BOOT_UART_DOWNLOAD: ret = NS_BL1U_IMAGE_ID; @@ -563,7 +560,7 @@ void bl1_plat_set_ep_info(unsigned int image_id, unsigned int data = 0; if (image_id == BL2_IMAGE_ID) - return; + panic(); inv_dcache_range(NS_BL1U_BASE, NS_BL1U_SIZE); __asm__ volatile ("mrs %0, cpacr_el1" : "=r"(data)); do { diff --git a/plat/hisilicon/hikey/hikey_bl2_mem_params_desc.c b/plat/hisilicon/hikey/hikey_bl2_mem_params_desc.c index 50ca01573..7c025c34d 100644 --- a/plat/hisilicon/hikey/hikey_bl2_mem_params_desc.c +++ b/plat/hisilicon/hikey/hikey_bl2_mem_params_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -28,7 +28,7 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE), SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, - VERSION_2, image_info_t, 0), + VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP), .image_info.image_base = SCP_BL2_BASE, .image_info.image_max_size = SCP_BL2_SIZE, diff --git a/plat/hisilicon/hikey/hikey_bl2_setup.c b/plat/hisilicon/hikey/hikey_bl2_setup.c index 6080f84f2..fc0734528 100644 --- a/plat/hisilicon/hikey/hikey_bl2_setup.c +++ b/plat/hisilicon/hikey/hikey_bl2_setup.c @@ -13,13 +13,17 @@ #include #include #include +#include #include +#include #include #include #include #ifdef SPD_opteed #include #endif +#include +#include #include #include #include @@ -36,6 +40,8 @@ #define BL2_RO_BASE (unsigned long)(&__RO_START__) #define BL2_RO_LIMIT (unsigned long)(&__RO_END__) +#define BL2_RW_BASE (BL2_RO_LIMIT) + /* * The next 2 constants identify the extents of the coherent memory region. * These addresses are used by the MMU setup code and therefore they must be @@ -46,7 +52,13 @@ #define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) #define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) -static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); +static meminfo_t bl2_el3_tzram_layout; + +enum { + BOOT_MODE_RECOVERY = 0, + BOOT_MODE_NORMAL, + BOOT_MODE_MASK = 1, +}; /******************************************************************************* * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol. @@ -264,29 +276,428 @@ static void hikey_jumper_init(void) mmio_write_32(IOMG_GPIO24, IOMG_MUX_FUNC0); } -void bl2_early_platform_setup(meminfo_t *mem_layout) +static void hikey_sp804_init(void) +{ + uint32_t data; + + /* select the clock of dual timer0 */ + data = mmio_read_32(AO_SC_TIMER_EN0); + while (data & 3) { + data &= ~3; + data |= 3 << 16; + mmio_write_32(AO_SC_TIMER_EN0, data); + data = mmio_read_32(AO_SC_TIMER_EN0); + } + /* enable the pclk of dual timer0 */ + data = mmio_read_32(AO_SC_PERIPH_CLKSTAT4); + while (!(data & PCLK_TIMER1) || !(data & PCLK_TIMER0)) { + mmio_write_32(AO_SC_PERIPH_CLKEN4, PCLK_TIMER1 | PCLK_TIMER0); + data = mmio_read_32(AO_SC_PERIPH_CLKSTAT4); + } + /* reset dual timer0 */ + data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4); + mmio_write_32(AO_SC_PERIPH_RSTEN4, PCLK_TIMER1 | PCLK_TIMER0); + do { + data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4); + } while (!(data & PCLK_TIMER1) || !(data & PCLK_TIMER0)); + /* unreset dual timer0 */ + mmio_write_32(AO_SC_PERIPH_RSTDIS4, PCLK_TIMER1 | PCLK_TIMER0); + do { + data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4); + } while ((data & PCLK_TIMER1) || (data & PCLK_TIMER0)); + + sp804_timer_init(SP804_TIMER0_BASE, 10, 192); +} + +static void hikey_gpio_init(void) +{ + pl061_gpio_init(); + pl061_gpio_register(GPIO0_BASE, 0); + pl061_gpio_register(GPIO1_BASE, 1); + pl061_gpio_register(GPIO2_BASE, 2); + pl061_gpio_register(GPIO3_BASE, 3); + pl061_gpio_register(GPIO4_BASE, 4); + pl061_gpio_register(GPIO5_BASE, 5); + pl061_gpio_register(GPIO6_BASE, 6); + pl061_gpio_register(GPIO7_BASE, 7); + pl061_gpio_register(GPIO8_BASE, 8); + pl061_gpio_register(GPIO9_BASE, 9); + pl061_gpio_register(GPIO10_BASE, 10); + pl061_gpio_register(GPIO11_BASE, 11); + pl061_gpio_register(GPIO12_BASE, 12); + pl061_gpio_register(GPIO13_BASE, 13); + pl061_gpio_register(GPIO14_BASE, 14); + pl061_gpio_register(GPIO15_BASE, 15); + pl061_gpio_register(GPIO16_BASE, 16); + pl061_gpio_register(GPIO17_BASE, 17); + pl061_gpio_register(GPIO18_BASE, 18); + pl061_gpio_register(GPIO19_BASE, 19); + + /* Power on indicator LED (USER_LED1). */ + gpio_set_direction(32, GPIO_DIR_OUT); /* LED1 */ + gpio_set_value(32, GPIO_LEVEL_HIGH); + gpio_set_direction(33, GPIO_DIR_OUT); /* LED2 */ + gpio_set_value(33, GPIO_LEVEL_LOW); + gpio_set_direction(34, GPIO_DIR_OUT); /* LED3 */ + gpio_set_direction(35, GPIO_DIR_OUT); /* LED4 */ +} + +static void hikey_pmussi_init(void) +{ + uint32_t data; + + /* Initialize PWR_HOLD GPIO */ + gpio_set_direction(0, GPIO_DIR_OUT); + gpio_set_value(0, GPIO_LEVEL_LOW); + + /* + * After reset, PMUSSI stays in reset mode. + * Now make it out of reset. + */ + mmio_write_32(AO_SC_PERIPH_RSTDIS4, + AO_SC_PERIPH_RSTDIS4_PRESET_PMUSSI_N); + do { + data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4); + } while (data & AO_SC_PERIPH_RSTDIS4_PRESET_PMUSSI_N); + + /* Set PMUSSI clock latency for read operation. */ + data = mmio_read_32(AO_SC_MCU_SUBSYS_CTRL3); + data &= ~AO_SC_MCU_SUBSYS_CTRL3_RCLK_MASK; + data |= AO_SC_MCU_SUBSYS_CTRL3_RCLK_3; + mmio_write_32(AO_SC_MCU_SUBSYS_CTRL3, data); + + /* enable PMUSSI clock */ + data = AO_SC_PERIPH_CLKEN5_PCLK_PMUSSI_CCPU | + AO_SC_PERIPH_CLKEN5_PCLK_PMUSSI_MCU; + mmio_write_32(AO_SC_PERIPH_CLKEN5, data); + data = AO_SC_PERIPH_CLKEN4_PCLK_PMUSSI; + mmio_write_32(AO_SC_PERIPH_CLKEN4, data); + + gpio_set_value(0, GPIO_LEVEL_HIGH); +} + +static void hikey_hi6553_init(void) +{ + uint8_t data; + + mmio_write_8(HI6553_PERI_EN_MARK, 0x1e); + mmio_write_8(HI6553_NP_REG_ADJ1, 0); + data = DISABLE6_XO_CLK_CONN | DISABLE6_XO_CLK_NFC | + DISABLE6_XO_CLK_RF1 | DISABLE6_XO_CLK_RF2; + mmio_write_8(HI6553_DISABLE6_XO_CLK, data); + + /* configure BUCK0 & BUCK1 */ + mmio_write_8(HI6553_BUCK01_CTRL2, 0x5e); + mmio_write_8(HI6553_BUCK0_CTRL7, 0x10); + mmio_write_8(HI6553_BUCK1_CTRL7, 0x10); + mmio_write_8(HI6553_BUCK0_CTRL5, 0x1e); + mmio_write_8(HI6553_BUCK1_CTRL5, 0x1e); + mmio_write_8(HI6553_BUCK0_CTRL1, 0xfc); + mmio_write_8(HI6553_BUCK1_CTRL1, 0xfc); + + /* configure BUCK2 */ + mmio_write_8(HI6553_BUCK2_REG1, 0x4f); + mmio_write_8(HI6553_BUCK2_REG5, 0x99); + mmio_write_8(HI6553_BUCK2_REG6, 0x45); + mdelay(1); + mmio_write_8(HI6553_VSET_BUCK2_ADJ, 0x22); + mdelay(1); + + /* configure BUCK3 */ + mmio_write_8(HI6553_BUCK3_REG3, 0x02); + mmio_write_8(HI6553_BUCK3_REG5, 0x99); + mmio_write_8(HI6553_BUCK3_REG6, 0x41); + mmio_write_8(HI6553_VSET_BUCK3_ADJ, 0x02); + mdelay(1); + + /* configure BUCK4 */ + mmio_write_8(HI6553_BUCK4_REG2, 0x9a); + mmio_write_8(HI6553_BUCK4_REG5, 0x99); + mmio_write_8(HI6553_BUCK4_REG6, 0x45); + + /* configure LDO20 */ + mmio_write_8(HI6553_LDO20_REG_ADJ, 0x50); + + mmio_write_8(HI6553_NP_REG_CHG, 0x0f); + mmio_write_8(HI6553_CLK_TOP0, 0x06); + mmio_write_8(HI6553_CLK_TOP3, 0xc0); + mmio_write_8(HI6553_CLK_TOP4, 0x00); + + /* configure LDO7 & LDO10 for SD slot */ + /* enable LDO7 */ + data = mmio_read_8(HI6553_LDO7_REG_ADJ); + data = (data & 0xf8) | 0x2; + mmio_write_8(HI6553_LDO7_REG_ADJ, data); + mdelay(5); + mmio_write_8(HI6553_ENABLE2_LDO1_8, 1 << 6); + mdelay(5); + /* enable LDO10 */ + data = mmio_read_8(HI6553_LDO10_REG_ADJ); + data = (data & 0xf8) | 0x5; + mmio_write_8(HI6553_LDO10_REG_ADJ, data); + mdelay(5); + mmio_write_8(HI6553_ENABLE3_LDO9_16, 1 << 1); + mdelay(5); + /* enable LDO15 */ + data = mmio_read_8(HI6553_LDO15_REG_ADJ); + data = (data & 0xf8) | 0x4; + mmio_write_8(HI6553_LDO15_REG_ADJ, data); + mmio_write_8(HI6553_ENABLE3_LDO9_16, 1 << 6); + mdelay(5); + /* enable LDO19 */ + data = mmio_read_8(HI6553_LDO19_REG_ADJ); + data |= 0x7; + mmio_write_8(HI6553_LDO19_REG_ADJ, data); + mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 2); + mdelay(5); + /* enable LDO21 */ + data = mmio_read_8(HI6553_LDO21_REG_ADJ); + data = (data & 0xf8) | 0x3; + mmio_write_8(HI6553_LDO21_REG_ADJ, data); + mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 4); + mdelay(5); + /* enable LDO22 */ + data = mmio_read_8(HI6553_LDO22_REG_ADJ); + data = (data & 0xf8) | 0x7; + mmio_write_8(HI6553_LDO22_REG_ADJ, data); + mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 5); + mdelay(5); + + /* select 32.764KHz */ + mmio_write_8(HI6553_CLK19M2_600_586_EN, 0x01); + + /* Disable vbus_det interrupts */ + data = mmio_read_8(HI6553_IRQ2_MASK); + data = data | 0x3; + mmio_write_8(HI6553_IRQ2_MASK, data); +} + +static void init_mmc0_pll(void) +{ + unsigned int data; + + /* select SYSPLL as the source of MMC0 */ + /* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */ + mmio_write_32(PERI_SC_CLK_SEL0, 1 << 5 | 1 << 21); + do { + data = mmio_read_32(PERI_SC_CLK_SEL0); + } while (!(data & (1 << 5))); + /* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */ + mmio_write_32(PERI_SC_CLK_SEL0, 1 << 29); + do { + data = mmio_read_32(PERI_SC_CLK_SEL0); + } while (data & (1 << 13)); + + mmio_write_32(PERI_SC_PERIPH_CLKEN0, (1 << 0)); + do { + data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); + } while (!(data & (1 << 0))); + + data = mmio_read_32(PERI_SC_PERIPH_CLKEN12); + data |= 1 << 1; + mmio_write_32(PERI_SC_PERIPH_CLKEN12, data); + + do { + mmio_write_32(PERI_SC_CLKCFG8BIT1, (1 << 7) | 0xb); + data = mmio_read_32(PERI_SC_CLKCFG8BIT1); + } while ((data & 0xb) != 0xb); +} + +static void reset_mmc0_clk(void) +{ + unsigned int data; + + /* disable mmc0 bus clock */ + mmio_write_32(PERI_SC_PERIPH_CLKDIS0, PERI_CLK0_MMC0); + do { + data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); + } while (data & PERI_CLK0_MMC0); + /* enable mmc0 bus clock */ + mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_MMC0); + do { + data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); + } while (!(data & PERI_CLK0_MMC0)); + /* reset mmc0 clock domain */ + mmio_write_32(PERI_SC_PERIPH_RSTEN0, PERI_RST0_MMC0); + + /* bypass mmc0 clock phase */ + data = mmio_read_32(PERI_SC_PERIPH_CTRL2); + data |= 3; + mmio_write_32(PERI_SC_PERIPH_CTRL2, data); + + /* disable low power */ + data = mmio_read_32(PERI_SC_PERIPH_CTRL13); + data |= 1 << 3; + mmio_write_32(PERI_SC_PERIPH_CTRL13, data); + do { + data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); + } while (!(data & PERI_RST0_MMC0)); + + /* unreset mmc0 clock domain */ + mmio_write_32(PERI_SC_PERIPH_RSTDIS0, PERI_RST0_MMC0); + do { + data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); + } while (data & PERI_RST0_MMC0); +} + +static void init_media_clk(void) +{ + unsigned int data, value; + + data = mmio_read_32(PMCTRL_MEDPLLCTRL); + data |= 1; + mmio_write_32(PMCTRL_MEDPLLCTRL, data); + + for (;;) { + data = mmio_read_32(PMCTRL_MEDPLLCTRL); + value = 1 << 28; + if ((data & value) == value) + break; + } + + data = mmio_read_32(PERI_SC_PERIPH_CLKEN12); + data = 1 << 10; + mmio_write_32(PERI_SC_PERIPH_CLKEN12, data); +} + +static void init_mmc1_pll(void) +{ + uint32_t data; + + /* select SYSPLL as the source of MMC1 */ + /* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */ + mmio_write_32(PERI_SC_CLK_SEL0, 1 << 11 | 1 << 27); + do { + data = mmio_read_32(PERI_SC_CLK_SEL0); + } while (!(data & (1 << 11))); + /* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */ + mmio_write_32(PERI_SC_CLK_SEL0, 1 << 30); + do { + data = mmio_read_32(PERI_SC_CLK_SEL0); + } while (data & (1 << 14)); + + mmio_write_32(PERI_SC_PERIPH_CLKEN0, (1 << 1)); + do { + data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); + } while (!(data & (1 << 1))); + + data = mmio_read_32(PERI_SC_PERIPH_CLKEN12); + data |= 1 << 2; + mmio_write_32(PERI_SC_PERIPH_CLKEN12, data); + + do { + /* 1.2GHz / 50 = 24MHz */ + mmio_write_32(PERI_SC_CLKCFG8BIT2, 0x31 | (1 << 7)); + data = mmio_read_32(PERI_SC_CLKCFG8BIT2); + } while ((data & 0x31) != 0x31); +} + +static void reset_mmc1_clk(void) +{ + unsigned int data; + + /* disable mmc1 bus clock */ + mmio_write_32(PERI_SC_PERIPH_CLKDIS0, PERI_CLK0_MMC1); + do { + data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); + } while (data & PERI_CLK0_MMC1); + /* enable mmc1 bus clock */ + mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_MMC1); + do { + data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); + } while (!(data & PERI_CLK0_MMC1)); + /* reset mmc1 clock domain */ + mmio_write_32(PERI_SC_PERIPH_RSTEN0, PERI_RST0_MMC1); + + /* bypass mmc1 clock phase */ + data = mmio_read_32(PERI_SC_PERIPH_CTRL2); + data |= 3 << 2; + mmio_write_32(PERI_SC_PERIPH_CTRL2, data); + + /* disable low power */ + data = mmio_read_32(PERI_SC_PERIPH_CTRL13); + data |= 1 << 4; + mmio_write_32(PERI_SC_PERIPH_CTRL13, data); + do { + data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); + } while (!(data & PERI_RST0_MMC1)); + + /* unreset mmc0 clock domain */ + mmio_write_32(PERI_SC_PERIPH_RSTDIS0, PERI_RST0_MMC1); + do { + data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); + } while (data & PERI_RST0_MMC1); +} + +/* Initialize PLL of both eMMC and SD controllers. */ +static void hikey_mmc_pll_init(void) +{ + init_mmc0_pll(); + reset_mmc0_clk(); + init_media_clk(); + + dsb(); + + init_mmc1_pll(); + reset_mmc1_clk(); +} + +static void hikey_rtc_init(void) +{ + uint32_t data; + + data = mmio_read_32(AO_SC_PERIPH_CLKEN4); + data |= AO_SC_PERIPH_RSTDIS4_RESET_RTC0_N; + mmio_write_32(AO_SC_PERIPH_CLKEN4, data); +} + +void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, + u_register_t arg3, u_register_t arg4) +{ + /* Initialize the console to provide early debug support */ + console_init(CONSOLE_BASE, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE); + /* + * Allow BL2 to see the whole Trusted RAM. + */ + bl2_el3_tzram_layout.total_base = BL2_RW_BASE; + bl2_el3_tzram_layout.total_size = BL31_LIMIT - BL2_RW_BASE; +} + +void bl2_el3_plat_arch_setup(void) +{ + hikey_init_mmu_el3(bl2_el3_tzram_layout.total_base, + bl2_el3_tzram_layout.total_size, + BL2_RO_BASE, + BL2_RO_LIMIT, + BL2_COHERENT_RAM_BASE, + BL2_COHERENT_RAM_LIMIT); +} + +void bl2_platform_setup(void) { dw_mmc_params_t params; - /* Initialize the console to provide early debug support */ - console_init(CONSOLE_BASE, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE); + hikey_sp804_init(); + hikey_gpio_init(); + hikey_pmussi_init(); + hikey_hi6553_init(); - /* Setup the BL2 memory layout */ - bl2_tzram_layout = *mem_layout; + dsb(); + hikey_ddr_init(); + hikey_security_setup(); /* Clear SRAM since it'll be used by MCU right now. */ memset((void *)SRAM_BASE, 0, SRAM_SIZE); clean_dcache_range(SRAM_BASE, SRAM_SIZE); - sp804_timer_init(SP804_TIMER0_BASE, 10, 192); - dsb(); - hikey_ddr_init(); - hikey_boardid_init(); init_acpu_dvfs(); + hikey_rtc_init(); hikey_sd_init(); hikey_jumper_init(); + hikey_mmc_pll_init(); + reset_dwmmc_clk(); memset(¶ms, 0, sizeof(dw_mmc_params_t)); params.reg_base = DWMMC0_BASE; @@ -299,18 +710,3 @@ void bl2_early_platform_setup(meminfo_t *mem_layout) hikey_io_setup(); } - -void bl2_plat_arch_setup(void) -{ - hikey_init_mmu_el1(bl2_tzram_layout.total_base, - bl2_tzram_layout.total_size, - BL2_RO_BASE, - BL2_RO_LIMIT, - BL2_COHERENT_RAM_BASE, - BL2_COHERENT_RAM_LIMIT); -} - -void bl2_platform_setup(void) -{ - hikey_security_setup(); -} diff --git a/plat/hisilicon/hikey/hikey_io_storage.c b/plat/hisilicon/hikey/hikey_io_storage.c index 57c66d501..90c2f8165 100644 --- a/plat/hisilicon/hikey/hikey_io_storage.c +++ b/plat/hisilicon/hikey/hikey_io_storage.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -65,10 +65,6 @@ static const io_block_dev_spec_t emmc_dev_spec = { .block_size = EMMC_BLOCK_SIZE, }; -static const io_uuid_spec_t bl2_uuid_spec = { - .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, -}; - static const io_uuid_spec_t bl31_uuid_spec = { .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, }; @@ -99,11 +95,6 @@ static const struct plat_io_policy policies[] = { (uintptr_t)&emmc_fip_spec, check_emmc }, - [BL2_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl2_uuid_spec, - check_fip - }, [SCP_BL2_IMAGE_ID] = { &fip_dev_handle, (uintptr_t)&scp_bl2_uuid_spec, diff --git a/plat/hisilicon/hikey/include/platform_def.h b/plat/hisilicon/hikey/include/platform_def.h index 36418e174..ae99d5849 100644 --- a/plat/hisilicon/hikey/include/platform_def.h +++ b/plat/hisilicon/hikey/include/platform_def.h @@ -80,9 +80,18 @@ /* * BL2 specific defines. + * + * Both loader and BL2 region stay in SRAM. + * Loader is used to switch Hi6220 SoC from 32-bit to 64-bit mode. + * + * ++++++++++ 0xF980_0000 + * + loader + + * ++++++++++ 0xF980_1000 + * + BL2 + + * ++++++++++ 0xF981_8000 */ -#define BL2_BASE (BL1_RW_BASE + 0x8000) /* 0xf981_8000 */ -#define BL2_LIMIT (BL2_BASE + 0x40000) +#define BL2_BASE (BL1_RO_BASE) /* 0xf980_1000 */ +#define BL2_LIMIT (0xF9818000) /* 0xf981_8000 */ /* * SCP_BL2 specific defines. @@ -97,8 +106,8 @@ /* * BL31 specific defines. */ -#define BL31_BASE BL2_LIMIT /* 0xf985_8000 */ -#define BL31_LIMIT 0xF9898000 +#define BL31_BASE (0xF9858000) /* 0xf985_8000 */ +#define BL31_LIMIT (0xF9898000) /* * BL3-2 specific defines. @@ -140,7 +149,7 @@ #endif /* SPD_none */ #endif -#define NS_BL1U_BASE (BL2_BASE) +#define NS_BL1U_BASE (0xf9818000) #define NS_BL1U_SIZE (0x00010000) #define NS_BL1U_LIMIT (NS_BL1U_BASE + NS_BL1U_SIZE) @@ -158,15 +167,7 @@ #endif #ifdef IMAGE_BL2 -#if LOAD_IMAGE_V2 -#ifdef SPD_opteed #define MAX_XLAT_TABLES 4 -#else -#define MAX_XLAT_TABLES 3 -#endif -#else -#define MAX_XLAT_TABLES 3 -#endif #endif #define MAX_MMAP_REGIONS 16 diff --git a/plat/hisilicon/hikey/platform.mk b/plat/hisilicon/hikey/platform.mk index faaf88f36..9add4b444 100644 --- a/plat/hisilicon/hikey/platform.mk +++ b/plat/hisilicon/hikey/platform.mk @@ -7,6 +7,9 @@ # Enable version2 of image loading LOAD_IMAGE_V2 := 1 +# Non-TF Boot ROM +BL2_AT_EL3 := 1 + # On Hikey, the TSP can execute from TZC secure area in DRAM (default) # or SRAM. HIKEY_TSP_RAM_LOCATION := dram @@ -70,13 +73,16 @@ BL1_SOURCES += bl1/tbbr/tbbr_img_desc.c \ plat/hisilicon/hikey/hikey_io_storage.c BL2_SOURCES += common/desc_image_load.c \ + drivers/arm/pl061/pl061_gpio.c \ drivers/arm/sp804/sp804_delay_timer.c \ drivers/delay_timer/delay_timer.c \ + drivers/gpio/gpio.c \ drivers/io/io_block.c \ drivers/io/io_fip.c \ drivers/io/io_storage.c \ drivers/emmc/emmc.c \ drivers/synopsys/emmc/dw_mmc.c \ + lib/cpus/aarch64/cortex_a53.S \ plat/hisilicon/hikey/aarch64/hikey_helpers.S \ plat/hisilicon/hikey/hikey_bl2_mem_params_desc.c \ plat/hisilicon/hikey/hikey_bl2_setup.c \ From 054c3e0fa3d411795de4b8710d5e3e51cc88347a Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Mon, 5 Mar 2018 13:03:53 +0800 Subject: [PATCH 05/11] hikey: move out duplicated code Create hikey_bl_common.c to store duplicated initialization code in BL1 and BL2. Signed-off-by: Haojian Zhuang --- plat/hisilicon/hikey/hikey_bl1_setup.c | 379 ------------------------ plat/hisilicon/hikey/hikey_bl2_setup.c | 379 ------------------------ plat/hisilicon/hikey/hikey_bl_common.c | 390 +++++++++++++++++++++++++ plat/hisilicon/hikey/hikey_private.h | 12 + plat/hisilicon/hikey/platform.mk | 2 + 5 files changed, 404 insertions(+), 758 deletions(-) create mode 100644 plat/hisilicon/hikey/hikey_bl_common.c diff --git a/plat/hisilicon/hikey/hikey_bl1_setup.c b/plat/hisilicon/hikey/hikey_bl1_setup.c index 6fdfae558..cdfbb16cf 100644 --- a/plat/hisilicon/hikey/hikey_bl1_setup.c +++ b/plat/hisilicon/hikey/hikey_bl1_setup.c @@ -12,14 +12,10 @@ #include #include #include -#include #include -#include #include -#include #include #include -#include #include #include @@ -111,381 +107,6 @@ void bl1_plat_arch_setup(void) BL1_COHERENT_RAM_LIMIT); } -static void hikey_sp804_init(void) -{ - uint32_t data; - - /* select the clock of dual timer0 */ - data = mmio_read_32(AO_SC_TIMER_EN0); - while (data & 3) { - data &= ~3; - data |= 3 << 16; - mmio_write_32(AO_SC_TIMER_EN0, data); - data = mmio_read_32(AO_SC_TIMER_EN0); - } - /* enable the pclk of dual timer0 */ - data = mmio_read_32(AO_SC_PERIPH_CLKSTAT4); - while (!(data & PCLK_TIMER1) || !(data & PCLK_TIMER0)) { - mmio_write_32(AO_SC_PERIPH_CLKEN4, PCLK_TIMER1 | PCLK_TIMER0); - data = mmio_read_32(AO_SC_PERIPH_CLKSTAT4); - } - /* reset dual timer0 */ - data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4); - mmio_write_32(AO_SC_PERIPH_RSTEN4, PCLK_TIMER1 | PCLK_TIMER0); - do { - data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4); - } while (!(data & PCLK_TIMER1) || !(data & PCLK_TIMER0)); - /* unreset dual timer0 */ - mmio_write_32(AO_SC_PERIPH_RSTDIS4, PCLK_TIMER1 | PCLK_TIMER0); - do { - data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4); - } while ((data & PCLK_TIMER1) || (data & PCLK_TIMER0)); - - sp804_timer_init(SP804_TIMER0_BASE, 10, 192); -} - -static void hikey_gpio_init(void) -{ - pl061_gpio_init(); - pl061_gpio_register(GPIO0_BASE, 0); - pl061_gpio_register(GPIO1_BASE, 1); - pl061_gpio_register(GPIO2_BASE, 2); - pl061_gpio_register(GPIO3_BASE, 3); - pl061_gpio_register(GPIO4_BASE, 4); - pl061_gpio_register(GPIO5_BASE, 5); - pl061_gpio_register(GPIO6_BASE, 6); - pl061_gpio_register(GPIO7_BASE, 7); - pl061_gpio_register(GPIO8_BASE, 8); - pl061_gpio_register(GPIO9_BASE, 9); - pl061_gpio_register(GPIO10_BASE, 10); - pl061_gpio_register(GPIO11_BASE, 11); - pl061_gpio_register(GPIO12_BASE, 12); - pl061_gpio_register(GPIO13_BASE, 13); - pl061_gpio_register(GPIO14_BASE, 14); - pl061_gpio_register(GPIO15_BASE, 15); - pl061_gpio_register(GPIO16_BASE, 16); - pl061_gpio_register(GPIO17_BASE, 17); - pl061_gpio_register(GPIO18_BASE, 18); - pl061_gpio_register(GPIO19_BASE, 19); - - /* Power on indicator LED (USER_LED1). */ - gpio_set_direction(32, GPIO_DIR_OUT); /* LED1 */ - gpio_set_value(32, GPIO_LEVEL_HIGH); - gpio_set_direction(33, GPIO_DIR_OUT); /* LED2 */ - gpio_set_value(33, GPIO_LEVEL_LOW); - gpio_set_direction(34, GPIO_DIR_OUT); /* LED3 */ - gpio_set_direction(35, GPIO_DIR_OUT); /* LED4 */ -} - -static void hikey_pmussi_init(void) -{ - uint32_t data; - - /* Initialize PWR_HOLD GPIO */ - gpio_set_direction(0, GPIO_DIR_OUT); - gpio_set_value(0, GPIO_LEVEL_LOW); - - /* - * After reset, PMUSSI stays in reset mode. - * Now make it out of reset. - */ - mmio_write_32(AO_SC_PERIPH_RSTDIS4, - AO_SC_PERIPH_RSTDIS4_PRESET_PMUSSI_N); - do { - data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4); - } while (data & AO_SC_PERIPH_RSTDIS4_PRESET_PMUSSI_N); - - /* Set PMUSSI clock latency for read operation. */ - data = mmio_read_32(AO_SC_MCU_SUBSYS_CTRL3); - data &= ~AO_SC_MCU_SUBSYS_CTRL3_RCLK_MASK; - data |= AO_SC_MCU_SUBSYS_CTRL3_RCLK_3; - mmio_write_32(AO_SC_MCU_SUBSYS_CTRL3, data); - - /* enable PMUSSI clock */ - data = AO_SC_PERIPH_CLKEN5_PCLK_PMUSSI_CCPU | - AO_SC_PERIPH_CLKEN5_PCLK_PMUSSI_MCU; - mmio_write_32(AO_SC_PERIPH_CLKEN5, data); - data = AO_SC_PERIPH_CLKEN4_PCLK_PMUSSI; - mmio_write_32(AO_SC_PERIPH_CLKEN4, data); - - gpio_set_value(0, GPIO_LEVEL_HIGH); -} - -static void hikey_hi6553_init(void) -{ - uint8_t data; - - mmio_write_8(HI6553_PERI_EN_MARK, 0x1e); - mmio_write_8(HI6553_NP_REG_ADJ1, 0); - data = DISABLE6_XO_CLK_CONN | DISABLE6_XO_CLK_NFC | - DISABLE6_XO_CLK_RF1 | DISABLE6_XO_CLK_RF2; - mmio_write_8(HI6553_DISABLE6_XO_CLK, data); - - /* configure BUCK0 & BUCK1 */ - mmio_write_8(HI6553_BUCK01_CTRL2, 0x5e); - mmio_write_8(HI6553_BUCK0_CTRL7, 0x10); - mmio_write_8(HI6553_BUCK1_CTRL7, 0x10); - mmio_write_8(HI6553_BUCK0_CTRL5, 0x1e); - mmio_write_8(HI6553_BUCK1_CTRL5, 0x1e); - mmio_write_8(HI6553_BUCK0_CTRL1, 0xfc); - mmio_write_8(HI6553_BUCK1_CTRL1, 0xfc); - - /* configure BUCK2 */ - mmio_write_8(HI6553_BUCK2_REG1, 0x4f); - mmio_write_8(HI6553_BUCK2_REG5, 0x99); - mmio_write_8(HI6553_BUCK2_REG6, 0x45); - mdelay(1); - mmio_write_8(HI6553_VSET_BUCK2_ADJ, 0x22); - mdelay(1); - - /* configure BUCK3 */ - mmio_write_8(HI6553_BUCK3_REG3, 0x02); - mmio_write_8(HI6553_BUCK3_REG5, 0x99); - mmio_write_8(HI6553_BUCK3_REG6, 0x41); - mmio_write_8(HI6553_VSET_BUCK3_ADJ, 0x02); - mdelay(1); - - /* configure BUCK4 */ - mmio_write_8(HI6553_BUCK4_REG2, 0x9a); - mmio_write_8(HI6553_BUCK4_REG5, 0x99); - mmio_write_8(HI6553_BUCK4_REG6, 0x45); - - /* configure LDO20 */ - mmio_write_8(HI6553_LDO20_REG_ADJ, 0x50); - - mmio_write_8(HI6553_NP_REG_CHG, 0x0f); - mmio_write_8(HI6553_CLK_TOP0, 0x06); - mmio_write_8(HI6553_CLK_TOP3, 0xc0); - mmio_write_8(HI6553_CLK_TOP4, 0x00); - - /* configure LDO7 & LDO10 for SD slot */ - /* enable LDO7 */ - data = mmio_read_8(HI6553_LDO7_REG_ADJ); - data = (data & 0xf8) | 0x2; - mmio_write_8(HI6553_LDO7_REG_ADJ, data); - mdelay(5); - mmio_write_8(HI6553_ENABLE2_LDO1_8, 1 << 6); - mdelay(5); - /* enable LDO10 */ - data = mmio_read_8(HI6553_LDO10_REG_ADJ); - data = (data & 0xf8) | 0x5; - mmio_write_8(HI6553_LDO10_REG_ADJ, data); - mdelay(5); - mmio_write_8(HI6553_ENABLE3_LDO9_16, 1 << 1); - mdelay(5); - /* enable LDO15 */ - data = mmio_read_8(HI6553_LDO15_REG_ADJ); - data = (data & 0xf8) | 0x4; - mmio_write_8(HI6553_LDO15_REG_ADJ, data); - mmio_write_8(HI6553_ENABLE3_LDO9_16, 1 << 6); - mdelay(5); - /* enable LDO19 */ - data = mmio_read_8(HI6553_LDO19_REG_ADJ); - data |= 0x7; - mmio_write_8(HI6553_LDO19_REG_ADJ, data); - mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 2); - mdelay(5); - /* enable LDO21 */ - data = mmio_read_8(HI6553_LDO21_REG_ADJ); - data = (data & 0xf8) | 0x3; - mmio_write_8(HI6553_LDO21_REG_ADJ, data); - mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 4); - mdelay(5); - /* enable LDO22 */ - data = mmio_read_8(HI6553_LDO22_REG_ADJ); - data = (data & 0xf8) | 0x7; - mmio_write_8(HI6553_LDO22_REG_ADJ, data); - mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 5); - mdelay(5); - - /* select 32.764KHz */ - mmio_write_8(HI6553_CLK19M2_600_586_EN, 0x01); - - /* Disable vbus_det interrupts */ - data = mmio_read_8(HI6553_IRQ2_MASK); - data = data | 0x3; - mmio_write_8(HI6553_IRQ2_MASK, data); -} - -static void init_mmc0_pll(void) -{ - unsigned int data; - - /* select SYSPLL as the source of MMC0 */ - /* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */ - mmio_write_32(PERI_SC_CLK_SEL0, 1 << 5 | 1 << 21); - do { - data = mmio_read_32(PERI_SC_CLK_SEL0); - } while (!(data & (1 << 5))); - /* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */ - mmio_write_32(PERI_SC_CLK_SEL0, 1 << 29); - do { - data = mmio_read_32(PERI_SC_CLK_SEL0); - } while (data & (1 << 13)); - - mmio_write_32(PERI_SC_PERIPH_CLKEN0, (1 << 0)); - do { - data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); - } while (!(data & (1 << 0))); - - data = mmio_read_32(PERI_SC_PERIPH_CLKEN12); - data |= 1 << 1; - mmio_write_32(PERI_SC_PERIPH_CLKEN12, data); - - do { - mmio_write_32(PERI_SC_CLKCFG8BIT1, (1 << 7) | 0xb); - data = mmio_read_32(PERI_SC_CLKCFG8BIT1); - } while ((data & 0xb) != 0xb); -} - -static void reset_mmc0_clk(void) -{ - unsigned int data; - - /* disable mmc0 bus clock */ - mmio_write_32(PERI_SC_PERIPH_CLKDIS0, PERI_CLK0_MMC0); - do { - data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); - } while (data & PERI_CLK0_MMC0); - /* enable mmc0 bus clock */ - mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_MMC0); - do { - data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); - } while (!(data & PERI_CLK0_MMC0)); - /* reset mmc0 clock domain */ - mmio_write_32(PERI_SC_PERIPH_RSTEN0, PERI_RST0_MMC0); - - /* bypass mmc0 clock phase */ - data = mmio_read_32(PERI_SC_PERIPH_CTRL2); - data |= 3; - mmio_write_32(PERI_SC_PERIPH_CTRL2, data); - - /* disable low power */ - data = mmio_read_32(PERI_SC_PERIPH_CTRL13); - data |= 1 << 3; - mmio_write_32(PERI_SC_PERIPH_CTRL13, data); - do { - data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); - } while (!(data & PERI_RST0_MMC0)); - - /* unreset mmc0 clock domain */ - mmio_write_32(PERI_SC_PERIPH_RSTDIS0, PERI_RST0_MMC0); - do { - data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); - } while (data & PERI_RST0_MMC0); -} - -static void init_media_clk(void) -{ - unsigned int data, value; - - data = mmio_read_32(PMCTRL_MEDPLLCTRL); - data |= 1; - mmio_write_32(PMCTRL_MEDPLLCTRL, data); - - for (;;) { - data = mmio_read_32(PMCTRL_MEDPLLCTRL); - value = 1 << 28; - if ((data & value) == value) - break; - } - - data = mmio_read_32(PERI_SC_PERIPH_CLKEN12); - data = 1 << 10; - mmio_write_32(PERI_SC_PERIPH_CLKEN12, data); -} - -static void init_mmc1_pll(void) -{ - uint32_t data; - - /* select SYSPLL as the source of MMC1 */ - /* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */ - mmio_write_32(PERI_SC_CLK_SEL0, 1 << 11 | 1 << 27); - do { - data = mmio_read_32(PERI_SC_CLK_SEL0); - } while (!(data & (1 << 11))); - /* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */ - mmio_write_32(PERI_SC_CLK_SEL0, 1 << 30); - do { - data = mmio_read_32(PERI_SC_CLK_SEL0); - } while (data & (1 << 14)); - - mmio_write_32(PERI_SC_PERIPH_CLKEN0, (1 << 1)); - do { - data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); - } while (!(data & (1 << 1))); - - data = mmio_read_32(PERI_SC_PERIPH_CLKEN12); - data |= 1 << 2; - mmio_write_32(PERI_SC_PERIPH_CLKEN12, data); - - do { - /* 1.2GHz / 50 = 24MHz */ - mmio_write_32(PERI_SC_CLKCFG8BIT2, 0x31 | (1 << 7)); - data = mmio_read_32(PERI_SC_CLKCFG8BIT2); - } while ((data & 0x31) != 0x31); -} - -static void reset_mmc1_clk(void) -{ - unsigned int data; - - /* disable mmc1 bus clock */ - mmio_write_32(PERI_SC_PERIPH_CLKDIS0, PERI_CLK0_MMC1); - do { - data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); - } while (data & PERI_CLK0_MMC1); - /* enable mmc1 bus clock */ - mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_MMC1); - do { - data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); - } while (!(data & PERI_CLK0_MMC1)); - /* reset mmc1 clock domain */ - mmio_write_32(PERI_SC_PERIPH_RSTEN0, PERI_RST0_MMC1); - - /* bypass mmc1 clock phase */ - data = mmio_read_32(PERI_SC_PERIPH_CTRL2); - data |= 3 << 2; - mmio_write_32(PERI_SC_PERIPH_CTRL2, data); - - /* disable low power */ - data = mmio_read_32(PERI_SC_PERIPH_CTRL13); - data |= 1 << 4; - mmio_write_32(PERI_SC_PERIPH_CTRL13, data); - do { - data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); - } while (!(data & PERI_RST0_MMC1)); - - /* unreset mmc0 clock domain */ - mmio_write_32(PERI_SC_PERIPH_RSTDIS0, PERI_RST0_MMC1); - do { - data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); - } while (data & PERI_RST0_MMC1); -} - -/* Initialize PLL of both eMMC and SD controllers. */ -static void hikey_mmc_pll_init(void) -{ - init_mmc0_pll(); - reset_mmc0_clk(); - init_media_clk(); - - dsb(); - - init_mmc1_pll(); - reset_mmc1_clk(); -} - -static void hikey_rtc_init(void) -{ - uint32_t data; - - data = mmio_read_32(AO_SC_PERIPH_CLKEN4); - data |= AO_SC_PERIPH_RSTDIS4_RESET_RTC0_N; - mmio_write_32(AO_SC_PERIPH_CLKEN4, data); -} - /* * Function which will perform any remaining platform-specific setup that can * occur after the MMU and data cache have been enabled. diff --git a/plat/hisilicon/hikey/hikey_bl2_setup.c b/plat/hisilicon/hikey/hikey_bl2_setup.c index fc0734528..20bb7527e 100644 --- a/plat/hisilicon/hikey/hikey_bl2_setup.c +++ b/plat/hisilicon/hikey/hikey_bl2_setup.c @@ -13,19 +13,15 @@ #include #include #include -#include #include -#include #include #include #include #ifdef SPD_opteed #include #endif -#include #include #include -#include #include #include "hikey_def.h" @@ -276,381 +272,6 @@ static void hikey_jumper_init(void) mmio_write_32(IOMG_GPIO24, IOMG_MUX_FUNC0); } -static void hikey_sp804_init(void) -{ - uint32_t data; - - /* select the clock of dual timer0 */ - data = mmio_read_32(AO_SC_TIMER_EN0); - while (data & 3) { - data &= ~3; - data |= 3 << 16; - mmio_write_32(AO_SC_TIMER_EN0, data); - data = mmio_read_32(AO_SC_TIMER_EN0); - } - /* enable the pclk of dual timer0 */ - data = mmio_read_32(AO_SC_PERIPH_CLKSTAT4); - while (!(data & PCLK_TIMER1) || !(data & PCLK_TIMER0)) { - mmio_write_32(AO_SC_PERIPH_CLKEN4, PCLK_TIMER1 | PCLK_TIMER0); - data = mmio_read_32(AO_SC_PERIPH_CLKSTAT4); - } - /* reset dual timer0 */ - data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4); - mmio_write_32(AO_SC_PERIPH_RSTEN4, PCLK_TIMER1 | PCLK_TIMER0); - do { - data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4); - } while (!(data & PCLK_TIMER1) || !(data & PCLK_TIMER0)); - /* unreset dual timer0 */ - mmio_write_32(AO_SC_PERIPH_RSTDIS4, PCLK_TIMER1 | PCLK_TIMER0); - do { - data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4); - } while ((data & PCLK_TIMER1) || (data & PCLK_TIMER0)); - - sp804_timer_init(SP804_TIMER0_BASE, 10, 192); -} - -static void hikey_gpio_init(void) -{ - pl061_gpio_init(); - pl061_gpio_register(GPIO0_BASE, 0); - pl061_gpio_register(GPIO1_BASE, 1); - pl061_gpio_register(GPIO2_BASE, 2); - pl061_gpio_register(GPIO3_BASE, 3); - pl061_gpio_register(GPIO4_BASE, 4); - pl061_gpio_register(GPIO5_BASE, 5); - pl061_gpio_register(GPIO6_BASE, 6); - pl061_gpio_register(GPIO7_BASE, 7); - pl061_gpio_register(GPIO8_BASE, 8); - pl061_gpio_register(GPIO9_BASE, 9); - pl061_gpio_register(GPIO10_BASE, 10); - pl061_gpio_register(GPIO11_BASE, 11); - pl061_gpio_register(GPIO12_BASE, 12); - pl061_gpio_register(GPIO13_BASE, 13); - pl061_gpio_register(GPIO14_BASE, 14); - pl061_gpio_register(GPIO15_BASE, 15); - pl061_gpio_register(GPIO16_BASE, 16); - pl061_gpio_register(GPIO17_BASE, 17); - pl061_gpio_register(GPIO18_BASE, 18); - pl061_gpio_register(GPIO19_BASE, 19); - - /* Power on indicator LED (USER_LED1). */ - gpio_set_direction(32, GPIO_DIR_OUT); /* LED1 */ - gpio_set_value(32, GPIO_LEVEL_HIGH); - gpio_set_direction(33, GPIO_DIR_OUT); /* LED2 */ - gpio_set_value(33, GPIO_LEVEL_LOW); - gpio_set_direction(34, GPIO_DIR_OUT); /* LED3 */ - gpio_set_direction(35, GPIO_DIR_OUT); /* LED4 */ -} - -static void hikey_pmussi_init(void) -{ - uint32_t data; - - /* Initialize PWR_HOLD GPIO */ - gpio_set_direction(0, GPIO_DIR_OUT); - gpio_set_value(0, GPIO_LEVEL_LOW); - - /* - * After reset, PMUSSI stays in reset mode. - * Now make it out of reset. - */ - mmio_write_32(AO_SC_PERIPH_RSTDIS4, - AO_SC_PERIPH_RSTDIS4_PRESET_PMUSSI_N); - do { - data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4); - } while (data & AO_SC_PERIPH_RSTDIS4_PRESET_PMUSSI_N); - - /* Set PMUSSI clock latency for read operation. */ - data = mmio_read_32(AO_SC_MCU_SUBSYS_CTRL3); - data &= ~AO_SC_MCU_SUBSYS_CTRL3_RCLK_MASK; - data |= AO_SC_MCU_SUBSYS_CTRL3_RCLK_3; - mmio_write_32(AO_SC_MCU_SUBSYS_CTRL3, data); - - /* enable PMUSSI clock */ - data = AO_SC_PERIPH_CLKEN5_PCLK_PMUSSI_CCPU | - AO_SC_PERIPH_CLKEN5_PCLK_PMUSSI_MCU; - mmio_write_32(AO_SC_PERIPH_CLKEN5, data); - data = AO_SC_PERIPH_CLKEN4_PCLK_PMUSSI; - mmio_write_32(AO_SC_PERIPH_CLKEN4, data); - - gpio_set_value(0, GPIO_LEVEL_HIGH); -} - -static void hikey_hi6553_init(void) -{ - uint8_t data; - - mmio_write_8(HI6553_PERI_EN_MARK, 0x1e); - mmio_write_8(HI6553_NP_REG_ADJ1, 0); - data = DISABLE6_XO_CLK_CONN | DISABLE6_XO_CLK_NFC | - DISABLE6_XO_CLK_RF1 | DISABLE6_XO_CLK_RF2; - mmio_write_8(HI6553_DISABLE6_XO_CLK, data); - - /* configure BUCK0 & BUCK1 */ - mmio_write_8(HI6553_BUCK01_CTRL2, 0x5e); - mmio_write_8(HI6553_BUCK0_CTRL7, 0x10); - mmio_write_8(HI6553_BUCK1_CTRL7, 0x10); - mmio_write_8(HI6553_BUCK0_CTRL5, 0x1e); - mmio_write_8(HI6553_BUCK1_CTRL5, 0x1e); - mmio_write_8(HI6553_BUCK0_CTRL1, 0xfc); - mmio_write_8(HI6553_BUCK1_CTRL1, 0xfc); - - /* configure BUCK2 */ - mmio_write_8(HI6553_BUCK2_REG1, 0x4f); - mmio_write_8(HI6553_BUCK2_REG5, 0x99); - mmio_write_8(HI6553_BUCK2_REG6, 0x45); - mdelay(1); - mmio_write_8(HI6553_VSET_BUCK2_ADJ, 0x22); - mdelay(1); - - /* configure BUCK3 */ - mmio_write_8(HI6553_BUCK3_REG3, 0x02); - mmio_write_8(HI6553_BUCK3_REG5, 0x99); - mmio_write_8(HI6553_BUCK3_REG6, 0x41); - mmio_write_8(HI6553_VSET_BUCK3_ADJ, 0x02); - mdelay(1); - - /* configure BUCK4 */ - mmio_write_8(HI6553_BUCK4_REG2, 0x9a); - mmio_write_8(HI6553_BUCK4_REG5, 0x99); - mmio_write_8(HI6553_BUCK4_REG6, 0x45); - - /* configure LDO20 */ - mmio_write_8(HI6553_LDO20_REG_ADJ, 0x50); - - mmio_write_8(HI6553_NP_REG_CHG, 0x0f); - mmio_write_8(HI6553_CLK_TOP0, 0x06); - mmio_write_8(HI6553_CLK_TOP3, 0xc0); - mmio_write_8(HI6553_CLK_TOP4, 0x00); - - /* configure LDO7 & LDO10 for SD slot */ - /* enable LDO7 */ - data = mmio_read_8(HI6553_LDO7_REG_ADJ); - data = (data & 0xf8) | 0x2; - mmio_write_8(HI6553_LDO7_REG_ADJ, data); - mdelay(5); - mmio_write_8(HI6553_ENABLE2_LDO1_8, 1 << 6); - mdelay(5); - /* enable LDO10 */ - data = mmio_read_8(HI6553_LDO10_REG_ADJ); - data = (data & 0xf8) | 0x5; - mmio_write_8(HI6553_LDO10_REG_ADJ, data); - mdelay(5); - mmio_write_8(HI6553_ENABLE3_LDO9_16, 1 << 1); - mdelay(5); - /* enable LDO15 */ - data = mmio_read_8(HI6553_LDO15_REG_ADJ); - data = (data & 0xf8) | 0x4; - mmio_write_8(HI6553_LDO15_REG_ADJ, data); - mmio_write_8(HI6553_ENABLE3_LDO9_16, 1 << 6); - mdelay(5); - /* enable LDO19 */ - data = mmio_read_8(HI6553_LDO19_REG_ADJ); - data |= 0x7; - mmio_write_8(HI6553_LDO19_REG_ADJ, data); - mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 2); - mdelay(5); - /* enable LDO21 */ - data = mmio_read_8(HI6553_LDO21_REG_ADJ); - data = (data & 0xf8) | 0x3; - mmio_write_8(HI6553_LDO21_REG_ADJ, data); - mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 4); - mdelay(5); - /* enable LDO22 */ - data = mmio_read_8(HI6553_LDO22_REG_ADJ); - data = (data & 0xf8) | 0x7; - mmio_write_8(HI6553_LDO22_REG_ADJ, data); - mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 5); - mdelay(5); - - /* select 32.764KHz */ - mmio_write_8(HI6553_CLK19M2_600_586_EN, 0x01); - - /* Disable vbus_det interrupts */ - data = mmio_read_8(HI6553_IRQ2_MASK); - data = data | 0x3; - mmio_write_8(HI6553_IRQ2_MASK, data); -} - -static void init_mmc0_pll(void) -{ - unsigned int data; - - /* select SYSPLL as the source of MMC0 */ - /* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */ - mmio_write_32(PERI_SC_CLK_SEL0, 1 << 5 | 1 << 21); - do { - data = mmio_read_32(PERI_SC_CLK_SEL0); - } while (!(data & (1 << 5))); - /* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */ - mmio_write_32(PERI_SC_CLK_SEL0, 1 << 29); - do { - data = mmio_read_32(PERI_SC_CLK_SEL0); - } while (data & (1 << 13)); - - mmio_write_32(PERI_SC_PERIPH_CLKEN0, (1 << 0)); - do { - data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); - } while (!(data & (1 << 0))); - - data = mmio_read_32(PERI_SC_PERIPH_CLKEN12); - data |= 1 << 1; - mmio_write_32(PERI_SC_PERIPH_CLKEN12, data); - - do { - mmio_write_32(PERI_SC_CLKCFG8BIT1, (1 << 7) | 0xb); - data = mmio_read_32(PERI_SC_CLKCFG8BIT1); - } while ((data & 0xb) != 0xb); -} - -static void reset_mmc0_clk(void) -{ - unsigned int data; - - /* disable mmc0 bus clock */ - mmio_write_32(PERI_SC_PERIPH_CLKDIS0, PERI_CLK0_MMC0); - do { - data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); - } while (data & PERI_CLK0_MMC0); - /* enable mmc0 bus clock */ - mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_MMC0); - do { - data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); - } while (!(data & PERI_CLK0_MMC0)); - /* reset mmc0 clock domain */ - mmio_write_32(PERI_SC_PERIPH_RSTEN0, PERI_RST0_MMC0); - - /* bypass mmc0 clock phase */ - data = mmio_read_32(PERI_SC_PERIPH_CTRL2); - data |= 3; - mmio_write_32(PERI_SC_PERIPH_CTRL2, data); - - /* disable low power */ - data = mmio_read_32(PERI_SC_PERIPH_CTRL13); - data |= 1 << 3; - mmio_write_32(PERI_SC_PERIPH_CTRL13, data); - do { - data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); - } while (!(data & PERI_RST0_MMC0)); - - /* unreset mmc0 clock domain */ - mmio_write_32(PERI_SC_PERIPH_RSTDIS0, PERI_RST0_MMC0); - do { - data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); - } while (data & PERI_RST0_MMC0); -} - -static void init_media_clk(void) -{ - unsigned int data, value; - - data = mmio_read_32(PMCTRL_MEDPLLCTRL); - data |= 1; - mmio_write_32(PMCTRL_MEDPLLCTRL, data); - - for (;;) { - data = mmio_read_32(PMCTRL_MEDPLLCTRL); - value = 1 << 28; - if ((data & value) == value) - break; - } - - data = mmio_read_32(PERI_SC_PERIPH_CLKEN12); - data = 1 << 10; - mmio_write_32(PERI_SC_PERIPH_CLKEN12, data); -} - -static void init_mmc1_pll(void) -{ - uint32_t data; - - /* select SYSPLL as the source of MMC1 */ - /* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */ - mmio_write_32(PERI_SC_CLK_SEL0, 1 << 11 | 1 << 27); - do { - data = mmio_read_32(PERI_SC_CLK_SEL0); - } while (!(data & (1 << 11))); - /* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */ - mmio_write_32(PERI_SC_CLK_SEL0, 1 << 30); - do { - data = mmio_read_32(PERI_SC_CLK_SEL0); - } while (data & (1 << 14)); - - mmio_write_32(PERI_SC_PERIPH_CLKEN0, (1 << 1)); - do { - data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); - } while (!(data & (1 << 1))); - - data = mmio_read_32(PERI_SC_PERIPH_CLKEN12); - data |= 1 << 2; - mmio_write_32(PERI_SC_PERIPH_CLKEN12, data); - - do { - /* 1.2GHz / 50 = 24MHz */ - mmio_write_32(PERI_SC_CLKCFG8BIT2, 0x31 | (1 << 7)); - data = mmio_read_32(PERI_SC_CLKCFG8BIT2); - } while ((data & 0x31) != 0x31); -} - -static void reset_mmc1_clk(void) -{ - unsigned int data; - - /* disable mmc1 bus clock */ - mmio_write_32(PERI_SC_PERIPH_CLKDIS0, PERI_CLK0_MMC1); - do { - data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); - } while (data & PERI_CLK0_MMC1); - /* enable mmc1 bus clock */ - mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_MMC1); - do { - data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); - } while (!(data & PERI_CLK0_MMC1)); - /* reset mmc1 clock domain */ - mmio_write_32(PERI_SC_PERIPH_RSTEN0, PERI_RST0_MMC1); - - /* bypass mmc1 clock phase */ - data = mmio_read_32(PERI_SC_PERIPH_CTRL2); - data |= 3 << 2; - mmio_write_32(PERI_SC_PERIPH_CTRL2, data); - - /* disable low power */ - data = mmio_read_32(PERI_SC_PERIPH_CTRL13); - data |= 1 << 4; - mmio_write_32(PERI_SC_PERIPH_CTRL13, data); - do { - data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); - } while (!(data & PERI_RST0_MMC1)); - - /* unreset mmc0 clock domain */ - mmio_write_32(PERI_SC_PERIPH_RSTDIS0, PERI_RST0_MMC1); - do { - data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); - } while (data & PERI_RST0_MMC1); -} - -/* Initialize PLL of both eMMC and SD controllers. */ -static void hikey_mmc_pll_init(void) -{ - init_mmc0_pll(); - reset_mmc0_clk(); - init_media_clk(); - - dsb(); - - init_mmc1_pll(); - reset_mmc1_clk(); -} - -static void hikey_rtc_init(void) -{ - uint32_t data; - - data = mmio_read_32(AO_SC_PERIPH_CLKEN4); - data |= AO_SC_PERIPH_RSTDIS4_RESET_RTC0_N; - mmio_write_32(AO_SC_PERIPH_CLKEN4, data); -} - void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, u_register_t arg3, u_register_t arg4) { diff --git a/plat/hisilicon/hikey/hikey_bl_common.c b/plat/hisilicon/hikey/hikey_bl_common.c new file mode 100644 index 000000000..b254a900d --- /dev/null +++ b/plat/hisilicon/hikey/hikey_bl_common.c @@ -0,0 +1,390 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "hikey_private.h" + +void hikey_sp804_init(void) +{ + uint32_t data; + + /* select the clock of dual timer0 */ + data = mmio_read_32(AO_SC_TIMER_EN0); + while (data & 3) { + data &= ~3; + data |= 3 << 16; + mmio_write_32(AO_SC_TIMER_EN0, data); + data = mmio_read_32(AO_SC_TIMER_EN0); + } + /* enable the pclk of dual timer0 */ + data = mmio_read_32(AO_SC_PERIPH_CLKSTAT4); + while (!(data & PCLK_TIMER1) || !(data & PCLK_TIMER0)) { + mmio_write_32(AO_SC_PERIPH_CLKEN4, PCLK_TIMER1 | PCLK_TIMER0); + data = mmio_read_32(AO_SC_PERIPH_CLKSTAT4); + } + /* reset dual timer0 */ + data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4); + mmio_write_32(AO_SC_PERIPH_RSTEN4, PCLK_TIMER1 | PCLK_TIMER0); + do { + data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4); + } while (!(data & PCLK_TIMER1) || !(data & PCLK_TIMER0)); + /* unreset dual timer0 */ + mmio_write_32(AO_SC_PERIPH_RSTDIS4, PCLK_TIMER1 | PCLK_TIMER0); + do { + data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4); + } while ((data & PCLK_TIMER1) || (data & PCLK_TIMER0)); + + sp804_timer_init(SP804_TIMER0_BASE, 10, 192); +} + +void hikey_gpio_init(void) +{ + pl061_gpio_init(); + pl061_gpio_register(GPIO0_BASE, 0); + pl061_gpio_register(GPIO1_BASE, 1); + pl061_gpio_register(GPIO2_BASE, 2); + pl061_gpio_register(GPIO3_BASE, 3); + pl061_gpio_register(GPIO4_BASE, 4); + pl061_gpio_register(GPIO5_BASE, 5); + pl061_gpio_register(GPIO6_BASE, 6); + pl061_gpio_register(GPIO7_BASE, 7); + pl061_gpio_register(GPIO8_BASE, 8); + pl061_gpio_register(GPIO9_BASE, 9); + pl061_gpio_register(GPIO10_BASE, 10); + pl061_gpio_register(GPIO11_BASE, 11); + pl061_gpio_register(GPIO12_BASE, 12); + pl061_gpio_register(GPIO13_BASE, 13); + pl061_gpio_register(GPIO14_BASE, 14); + pl061_gpio_register(GPIO15_BASE, 15); + pl061_gpio_register(GPIO16_BASE, 16); + pl061_gpio_register(GPIO17_BASE, 17); + pl061_gpio_register(GPIO18_BASE, 18); + pl061_gpio_register(GPIO19_BASE, 19); + + /* Power on indicator LED (USER_LED1). */ + gpio_set_direction(32, GPIO_DIR_OUT); /* LED1 */ + gpio_set_value(32, GPIO_LEVEL_HIGH); + gpio_set_direction(33, GPIO_DIR_OUT); /* LED2 */ + gpio_set_value(33, GPIO_LEVEL_LOW); + gpio_set_direction(34, GPIO_DIR_OUT); /* LED3 */ + gpio_set_direction(35, GPIO_DIR_OUT); /* LED4 */ +} + +void hikey_pmussi_init(void) +{ + uint32_t data; + + /* Initialize PWR_HOLD GPIO */ + gpio_set_direction(0, GPIO_DIR_OUT); + gpio_set_value(0, GPIO_LEVEL_LOW); + + /* + * After reset, PMUSSI stays in reset mode. + * Now make it out of reset. + */ + mmio_write_32(AO_SC_PERIPH_RSTDIS4, + AO_SC_PERIPH_RSTDIS4_PRESET_PMUSSI_N); + do { + data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4); + } while (data & AO_SC_PERIPH_RSTDIS4_PRESET_PMUSSI_N); + + /* Set PMUSSI clock latency for read operation. */ + data = mmio_read_32(AO_SC_MCU_SUBSYS_CTRL3); + data &= ~AO_SC_MCU_SUBSYS_CTRL3_RCLK_MASK; + data |= AO_SC_MCU_SUBSYS_CTRL3_RCLK_3; + mmio_write_32(AO_SC_MCU_SUBSYS_CTRL3, data); + + /* enable PMUSSI clock */ + data = AO_SC_PERIPH_CLKEN5_PCLK_PMUSSI_CCPU | + AO_SC_PERIPH_CLKEN5_PCLK_PMUSSI_MCU; + mmio_write_32(AO_SC_PERIPH_CLKEN5, data); + data = AO_SC_PERIPH_CLKEN4_PCLK_PMUSSI; + mmio_write_32(AO_SC_PERIPH_CLKEN4, data); + + gpio_set_value(0, GPIO_LEVEL_HIGH); +} + +void hikey_hi6553_init(void) +{ + uint8_t data; + + mmio_write_8(HI6553_PERI_EN_MARK, 0x1e); + mmio_write_8(HI6553_NP_REG_ADJ1, 0); + data = DISABLE6_XO_CLK_CONN | DISABLE6_XO_CLK_NFC | + DISABLE6_XO_CLK_RF1 | DISABLE6_XO_CLK_RF2; + mmio_write_8(HI6553_DISABLE6_XO_CLK, data); + + /* configure BUCK0 & BUCK1 */ + mmio_write_8(HI6553_BUCK01_CTRL2, 0x5e); + mmio_write_8(HI6553_BUCK0_CTRL7, 0x10); + mmio_write_8(HI6553_BUCK1_CTRL7, 0x10); + mmio_write_8(HI6553_BUCK0_CTRL5, 0x1e); + mmio_write_8(HI6553_BUCK1_CTRL5, 0x1e); + mmio_write_8(HI6553_BUCK0_CTRL1, 0xfc); + mmio_write_8(HI6553_BUCK1_CTRL1, 0xfc); + + /* configure BUCK2 */ + mmio_write_8(HI6553_BUCK2_REG1, 0x4f); + mmio_write_8(HI6553_BUCK2_REG5, 0x99); + mmio_write_8(HI6553_BUCK2_REG6, 0x45); + mdelay(1); + mmio_write_8(HI6553_VSET_BUCK2_ADJ, 0x22); + mdelay(1); + + /* configure BUCK3 */ + mmio_write_8(HI6553_BUCK3_REG3, 0x02); + mmio_write_8(HI6553_BUCK3_REG5, 0x99); + mmio_write_8(HI6553_BUCK3_REG6, 0x41); + mmio_write_8(HI6553_VSET_BUCK3_ADJ, 0x02); + mdelay(1); + + /* configure BUCK4 */ + mmio_write_8(HI6553_BUCK4_REG2, 0x9a); + mmio_write_8(HI6553_BUCK4_REG5, 0x99); + mmio_write_8(HI6553_BUCK4_REG6, 0x45); + + /* configure LDO20 */ + mmio_write_8(HI6553_LDO20_REG_ADJ, 0x50); + + mmio_write_8(HI6553_NP_REG_CHG, 0x0f); + mmio_write_8(HI6553_CLK_TOP0, 0x06); + mmio_write_8(HI6553_CLK_TOP3, 0xc0); + mmio_write_8(HI6553_CLK_TOP4, 0x00); + + /* configure LDO7 & LDO10 for SD slot */ + /* enable LDO7 */ + data = mmio_read_8(HI6553_LDO7_REG_ADJ); + data = (data & 0xf8) | 0x2; + mmio_write_8(HI6553_LDO7_REG_ADJ, data); + mdelay(5); + mmio_write_8(HI6553_ENABLE2_LDO1_8, 1 << 6); + mdelay(5); + /* enable LDO10 */ + data = mmio_read_8(HI6553_LDO10_REG_ADJ); + data = (data & 0xf8) | 0x5; + mmio_write_8(HI6553_LDO10_REG_ADJ, data); + mdelay(5); + mmio_write_8(HI6553_ENABLE3_LDO9_16, 1 << 1); + mdelay(5); + /* enable LDO15 */ + data = mmio_read_8(HI6553_LDO15_REG_ADJ); + data = (data & 0xf8) | 0x4; + mmio_write_8(HI6553_LDO15_REG_ADJ, data); + mmio_write_8(HI6553_ENABLE3_LDO9_16, 1 << 6); + mdelay(5); + /* enable LDO19 */ + data = mmio_read_8(HI6553_LDO19_REG_ADJ); + data |= 0x7; + mmio_write_8(HI6553_LDO19_REG_ADJ, data); + mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 2); + mdelay(5); + /* enable LDO21 */ + data = mmio_read_8(HI6553_LDO21_REG_ADJ); + data = (data & 0xf8) | 0x3; + mmio_write_8(HI6553_LDO21_REG_ADJ, data); + mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 4); + mdelay(5); + /* enable LDO22 */ + data = mmio_read_8(HI6553_LDO22_REG_ADJ); + data = (data & 0xf8) | 0x7; + mmio_write_8(HI6553_LDO22_REG_ADJ, data); + mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 5); + mdelay(5); + + /* select 32.764KHz */ + mmio_write_8(HI6553_CLK19M2_600_586_EN, 0x01); + + /* Disable vbus_det interrupts */ + data = mmio_read_8(HI6553_IRQ2_MASK); + data = data | 0x3; + mmio_write_8(HI6553_IRQ2_MASK, data); +} + +void init_mmc0_pll(void) +{ + unsigned int data; + + /* select SYSPLL as the source of MMC0 */ + /* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */ + mmio_write_32(PERI_SC_CLK_SEL0, 1 << 5 | 1 << 21); + do { + data = mmio_read_32(PERI_SC_CLK_SEL0); + } while (!(data & (1 << 5))); + /* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */ + mmio_write_32(PERI_SC_CLK_SEL0, 1 << 29); + do { + data = mmio_read_32(PERI_SC_CLK_SEL0); + } while (data & (1 << 13)); + + mmio_write_32(PERI_SC_PERIPH_CLKEN0, (1 << 0)); + do { + data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); + } while (!(data & (1 << 0))); + + data = mmio_read_32(PERI_SC_PERIPH_CLKEN12); + data |= 1 << 1; + mmio_write_32(PERI_SC_PERIPH_CLKEN12, data); + + do { + mmio_write_32(PERI_SC_CLKCFG8BIT1, (1 << 7) | 0xb); + data = mmio_read_32(PERI_SC_CLKCFG8BIT1); + } while ((data & 0xb) != 0xb); +} + +void reset_mmc0_clk(void) +{ + unsigned int data; + + /* disable mmc0 bus clock */ + mmio_write_32(PERI_SC_PERIPH_CLKDIS0, PERI_CLK0_MMC0); + do { + data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); + } while (data & PERI_CLK0_MMC0); + /* enable mmc0 bus clock */ + mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_MMC0); + do { + data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); + } while (!(data & PERI_CLK0_MMC0)); + /* reset mmc0 clock domain */ + mmio_write_32(PERI_SC_PERIPH_RSTEN0, PERI_RST0_MMC0); + + /* bypass mmc0 clock phase */ + data = mmio_read_32(PERI_SC_PERIPH_CTRL2); + data |= 3; + mmio_write_32(PERI_SC_PERIPH_CTRL2, data); + + /* disable low power */ + data = mmio_read_32(PERI_SC_PERIPH_CTRL13); + data |= 1 << 3; + mmio_write_32(PERI_SC_PERIPH_CTRL13, data); + do { + data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); + } while (!(data & PERI_RST0_MMC0)); + + /* unreset mmc0 clock domain */ + mmio_write_32(PERI_SC_PERIPH_RSTDIS0, PERI_RST0_MMC0); + do { + data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); + } while (data & PERI_RST0_MMC0); +} + +void init_media_clk(void) +{ + unsigned int data, value; + + data = mmio_read_32(PMCTRL_MEDPLLCTRL); + data |= 1; + mmio_write_32(PMCTRL_MEDPLLCTRL, data); + + for (;;) { + data = mmio_read_32(PMCTRL_MEDPLLCTRL); + value = 1 << 28; + if ((data & value) == value) + break; + } + + data = mmio_read_32(PERI_SC_PERIPH_CLKEN12); + data = 1 << 10; + mmio_write_32(PERI_SC_PERIPH_CLKEN12, data); +} + +void init_mmc1_pll(void) +{ + uint32_t data; + + /* select SYSPLL as the source of MMC1 */ + /* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */ + mmio_write_32(PERI_SC_CLK_SEL0, 1 << 11 | 1 << 27); + do { + data = mmio_read_32(PERI_SC_CLK_SEL0); + } while (!(data & (1 << 11))); + /* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */ + mmio_write_32(PERI_SC_CLK_SEL0, 1 << 30); + do { + data = mmio_read_32(PERI_SC_CLK_SEL0); + } while (data & (1 << 14)); + + mmio_write_32(PERI_SC_PERIPH_CLKEN0, (1 << 1)); + do { + data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); + } while (!(data & (1 << 1))); + + data = mmio_read_32(PERI_SC_PERIPH_CLKEN12); + data |= 1 << 2; + mmio_write_32(PERI_SC_PERIPH_CLKEN12, data); + + do { + /* 1.2GHz / 50 = 24MHz */ + mmio_write_32(PERI_SC_CLKCFG8BIT2, 0x31 | (1 << 7)); + data = mmio_read_32(PERI_SC_CLKCFG8BIT2); + } while ((data & 0x31) != 0x31); +} + +void reset_mmc1_clk(void) +{ + unsigned int data; + + /* disable mmc1 bus clock */ + mmio_write_32(PERI_SC_PERIPH_CLKDIS0, PERI_CLK0_MMC1); + do { + data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); + } while (data & PERI_CLK0_MMC1); + /* enable mmc1 bus clock */ + mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_MMC1); + do { + data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); + } while (!(data & PERI_CLK0_MMC1)); + /* reset mmc1 clock domain */ + mmio_write_32(PERI_SC_PERIPH_RSTEN0, PERI_RST0_MMC1); + + /* bypass mmc1 clock phase */ + data = mmio_read_32(PERI_SC_PERIPH_CTRL2); + data |= 3 << 2; + mmio_write_32(PERI_SC_PERIPH_CTRL2, data); + + /* disable low power */ + data = mmio_read_32(PERI_SC_PERIPH_CTRL13); + data |= 1 << 4; + mmio_write_32(PERI_SC_PERIPH_CTRL13, data); + do { + data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); + } while (!(data & PERI_RST0_MMC1)); + + /* unreset mmc0 clock domain */ + mmio_write_32(PERI_SC_PERIPH_RSTDIS0, PERI_RST0_MMC1); + do { + data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); + } while (data & PERI_RST0_MMC1); +} + +/* Initialize PLL of both eMMC and SD controllers. */ +void hikey_mmc_pll_init(void) +{ + init_mmc0_pll(); + reset_mmc0_clk(); + init_media_clk(); + + dsb(); + + init_mmc1_pll(); + reset_mmc1_clk(); +} + +void hikey_rtc_init(void) +{ + uint32_t data; + + data = mmio_read_32(AO_SC_PERIPH_CLKEN4); + data |= AO_SC_PERIPH_RSTDIS4_RESET_RTC0_N; + mmio_write_32(AO_SC_PERIPH_CLKEN4, data); +} diff --git a/plat/hisilicon/hikey/hikey_private.h b/plat/hisilicon/hikey/hikey_private.h index da9873495..7654921d6 100644 --- a/plat/hisilicon/hikey/hikey_private.h +++ b/plat/hisilicon/hikey/hikey_private.h @@ -37,6 +37,18 @@ void hikey_init_mmu_el3(unsigned long total_base, void hikey_ddr_init(void); void hikey_io_setup(void); +void hikey_sp804_init(void); +void hikey_gpio_init(void); +void hikey_pmussi_init(void); +void hikey_hi6553_init(void); +void init_mmc0_pll(void); +void reset_mmc0_clk(void); +void init_media_clk(void); +void init_mmc1_pll(void); +void reset_mmc1_clk(void); +void hikey_mmc_pll_init(void); +void hikey_rtc_init(void); + int hikey_get_partition_size(const char *arg, int left, char *response); int hikey_get_partition_type(const char *arg, int left, char *response); diff --git a/plat/hisilicon/hikey/platform.mk b/plat/hisilicon/hikey/platform.mk index 9add4b444..81bf1f524 100644 --- a/plat/hisilicon/hikey/platform.mk +++ b/plat/hisilicon/hikey/platform.mk @@ -70,6 +70,7 @@ BL1_SOURCES += bl1/tbbr/tbbr_img_desc.c \ lib/cpus/aarch64/cortex_a53.S \ plat/hisilicon/hikey/aarch64/hikey_helpers.S \ plat/hisilicon/hikey/hikey_bl1_setup.c \ + plat/hisilicon/hikey/hikey_bl_common.c \ plat/hisilicon/hikey/hikey_io_storage.c BL2_SOURCES += common/desc_image_load.c \ @@ -86,6 +87,7 @@ BL2_SOURCES += common/desc_image_load.c \ plat/hisilicon/hikey/aarch64/hikey_helpers.S \ plat/hisilicon/hikey/hikey_bl2_mem_params_desc.c \ plat/hisilicon/hikey/hikey_bl2_setup.c \ + plat/hisilicon/hikey/hikey_bl_common.c \ plat/hisilicon/hikey/hikey_security.c \ plat/hisilicon/hikey/hikey_ddr.c \ plat/hisilicon/hikey/hikey_image_load.c \ From 17cf8ab1d0ddd6bb28cae09a37a17c82b8561a97 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Sat, 27 Jan 2018 19:29:36 +0800 Subject: [PATCH 06/11] hikey960: avoid to dump message when fetch boardid The main difference between HiKey960 v1 hardware and HiKey960 v2 hardware is on UART console. But the function of detecting boardid dumps message before console ready. So fix it by removing those messages. Signed-off-by: Haojian Zhuang --- plat/hisilicon/hikey960/hikey960_boardid.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/plat/hisilicon/hikey960/hikey960_boardid.c b/plat/hisilicon/hikey960/hikey960_boardid.c index 90faa9d30..f39c15385 100644 --- a/plat/hisilicon/hikey960/hikey960_boardid.c +++ b/plat/hisilicon/hikey960/hikey960_boardid.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -148,23 +148,19 @@ int hikey960_read_boardid(unsigned int *id) /* read ADC channel0 data */ get_value(ADC_ADCIN0, &adcin0); adcin0_remap = adcin_data_remap(adcin0); - INFO("[BDID]adcin0:%d adcin0_remap:%d\n", adcin0, adcin0_remap); if (adcin0_remap == BOARDID_UNKNOWN) return -EINVAL; /* read ADC channel1 data */ get_value(ADC_ADCIN1, &adcin1); adcin1_remap = adcin_data_remap(adcin1); - INFO("[BDID]adcin1:%d adcin1_remap:%d\n", adcin1, adcin1_remap); if (adcin1_remap == BOARDID_UNKNOWN) return -EINVAL; /* read ADC channel2 data */ get_value(ADC_ADCIN2, &adcin2); adcin2_remap = adcin_data_remap(adcin2); - INFO("[BDID]adcin2:%d adcin2_remap:%d\n", adcin2, adcin2_remap); if (adcin2_remap == BOARDID_UNKNOWN) return -EINVAL; *id = BOARDID3_BASE * 1000 + (adcin2_remap * 100) + (adcin1_remap * 10) + adcin0_remap; - INFO("[BDID]boardid: %d\n", *id); return 0; } From 8495c03af48ea5fd5becd4d1efbdfe15575b45b5 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Mon, 29 Jan 2018 12:36:03 +0800 Subject: [PATCH 07/11] hikey960: fix memory overlapped in memory map MAP_TSP_MEM could be either in SRAM or DRAM. When MAP_TSP_MEM is in DRAM, it's overlapped with MAP_DDR. Since TSP_MEM is always configured in DRAM case, it means MAP_OPTEE_PAGEABLE is always disabled. Just remove it. Signed-off-by: Haojian Zhuang --- .../hikey960/aarch64/hikey960_common.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/plat/hisilicon/hikey960/aarch64/hikey960_common.c b/plat/hisilicon/hikey960/aarch64/hikey960_common.c index b1020a683..67571ff8a 100644 --- a/plat/hisilicon/hikey960/aarch64/hikey960_common.c +++ b/plat/hisilicon/hikey960/aarch64/hikey960_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -18,7 +18,7 @@ #include "../hikey960_private.h" #define MAP_DDR MAP_REGION_FLAT(DDR_BASE, \ - DDR_SIZE, \ + DDR_SIZE - DDR_SEC_SIZE, \ MT_MEMORY | MT_RW | MT_NS) #define MAP_DEVICE MAP_REGION_FLAT(DEVICE_BASE, \ @@ -41,15 +41,6 @@ TSP_SEC_MEM_SIZE, \ MT_MEMORY | MT_RW | MT_SECURE) -#if LOAD_IMAGE_V2 -#ifdef SPD_opteed -#define MAP_OPTEE_PAGEABLE MAP_REGION_FLAT( \ - HIKEY960_OPTEE_PAGEABLE_LOAD_BASE, \ - HIKEY960_OPTEE_PAGEABLE_LOAD_SIZE, \ - MT_MEMORY | MT_RW | MT_SECURE) -#endif -#endif - /* * Table of regions for different BL stages to map using the MMU. * This doesn't include Trusted RAM as the 'mem_layout' argument passed to @@ -70,11 +61,6 @@ static const mmap_region_t hikey960_mmap[] = { MAP_DDR, MAP_DEVICE, MAP_TSP_MEM, -#if LOAD_IMAGE_V2 -#ifdef SPD_opteed - MAP_OPTEE_PAGEABLE, -#endif -#endif {0} }; #endif From 99ffcaf2efac457806d558c7e7bc36cc23144894 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Mon, 29 Jan 2018 12:45:28 +0800 Subject: [PATCH 08/11] hikey960: drop LOAD_IMAGE v1 Since LOAD_IMAGE_V2 is always enabled in HiKey960 platform. Drop LOAD_IMAGE v1 to simplify code. Signed-off-by: Haojian Zhuang --- plat/hisilicon/hikey960/hikey960_bl1_setup.c | 12 -- plat/hisilicon/hikey960/hikey960_bl2_setup.c | 182 ------------------ plat/hisilicon/hikey960/hikey960_bl31_setup.c | 23 --- .../hisilicon/hikey960/include/platform_def.h | 6 - plat/hisilicon/hikey960/platform.mk | 11 +- 5 files changed, 4 insertions(+), 230 deletions(-) diff --git a/plat/hisilicon/hikey960/hikey960_bl1_setup.c b/plat/hisilicon/hikey960/hikey960_bl1_setup.c index 11f143a82..4f1640da3 100644 --- a/plat/hisilicon/hikey960/hikey960_bl1_setup.c +++ b/plat/hisilicon/hikey960/hikey960_bl1_setup.c @@ -74,7 +74,6 @@ meminfo_t *bl1_plat_sec_mem_layout(void) return &bl1_tzram_layout; } -#if LOAD_IMAGE_V2 /******************************************************************************* * Function that takes a memory layout into which BL2 has been loaded and * populates a new memory layout for BL2 that ensures that BL1's data sections @@ -96,7 +95,6 @@ void bl1_init_bl2_mem_layout(const meminfo_t *bl1_mem_layout, flush_dcache_range((unsigned long)bl2_mem_layout, sizeof(meminfo_t)); } -#endif /* LOAD_IMAGE_V2 */ /* * Perform any BL1 specific platform actions. @@ -118,16 +116,6 @@ void bl1_early_platform_setup(void) bl1_tzram_layout.total_base = BL1_RW_BASE; bl1_tzram_layout.total_size = BL1_RW_SIZE; -#if !LOAD_IMAGE_V2 - /* Calculate how much RAM BL1 is using and how much remains free */ - bl1_tzram_layout.free_base = BL1_RW_BASE; - bl1_tzram_layout.free_size = BL1_RW_SIZE; - reserve_mem(&bl1_tzram_layout.free_base, - &bl1_tzram_layout.free_size, - BL1_RAM_BASE, - BL1_RAM_LIMIT - BL1_RAM_BASE); /* bl1_size */ -#endif /* LOAD_IMAGE_V2 */ - INFO("BL1: 0x%lx - 0x%lx [size = %lu]\n", BL1_RAM_BASE, BL1_RAM_LIMIT, BL1_RAM_LIMIT - BL1_RAM_BASE); /* bl1_size */ } diff --git a/plat/hisilicon/hikey960/hikey960_bl2_setup.c b/plat/hisilicon/hikey960/hikey960_bl2_setup.c index b50ed87f0..f85e866bf 100644 --- a/plat/hisilicon/hikey960/hikey960_bl2_setup.c +++ b/plat/hisilicon/hikey960/hikey960_bl2_setup.c @@ -14,11 +14,9 @@ #include #include #include -#if LOAD_IMAGE_V2 #ifdef SPD_opteed #include #endif -#endif #include #include #include @@ -47,98 +45,13 @@ static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); -#if !LOAD_IMAGE_V2 - -/******************************************************************************* - * This structure represents the superset of information that is passed to - * BL31, e.g. while passing control to it from BL2, bl31_params - * and other platform specific params - ******************************************************************************/ -typedef struct bl2_to_bl31_params_mem { - bl31_params_t bl31_params; - image_info_t bl31_image_info; - image_info_t bl32_image_info; - image_info_t bl33_image_info; - entry_point_info_t bl33_ep_info; - entry_point_info_t bl32_ep_info; - entry_point_info_t bl31_ep_info; -} bl2_to_bl31_params_mem_t; - -static bl2_to_bl31_params_mem_t bl31_params_mem; - -meminfo_t *bl2_plat_sec_mem_layout(void) -{ - return &bl2_tzram_layout; -} - -bl31_params_t *bl2_plat_get_bl31_params(void) -{ - bl31_params_t *bl2_to_bl31_params = NULL; - - /* - * Initialise the memory for all the arguments that needs to - * be passed to BL3-1 - */ - memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t)); - - /* Assign memory for TF related information */ - bl2_to_bl31_params = &bl31_params_mem.bl31_params; - SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0); - - /* Fill BL3-1 related information */ - bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info; - SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY, - VERSION_1, 0); - - /* Fill BL3-2 related information if it exists */ -#ifdef BL32_BASE - bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info; - SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP, - VERSION_1, 0); - bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info; - SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY, - VERSION_1, 0); -#endif - - /* Fill BL3-3 related information */ - bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info; - SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info, - PARAM_EP, VERSION_1, 0); - - /* BL3-3 expects to receive the primary CPU MPID (through x0) */ - bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr(); - - bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info; - SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY, - VERSION_1, 0); - - return bl2_to_bl31_params; -} - -/******************************************************************************* - * Populate the extents of memory available for loading SCP_BL2 (if used), - * i.e. anywhere in trusted RAM as long as it doesn't overwrite BL2. - ******************************************************************************/ -void bl2_plat_get_scp_bl2_meminfo(meminfo_t *scp_bl2_meminfo) -{ - hikey960_init_ufs(); - hikey960_io_setup(); - - *scp_bl2_meminfo = bl2_tzram_layout; -} -#endif /* LOAD_IMAGE_V2 */ - extern int load_lpm3(void); /******************************************************************************* * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol. * Return 0 on success, -1 otherwise. ******************************************************************************/ -#if LOAD_IMAGE_V2 int plat_hikey960_bl2_handle_scp_bl2(image_info_t *scp_bl2_image_info) -#else -int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info) -#endif { int i; int *buf; @@ -238,7 +151,6 @@ uint32_t hikey960_get_spsr_for_bl33_entry(void) } #endif /* AARCH32 */ -#if LOAD_IMAGE_V2 int hikey960_bl2_handle_post_image_load(unsigned int image_id) { int err = 0; @@ -299,100 +211,6 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) return hikey960_bl2_handle_post_image_load(image_id); } -#else /* LOAD_IMAGE_V2 */ - -struct entry_point_info *bl2_plat_get_bl31_ep_info(void) -{ -#if DEBUG - bl31_params_mem.bl31_ep_info.args.arg1 = HIKEY960_BL31_PLAT_PARAM_VAL; -#endif - - return &bl31_params_mem.bl31_ep_info; -} - -void bl2_plat_set_bl31_ep_info(image_info_t *image, - entry_point_info_t *bl31_ep_info) -{ - SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE); - bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, - DISABLE_ALL_EXCEPTIONS); -} - -/******************************************************************************* - * Before calling this function BL32 is loaded in memory and its entrypoint - * is set by load_image. This is a placeholder for the platform to change - * the entrypoint of BL32 and set SPSR and security state. - * On Hikey we only set the security state of the entrypoint - ******************************************************************************/ -#ifdef BL32_BASE -void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info, - entry_point_info_t *bl32_ep_info) -{ - SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE); - /* - * The Secure Payload Dispatcher service is responsible for - * setting the SPSR prior to entry into the BL32 image. - */ - bl32_ep_info->spsr = 0; -} - -/******************************************************************************* - * Populate the extents of memory available for loading BL32 - ******************************************************************************/ -void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo) -{ - /* - * Populate the extents of memory available for loading BL32. - */ - bl32_meminfo->total_base = BL32_BASE; - bl32_meminfo->free_base = BL32_BASE; - bl32_meminfo->total_size = - (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE; - bl32_meminfo->free_size = - (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE; -} -#endif /* BL32_BASE */ - -void bl2_plat_set_bl33_ep_info(image_info_t *image, - entry_point_info_t *bl33_ep_info) -{ - unsigned long el_status; - unsigned int mode; - - /* Figure out what mode we enter the non-secure world in */ - el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; - el_status &= ID_AA64PFR0_ELX_MASK; - - if (el_status) - mode = MODE_EL2; - else - mode = MODE_EL1; - - /* - * TODO: Consider the possibility of specifying the SPSR in - * the FIP ToC and allowing the platform to have a say as - * well. - */ - bl33_ep_info->spsr = SPSR_64(mode, MODE_SP_ELX, - DISABLE_ALL_EXCEPTIONS); - SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE); -} - -void bl2_plat_flush_bl31_params(void) -{ - flush_dcache_range((unsigned long)&bl31_params_mem, - sizeof(bl2_to_bl31_params_mem_t)); -} - -void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo) -{ - bl33_meminfo->total_base = DDR_BASE; - bl33_meminfo->total_size = DDR_SIZE; - bl33_meminfo->free_base = DDR_BASE; - bl33_meminfo->free_size = DDR_SIZE; -} -#endif /* LOAD_IMAGE_V2 */ - void bl2_early_platform_setup(meminfo_t *mem_layout) { unsigned int id, uart_base; diff --git a/plat/hisilicon/hikey960/hikey960_bl31_setup.c b/plat/hisilicon/hikey960/hikey960_bl31_setup.c index f0d15a358..f8921f270 100644 --- a/plat/hisilicon/hikey960/hikey960_bl31_setup.c +++ b/plat/hisilicon/hikey960/hikey960_bl31_setup.c @@ -78,13 +78,8 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) return NULL; } -#if LOAD_IMAGE_V2 void bl31_early_platform_setup(void *from_bl2, void *plat_params_from_bl2) -#else -void bl31_early_platform_setup(bl31_params_t *from_bl2, - void *plat_params_from_bl2) -#endif { unsigned int id, uart_base; @@ -102,7 +97,6 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2, cci_init(CCI400_REG_BASE, cci_map, ARRAY_SIZE(cci_map)); cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1())); -#if LOAD_IMAGE_V2 /* * Check params passed from BL2 should not be NULL, */ @@ -129,23 +123,6 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2, if (bl33_ep_info.pc == 0) panic(); - -#else /* LOAD_IMAGE_V2 */ - - /* - * Check params passed from BL2 should not be NULL, - */ - assert(from_bl2 != NULL); - assert(from_bl2->h.type == PARAM_BL31); - assert(from_bl2->h.version >= VERSION_1); - - /* - * Copy BL3-2 and BL3-3 entry point information. - * They are stored in Secure RAM, in BL2's address space. - */ - bl32_ep_info = *from_bl2->bl32_ep_info; - bl33_ep_info = *from_bl2->bl33_ep_info; -#endif /* LOAD_IMAGE_V2 */ } void bl31_plat_arch_setup(void) diff --git a/plat/hisilicon/hikey960/include/platform_def.h b/plat/hisilicon/hikey960/include/platform_def.h index cb7609076..f058fd06c 100644 --- a/plat/hisilicon/hikey960/include/platform_def.h +++ b/plat/hisilicon/hikey960/include/platform_def.h @@ -75,13 +75,11 @@ #define BL32_DRAM_BASE DDR_SEC_BASE #define BL32_DRAM_LIMIT (DDR_SEC_BASE+DDR_SEC_SIZE) -#if LOAD_IMAGE_V2 #ifdef SPD_opteed /* Load pageable part of OP-TEE at end of allocated DRAM space for BL32 */ #define HIKEY960_OPTEE_PAGEABLE_LOAD_BASE (BL32_DRAM_LIMIT - HIKEY960_OPTEE_PAGEABLE_LOAD_SIZE) /* 0x3FC0_0000 */ #define HIKEY960_OPTEE_PAGEABLE_LOAD_SIZE 0x400000 /* 4MB */ #endif -#endif #if (HIKEY960_TSP_RAM_LOCATION_ID == HIKEY960_DRAM_ID) #define TSP_SEC_MEM_BASE BL32_DRAM_BASE @@ -121,15 +119,11 @@ #endif #ifdef IMAGE_BL2 -#if LOAD_IMAGE_V2 #ifdef SPD_opteed #define MAX_XLAT_TABLES 4 #else #define MAX_XLAT_TABLES 3 #endif -#else -#define MAX_XLAT_TABLES 3 -#endif #endif #define MAX_MMAP_REGIONS 16 diff --git a/plat/hisilicon/hikey960/platform.mk b/plat/hisilicon/hikey960/platform.mk index cb97deb6d..d2ec07397 100644 --- a/plat/hisilicon/hikey960/platform.mk +++ b/plat/hisilicon/hikey960/platform.mk @@ -66,23 +66,20 @@ BL1_SOURCES += bl1/tbbr/tbbr_img_desc.c \ plat/hisilicon/hikey960/hikey960_io_storage.c \ ${HIKEY960_GIC_SOURCES} -BL2_SOURCES += drivers/io/io_block.c \ +BL2_SOURCES += common/desc_image_load.c \ + drivers/io/io_block.c \ drivers/io/io_fip.c \ drivers/io/io_storage.c \ drivers/ufs/ufs.c \ + plat/hisilicon/hikey960/hikey960_bl2_mem_params_desc.c \ plat/hisilicon/hikey960/hikey960_bl2_setup.c \ + plat/hisilicon/hikey960/hikey960_image_load.c \ plat/hisilicon/hikey960/hikey960_io_storage.c \ plat/hisilicon/hikey960/hikey960_mcu_load.c -ifeq (${LOAD_IMAGE_V2},1) -BL2_SOURCES += plat/hisilicon/hikey960/hikey960_bl2_mem_params_desc.c \ - plat/hisilicon/hikey960/hikey960_image_load.c \ - common/desc_image_load.c - ifeq (${SPD},opteed) BL2_SOURCES += lib/optee/optee_utils.c endif -endif BL31_SOURCES += drivers/arm/cci/cci.c \ lib/cpus/aarch64/cortex_a53.S \ From d2128731a93e0bd1c3580d045232cf9a984db606 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Thu, 25 Jan 2018 16:13:05 +0800 Subject: [PATCH 09/11] hikey960: migrate to bl2_el3 Since non-TF ROM is used in HiKey960 platform (Hisilicon Hi3660 SoC), replace BL1 by BL2_EL3 in normal boot mode. When flush images in recovery mode, keep to use BL1. Signed-off-by: Haojian Zhuang --- docs/plat/hikey960.rst | 8 +- plat/hisilicon/hikey960/hikey960_bl1_setup.c | 9 +- .../hikey960/hikey960_bl2_mem_params_desc.c | 4 +- plat/hisilicon/hikey960/hikey960_bl2_setup.c | 528 +++++++++++++++++- plat/hisilicon/hikey960/hikey960_io_storage.c | 21 +- .../hisilicon/hikey960/include/platform_def.h | 6 +- plat/hisilicon/hikey960/platform.mk | 8 +- 7 files changed, 535 insertions(+), 49 deletions(-) diff --git a/docs/plat/hikey960.rst b/docs/plat/hikey960.rst index 8524b48af..63cfc9265 100644 --- a/docs/plat/hikey960.rst +++ b/docs/plat/hikey960.rst @@ -83,6 +83,7 @@ Build Procedure cd ${BUILD_PATH}/l-loader ln -sf ${EDK2_OUTPUT_DIR}/FV/bl1.bin + ln -sf ${EDK2_OUTPUT_DIR}/FV/bl2.bin ln -sf ${EDK2_OUTPUT_DIR}/FV/fip.bin ln -sf ${EDK2_OUTPUT_DIR}/FV/BL33_AP_UEFI.fd make hikey960 @@ -130,13 +131,14 @@ Boot UEFI in recovery mode - Fetch that are used in recovery mode. The code location is in below. `link `__ -- Generate l-loader.bin. +- Prepare recovery binary. .. code:: shell $cd tools-images-hikey960 $ln -sf ${BUILD_PATH}/l-loader/l-loader.bin $ln -sf ${BUILD_PATH}/l-loader/fip.bin + $ln -sf ${BUILD_PATH}/l-loader/recovery.bin - Prepare config file. @@ -146,7 +148,7 @@ Boot UEFI in recovery mode # The content of config file ./sec_usb_xloader.img 0x00020000 ./sec_uce_boot.img 0x6A908000 - ./l-loader.bin 0x1AC00000 + ./recovery.bin 0x1AC00000 - Remove the modemmanager package. This package may causes hikey\_idt tool failure. @@ -154,7 +156,7 @@ Boot UEFI in recovery mode $sudo apt-get purge modemmanager -- Run the command to download l-loader.bin into HiKey960. +- Run the command to download recovery.bin into HiKey960. .. code:: shell diff --git a/plat/hisilicon/hikey960/hikey960_bl1_setup.c b/plat/hisilicon/hikey960/hikey960_bl1_setup.c index 4f1640da3..d45cea0fb 100644 --- a/plat/hisilicon/hikey960/hikey960_bl1_setup.c +++ b/plat/hisilicon/hikey960/hikey960_bl1_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -668,9 +668,6 @@ unsigned int bl1_plat_get_next_image_id(void) case BOOT_MODE_RECOVERY: ret = NS_BL1U_IMAGE_ID; break; - case BOOT_MODE_NORMAL: - ret = BL2_IMAGE_ID; - break; default: WARN("Invalid boot mode is found:%d\n", mode); panic(); @@ -697,8 +694,8 @@ void bl1_plat_set_ep_info(unsigned int image_id, unsigned int data = 0; uintptr_t tmp = HIKEY960_NS_TMP_OFFSET; - if (image_id == BL2_IMAGE_ID) - return; + if (image_id != NS_BL1U_IMAGE_ID) + panic(); /* Copy NS BL1U from 0x1AC1_8000 to 0x1AC9_8000 */ memcpy((void *)tmp, (void *)HIKEY960_NS_IMAGE_OFFSET, NS_BL1U_SIZE); diff --git a/plat/hisilicon/hikey960/hikey960_bl2_mem_params_desc.c b/plat/hisilicon/hikey960/hikey960_bl2_mem_params_desc.c index b59f89708..2944b1f7c 100644 --- a/plat/hisilicon/hikey960/hikey960_bl2_mem_params_desc.c +++ b/plat/hisilicon/hikey960/hikey960_bl2_mem_params_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -28,7 +28,7 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE), SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, - VERSION_2, image_info_t, 0), + VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP), .image_info.image_base = SCP_BL2_BASE, .image_info.image_max_size = SCP_BL2_SIZE, diff --git a/plat/hisilicon/hikey960/hikey960_bl2_setup.c b/plat/hisilicon/hikey960/hikey960_bl2_setup.c index f85e866bf..d443d8e83 100644 --- a/plat/hisilicon/hikey960/hikey960_bl2_setup.c +++ b/plat/hisilicon/hikey960/hikey960_bl2_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,7 +9,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -33,6 +35,8 @@ #define BL2_RO_BASE (unsigned long)(&__RO_START__) #define BL2_RO_LIMIT (unsigned long)(&__RO_END__) +#define BL2_RW_BASE (BL2_RO_LIMIT) + /* * The next 2 constants identify the extents of the coherent memory region. * These addresses are used by the MMU setup code and therefore they must be @@ -43,10 +47,15 @@ #define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) #define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) -static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); - +static meminfo_t bl2_el3_tzram_layout; extern int load_lpm3(void); +enum { + BOOT_MODE_RECOVERY = 0, + BOOT_MODE_NORMAL, + BOOT_MODE_MASK = 1, +}; + /******************************************************************************* * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol. * Return 0 on success, -1 otherwise. @@ -87,16 +96,77 @@ int plat_hikey960_bl2_handle_scp_bl2(image_info_t *scp_bl2_image_info) return 0; } +static void hikey960_ufs_reset(void) +{ + unsigned int data, mask; + + mmio_write_32(CRG_PERDIS7_REG, 1 << 14); + mmio_clrbits_32(UFS_SYS_PHY_CLK_CTRL_REG, BIT_SYSCTRL_REF_CLOCK_EN); + do { + data = mmio_read_32(UFS_SYS_PHY_CLK_CTRL_REG); + } while (data & BIT_SYSCTRL_REF_CLOCK_EN); + /* use abb clk */ + mmio_clrbits_32(UFS_SYS_UFS_SYSCTRL_REG, BIT_UFS_REFCLK_SRC_SE1); + mmio_clrbits_32(UFS_SYS_PHY_ISO_EN_REG, BIT_UFS_REFCLK_ISO_EN); + mmio_write_32(PCTRL_PERI_CTRL3_REG, (1 << 0) | (1 << 16)); + mdelay(1); + mmio_write_32(CRG_PEREN7_REG, 1 << 14); + mmio_setbits_32(UFS_SYS_PHY_CLK_CTRL_REG, BIT_SYSCTRL_REF_CLOCK_EN); + + mmio_write_32(CRG_PERRSTEN3_REG, PERI_UFS_BIT); + do { + data = mmio_read_32(CRG_PERRSTSTAT3_REG); + } while ((data & PERI_UFS_BIT) == 0); + mmio_setbits_32(UFS_SYS_PSW_POWER_CTRL_REG, BIT_UFS_PSW_MTCMOS_EN); + mdelay(1); + mmio_setbits_32(UFS_SYS_HC_LP_CTRL_REG, BIT_SYSCTRL_PWR_READY); + mmio_write_32(UFS_SYS_UFS_DEVICE_RESET_CTRL_REG, + MASK_UFS_DEVICE_RESET); + /* clear SC_DIV_UFS_PERIBUS */ + mask = SC_DIV_UFS_PERIBUS << 16; + mmio_write_32(CRG_CLKDIV17_REG, mask); + /* set SC_DIV_UFSPHY_CFG(3) */ + mask = SC_DIV_UFSPHY_CFG_MASK << 16; + data = SC_DIV_UFSPHY_CFG(3); + mmio_write_32(CRG_CLKDIV16_REG, mask | data); + data = mmio_read_32(UFS_SYS_PHY_CLK_CTRL_REG); + data &= ~MASK_SYSCTRL_CFG_CLOCK_FREQ; + data |= 0x39; + mmio_write_32(UFS_SYS_PHY_CLK_CTRL_REG, data); + mmio_clrbits_32(UFS_SYS_PHY_CLK_CTRL_REG, MASK_SYSCTRL_REF_CLOCK_SEL); + mmio_setbits_32(UFS_SYS_CLOCK_GATE_BYPASS_REG, + MASK_UFS_CLK_GATE_BYPASS); + mmio_setbits_32(UFS_SYS_UFS_SYSCTRL_REG, MASK_UFS_SYSCTRL_BYPASS); + + mmio_setbits_32(UFS_SYS_PSW_CLK_CTRL_REG, BIT_SYSCTRL_PSW_CLK_EN); + mmio_clrbits_32(UFS_SYS_PSW_POWER_CTRL_REG, BIT_UFS_PSW_ISO_CTRL); + mmio_clrbits_32(UFS_SYS_PHY_ISO_EN_REG, BIT_UFS_PHY_ISO_CTRL); + mmio_clrbits_32(UFS_SYS_HC_LP_CTRL_REG, BIT_SYSCTRL_LP_ISOL_EN); + mmio_write_32(CRG_PERRSTDIS3_REG, PERI_ARST_UFS_BIT); + mmio_setbits_32(UFS_SYS_RESET_CTRL_EN_REG, BIT_SYSCTRL_LP_RESET_N); + mdelay(1); + mmio_write_32(UFS_SYS_UFS_DEVICE_RESET_CTRL_REG, + MASK_UFS_DEVICE_RESET | BIT_UFS_DEVICE_RESET); + mdelay(20); + mmio_write_32(UFS_SYS_UFS_DEVICE_RESET_CTRL_REG, + 0x03300330); + + mmio_write_32(CRG_PERRSTDIS3_REG, PERI_UFS_BIT); + do { + data = mmio_read_32(CRG_PERRSTSTAT3_REG); + } while (data & PERI_UFS_BIT); +} + void hikey960_init_ufs(void) { - ufs_params_t ufs_params; + dw_ufs_params_t ufs_params; memset(&ufs_params, 0, sizeof(ufs_params_t)); ufs_params.reg_base = UFS_REG_BASE; ufs_params.desc_base = HIKEY960_UFS_DESC_BASE; ufs_params.desc_size = HIKEY960_UFS_DESC_SIZE; - ufs_params.flags = UFS_FLAGS_SKIPINIT; - ufs_init(NULL, &ufs_params); + hikey960_ufs_reset(); + dw_ufs_init(&ufs_params); } /******************************************************************************* @@ -202,6 +272,428 @@ int hikey960_bl2_handle_post_image_load(unsigned int image_id) return err; } +static void hikey960_clk_init(void) +{ + /* change ldi0 sel to ppll2 */ + mmio_write_32(0xfff350b4, 0xf0002000); + /* ldi0 20' */ + mmio_write_32(0xfff350bc, 0xfc004c00); +} + +static void hikey960_pmu_init(void) +{ + /* clear np_xo_abb_dig_START bit in PMIC_CLK_TOP_CTRL7 register */ + mmio_clrbits_32(PMU_SSI0_CLK_TOP_CTRL7_REG, NP_XO_ABB_DIG); +} + +static void hikey960_enable_ppll3(void) +{ + /* enable ppll3 */ + mmio_write_32(PMC_PPLL3_CTRL0_REG, 0x4904305); + mmio_write_32(PMC_PPLL3_CTRL1_REG, 0x2300000); + mmio_write_32(PMC_PPLL3_CTRL1_REG, 0x6300000); +} + +static void bus_idle_clear(unsigned int value) +{ + unsigned int pmc_value, value1, value2; + int timeout = 100; + + pmc_value = value << 16; + pmc_value &= ~value; + mmio_write_32(PMC_NOC_POWER_IDLEREQ_REG, pmc_value); + + for (;;) { + value1 = (unsigned int)mmio_read_32(PMC_NOC_POWER_IDLEACK_REG); + value2 = (unsigned int)mmio_read_32(PMC_NOC_POWER_IDLE_REG); + if (((value1 & value) == 0) && ((value2 & value) == 0)) + break; + udelay(1); + timeout--; + if (timeout <= 0) { + WARN("%s timeout\n", __func__); + break; + } + } +} + +static void set_vivobus_power_up(void) +{ + /* clk enable */ + mmio_write_32(CRG_CLKDIV20_REG, 0x00020002); + mmio_write_32(CRG_PEREN0_REG, 0x00001000); +} + +static void set_dss_power_up(void) +{ + /* set edc0 133MHz = 1600MHz / 12 */ + mmio_write_32(CRG_CLKDIV5_REG, 0x003f000b); + /* set ldi0 ppl0 */ + mmio_write_32(CRG_CLKDIV3_REG, 0xf0001000); + /* set ldi0 133MHz, 1600MHz / 12 */ + mmio_write_32(CRG_CLKDIV5_REG, 0xfc002c00); + /* mtcmos on */ + mmio_write_32(CRG_PERPWREN_REG, 0x00000020); + udelay(100); + /* DISP CRG */ + mmio_write_32(CRG_PERRSTDIS4_REG, 0x00000010); + /* clk enable */ + mmio_write_32(CRG_CLKDIV18_REG, 0x01400140); + mmio_write_32(CRG_PEREN0_REG, 0x00002000); + mmio_write_32(CRG_PEREN3_REG, 0x0003b000); + udelay(1); + /* clk disable */ + mmio_write_32(CRG_PERDIS3_REG, 0x0003b000); + mmio_write_32(CRG_PERDIS0_REG, 0x00002000); + mmio_write_32(CRG_CLKDIV18_REG, 0x01400000); + udelay(1); + /* iso disable */ + mmio_write_32(CRG_ISODIS_REG, 0x00000040); + /* unreset */ + mmio_write_32(CRG_PERRSTDIS4_REG, 0x00000006); + mmio_write_32(CRG_PERRSTDIS3_REG, 0x00000c00); + /* clk enable */ + mmio_write_32(CRG_CLKDIV18_REG, 0x01400140); + mmio_write_32(CRG_PEREN0_REG, 0x00002000); + mmio_write_32(CRG_PEREN3_REG, 0x0003b000); + /* bus idle clear */ + bus_idle_clear(PMC_NOC_POWER_IDLEREQ_DSS); + /* set edc0 400MHz for 2K 1600MHz / 4 */ + mmio_write_32(CRG_CLKDIV5_REG, 0x003f0003); + /* set ldi 266MHz, 1600MHz / 6 */ + mmio_write_32(CRG_CLKDIV5_REG, 0xfc001400); +} + +static void set_vcodec_power_up(void) +{ + /* clk enable */ + mmio_write_32(CRG_CLKDIV20_REG, 0x00040004); + mmio_write_32(CRG_PEREN0_REG, 0x00000060); + mmio_write_32(CRG_PEREN2_REG, 0x10000000); + /* unreset */ + mmio_write_32(CRG_PERRSTDIS0_REG, 0x00000018); + /* bus idle clear */ + bus_idle_clear(PMC_NOC_POWER_IDLEREQ_VCODEC); +} + +static void set_vdec_power_up(void) +{ + /* mtcmos on */ + mmio_write_32(CRG_PERPWREN_REG, 0x00000004); + udelay(100); + /* clk enable */ + mmio_write_32(CRG_CLKDIV18_REG, 0x80008000); + mmio_write_32(CRG_PEREN2_REG, 0x20080000); + mmio_write_32(CRG_PEREN3_REG, 0x00000800); + udelay(1); + /* clk disable */ + mmio_write_32(CRG_PERDIS3_REG, 0x00000800); + mmio_write_32(CRG_PERDIS2_REG, 0x20080000); + mmio_write_32(CRG_CLKDIV18_REG, 0x80000000); + udelay(1); + /* iso disable */ + mmio_write_32(CRG_ISODIS_REG, 0x00000004); + /* unreset */ + mmio_write_32(CRG_PERRSTDIS3_REG, 0x00000200); + /* clk enable */ + mmio_write_32(CRG_CLKDIV18_REG, 0x80008000); + mmio_write_32(CRG_PEREN2_REG, 0x20080000); + mmio_write_32(CRG_PEREN3_REG, 0x00000800); + /* bus idle clear */ + bus_idle_clear(PMC_NOC_POWER_IDLEREQ_VDEC); +} + +static void set_venc_power_up(void) +{ + /* set venc ppll3 */ + mmio_write_32(CRG_CLKDIV8_REG, 0x18001000); + /* set venc 258MHz, 1290MHz / 5 */ + mmio_write_32(CRG_CLKDIV8_REG, 0x07c00100); + /* mtcmos on */ + mmio_write_32(CRG_PERPWREN_REG, 0x00000002); + udelay(100); + /* clk enable */ + mmio_write_32(CRG_CLKDIV19_REG, 0x00010001); + mmio_write_32(CRG_PEREN2_REG, 0x40000100); + mmio_write_32(CRG_PEREN3_REG, 0x00000400); + udelay(1); + /* clk disable */ + mmio_write_32(CRG_PERDIS3_REG, 0x00000400); + mmio_write_32(CRG_PERDIS2_REG, 0x40000100); + mmio_write_32(CRG_CLKDIV19_REG, 0x00010000); + udelay(1); + /* iso disable */ + mmio_write_32(CRG_ISODIS_REG, 0x00000002); + /* unreset */ + mmio_write_32(CRG_PERRSTDIS3_REG, 0x00000100); + /* clk enable */ + mmio_write_32(CRG_CLKDIV19_REG, 0x00010001); + mmio_write_32(CRG_PEREN2_REG, 0x40000100); + mmio_write_32(CRG_PEREN3_REG, 0x00000400); + /* bus idle clear */ + bus_idle_clear(PMC_NOC_POWER_IDLEREQ_VENC); + /* set venc 645MHz, 1290MHz / 2 */ + mmio_write_32(CRG_CLKDIV8_REG, 0x07c00040); +} + +static void set_isp_power_up(void) +{ + /* mtcmos on */ + mmio_write_32(CRG_PERPWREN_REG, 0x00000001); + udelay(100); + /* clk enable */ + mmio_write_32(CRG_CLKDIV18_REG, 0x70007000); + mmio_write_32(CRG_CLKDIV20_REG, 0x00100010); + mmio_write_32(CRG_PEREN5_REG, 0x01000010); + mmio_write_32(CRG_PEREN3_REG, 0x0bf00000); + udelay(1); + /* clk disable */ + mmio_write_32(CRG_PERDIS5_REG, 0x01000010); + mmio_write_32(CRG_PERDIS3_REG, 0x0bf00000); + mmio_write_32(CRG_CLKDIV18_REG, 0x70000000); + mmio_write_32(CRG_CLKDIV20_REG, 0x00100000); + udelay(1); + /* iso disable */ + mmio_write_32(CRG_ISODIS_REG, 0x00000001); + /* unreset */ + mmio_write_32(CRG_ISP_SEC_RSTDIS_REG, 0x0000002f); + /* clk enable */ + mmio_write_32(CRG_CLKDIV18_REG, 0x70007000); + mmio_write_32(CRG_CLKDIV20_REG, 0x00100010); + mmio_write_32(CRG_PEREN5_REG, 0x01000010); + mmio_write_32(CRG_PEREN3_REG, 0x0bf00000); + /* bus idle clear */ + bus_idle_clear(PMC_NOC_POWER_IDLEREQ_ISP); + /* csi clk enable */ + mmio_write_32(CRG_PEREN3_REG, 0x00700000); +} + +static void set_ivp_power_up(void) +{ + /* set ivp ppll0 */ + mmio_write_32(CRG_CLKDIV0_REG, 0xc0000000); + /* set ivp 267MHz, 1600MHz / 6 */ + mmio_write_32(CRG_CLKDIV0_REG, 0x3c001400); + /* mtcmos on */ + mmio_write_32(CRG_PERPWREN_REG, 0x00200000); + udelay(100); + /* IVP CRG unreset */ + mmio_write_32(CRG_IVP_SEC_RSTDIS_REG, 0x00000001); + /* clk enable */ + mmio_write_32(CRG_CLKDIV20_REG, 0x02000200); + mmio_write_32(CRG_PEREN4_REG, 0x000000a8); + udelay(1); + /* clk disable */ + mmio_write_32(CRG_PERDIS4_REG, 0x000000a8); + mmio_write_32(CRG_CLKDIV20_REG, 0x02000000); + udelay(1); + /* iso disable */ + mmio_write_32(CRG_ISODIS_REG, 0x01000000); + /* unreset */ + mmio_write_32(CRG_IVP_SEC_RSTDIS_REG, 0x00000002); + /* clk enable */ + mmio_write_32(CRG_CLKDIV20_REG, 0x02000200); + mmio_write_32(CRG_PEREN4_REG, 0x000000a8); + /* bus idle clear */ + bus_idle_clear(PMC_NOC_POWER_IDLEREQ_IVP); + /* set ivp 533MHz, 1600MHz / 3 */ + mmio_write_32(CRG_CLKDIV0_REG, 0x3c000800); +} + +static void set_audio_power_up(void) +{ + unsigned int ret; + int timeout = 100; + /* mtcmos on */ + mmio_write_32(SCTRL_SCPWREN_REG, 0x00000001); + udelay(100); + /* clk enable */ + mmio_write_32(CRG_CLKDIV19_REG, 0x80108010); + mmio_write_32(SCTRL_SCCLKDIV2_REG, 0x00010001); + mmio_write_32(SCTRL_SCPEREN0_REG, 0x0c000000); + mmio_write_32(CRG_PEREN0_REG, 0x04000000); + mmio_write_32(CRG_PEREN5_REG, 0x00000080); + mmio_write_32(SCTRL_SCPEREN1_REG, 0x0000000f); + udelay(1); + /* clk disable */ + mmio_write_32(SCTRL_SCPERDIS1_REG, 0x0000000f); + mmio_write_32(SCTRL_SCPERDIS0_REG, 0x0c000000); + mmio_write_32(CRG_PERDIS5_REG, 0x00000080); + mmio_write_32(CRG_PERDIS0_REG, 0x04000000); + mmio_write_32(SCTRL_SCCLKDIV2_REG, 0x00010000); + mmio_write_32(CRG_CLKDIV19_REG, 0x80100000); + udelay(1); + /* iso disable */ + mmio_write_32(SCTRL_SCISODIS_REG, 0x00000001); + udelay(1); + /* unreset */ + mmio_write_32(SCTRL_PERRSTDIS1_SEC_REG, 0x00000001); + mmio_write_32(SCTRL_SCPERRSTDIS0_REG, 0x00000780); + /* clk enable */ + mmio_write_32(CRG_CLKDIV19_REG, 0x80108010); + mmio_write_32(SCTRL_SCCLKDIV2_REG, 0x00010001); + mmio_write_32(SCTRL_SCPEREN0_REG, 0x0c000000); + mmio_write_32(CRG_PEREN0_REG, 0x04000000); + mmio_write_32(CRG_PEREN5_REG, 0x00000080); + mmio_write_32(SCTRL_SCPEREN1_REG, 0x0000000f); + /* bus idle clear */ + mmio_write_32(SCTRL_SCPERCTRL7_REG, 0x00040000); + for (;;) { + ret = mmio_read_32(SCTRL_SCPERSTAT6_REG); + if (((ret & (1 << 5)) == 0) && ((ret & (1 << 8)) == 0)) + break; + udelay(1); + timeout--; + if (timeout <= 0) { + WARN("%s timeout\n", __func__); + break; + } + } + mmio_write_32(ASP_CFG_MMBUF_CTRL_REG, 0x00ff0000); +} + +static void set_pcie_power_up(void) +{ + /* mtcmos on */ + mmio_write_32(SCTRL_SCPWREN_REG, 0x00000010); + udelay(100); + /* clk enable */ + mmio_write_32(SCTRL_SCCLKDIV6_REG, 0x08000800); + mmio_write_32(SCTRL_SCPEREN2_REG, 0x00104000); + mmio_write_32(CRG_PEREN7_REG, 0x000003a0); + udelay(1); + /* clk disable */ + mmio_write_32(SCTRL_SCPERDIS2_REG, 0x00104000); + mmio_write_32(CRG_PERDIS7_REG, 0x000003a0); + mmio_write_32(SCTRL_SCCLKDIV6_REG, 0x08000000); + udelay(1); + /* iso disable */ + mmio_write_32(SCTRL_SCISODIS_REG, 0x00000030); + /* unreset */ + mmio_write_32(CRG_PERRSTDIS3_REG, 0x8c000000); + /* clk enable */ + mmio_write_32(SCTRL_SCCLKDIV6_REG, 0x08000800); + mmio_write_32(SCTRL_SCPEREN2_REG, 0x00104000); + mmio_write_32(CRG_PEREN7_REG, 0x000003a0); +} + +static void ispfunc_enable(void) +{ + /* enable ispfunc. Otherwise powerup isp_srt causes exception. */ + mmio_write_32(0xfff35000, 0x00000008); + mmio_write_32(0xfff35460, 0xc004ffff); + mmio_write_32(0xfff35030, 0x02000000); + mdelay(10); +} + +static void isps_control_clock(int flag) +{ + unsigned int ret; + + /* flag: 0 -- disable clock, 1 -- enable clock */ + if (flag) { + ret = mmio_read_32(0xe8420364); + ret |= 1; + mmio_write_32(0xe8420364, ret); + } else { + ret = mmio_read_32(0xe8420364); + ret &= ~1; + mmio_write_32(0xe8420364, ret); + } +} + +static void set_isp_srt_power_up(void) +{ + unsigned int ret; + + ispfunc_enable(); + /* reset */ + mmio_write_32(0xe8420374, 0x00000001); + mmio_write_32(0xe8420350, 0x00000000); + mmio_write_32(0xe8420358, 0x00000000); + /* mtcmos on */ + mmio_write_32(0xfff35150, 0x00400000); + udelay(100); + /* clk enable */ + isps_control_clock(1); + udelay(1); + isps_control_clock(0); + udelay(1); + /* iso disable */ + mmio_write_32(0xfff35148, 0x08000000); + /* unreset */ + ret = mmio_read_32(0xe8420374); + ret &= ~0x1; + mmio_write_32(0xe8420374, ret); + /* clk enable */ + isps_control_clock(1); + /* enable clock gating for accessing csi registers */ + mmio_write_32(0xe8420010, ~0); +} + +static void hikey960_regulator_enable(void) +{ + set_vivobus_power_up(); + hikey960_enable_ppll3(); + set_dss_power_up(); + set_vcodec_power_up(); + set_vdec_power_up(); + set_venc_power_up(); + set_isp_power_up(); + set_ivp_power_up(); + set_audio_power_up(); + set_pcie_power_up(); + set_isp_srt_power_up(); +} + +static void hikey960_tzc_init(void) +{ + mmio_write_32(TZC_EN0_REG, 0x7fbff066); + mmio_write_32(TZC_EN1_REG, 0xfffff5fc); + mmio_write_32(TZC_EN2_REG, 0x0007005c); + mmio_write_32(TZC_EN3_REG, 0x37030700); + mmio_write_32(TZC_EN4_REG, 0xf63fefae); + mmio_write_32(TZC_EN5_REG, 0x000410fd); + mmio_write_32(TZC_EN6_REG, 0x0063ff68); + mmio_write_32(TZC_EN7_REG, 0x030000f3); + mmio_write_32(TZC_EN8_REG, 0x00000007); +} + +static void hikey960_peri_init(void) +{ + /* unreset */ + mmio_setbits_32(CRG_PERRSTDIS4_REG, 1); +} + +static void hikey960_pinmux_init(void) +{ + unsigned int id; + + hikey960_read_boardid(&id); + if (id == 5301) { + /* hikey960 hardware v2 */ + /* GPIO150: LED */ + mmio_write_32(IOMG_FIX_006_REG, 0); + /* GPIO151: LED */ + mmio_write_32(IOMG_FIX_007_REG, 0); + /* GPIO189: LED */ + mmio_write_32(IOMG_AO_011_REG, 0); + /* GPIO190: LED */ + mmio_write_32(IOMG_AO_012_REG, 0); + /* GPIO46 */ + mmio_write_32(IOMG_044_REG, 0); + /* GPIO202 */ + mmio_write_32(IOMG_AO_023_REG, 0); + /* GPIO206 */ + mmio_write_32(IOMG_AO_026_REG, 0); + /* GPIO219 - PD pullup */ + mmio_write_32(IOMG_AO_039_REG, 0); + mmio_write_32(IOCG_AO_043_REG, 1 << 0); + } + /* GPIO005 - PMU SSI, 10mA */ + mmio_write_32(IOCG_006_REG, 2 << 4); +} + /******************************************************************************* * This function can be used by the platforms to update/use image * information for given `image_id`. @@ -211,7 +703,8 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) return hikey960_bl2_handle_post_image_load(image_id); } -void bl2_early_platform_setup(meminfo_t *mem_layout) +void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, + u_register_t arg3, u_register_t arg4) { unsigned int id, uart_base; @@ -221,18 +714,19 @@ void bl2_early_platform_setup(meminfo_t *mem_layout) uart_base = PL011_UART5_BASE; else uart_base = PL011_UART6_BASE; - /* Initialize the console to provide early debug support */ console_init(uart_base, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE); - - /* Setup the BL2 memory layout */ - bl2_tzram_layout = *mem_layout; + /* + * Allow BL2 to see the whole Trusted RAM. + */ + bl2_el3_tzram_layout.total_base = BL2_RW_BASE; + bl2_el3_tzram_layout.total_size = BL31_LIMIT - BL2_RW_BASE; } -void bl2_plat_arch_setup(void) +void bl2_el3_plat_arch_setup(void) { - hikey960_init_mmu_el1(bl2_tzram_layout.total_base, - bl2_tzram_layout.total_size, + hikey960_init_mmu_el3(bl2_el3_tzram_layout.total_base, + bl2_el3_tzram_layout.total_size, BL2_RO_BASE, BL2_RO_LIMIT, BL2_COHERENT_RAM_BASE, @@ -247,4 +741,10 @@ void bl2_platform_setup(void) mmio_write_32(WDT0_REG_BASE + WDT_CONTROL_OFFSET, 0); mmio_write_32(WDT0_REG_BASE + WDT_LOCK_OFFSET, 0); } + hikey960_clk_init(); + hikey960_pmu_init(); + hikey960_regulator_enable(); + hikey960_tzc_init(); + hikey960_peri_init(); + hikey960_pinmux_init(); } diff --git a/plat/hisilicon/hikey960/hikey960_io_storage.c b/plat/hisilicon/hikey960/hikey960_io_storage.c index 1a1d84604..be7c941ff 100644 --- a/plat/hisilicon/hikey960/hikey960_io_storage.c +++ b/plat/hisilicon/hikey960/hikey960_io_storage.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -39,11 +39,6 @@ static const io_block_spec_t ufs_fip_spec = { .length = HIKEY960_FIP_MAX_SIZE, }; -static const io_block_spec_t ufs_data_spec = { - .offset = 0, - .length = 256 << 20, -}; - static const io_block_dev_spec_t ufs_dev_spec = { /* It's used as temp buffer in block driver. */ .buffer = { @@ -57,10 +52,6 @@ static const io_block_dev_spec_t ufs_dev_spec = { .block_size = UFS_BLOCK_SIZE, }; -static const io_uuid_spec_t bl2_uuid_spec = { - .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, -}; - static const io_uuid_spec_t scp_bl2_uuid_spec = { .uuid = UUID_SCP_FIRMWARE_SCP_BL2, }; @@ -91,11 +82,6 @@ static const struct plat_io_policy policies[] = { (uintptr_t)&ufs_fip_spec, check_ufs }, - [BL2_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl2_uuid_spec, - check_fip - }, [SCP_BL2_IMAGE_ID] = { &fip_dev_handle, (uintptr_t)&scp_bl2_uuid_spec, @@ -125,11 +111,6 @@ static const struct plat_io_policy policies[] = { &fip_dev_handle, (uintptr_t)&bl33_uuid_spec, check_fip - }, - [BL2U_IMAGE_ID] = { - &ufs_dev_handle, - (uintptr_t)&ufs_data_spec, - check_ufs } }; diff --git a/plat/hisilicon/hikey960/include/platform_def.h b/plat/hisilicon/hikey960/include/platform_def.h index f058fd06c..a8c05cdd6 100644 --- a/plat/hisilicon/hikey960/include/platform_def.h +++ b/plat/hisilicon/hikey960/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -56,8 +56,8 @@ /* * BL2 specific defines. */ -#define BL2_BASE (BL1_RW_BASE + 0x8000) /* 1AC1_8000 */ -#define BL2_LIMIT (BL2_BASE + 0x40000) /* 1AC5_8000 */ +#define BL2_BASE (0x1AC00000) +#define BL2_LIMIT (BL2_BASE + 0x58000) /* 1AC5_8000 */ /* * BL31 specific defines. diff --git a/plat/hisilicon/hikey960/platform.mk b/plat/hisilicon/hikey960/platform.mk index d2ec07397..f20e59a00 100644 --- a/plat/hisilicon/hikey960/platform.mk +++ b/plat/hisilicon/hikey960/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -7,6 +7,9 @@ # Enable version2 of image loading LOAD_IMAGE_V2 := 1 +# Non-TF Boot ROM +BL2_AT_EL3 := 1 + # On Hikey960, the TSP can execute from TZC secure area in DRAM. HIKEY960_TSP_RAM_LOCATION := dram ifeq (${HIKEY960_TSP_RAM_LOCATION}, dram) @@ -70,7 +73,10 @@ BL2_SOURCES += common/desc_image_load.c \ drivers/io/io_block.c \ drivers/io/io_fip.c \ drivers/io/io_storage.c \ + drivers/synopsys/ufs/dw_ufs.c \ drivers/ufs/ufs.c \ + lib/cpus/aarch64/cortex_a53.S \ + plat/hisilicon/hikey960/aarch64/hikey960_helpers.S \ plat/hisilicon/hikey960/hikey960_bl2_mem_params_desc.c \ plat/hisilicon/hikey960/hikey960_bl2_setup.c \ plat/hisilicon/hikey960/hikey960_image_load.c \ From 19b731e810399145ee085cfe25411f91bbb0625b Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Tue, 30 Jan 2018 10:35:17 +0800 Subject: [PATCH 10/11] hikey960: fix invoking driver init in image load driver It's unnecessary to call platform driver initialization in image load driver. We could make bl2_platform_setup() to executing just before SCP_BL2 by setting flag IMAGE_ATTRIB_PLAT_SETUP. Signed-off-by: Haojian Zhuang --- plat/hisilicon/hikey960/hikey960_bl2_setup.c | 4 +++- plat/hisilicon/hikey960/hikey960_image_load.c | 8 +------- plat/hisilicon/hikey960/hikey960_private.h | 1 - 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/plat/hisilicon/hikey960/hikey960_bl2_setup.c b/plat/hisilicon/hikey960/hikey960_bl2_setup.c index d443d8e83..50bc7f0a8 100644 --- a/plat/hisilicon/hikey960/hikey960_bl2_setup.c +++ b/plat/hisilicon/hikey960/hikey960_bl2_setup.c @@ -157,7 +157,7 @@ static void hikey960_ufs_reset(void) } while (data & PERI_UFS_BIT); } -void hikey960_init_ufs(void) +static void hikey960_init_ufs(void) { dw_ufs_params_t ufs_params; @@ -747,4 +747,6 @@ void bl2_platform_setup(void) hikey960_tzc_init(); hikey960_peri_init(); hikey960_pinmux_init(); + hikey960_init_ufs(); + hikey960_io_setup(); } diff --git a/plat/hisilicon/hikey960/hikey960_image_load.c b/plat/hisilicon/hikey960/hikey960_image_load.c index 8e91adbf2..ad7be5081 100644 --- a/plat/hisilicon/hikey960/hikey960_image_load.c +++ b/plat/hisilicon/hikey960/hikey960_image_load.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,8 +8,6 @@ #include #include -#include "hikey960_private.h" - /******************************************************************************* * This function flushes the data structures so that they are visible * in memory for the next BL image. @@ -24,10 +22,6 @@ void plat_flush_next_bl_params(void) ******************************************************************************/ bl_load_info_t *plat_get_bl_image_load_info(void) { - /* Required before loading scp_bl2 */ - hikey960_init_ufs(); - hikey960_io_setup(); - return get_bl_load_info_from_mem_params_desc(); } diff --git a/plat/hisilicon/hikey960/hikey960_private.h b/plat/hisilicon/hikey960/hikey960_private.h index e3c9d2153..8f2a842e2 100644 --- a/plat/hisilicon/hikey960/hikey960_private.h +++ b/plat/hisilicon/hikey960/hikey960_private.h @@ -24,7 +24,6 @@ void hikey960_init_mmu_el3(unsigned long total_base, unsigned long ro_limit, unsigned long coh_start, unsigned long coh_limit); -void hikey960_init_ufs(void); void hikey960_io_setup(void); int hikey960_read_boardid(unsigned int *id); void set_retention_ticks(unsigned int val); From 4e858ba0edaf69d3adf6fd1382299905fcb7c7fe Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Mon, 5 Mar 2018 13:20:33 +0800 Subject: [PATCH 11/11] hikey960: move out duplicated code Create hikey960_bl_common.c to store duplication initialization code in both BL1 and BL2. Signed-off-by: Haojian Zhuang --- plat/hisilicon/hikey960/hikey960_bl1_setup.c | 429 ------------------ plat/hisilicon/hikey960/hikey960_bl2_setup.c | 422 ------------------ plat/hisilicon/hikey960/hikey960_bl_common.c | 441 +++++++++++++++++++ plat/hisilicon/hikey960/hikey960_private.h | 6 + plat/hisilicon/hikey960/platform.mk | 4 +- 5 files changed, 450 insertions(+), 852 deletions(-) create mode 100644 plat/hisilicon/hikey960/hikey960_bl_common.c diff --git a/plat/hisilicon/hikey960/hikey960_bl1_setup.c b/plat/hisilicon/hikey960/hikey960_bl1_setup.c index d45cea0fb..9cadba0bb 100644 --- a/plat/hisilicon/hikey960/hikey960_bl1_setup.c +++ b/plat/hisilicon/hikey960/hikey960_bl1_setup.c @@ -135,385 +135,6 @@ void bl1_plat_arch_setup(void) BL1_COHERENT_RAM_LIMIT); } -static void hikey960_clk_init(void) -{ - /* change ldi0 sel to ppll2 */ - mmio_write_32(0xfff350b4, 0xf0002000); - /* ldi0 20' */ - mmio_write_32(0xfff350bc, 0xfc004c00); -} - -static void hikey960_pmu_init(void) -{ - /* clear np_xo_abb_dig_START bit in PMIC_CLK_TOP_CTRL7 register */ - mmio_clrbits_32(PMU_SSI0_CLK_TOP_CTRL7_REG, NP_XO_ABB_DIG); -} - -static void hikey960_enable_ppll3(void) -{ - /* enable ppll3 */ - mmio_write_32(PMC_PPLL3_CTRL0_REG, 0x4904305); - mmio_write_32(PMC_PPLL3_CTRL1_REG, 0x2300000); - mmio_write_32(PMC_PPLL3_CTRL1_REG, 0x6300000); -} - -static void bus_idle_clear(unsigned int value) -{ - unsigned int pmc_value, value1, value2; - int timeout = 100; - - pmc_value = value << 16; - pmc_value &= ~value; - mmio_write_32(PMC_NOC_POWER_IDLEREQ_REG, pmc_value); - - for (;;) { - value1 = (unsigned int)mmio_read_32(PMC_NOC_POWER_IDLEACK_REG); - value2 = (unsigned int)mmio_read_32(PMC_NOC_POWER_IDLE_REG); - if (((value1 & value) == 0) && ((value2 & value) == 0)) - break; - udelay(1); - timeout--; - if (timeout <= 0) { - WARN("%s timeout\n", __func__); - break; - } - } -} - -static void set_vivobus_power_up(void) -{ - /* clk enable */ - mmio_write_32(CRG_CLKDIV20_REG, 0x00020002); - mmio_write_32(CRG_PEREN0_REG, 0x00001000); -} - -static void set_dss_power_up(void) -{ - /* set edc0 133MHz = 1600MHz / 12 */ - mmio_write_32(CRG_CLKDIV5_REG, 0x003f000b); - /* set ldi0 ppl0 */ - mmio_write_32(CRG_CLKDIV3_REG, 0xf0001000); - /* set ldi0 133MHz, 1600MHz / 12 */ - mmio_write_32(CRG_CLKDIV5_REG, 0xfc002c00); - /* mtcmos on */ - mmio_write_32(CRG_PERPWREN_REG, 0x00000020); - udelay(100); - /* DISP CRG */ - mmio_write_32(CRG_PERRSTDIS4_REG, 0x00000010); - /* clk enable */ - mmio_write_32(CRG_CLKDIV18_REG, 0x01400140); - mmio_write_32(CRG_PEREN0_REG, 0x00002000); - mmio_write_32(CRG_PEREN3_REG, 0x0003b000); - udelay(1); - /* clk disable */ - mmio_write_32(CRG_PERDIS3_REG, 0x0003b000); - mmio_write_32(CRG_PERDIS0_REG, 0x00002000); - mmio_write_32(CRG_CLKDIV18_REG, 0x01400000); - udelay(1); - /* iso disable */ - mmio_write_32(CRG_ISODIS_REG, 0x00000040); - /* unreset */ - mmio_write_32(CRG_PERRSTDIS4_REG, 0x00000006); - mmio_write_32(CRG_PERRSTDIS3_REG, 0x00000c00); - /* clk enable */ - mmio_write_32(CRG_CLKDIV18_REG, 0x01400140); - mmio_write_32(CRG_PEREN0_REG, 0x00002000); - mmio_write_32(CRG_PEREN3_REG, 0x0003b000); - /* bus idle clear */ - bus_idle_clear(PMC_NOC_POWER_IDLEREQ_DSS); - /* set edc0 400MHz for 2K 1600MHz / 4 */ - mmio_write_32(CRG_CLKDIV5_REG, 0x003f0003); - /* set ldi 266MHz, 1600MHz / 6 */ - mmio_write_32(CRG_CLKDIV5_REG, 0xfc001400); -} - -static void set_vcodec_power_up(void) -{ - /* clk enable */ - mmio_write_32(CRG_CLKDIV20_REG, 0x00040004); - mmio_write_32(CRG_PEREN0_REG, 0x00000060); - mmio_write_32(CRG_PEREN2_REG, 0x10000000); - /* unreset */ - mmio_write_32(CRG_PERRSTDIS0_REG, 0x00000018); - /* bus idle clear */ - bus_idle_clear(PMC_NOC_POWER_IDLEREQ_VCODEC); -} - -static void set_vdec_power_up(void) -{ - /* mtcmos on */ - mmio_write_32(CRG_PERPWREN_REG, 0x00000004); - udelay(100); - /* clk enable */ - mmio_write_32(CRG_CLKDIV18_REG, 0x80008000); - mmio_write_32(CRG_PEREN2_REG, 0x20080000); - mmio_write_32(CRG_PEREN3_REG, 0x00000800); - udelay(1); - /* clk disable */ - mmio_write_32(CRG_PERDIS3_REG, 0x00000800); - mmio_write_32(CRG_PERDIS2_REG, 0x20080000); - mmio_write_32(CRG_CLKDIV18_REG, 0x80000000); - udelay(1); - /* iso disable */ - mmio_write_32(CRG_ISODIS_REG, 0x00000004); - /* unreset */ - mmio_write_32(CRG_PERRSTDIS3_REG, 0x00000200); - /* clk enable */ - mmio_write_32(CRG_CLKDIV18_REG, 0x80008000); - mmio_write_32(CRG_PEREN2_REG, 0x20080000); - mmio_write_32(CRG_PEREN3_REG, 0x00000800); - /* bus idle clear */ - bus_idle_clear(PMC_NOC_POWER_IDLEREQ_VDEC); -} - -static void set_venc_power_up(void) -{ - /* set venc ppll3 */ - mmio_write_32(CRG_CLKDIV8_REG, 0x18001000); - /* set venc 258MHz, 1290MHz / 5 */ - mmio_write_32(CRG_CLKDIV8_REG, 0x07c00100); - /* mtcmos on */ - mmio_write_32(CRG_PERPWREN_REG, 0x00000002); - udelay(100); - /* clk enable */ - mmio_write_32(CRG_CLKDIV19_REG, 0x00010001); - mmio_write_32(CRG_PEREN2_REG, 0x40000100); - mmio_write_32(CRG_PEREN3_REG, 0x00000400); - udelay(1); - /* clk disable */ - mmio_write_32(CRG_PERDIS3_REG, 0x00000400); - mmio_write_32(CRG_PERDIS2_REG, 0x40000100); - mmio_write_32(CRG_CLKDIV19_REG, 0x00010000); - udelay(1); - /* iso disable */ - mmio_write_32(CRG_ISODIS_REG, 0x00000002); - /* unreset */ - mmio_write_32(CRG_PERRSTDIS3_REG, 0x00000100); - /* clk enable */ - mmio_write_32(CRG_CLKDIV19_REG, 0x00010001); - mmio_write_32(CRG_PEREN2_REG, 0x40000100); - mmio_write_32(CRG_PEREN3_REG, 0x00000400); - /* bus idle clear */ - bus_idle_clear(PMC_NOC_POWER_IDLEREQ_VENC); - /* set venc 645MHz, 1290MHz / 2 */ - mmio_write_32(CRG_CLKDIV8_REG, 0x07c00040); -} - -static void set_isp_power_up(void) -{ - /* mtcmos on */ - mmio_write_32(CRG_PERPWREN_REG, 0x00000001); - udelay(100); - /* clk enable */ - mmio_write_32(CRG_CLKDIV18_REG, 0x70007000); - mmio_write_32(CRG_CLKDIV20_REG, 0x00100010); - mmio_write_32(CRG_PEREN5_REG, 0x01000010); - mmio_write_32(CRG_PEREN3_REG, 0x0bf00000); - udelay(1); - /* clk disable */ - mmio_write_32(CRG_PERDIS5_REG, 0x01000010); - mmio_write_32(CRG_PERDIS3_REG, 0x0bf00000); - mmio_write_32(CRG_CLKDIV18_REG, 0x70000000); - mmio_write_32(CRG_CLKDIV20_REG, 0x00100000); - udelay(1); - /* iso disable */ - mmio_write_32(CRG_ISODIS_REG, 0x00000001); - /* unreset */ - mmio_write_32(CRG_ISP_SEC_RSTDIS_REG, 0x0000002f); - /* clk enable */ - mmio_write_32(CRG_CLKDIV18_REG, 0x70007000); - mmio_write_32(CRG_CLKDIV20_REG, 0x00100010); - mmio_write_32(CRG_PEREN5_REG, 0x01000010); - mmio_write_32(CRG_PEREN3_REG, 0x0bf00000); - /* bus idle clear */ - bus_idle_clear(PMC_NOC_POWER_IDLEREQ_ISP); - /* csi clk enable */ - mmio_write_32(CRG_PEREN3_REG, 0x00700000); -} - -static void set_ivp_power_up(void) -{ - /* set ivp ppll0 */ - mmio_write_32(CRG_CLKDIV0_REG, 0xc0000000); - /* set ivp 267MHz, 1600MHz / 6 */ - mmio_write_32(CRG_CLKDIV0_REG, 0x3c001400); - /* mtcmos on */ - mmio_write_32(CRG_PERPWREN_REG, 0x00200000); - udelay(100); - /* IVP CRG unreset */ - mmio_write_32(CRG_IVP_SEC_RSTDIS_REG, 0x00000001); - /* clk enable */ - mmio_write_32(CRG_CLKDIV20_REG, 0x02000200); - mmio_write_32(CRG_PEREN4_REG, 0x000000a8); - udelay(1); - /* clk disable */ - mmio_write_32(CRG_PERDIS4_REG, 0x000000a8); - mmio_write_32(CRG_CLKDIV20_REG, 0x02000000); - udelay(1); - /* iso disable */ - mmio_write_32(CRG_ISODIS_REG, 0x01000000); - /* unreset */ - mmio_write_32(CRG_IVP_SEC_RSTDIS_REG, 0x00000002); - /* clk enable */ - mmio_write_32(CRG_CLKDIV20_REG, 0x02000200); - mmio_write_32(CRG_PEREN4_REG, 0x000000a8); - /* bus idle clear */ - bus_idle_clear(PMC_NOC_POWER_IDLEREQ_IVP); - /* set ivp 533MHz, 1600MHz / 3 */ - mmio_write_32(CRG_CLKDIV0_REG, 0x3c000800); -} - -static void set_audio_power_up(void) -{ - unsigned int ret; - int timeout = 100; - /* mtcmos on */ - mmio_write_32(SCTRL_SCPWREN_REG, 0x00000001); - udelay(100); - /* clk enable */ - mmio_write_32(CRG_CLKDIV19_REG, 0x80108010); - mmio_write_32(SCTRL_SCCLKDIV2_REG, 0x00010001); - mmio_write_32(SCTRL_SCPEREN0_REG, 0x0c000000); - mmio_write_32(CRG_PEREN0_REG, 0x04000000); - mmio_write_32(CRG_PEREN5_REG, 0x00000080); - mmio_write_32(SCTRL_SCPEREN1_REG, 0x0000000f); - udelay(1); - /* clk disable */ - mmio_write_32(SCTRL_SCPERDIS1_REG, 0x0000000f); - mmio_write_32(SCTRL_SCPERDIS0_REG, 0x0c000000); - mmio_write_32(CRG_PERDIS5_REG, 0x00000080); - mmio_write_32(CRG_PERDIS0_REG, 0x04000000); - mmio_write_32(SCTRL_SCCLKDIV2_REG, 0x00010000); - mmio_write_32(CRG_CLKDIV19_REG, 0x80100000); - udelay(1); - /* iso disable */ - mmio_write_32(SCTRL_SCISODIS_REG, 0x00000001); - udelay(1); - /* unreset */ - mmio_write_32(SCTRL_PERRSTDIS1_SEC_REG, 0x00000001); - mmio_write_32(SCTRL_SCPERRSTDIS0_REG, 0x00000780); - /* clk enable */ - mmio_write_32(CRG_CLKDIV19_REG, 0x80108010); - mmio_write_32(SCTRL_SCCLKDIV2_REG, 0x00010001); - mmio_write_32(SCTRL_SCPEREN0_REG, 0x0c000000); - mmio_write_32(CRG_PEREN0_REG, 0x04000000); - mmio_write_32(CRG_PEREN5_REG, 0x00000080); - mmio_write_32(SCTRL_SCPEREN1_REG, 0x0000000f); - /* bus idle clear */ - mmio_write_32(SCTRL_SCPERCTRL7_REG, 0x00040000); - for (;;) { - ret = mmio_read_32(SCTRL_SCPERSTAT6_REG); - if (((ret & (1 << 5)) == 0) && ((ret & (1 << 8)) == 0)) - break; - udelay(1); - timeout--; - if (timeout <= 0) { - WARN("%s timeout\n", __func__); - break; - } - } - mmio_write_32(ASP_CFG_MMBUF_CTRL_REG, 0x00ff0000); -} - -static void set_pcie_power_up(void) -{ - /* mtcmos on */ - mmio_write_32(SCTRL_SCPWREN_REG, 0x00000010); - udelay(100); - /* clk enable */ - mmio_write_32(SCTRL_SCCLKDIV6_REG, 0x08000800); - mmio_write_32(SCTRL_SCPEREN2_REG, 0x00104000); - mmio_write_32(CRG_PEREN7_REG, 0x000003a0); - udelay(1); - /* clk disable */ - mmio_write_32(SCTRL_SCPERDIS2_REG, 0x00104000); - mmio_write_32(CRG_PERDIS7_REG, 0x000003a0); - mmio_write_32(SCTRL_SCCLKDIV6_REG, 0x08000000); - udelay(1); - /* iso disable */ - mmio_write_32(SCTRL_SCISODIS_REG, 0x00000030); - /* unreset */ - mmio_write_32(CRG_PERRSTDIS3_REG, 0x8c000000); - /* clk enable */ - mmio_write_32(SCTRL_SCCLKDIV6_REG, 0x08000800); - mmio_write_32(SCTRL_SCPEREN2_REG, 0x00104000); - mmio_write_32(CRG_PEREN7_REG, 0x000003a0); -} - -static void ispfunc_enable(void) -{ - /* enable ispfunc. Otherwise powerup isp_srt causes exception. */ - mmio_write_32(0xfff35000, 0x00000008); - mmio_write_32(0xfff35460, 0xc004ffff); - mmio_write_32(0xfff35030, 0x02000000); - mdelay(10); -} - -static void isps_control_clock(int flag) -{ - unsigned int ret; - - /* flag: 0 -- disable clock, 1 -- enable clock */ - if (flag) { - ret = mmio_read_32(0xe8420364); - ret |= 1; - mmio_write_32(0xe8420364, ret); - } else { - ret = mmio_read_32(0xe8420364); - ret &= ~1; - mmio_write_32(0xe8420364, ret); - } -} - -static void set_isp_srt_power_up(void) -{ - unsigned int ret; - - ispfunc_enable(); - /* reset */ - mmio_write_32(0xe8420374, 0x00000001); - mmio_write_32(0xe8420350, 0x00000000); - mmio_write_32(0xe8420358, 0x00000000); - /* mtcmos on */ - mmio_write_32(0xfff35150, 0x00400000); - udelay(100); - /* clk enable */ - isps_control_clock(1); - udelay(1); - isps_control_clock(0); - udelay(1); - /* iso disable */ - mmio_write_32(0xfff35148, 0x08000000); - /* unreset */ - ret = mmio_read_32(0xe8420374); - ret &= ~0x1; - mmio_write_32(0xe8420374, ret); - /* clk enable */ - isps_control_clock(1); - /* enable clock gating for accessing csi registers */ - mmio_write_32(0xe8420010, ~0); -} - -static void hikey960_regulator_enable(void) -{ - set_vivobus_power_up(); - hikey960_enable_ppll3(); - set_dss_power_up(); - set_vcodec_power_up(); - set_vdec_power_up(); - set_venc_power_up(); - set_isp_power_up(); - set_ivp_power_up(); - set_audio_power_up(); - set_pcie_power_up(); - set_isp_srt_power_up(); - - /* set ISP_CORE_CTRL_S to unsecure mode */ - mmio_write_32(0xe8583800, 0x7); - /* set ISP_SUB_CTRL_S to unsecure mode */ - mmio_write_32(0xe8583804, 0xf); -} - static void hikey960_ufs_reset(void) { unsigned int data, mask; @@ -589,56 +210,6 @@ static void hikey960_ufs_init(void) dw_ufs_init(&ufs_params); } -static void hikey960_tzc_init(void) -{ - mmio_write_32(TZC_EN0_REG, 0x7fbff066); - mmio_write_32(TZC_EN1_REG, 0xfffff5fc); - mmio_write_32(TZC_EN2_REG, 0x0007005c); - mmio_write_32(TZC_EN3_REG, 0x37030700); - mmio_write_32(TZC_EN4_REG, 0xf63fefae); - mmio_write_32(TZC_EN5_REG, 0x000410fd); - mmio_write_32(TZC_EN6_REG, 0x0063ff68); - mmio_write_32(TZC_EN7_REG, 0x030000f3); - mmio_write_32(TZC_EN8_REG, 0x00000007); -} - -static void hikey960_peri_init(void) -{ - /* unreset */ - mmio_setbits_32(CRG_PERRSTDIS4_REG, 1); -} - -static void hikey960_pinmux_init(void) -{ - unsigned int id; - - hikey960_read_boardid(&id); - if (id == 5301) { - /* hikey960 hardware v2 */ - /* GPIO150: LED */ - mmio_write_32(IOMG_FIX_006_REG, 0); - /* GPIO151: LED */ - mmio_write_32(IOMG_FIX_007_REG, 0); - /* GPIO189: LED */ - mmio_write_32(IOMG_AO_011_REG, 0); - /* GPIO190: LED */ - mmio_write_32(IOMG_AO_012_REG, 0); - /* GPIO46 */ - mmio_write_32(IOMG_044_REG, 0); - /* GPIO202 */ - mmio_write_32(IOMG_AO_023_REG, 0); - /* GPIO206 */ - mmio_write_32(IOMG_AO_026_REG, 0); - /* GPIO219 - PD pullup */ - mmio_write_32(IOMG_AO_039_REG, 0); - mmio_write_32(IOCG_AO_043_REG, 1 << 0); - } - /* GPIO005 - PMU SSI, 10mA */ - mmio_write_32(IOCG_006_REG, 2 << 4); - /* GPIO213 - PCIE_CLKREQ_N */ - mmio_write_32(IOMG_AO_033_REG, 1); -} - /* * Function which will perform any remaining platform-specific setup that can * occur after the MMU and data cache have been enabled. diff --git a/plat/hisilicon/hikey960/hikey960_bl2_setup.c b/plat/hisilicon/hikey960/hikey960_bl2_setup.c index 50bc7f0a8..11bbf9e15 100644 --- a/plat/hisilicon/hikey960/hikey960_bl2_setup.c +++ b/plat/hisilicon/hikey960/hikey960_bl2_setup.c @@ -272,428 +272,6 @@ int hikey960_bl2_handle_post_image_load(unsigned int image_id) return err; } -static void hikey960_clk_init(void) -{ - /* change ldi0 sel to ppll2 */ - mmio_write_32(0xfff350b4, 0xf0002000); - /* ldi0 20' */ - mmio_write_32(0xfff350bc, 0xfc004c00); -} - -static void hikey960_pmu_init(void) -{ - /* clear np_xo_abb_dig_START bit in PMIC_CLK_TOP_CTRL7 register */ - mmio_clrbits_32(PMU_SSI0_CLK_TOP_CTRL7_REG, NP_XO_ABB_DIG); -} - -static void hikey960_enable_ppll3(void) -{ - /* enable ppll3 */ - mmio_write_32(PMC_PPLL3_CTRL0_REG, 0x4904305); - mmio_write_32(PMC_PPLL3_CTRL1_REG, 0x2300000); - mmio_write_32(PMC_PPLL3_CTRL1_REG, 0x6300000); -} - -static void bus_idle_clear(unsigned int value) -{ - unsigned int pmc_value, value1, value2; - int timeout = 100; - - pmc_value = value << 16; - pmc_value &= ~value; - mmio_write_32(PMC_NOC_POWER_IDLEREQ_REG, pmc_value); - - for (;;) { - value1 = (unsigned int)mmio_read_32(PMC_NOC_POWER_IDLEACK_REG); - value2 = (unsigned int)mmio_read_32(PMC_NOC_POWER_IDLE_REG); - if (((value1 & value) == 0) && ((value2 & value) == 0)) - break; - udelay(1); - timeout--; - if (timeout <= 0) { - WARN("%s timeout\n", __func__); - break; - } - } -} - -static void set_vivobus_power_up(void) -{ - /* clk enable */ - mmio_write_32(CRG_CLKDIV20_REG, 0x00020002); - mmio_write_32(CRG_PEREN0_REG, 0x00001000); -} - -static void set_dss_power_up(void) -{ - /* set edc0 133MHz = 1600MHz / 12 */ - mmio_write_32(CRG_CLKDIV5_REG, 0x003f000b); - /* set ldi0 ppl0 */ - mmio_write_32(CRG_CLKDIV3_REG, 0xf0001000); - /* set ldi0 133MHz, 1600MHz / 12 */ - mmio_write_32(CRG_CLKDIV5_REG, 0xfc002c00); - /* mtcmos on */ - mmio_write_32(CRG_PERPWREN_REG, 0x00000020); - udelay(100); - /* DISP CRG */ - mmio_write_32(CRG_PERRSTDIS4_REG, 0x00000010); - /* clk enable */ - mmio_write_32(CRG_CLKDIV18_REG, 0x01400140); - mmio_write_32(CRG_PEREN0_REG, 0x00002000); - mmio_write_32(CRG_PEREN3_REG, 0x0003b000); - udelay(1); - /* clk disable */ - mmio_write_32(CRG_PERDIS3_REG, 0x0003b000); - mmio_write_32(CRG_PERDIS0_REG, 0x00002000); - mmio_write_32(CRG_CLKDIV18_REG, 0x01400000); - udelay(1); - /* iso disable */ - mmio_write_32(CRG_ISODIS_REG, 0x00000040); - /* unreset */ - mmio_write_32(CRG_PERRSTDIS4_REG, 0x00000006); - mmio_write_32(CRG_PERRSTDIS3_REG, 0x00000c00); - /* clk enable */ - mmio_write_32(CRG_CLKDIV18_REG, 0x01400140); - mmio_write_32(CRG_PEREN0_REG, 0x00002000); - mmio_write_32(CRG_PEREN3_REG, 0x0003b000); - /* bus idle clear */ - bus_idle_clear(PMC_NOC_POWER_IDLEREQ_DSS); - /* set edc0 400MHz for 2K 1600MHz / 4 */ - mmio_write_32(CRG_CLKDIV5_REG, 0x003f0003); - /* set ldi 266MHz, 1600MHz / 6 */ - mmio_write_32(CRG_CLKDIV5_REG, 0xfc001400); -} - -static void set_vcodec_power_up(void) -{ - /* clk enable */ - mmio_write_32(CRG_CLKDIV20_REG, 0x00040004); - mmio_write_32(CRG_PEREN0_REG, 0x00000060); - mmio_write_32(CRG_PEREN2_REG, 0x10000000); - /* unreset */ - mmio_write_32(CRG_PERRSTDIS0_REG, 0x00000018); - /* bus idle clear */ - bus_idle_clear(PMC_NOC_POWER_IDLEREQ_VCODEC); -} - -static void set_vdec_power_up(void) -{ - /* mtcmos on */ - mmio_write_32(CRG_PERPWREN_REG, 0x00000004); - udelay(100); - /* clk enable */ - mmio_write_32(CRG_CLKDIV18_REG, 0x80008000); - mmio_write_32(CRG_PEREN2_REG, 0x20080000); - mmio_write_32(CRG_PEREN3_REG, 0x00000800); - udelay(1); - /* clk disable */ - mmio_write_32(CRG_PERDIS3_REG, 0x00000800); - mmio_write_32(CRG_PERDIS2_REG, 0x20080000); - mmio_write_32(CRG_CLKDIV18_REG, 0x80000000); - udelay(1); - /* iso disable */ - mmio_write_32(CRG_ISODIS_REG, 0x00000004); - /* unreset */ - mmio_write_32(CRG_PERRSTDIS3_REG, 0x00000200); - /* clk enable */ - mmio_write_32(CRG_CLKDIV18_REG, 0x80008000); - mmio_write_32(CRG_PEREN2_REG, 0x20080000); - mmio_write_32(CRG_PEREN3_REG, 0x00000800); - /* bus idle clear */ - bus_idle_clear(PMC_NOC_POWER_IDLEREQ_VDEC); -} - -static void set_venc_power_up(void) -{ - /* set venc ppll3 */ - mmio_write_32(CRG_CLKDIV8_REG, 0x18001000); - /* set venc 258MHz, 1290MHz / 5 */ - mmio_write_32(CRG_CLKDIV8_REG, 0x07c00100); - /* mtcmos on */ - mmio_write_32(CRG_PERPWREN_REG, 0x00000002); - udelay(100); - /* clk enable */ - mmio_write_32(CRG_CLKDIV19_REG, 0x00010001); - mmio_write_32(CRG_PEREN2_REG, 0x40000100); - mmio_write_32(CRG_PEREN3_REG, 0x00000400); - udelay(1); - /* clk disable */ - mmio_write_32(CRG_PERDIS3_REG, 0x00000400); - mmio_write_32(CRG_PERDIS2_REG, 0x40000100); - mmio_write_32(CRG_CLKDIV19_REG, 0x00010000); - udelay(1); - /* iso disable */ - mmio_write_32(CRG_ISODIS_REG, 0x00000002); - /* unreset */ - mmio_write_32(CRG_PERRSTDIS3_REG, 0x00000100); - /* clk enable */ - mmio_write_32(CRG_CLKDIV19_REG, 0x00010001); - mmio_write_32(CRG_PEREN2_REG, 0x40000100); - mmio_write_32(CRG_PEREN3_REG, 0x00000400); - /* bus idle clear */ - bus_idle_clear(PMC_NOC_POWER_IDLEREQ_VENC); - /* set venc 645MHz, 1290MHz / 2 */ - mmio_write_32(CRG_CLKDIV8_REG, 0x07c00040); -} - -static void set_isp_power_up(void) -{ - /* mtcmos on */ - mmio_write_32(CRG_PERPWREN_REG, 0x00000001); - udelay(100); - /* clk enable */ - mmio_write_32(CRG_CLKDIV18_REG, 0x70007000); - mmio_write_32(CRG_CLKDIV20_REG, 0x00100010); - mmio_write_32(CRG_PEREN5_REG, 0x01000010); - mmio_write_32(CRG_PEREN3_REG, 0x0bf00000); - udelay(1); - /* clk disable */ - mmio_write_32(CRG_PERDIS5_REG, 0x01000010); - mmio_write_32(CRG_PERDIS3_REG, 0x0bf00000); - mmio_write_32(CRG_CLKDIV18_REG, 0x70000000); - mmio_write_32(CRG_CLKDIV20_REG, 0x00100000); - udelay(1); - /* iso disable */ - mmio_write_32(CRG_ISODIS_REG, 0x00000001); - /* unreset */ - mmio_write_32(CRG_ISP_SEC_RSTDIS_REG, 0x0000002f); - /* clk enable */ - mmio_write_32(CRG_CLKDIV18_REG, 0x70007000); - mmio_write_32(CRG_CLKDIV20_REG, 0x00100010); - mmio_write_32(CRG_PEREN5_REG, 0x01000010); - mmio_write_32(CRG_PEREN3_REG, 0x0bf00000); - /* bus idle clear */ - bus_idle_clear(PMC_NOC_POWER_IDLEREQ_ISP); - /* csi clk enable */ - mmio_write_32(CRG_PEREN3_REG, 0x00700000); -} - -static void set_ivp_power_up(void) -{ - /* set ivp ppll0 */ - mmio_write_32(CRG_CLKDIV0_REG, 0xc0000000); - /* set ivp 267MHz, 1600MHz / 6 */ - mmio_write_32(CRG_CLKDIV0_REG, 0x3c001400); - /* mtcmos on */ - mmio_write_32(CRG_PERPWREN_REG, 0x00200000); - udelay(100); - /* IVP CRG unreset */ - mmio_write_32(CRG_IVP_SEC_RSTDIS_REG, 0x00000001); - /* clk enable */ - mmio_write_32(CRG_CLKDIV20_REG, 0x02000200); - mmio_write_32(CRG_PEREN4_REG, 0x000000a8); - udelay(1); - /* clk disable */ - mmio_write_32(CRG_PERDIS4_REG, 0x000000a8); - mmio_write_32(CRG_CLKDIV20_REG, 0x02000000); - udelay(1); - /* iso disable */ - mmio_write_32(CRG_ISODIS_REG, 0x01000000); - /* unreset */ - mmio_write_32(CRG_IVP_SEC_RSTDIS_REG, 0x00000002); - /* clk enable */ - mmio_write_32(CRG_CLKDIV20_REG, 0x02000200); - mmio_write_32(CRG_PEREN4_REG, 0x000000a8); - /* bus idle clear */ - bus_idle_clear(PMC_NOC_POWER_IDLEREQ_IVP); - /* set ivp 533MHz, 1600MHz / 3 */ - mmio_write_32(CRG_CLKDIV0_REG, 0x3c000800); -} - -static void set_audio_power_up(void) -{ - unsigned int ret; - int timeout = 100; - /* mtcmos on */ - mmio_write_32(SCTRL_SCPWREN_REG, 0x00000001); - udelay(100); - /* clk enable */ - mmio_write_32(CRG_CLKDIV19_REG, 0x80108010); - mmio_write_32(SCTRL_SCCLKDIV2_REG, 0x00010001); - mmio_write_32(SCTRL_SCPEREN0_REG, 0x0c000000); - mmio_write_32(CRG_PEREN0_REG, 0x04000000); - mmio_write_32(CRG_PEREN5_REG, 0x00000080); - mmio_write_32(SCTRL_SCPEREN1_REG, 0x0000000f); - udelay(1); - /* clk disable */ - mmio_write_32(SCTRL_SCPERDIS1_REG, 0x0000000f); - mmio_write_32(SCTRL_SCPERDIS0_REG, 0x0c000000); - mmio_write_32(CRG_PERDIS5_REG, 0x00000080); - mmio_write_32(CRG_PERDIS0_REG, 0x04000000); - mmio_write_32(SCTRL_SCCLKDIV2_REG, 0x00010000); - mmio_write_32(CRG_CLKDIV19_REG, 0x80100000); - udelay(1); - /* iso disable */ - mmio_write_32(SCTRL_SCISODIS_REG, 0x00000001); - udelay(1); - /* unreset */ - mmio_write_32(SCTRL_PERRSTDIS1_SEC_REG, 0x00000001); - mmio_write_32(SCTRL_SCPERRSTDIS0_REG, 0x00000780); - /* clk enable */ - mmio_write_32(CRG_CLKDIV19_REG, 0x80108010); - mmio_write_32(SCTRL_SCCLKDIV2_REG, 0x00010001); - mmio_write_32(SCTRL_SCPEREN0_REG, 0x0c000000); - mmio_write_32(CRG_PEREN0_REG, 0x04000000); - mmio_write_32(CRG_PEREN5_REG, 0x00000080); - mmio_write_32(SCTRL_SCPEREN1_REG, 0x0000000f); - /* bus idle clear */ - mmio_write_32(SCTRL_SCPERCTRL7_REG, 0x00040000); - for (;;) { - ret = mmio_read_32(SCTRL_SCPERSTAT6_REG); - if (((ret & (1 << 5)) == 0) && ((ret & (1 << 8)) == 0)) - break; - udelay(1); - timeout--; - if (timeout <= 0) { - WARN("%s timeout\n", __func__); - break; - } - } - mmio_write_32(ASP_CFG_MMBUF_CTRL_REG, 0x00ff0000); -} - -static void set_pcie_power_up(void) -{ - /* mtcmos on */ - mmio_write_32(SCTRL_SCPWREN_REG, 0x00000010); - udelay(100); - /* clk enable */ - mmio_write_32(SCTRL_SCCLKDIV6_REG, 0x08000800); - mmio_write_32(SCTRL_SCPEREN2_REG, 0x00104000); - mmio_write_32(CRG_PEREN7_REG, 0x000003a0); - udelay(1); - /* clk disable */ - mmio_write_32(SCTRL_SCPERDIS2_REG, 0x00104000); - mmio_write_32(CRG_PERDIS7_REG, 0x000003a0); - mmio_write_32(SCTRL_SCCLKDIV6_REG, 0x08000000); - udelay(1); - /* iso disable */ - mmio_write_32(SCTRL_SCISODIS_REG, 0x00000030); - /* unreset */ - mmio_write_32(CRG_PERRSTDIS3_REG, 0x8c000000); - /* clk enable */ - mmio_write_32(SCTRL_SCCLKDIV6_REG, 0x08000800); - mmio_write_32(SCTRL_SCPEREN2_REG, 0x00104000); - mmio_write_32(CRG_PEREN7_REG, 0x000003a0); -} - -static void ispfunc_enable(void) -{ - /* enable ispfunc. Otherwise powerup isp_srt causes exception. */ - mmio_write_32(0xfff35000, 0x00000008); - mmio_write_32(0xfff35460, 0xc004ffff); - mmio_write_32(0xfff35030, 0x02000000); - mdelay(10); -} - -static void isps_control_clock(int flag) -{ - unsigned int ret; - - /* flag: 0 -- disable clock, 1 -- enable clock */ - if (flag) { - ret = mmio_read_32(0xe8420364); - ret |= 1; - mmio_write_32(0xe8420364, ret); - } else { - ret = mmio_read_32(0xe8420364); - ret &= ~1; - mmio_write_32(0xe8420364, ret); - } -} - -static void set_isp_srt_power_up(void) -{ - unsigned int ret; - - ispfunc_enable(); - /* reset */ - mmio_write_32(0xe8420374, 0x00000001); - mmio_write_32(0xe8420350, 0x00000000); - mmio_write_32(0xe8420358, 0x00000000); - /* mtcmos on */ - mmio_write_32(0xfff35150, 0x00400000); - udelay(100); - /* clk enable */ - isps_control_clock(1); - udelay(1); - isps_control_clock(0); - udelay(1); - /* iso disable */ - mmio_write_32(0xfff35148, 0x08000000); - /* unreset */ - ret = mmio_read_32(0xe8420374); - ret &= ~0x1; - mmio_write_32(0xe8420374, ret); - /* clk enable */ - isps_control_clock(1); - /* enable clock gating for accessing csi registers */ - mmio_write_32(0xe8420010, ~0); -} - -static void hikey960_regulator_enable(void) -{ - set_vivobus_power_up(); - hikey960_enable_ppll3(); - set_dss_power_up(); - set_vcodec_power_up(); - set_vdec_power_up(); - set_venc_power_up(); - set_isp_power_up(); - set_ivp_power_up(); - set_audio_power_up(); - set_pcie_power_up(); - set_isp_srt_power_up(); -} - -static void hikey960_tzc_init(void) -{ - mmio_write_32(TZC_EN0_REG, 0x7fbff066); - mmio_write_32(TZC_EN1_REG, 0xfffff5fc); - mmio_write_32(TZC_EN2_REG, 0x0007005c); - mmio_write_32(TZC_EN3_REG, 0x37030700); - mmio_write_32(TZC_EN4_REG, 0xf63fefae); - mmio_write_32(TZC_EN5_REG, 0x000410fd); - mmio_write_32(TZC_EN6_REG, 0x0063ff68); - mmio_write_32(TZC_EN7_REG, 0x030000f3); - mmio_write_32(TZC_EN8_REG, 0x00000007); -} - -static void hikey960_peri_init(void) -{ - /* unreset */ - mmio_setbits_32(CRG_PERRSTDIS4_REG, 1); -} - -static void hikey960_pinmux_init(void) -{ - unsigned int id; - - hikey960_read_boardid(&id); - if (id == 5301) { - /* hikey960 hardware v2 */ - /* GPIO150: LED */ - mmio_write_32(IOMG_FIX_006_REG, 0); - /* GPIO151: LED */ - mmio_write_32(IOMG_FIX_007_REG, 0); - /* GPIO189: LED */ - mmio_write_32(IOMG_AO_011_REG, 0); - /* GPIO190: LED */ - mmio_write_32(IOMG_AO_012_REG, 0); - /* GPIO46 */ - mmio_write_32(IOMG_044_REG, 0); - /* GPIO202 */ - mmio_write_32(IOMG_AO_023_REG, 0); - /* GPIO206 */ - mmio_write_32(IOMG_AO_026_REG, 0); - /* GPIO219 - PD pullup */ - mmio_write_32(IOMG_AO_039_REG, 0); - mmio_write_32(IOCG_AO_043_REG, 1 << 0); - } - /* GPIO005 - PMU SSI, 10mA */ - mmio_write_32(IOCG_006_REG, 2 << 4); -} - /******************************************************************************* * This function can be used by the platforms to update/use image * information for given `image_id`. diff --git a/plat/hisilicon/hikey960/hikey960_bl_common.c b/plat/hisilicon/hikey960/hikey960_bl_common.c new file mode 100644 index 000000000..f192c1e0e --- /dev/null +++ b/plat/hisilicon/hikey960/hikey960_bl_common.c @@ -0,0 +1,441 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#include "hikey960_private.h" + +void hikey960_clk_init(void) +{ + /* change ldi0 sel to ppll2 */ + mmio_write_32(0xfff350b4, 0xf0002000); + /* ldi0 20' */ + mmio_write_32(0xfff350bc, 0xfc004c00); +} + +void hikey960_pmu_init(void) +{ + /* clear np_xo_abb_dig_START bit in PMIC_CLK_TOP_CTRL7 register */ + mmio_clrbits_32(PMU_SSI0_CLK_TOP_CTRL7_REG, NP_XO_ABB_DIG); +} + +static void hikey960_enable_ppll3(void) +{ + /* enable ppll3 */ + mmio_write_32(PMC_PPLL3_CTRL0_REG, 0x4904305); + mmio_write_32(PMC_PPLL3_CTRL1_REG, 0x2300000); + mmio_write_32(PMC_PPLL3_CTRL1_REG, 0x6300000); +} + +static void bus_idle_clear(unsigned int value) +{ + unsigned int pmc_value, value1, value2; + int timeout = 100; + + pmc_value = value << 16; + pmc_value &= ~value; + mmio_write_32(PMC_NOC_POWER_IDLEREQ_REG, pmc_value); + + for (;;) { + value1 = (unsigned int)mmio_read_32(PMC_NOC_POWER_IDLEACK_REG); + value2 = (unsigned int)mmio_read_32(PMC_NOC_POWER_IDLE_REG); + if (((value1 & value) == 0) && ((value2 & value) == 0)) + break; + udelay(1); + timeout--; + if (timeout <= 0) { + WARN("%s timeout\n", __func__); + break; + } + } +} + +static void set_vivobus_power_up(void) +{ + /* clk enable */ + mmio_write_32(CRG_CLKDIV20_REG, 0x00020002); + mmio_write_32(CRG_PEREN0_REG, 0x00001000); +} + +static void set_dss_power_up(void) +{ + /* set edc0 133MHz = 1600MHz / 12 */ + mmio_write_32(CRG_CLKDIV5_REG, 0x003f000b); + /* set ldi0 ppl0 */ + mmio_write_32(CRG_CLKDIV3_REG, 0xf0001000); + /* set ldi0 133MHz, 1600MHz / 12 */ + mmio_write_32(CRG_CLKDIV5_REG, 0xfc002c00); + /* mtcmos on */ + mmio_write_32(CRG_PERPWREN_REG, 0x00000020); + udelay(100); + /* DISP CRG */ + mmio_write_32(CRG_PERRSTDIS4_REG, 0x00000010); + /* clk enable */ + mmio_write_32(CRG_CLKDIV18_REG, 0x01400140); + mmio_write_32(CRG_PEREN0_REG, 0x00002000); + mmio_write_32(CRG_PEREN3_REG, 0x0003b000); + udelay(1); + /* clk disable */ + mmio_write_32(CRG_PERDIS3_REG, 0x0003b000); + mmio_write_32(CRG_PERDIS0_REG, 0x00002000); + mmio_write_32(CRG_CLKDIV18_REG, 0x01400000); + udelay(1); + /* iso disable */ + mmio_write_32(CRG_ISODIS_REG, 0x00000040); + /* unreset */ + mmio_write_32(CRG_PERRSTDIS4_REG, 0x00000006); + mmio_write_32(CRG_PERRSTDIS3_REG, 0x00000c00); + /* clk enable */ + mmio_write_32(CRG_CLKDIV18_REG, 0x01400140); + mmio_write_32(CRG_PEREN0_REG, 0x00002000); + mmio_write_32(CRG_PEREN3_REG, 0x0003b000); + /* bus idle clear */ + bus_idle_clear(PMC_NOC_POWER_IDLEREQ_DSS); + /* set edc0 400MHz for 2K 1600MHz / 4 */ + mmio_write_32(CRG_CLKDIV5_REG, 0x003f0003); + /* set ldi 266MHz, 1600MHz / 6 */ + mmio_write_32(CRG_CLKDIV5_REG, 0xfc001400); +} + +static void set_vcodec_power_up(void) +{ + /* clk enable */ + mmio_write_32(CRG_CLKDIV20_REG, 0x00040004); + mmio_write_32(CRG_PEREN0_REG, 0x00000060); + mmio_write_32(CRG_PEREN2_REG, 0x10000000); + /* unreset */ + mmio_write_32(CRG_PERRSTDIS0_REG, 0x00000018); + /* bus idle clear */ + bus_idle_clear(PMC_NOC_POWER_IDLEREQ_VCODEC); +} + +static void set_vdec_power_up(void) +{ + /* mtcmos on */ + mmio_write_32(CRG_PERPWREN_REG, 0x00000004); + udelay(100); + /* clk enable */ + mmio_write_32(CRG_CLKDIV18_REG, 0x80008000); + mmio_write_32(CRG_PEREN2_REG, 0x20080000); + mmio_write_32(CRG_PEREN3_REG, 0x00000800); + udelay(1); + /* clk disable */ + mmio_write_32(CRG_PERDIS3_REG, 0x00000800); + mmio_write_32(CRG_PERDIS2_REG, 0x20080000); + mmio_write_32(CRG_CLKDIV18_REG, 0x80000000); + udelay(1); + /* iso disable */ + mmio_write_32(CRG_ISODIS_REG, 0x00000004); + /* unreset */ + mmio_write_32(CRG_PERRSTDIS3_REG, 0x00000200); + /* clk enable */ + mmio_write_32(CRG_CLKDIV18_REG, 0x80008000); + mmio_write_32(CRG_PEREN2_REG, 0x20080000); + mmio_write_32(CRG_PEREN3_REG, 0x00000800); + /* bus idle clear */ + bus_idle_clear(PMC_NOC_POWER_IDLEREQ_VDEC); +} + +static void set_venc_power_up(void) +{ + /* set venc ppll3 */ + mmio_write_32(CRG_CLKDIV8_REG, 0x18001000); + /* set venc 258MHz, 1290MHz / 5 */ + mmio_write_32(CRG_CLKDIV8_REG, 0x07c00100); + /* mtcmos on */ + mmio_write_32(CRG_PERPWREN_REG, 0x00000002); + udelay(100); + /* clk enable */ + mmio_write_32(CRG_CLKDIV19_REG, 0x00010001); + mmio_write_32(CRG_PEREN2_REG, 0x40000100); + mmio_write_32(CRG_PEREN3_REG, 0x00000400); + udelay(1); + /* clk disable */ + mmio_write_32(CRG_PERDIS3_REG, 0x00000400); + mmio_write_32(CRG_PERDIS2_REG, 0x40000100); + mmio_write_32(CRG_CLKDIV19_REG, 0x00010000); + udelay(1); + /* iso disable */ + mmio_write_32(CRG_ISODIS_REG, 0x00000002); + /* unreset */ + mmio_write_32(CRG_PERRSTDIS3_REG, 0x00000100); + /* clk enable */ + mmio_write_32(CRG_CLKDIV19_REG, 0x00010001); + mmio_write_32(CRG_PEREN2_REG, 0x40000100); + mmio_write_32(CRG_PEREN3_REG, 0x00000400); + /* bus idle clear */ + bus_idle_clear(PMC_NOC_POWER_IDLEREQ_VENC); + /* set venc 645MHz, 1290MHz / 2 */ + mmio_write_32(CRG_CLKDIV8_REG, 0x07c00040); +} + +static void set_isp_power_up(void) +{ + /* mtcmos on */ + mmio_write_32(CRG_PERPWREN_REG, 0x00000001); + udelay(100); + /* clk enable */ + mmio_write_32(CRG_CLKDIV18_REG, 0x70007000); + mmio_write_32(CRG_CLKDIV20_REG, 0x00100010); + mmio_write_32(CRG_PEREN5_REG, 0x01000010); + mmio_write_32(CRG_PEREN3_REG, 0x0bf00000); + udelay(1); + /* clk disable */ + mmio_write_32(CRG_PERDIS5_REG, 0x01000010); + mmio_write_32(CRG_PERDIS3_REG, 0x0bf00000); + mmio_write_32(CRG_CLKDIV18_REG, 0x70000000); + mmio_write_32(CRG_CLKDIV20_REG, 0x00100000); + udelay(1); + /* iso disable */ + mmio_write_32(CRG_ISODIS_REG, 0x00000001); + /* unreset */ + mmio_write_32(CRG_ISP_SEC_RSTDIS_REG, 0x0000002f); + /* clk enable */ + mmio_write_32(CRG_CLKDIV18_REG, 0x70007000); + mmio_write_32(CRG_CLKDIV20_REG, 0x00100010); + mmio_write_32(CRG_PEREN5_REG, 0x01000010); + mmio_write_32(CRG_PEREN3_REG, 0x0bf00000); + /* bus idle clear */ + bus_idle_clear(PMC_NOC_POWER_IDLEREQ_ISP); + /* csi clk enable */ + mmio_write_32(CRG_PEREN3_REG, 0x00700000); +} + +static void set_ivp_power_up(void) +{ + /* set ivp ppll0 */ + mmio_write_32(CRG_CLKDIV0_REG, 0xc0000000); + /* set ivp 267MHz, 1600MHz / 6 */ + mmio_write_32(CRG_CLKDIV0_REG, 0x3c001400); + /* mtcmos on */ + mmio_write_32(CRG_PERPWREN_REG, 0x00200000); + udelay(100); + /* IVP CRG unreset */ + mmio_write_32(CRG_IVP_SEC_RSTDIS_REG, 0x00000001); + /* clk enable */ + mmio_write_32(CRG_CLKDIV20_REG, 0x02000200); + mmio_write_32(CRG_PEREN4_REG, 0x000000a8); + udelay(1); + /* clk disable */ + mmio_write_32(CRG_PERDIS4_REG, 0x000000a8); + mmio_write_32(CRG_CLKDIV20_REG, 0x02000000); + udelay(1); + /* iso disable */ + mmio_write_32(CRG_ISODIS_REG, 0x01000000); + /* unreset */ + mmio_write_32(CRG_IVP_SEC_RSTDIS_REG, 0x00000002); + /* clk enable */ + mmio_write_32(CRG_CLKDIV20_REG, 0x02000200); + mmio_write_32(CRG_PEREN4_REG, 0x000000a8); + /* bus idle clear */ + bus_idle_clear(PMC_NOC_POWER_IDLEREQ_IVP); + /* set ivp 533MHz, 1600MHz / 3 */ + mmio_write_32(CRG_CLKDIV0_REG, 0x3c000800); +} + +static void set_audio_power_up(void) +{ + unsigned int ret; + int timeout = 100; + /* mtcmos on */ + mmio_write_32(SCTRL_SCPWREN_REG, 0x00000001); + udelay(100); + /* clk enable */ + mmio_write_32(CRG_CLKDIV19_REG, 0x80108010); + mmio_write_32(SCTRL_SCCLKDIV2_REG, 0x00010001); + mmio_write_32(SCTRL_SCPEREN0_REG, 0x0c000000); + mmio_write_32(CRG_PEREN0_REG, 0x04000000); + mmio_write_32(CRG_PEREN5_REG, 0x00000080); + mmio_write_32(SCTRL_SCPEREN1_REG, 0x0000000f); + udelay(1); + /* clk disable */ + mmio_write_32(SCTRL_SCPERDIS1_REG, 0x0000000f); + mmio_write_32(SCTRL_SCPERDIS0_REG, 0x0c000000); + mmio_write_32(CRG_PERDIS5_REG, 0x00000080); + mmio_write_32(CRG_PERDIS0_REG, 0x04000000); + mmio_write_32(SCTRL_SCCLKDIV2_REG, 0x00010000); + mmio_write_32(CRG_CLKDIV19_REG, 0x80100000); + udelay(1); + /* iso disable */ + mmio_write_32(SCTRL_SCISODIS_REG, 0x00000001); + udelay(1); + /* unreset */ + mmio_write_32(SCTRL_PERRSTDIS1_SEC_REG, 0x00000001); + mmio_write_32(SCTRL_SCPERRSTDIS0_REG, 0x00000780); + /* clk enable */ + mmio_write_32(CRG_CLKDIV19_REG, 0x80108010); + mmio_write_32(SCTRL_SCCLKDIV2_REG, 0x00010001); + mmio_write_32(SCTRL_SCPEREN0_REG, 0x0c000000); + mmio_write_32(CRG_PEREN0_REG, 0x04000000); + mmio_write_32(CRG_PEREN5_REG, 0x00000080); + mmio_write_32(SCTRL_SCPEREN1_REG, 0x0000000f); + /* bus idle clear */ + mmio_write_32(SCTRL_SCPERCTRL7_REG, 0x00040000); + for (;;) { + ret = mmio_read_32(SCTRL_SCPERSTAT6_REG); + if (((ret & (1 << 5)) == 0) && ((ret & (1 << 8)) == 0)) + break; + udelay(1); + timeout--; + if (timeout <= 0) { + WARN("%s timeout\n", __func__); + break; + } + } + mmio_write_32(ASP_CFG_MMBUF_CTRL_REG, 0x00ff0000); +} + +static void set_pcie_power_up(void) +{ + /* mtcmos on */ + mmio_write_32(SCTRL_SCPWREN_REG, 0x00000010); + udelay(100); + /* clk enable */ + mmio_write_32(SCTRL_SCCLKDIV6_REG, 0x08000800); + mmio_write_32(SCTRL_SCPEREN2_REG, 0x00104000); + mmio_write_32(CRG_PEREN7_REG, 0x000003a0); + udelay(1); + /* clk disable */ + mmio_write_32(SCTRL_SCPERDIS2_REG, 0x00104000); + mmio_write_32(CRG_PERDIS7_REG, 0x000003a0); + mmio_write_32(SCTRL_SCCLKDIV6_REG, 0x08000000); + udelay(1); + /* iso disable */ + mmio_write_32(SCTRL_SCISODIS_REG, 0x00000030); + /* unreset */ + mmio_write_32(CRG_PERRSTDIS3_REG, 0x8c000000); + /* clk enable */ + mmio_write_32(SCTRL_SCCLKDIV6_REG, 0x08000800); + mmio_write_32(SCTRL_SCPEREN2_REG, 0x00104000); + mmio_write_32(CRG_PEREN7_REG, 0x000003a0); +} + +static void ispfunc_enable(void) +{ + /* enable ispfunc. Otherwise powerup isp_srt causes exception. */ + mmio_write_32(0xfff35000, 0x00000008); + mmio_write_32(0xfff35460, 0xc004ffff); + mmio_write_32(0xfff35030, 0x02000000); + mdelay(10); +} + +static void isps_control_clock(int flag) +{ + unsigned int ret; + + /* flag: 0 -- disable clock, 1 -- enable clock */ + if (flag) { + ret = mmio_read_32(0xe8420364); + ret |= 1; + mmio_write_32(0xe8420364, ret); + } else { + ret = mmio_read_32(0xe8420364); + ret &= ~1; + mmio_write_32(0xe8420364, ret); + } +} + +static void set_isp_srt_power_up(void) +{ + unsigned int ret; + + ispfunc_enable(); + /* reset */ + mmio_write_32(0xe8420374, 0x00000001); + mmio_write_32(0xe8420350, 0x00000000); + mmio_write_32(0xe8420358, 0x00000000); + /* mtcmos on */ + mmio_write_32(0xfff35150, 0x00400000); + udelay(100); + /* clk enable */ + isps_control_clock(1); + udelay(1); + isps_control_clock(0); + udelay(1); + /* iso disable */ + mmio_write_32(0xfff35148, 0x08000000); + /* unreset */ + ret = mmio_read_32(0xe8420374); + ret &= ~0x1; + mmio_write_32(0xe8420374, ret); + /* clk enable */ + isps_control_clock(1); + /* enable clock gating for accessing csi registers */ + mmio_write_32(0xe8420010, ~0); +} + +void hikey960_regulator_enable(void) +{ + set_vivobus_power_up(); + hikey960_enable_ppll3(); + set_dss_power_up(); + set_vcodec_power_up(); + set_vdec_power_up(); + set_venc_power_up(); + set_isp_power_up(); + set_ivp_power_up(); + set_audio_power_up(); + set_pcie_power_up(); + set_isp_srt_power_up(); + + /* set ISP_CORE_CTRL_S to unsecure mode */ + mmio_write_32(0xe8583800, 0x7); + /* set ISP_SUB_CTRL_S to unsecure mode */ + mmio_write_32(0xe8583804, 0xf); +} + +void hikey960_tzc_init(void) +{ + mmio_write_32(TZC_EN0_REG, 0x7fbff066); + mmio_write_32(TZC_EN1_REG, 0xfffff5fc); + mmio_write_32(TZC_EN2_REG, 0x0007005c); + mmio_write_32(TZC_EN3_REG, 0x37030700); + mmio_write_32(TZC_EN4_REG, 0xf63fefae); + mmio_write_32(TZC_EN5_REG, 0x000410fd); + mmio_write_32(TZC_EN6_REG, 0x0063ff68); + mmio_write_32(TZC_EN7_REG, 0x030000f3); + mmio_write_32(TZC_EN8_REG, 0x00000007); +} + +void hikey960_peri_init(void) +{ + /* unreset */ + mmio_setbits_32(CRG_PERRSTDIS4_REG, 1); +} + +void hikey960_pinmux_init(void) +{ + unsigned int id; + + hikey960_read_boardid(&id); + if (id == 5301) { + /* hikey960 hardware v2 */ + /* GPIO150: LED */ + mmio_write_32(IOMG_FIX_006_REG, 0); + /* GPIO151: LED */ + mmio_write_32(IOMG_FIX_007_REG, 0); + /* GPIO189: LED */ + mmio_write_32(IOMG_AO_011_REG, 0); + /* GPIO190: LED */ + mmio_write_32(IOMG_AO_012_REG, 0); + /* GPIO46 */ + mmio_write_32(IOMG_044_REG, 0); + /* GPIO202 */ + mmio_write_32(IOMG_AO_023_REG, 0); + /* GPIO206 */ + mmio_write_32(IOMG_AO_026_REG, 0); + /* GPIO219 - PD pullup */ + mmio_write_32(IOMG_AO_039_REG, 0); + mmio_write_32(IOCG_AO_043_REG, 1 << 0); + } + /* GPIO005 - PMU SSI, 10mA */ + mmio_write_32(IOCG_006_REG, 2 << 4); + /* GPIO213 - PCIE_CLKREQ_N */ + mmio_write_32(IOMG_AO_033_REG, 1); +} diff --git a/plat/hisilicon/hikey960/hikey960_private.h b/plat/hisilicon/hikey960/hikey960_private.h index 8f2a842e2..30166e56d 100644 --- a/plat/hisilicon/hikey960/hikey960_private.h +++ b/plat/hisilicon/hikey960/hikey960_private.h @@ -26,6 +26,12 @@ void hikey960_init_mmu_el3(unsigned long total_base, unsigned long coh_limit); void hikey960_io_setup(void); int hikey960_read_boardid(unsigned int *id); +void hikey960_clk_init(void); +void hikey960_pmu_init(void); +void hikey960_regulator_enable(void); +void hikey960_tzc_init(void); +void hikey960_peri_init(void); +void hikey960_pinmux_init(void); void set_retention_ticks(unsigned int val); void clr_retention_ticks(unsigned int val); void clr_ex(void); diff --git a/plat/hisilicon/hikey960/platform.mk b/plat/hisilicon/hikey960/platform.mk index f20e59a00..1dcf5c8ea 100644 --- a/plat/hisilicon/hikey960/platform.mk +++ b/plat/hisilicon/hikey960/platform.mk @@ -65,7 +65,8 @@ BL1_SOURCES += bl1/tbbr/tbbr_img_desc.c \ drivers/ufs/ufs.c \ lib/cpus/aarch64/cortex_a53.S \ plat/hisilicon/hikey960/aarch64/hikey960_helpers.S \ - plat/hisilicon/hikey960/hikey960_bl1_setup.c \ + plat/hisilicon/hikey960/hikey960_bl1_setup.c \ + plat/hisilicon/hikey960/hikey960_bl_common.c \ plat/hisilicon/hikey960/hikey960_io_storage.c \ ${HIKEY960_GIC_SOURCES} @@ -79,6 +80,7 @@ BL2_SOURCES += common/desc_image_load.c \ plat/hisilicon/hikey960/aarch64/hikey960_helpers.S \ plat/hisilicon/hikey960/hikey960_bl2_mem_params_desc.c \ plat/hisilicon/hikey960/hikey960_bl2_setup.c \ + plat/hisilicon/hikey960/hikey960_bl_common.c \ plat/hisilicon/hikey960/hikey960_image_load.c \ plat/hisilicon/hikey960/hikey960_io_storage.c \ plat/hisilicon/hikey960/hikey960_mcu_load.c