blob: 6080f84f2fd7138db435b34b1d0a0fda8c82179a [file] [log] [blame]
Haojian Zhuang934ae712017-05-24 08:47:49 +08001/*
Haojian Zhuang3bd94382018-01-28 23:33:02 +08002 * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
Haojian Zhuang934ae712017-05-24 08:47:49 +08003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch_helpers.h>
8#include <assert.h>
9#include <bl_common.h>
10#include <console.h>
11#include <debug.h>
Victor Chong2d9a42d2017-08-17 15:21:10 +090012#include <desc_image_load.h>
Haojian Zhuang934ae712017-05-24 08:47:49 +080013#include <dw_mmc.h>
14#include <emmc.h>
15#include <errno.h>
16#include <hi6220.h>
17#include <hisi_mcu.h>
18#include <hisi_sram_map.h>
19#include <mmio.h>
Victor Chong7d787f52017-08-16 13:53:56 +090020#ifdef SPD_opteed
21#include <optee_utils.h>
22#endif
Haojian Zhuang934ae712017-05-24 08:47:49 +080023#include <platform_def.h>
24#include <sp804_delay_timer.h>
25#include <string.h>
26
27#include "hikey_def.h"
28#include "hikey_private.h"
29
30/*
31 * The next 2 constants identify the extents of the code & RO data region.
32 * These addresses are used by the MMU setup code and therefore they must be
33 * page-aligned. It is the responsibility of the linker script to ensure that
34 * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
35 */
36#define BL2_RO_BASE (unsigned long)(&__RO_START__)
37#define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
38
39/*
40 * The next 2 constants identify the extents of the coherent memory region.
41 * These addresses are used by the MMU setup code and therefore they must be
42 * page-aligned. It is the responsibility of the linker script to ensure that
43 * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
44 * page-aligned addresses.
45 */
46#define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
47#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
48
49static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
50
Victor Chong2d9a42d2017-08-17 15:21:10 +090051/*******************************************************************************
52 * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol.
53 * Return 0 on success, -1 otherwise.
54 ******************************************************************************/
Victor Chong2d9a42d2017-08-17 15:21:10 +090055int plat_hikey_bl2_handle_scp_bl2(image_info_t *scp_bl2_image_info)
Haojian Zhuang934ae712017-05-24 08:47:49 +080056{
57 /* Enable MCU SRAM */
58 hisi_mcu_enable_sram();
59
60 /* Load MCU binary into SRAM */
61 hisi_mcu_load_image(scp_bl2_image_info->image_base,
62 scp_bl2_image_info->image_size);
63 /* Let MCU running */
64 hisi_mcu_start_run();
65
66 INFO("%s: MCU PC is at 0x%x\n",
67 __func__, mmio_read_32(AO_SC_MCU_SUBSYS_STAT2));
68 INFO("%s: AO_SC_PERIPH_CLKSTAT4 is 0x%x\n",
69 __func__, mmio_read_32(AO_SC_PERIPH_CLKSTAT4));
70 return 0;
71}
72
Victor Chong2d9a42d2017-08-17 15:21:10 +090073/*******************************************************************************
74 * Gets SPSR for BL32 entry
75 ******************************************************************************/
76uint32_t hikey_get_spsr_for_bl32_entry(void)
77{
78 /*
79 * The Secure Payload Dispatcher service is responsible for
80 * setting the SPSR prior to entry into the BL3-2 image.
81 */
82 return 0;
83}
84
85/*******************************************************************************
86 * Gets SPSR for BL33 entry
87 ******************************************************************************/
88#ifndef AARCH32
89uint32_t hikey_get_spsr_for_bl33_entry(void)
90{
91 unsigned int mode;
92 uint32_t spsr;
93
94 /* Figure out what mode we enter the non-secure world in */
95 mode = EL_IMPLEMENTED(2) ? MODE_EL2 : MODE_EL1;
96
97 /*
98 * TODO: Consider the possibility of specifying the SPSR in
99 * the FIP ToC and allowing the platform to have a say as
100 * well.
101 */
102 spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
103 return spsr;
104}
105#else
106uint32_t hikey_get_spsr_for_bl33_entry(void)
107{
108 unsigned int hyp_status, mode, spsr;
109
110 hyp_status = GET_VIRT_EXT(read_id_pfr1());
111
112 mode = (hyp_status) ? MODE32_hyp : MODE32_svc;
113
114 /*
115 * TODO: Consider the possibility of specifying the SPSR in
116 * the FIP ToC and allowing the platform to have a say as
117 * well.
118 */
119 spsr = SPSR_MODE32(mode, plat_get_ns_image_entrypoint() & 0x1,
120 SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS);
121 return spsr;
122}
123#endif /* AARCH32 */
124
Victor Chong2d9a42d2017-08-17 15:21:10 +0900125int hikey_bl2_handle_post_image_load(unsigned int image_id)
126{
127 int err = 0;
128 bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
Victor Chong7d787f52017-08-16 13:53:56 +0900129#ifdef SPD_opteed
130 bl_mem_params_node_t *pager_mem_params = NULL;
131 bl_mem_params_node_t *paged_mem_params = NULL;
132#endif
Victor Chong2d9a42d2017-08-17 15:21:10 +0900133 assert(bl_mem_params);
134
135 switch (image_id) {
136#ifdef AARCH64
137 case BL32_IMAGE_ID:
Victor Chong7d787f52017-08-16 13:53:56 +0900138#ifdef SPD_opteed
139 pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
140 assert(pager_mem_params);
141
142 paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
143 assert(paged_mem_params);
144
145 err = parse_optee_header(&bl_mem_params->ep_info,
146 &pager_mem_params->image_info,
147 &paged_mem_params->image_info);
148 if (err != 0) {
149 WARN("OPTEE header parse error.\n");
150 }
151#endif
Victor Chong2d9a42d2017-08-17 15:21:10 +0900152 bl_mem_params->ep_info.spsr = hikey_get_spsr_for_bl32_entry();
153 break;
154#endif
155
156 case BL33_IMAGE_ID:
157 /* BL33 expects to receive the primary CPU MPID (through r0) */
158 bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
159 bl_mem_params->ep_info.spsr = hikey_get_spsr_for_bl33_entry();
160 break;
161
162#ifdef SCP_BL2_BASE
163 case SCP_BL2_IMAGE_ID:
164 /* The subsequent handling of SCP_BL2 is platform specific */
165 err = plat_hikey_bl2_handle_scp_bl2(&bl_mem_params->image_info);
166 if (err) {
167 WARN("Failure in platform-specific handling of SCP_BL2 image.\n");
168 }
169 break;
170#endif
171 }
172
173 return err;
174}
175
176/*******************************************************************************
177 * This function can be used by the platforms to update/use image
178 * information for given `image_id`.
179 ******************************************************************************/
180int bl2_plat_handle_post_image_load(unsigned int image_id)
181{
182 return hikey_bl2_handle_post_image_load(image_id);
183}
Haojian Zhuang934ae712017-05-24 08:47:49 +0800184
185static void reset_dwmmc_clk(void)
186{
187 unsigned int data;
188
189 /* disable mmc0 bus clock */
190 mmio_write_32(PERI_SC_PERIPH_CLKDIS0, PERI_CLK0_MMC0);
191 do {
192 data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
193 } while (data & PERI_CLK0_MMC0);
194 /* enable mmc0 bus clock */
195 mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_MMC0);
196 do {
197 data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
198 } while (!(data & PERI_CLK0_MMC0));
199 /* reset mmc0 clock domain */
200 mmio_write_32(PERI_SC_PERIPH_RSTEN0, PERI_RST0_MMC0);
201
202 /* bypass mmc0 clock phase */
203 data = mmio_read_32(PERI_SC_PERIPH_CTRL2);
204 data |= 3;
205 mmio_write_32(PERI_SC_PERIPH_CTRL2, data);
206
207 /* disable low power */
208 data = mmio_read_32(PERI_SC_PERIPH_CTRL13);
209 data |= 1 << 3;
210 mmio_write_32(PERI_SC_PERIPH_CTRL13, data);
211 do {
212 data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
213 } while (!(data & PERI_RST0_MMC0));
214
215 /* unreset mmc0 clock domain */
216 mmio_write_32(PERI_SC_PERIPH_RSTDIS0, PERI_RST0_MMC0);
217 do {
218 data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
219 } while (data & PERI_RST0_MMC0);
220}
221
222static void hikey_boardid_init(void)
223{
224 u_register_t midr;
225
226 midr = read_midr();
227 mmio_write_32(MEMORY_AXI_CHIP_ADDR, midr);
228 INFO("[BDID] [%x] midr: 0x%x\n", MEMORY_AXI_CHIP_ADDR,
229 (unsigned int)midr);
230
231 mmio_write_32(MEMORY_AXI_BOARD_TYPE_ADDR, 0);
232 mmio_write_32(MEMORY_AXI_BOARD_ID_ADDR, 0x2b);
233
234 mmio_write_32(ACPU_ARM64_FLAGA, 0x1234);
235 mmio_write_32(ACPU_ARM64_FLAGB, 0x5678);
236}
237
238static void hikey_sd_init(void)
239{
240 /* switch pinmux to SD */
241 mmio_write_32(IOMG_SD_CLK, IOMG_MUX_FUNC0);
242 mmio_write_32(IOMG_SD_CMD, IOMG_MUX_FUNC0);
243 mmio_write_32(IOMG_SD_DATA0, IOMG_MUX_FUNC0);
244 mmio_write_32(IOMG_SD_DATA1, IOMG_MUX_FUNC0);
245 mmio_write_32(IOMG_SD_DATA2, IOMG_MUX_FUNC0);
246 mmio_write_32(IOMG_SD_DATA3, IOMG_MUX_FUNC0);
247
248 mmio_write_32(IOCG_SD_CLK, IOCG_INPUT_16MA);
249 mmio_write_32(IOCG_SD_CMD, IOCG_INPUT_12MA);
250 mmio_write_32(IOCG_SD_DATA0, IOCG_INPUT_12MA);
251 mmio_write_32(IOCG_SD_DATA1, IOCG_INPUT_12MA);
252 mmio_write_32(IOCG_SD_DATA2, IOCG_INPUT_12MA);
253 mmio_write_32(IOCG_SD_DATA3, IOCG_INPUT_12MA);
254
255 /* set SD Card detect as nopull */
256 mmio_write_32(IOCG_GPIO8, 0);
257}
258
259static void hikey_jumper_init(void)
260{
261 /* set jumper detect as nopull */
262 mmio_write_32(IOCG_GPIO24, 0);
263 /* set jumper detect as GPIO */
264 mmio_write_32(IOMG_GPIO24, IOMG_MUX_FUNC0);
265}
266
267void bl2_early_platform_setup(meminfo_t *mem_layout)
268{
269 dw_mmc_params_t params;
270
271 /* Initialize the console to provide early debug support */
272 console_init(CONSOLE_BASE, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE);
273
274 /* Setup the BL2 memory layout */
275 bl2_tzram_layout = *mem_layout;
276
277 /* Clear SRAM since it'll be used by MCU right now. */
278 memset((void *)SRAM_BASE, 0, SRAM_SIZE);
Haojian Zhuang1cb3b482018-01-29 11:42:42 +0800279 clean_dcache_range(SRAM_BASE, SRAM_SIZE);
Haojian Zhuang934ae712017-05-24 08:47:49 +0800280
281 sp804_timer_init(SP804_TIMER0_BASE, 10, 192);
282 dsb();
283 hikey_ddr_init();
284
285 hikey_boardid_init();
286 init_acpu_dvfs();
287 hikey_sd_init();
288 hikey_jumper_init();
289
290 reset_dwmmc_clk();
291 memset(&params, 0, sizeof(dw_mmc_params_t));
292 params.reg_base = DWMMC0_BASE;
293 params.desc_base = HIKEY_MMC_DESC_BASE;
294 params.desc_size = 1 << 20;
295 params.clk_rate = 24 * 1000 * 1000;
296 params.bus_width = EMMC_BUS_WIDTH_8;
297 params.flags = EMMC_FLAG_CMD23;
298 dw_mmc_init(&params);
299
300 hikey_io_setup();
301}
302
303void bl2_plat_arch_setup(void)
304{
305 hikey_init_mmu_el1(bl2_tzram_layout.total_base,
306 bl2_tzram_layout.total_size,
307 BL2_RO_BASE,
308 BL2_RO_LIMIT,
309 BL2_COHERENT_RAM_BASE,
310 BL2_COHERENT_RAM_LIMIT);
311}
312
313void bl2_platform_setup(void)
314{
Jerome Forissierc52e55f2015-05-04 09:40:03 +0200315 hikey_security_setup();
Haojian Zhuang934ae712017-05-24 08:47:49 +0800316}