blob: 67b06f498cc26a3f2da00f74459cc1bad839ed72 [file] [log] [blame]
Haojian Zhuang1b5c2252017-06-01 15:20:46 +08001/*
2 * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Haojian Zhuang1b5c2252017-06-01 15:20:46 +08007#include <assert.h>
Haojian Zhuang1b5c2252017-06-01 15:20:46 +08008#include <errno.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00009
Haojian Zhuang1b5c2252017-06-01 15:20:46 +080010#include <platform_def.h>
11
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000012#include <arch_helpers.h>
13#include <bl31/interrupt_mgmt.h>
14#include <common/bl_common.h>
15#include <common/debug.h>
16#include <common/interrupt_props.h>
17#include <drivers/arm/cci.h>
18#include <drivers/arm/gicv2.h>
19#include <drivers/arm/pl011.h>
20#include <drivers/console.h>
21#include <drivers/generic_delay_timer.h>
22#include <lib/mmio.h>
23#include <plat/common/platform.h>
24
25#include <hi3660.h>
26#include <hisi_ipc.h>
Haojian Zhuang1b5c2252017-06-01 15:20:46 +080027#include "hikey960_def.h"
28#include "hikey960_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 BL31_RO_BASE (unsigned long)(&__RO_START__)
37#define BL31_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 BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
47#define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
48
49static entry_point_info_t bl32_ep_info;
50static entry_point_info_t bl33_ep_info;
Jerome Forissier3fb19df2018-11-08 09:59:29 +010051static console_pl011_t console;
Haojian Zhuang1b5c2252017-06-01 15:20:46 +080052
53/******************************************************************************
54 * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
55 * interrupts.
56 *****************************************************************************/
Antonio Nino Diaz582c2d72018-09-24 17:23:47 +010057static const interrupt_prop_t g0_interrupt_props[] = {
58 INTR_PROP_DESC(IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY,
59 GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
60 INTR_PROP_DESC(IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY,
61 GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
Haojian Zhuang1b5c2252017-06-01 15:20:46 +080062};
63
64const gicv2_driver_data_t hikey960_gic_data = {
65 .gicd_base = GICD_REG_BASE,
66 .gicc_base = GICC_REG_BASE,
Antonio Nino Diaz582c2d72018-09-24 17:23:47 +010067 .interrupt_props = g0_interrupt_props,
68 .interrupt_props_num = ARRAY_SIZE(g0_interrupt_props),
Haojian Zhuang1b5c2252017-06-01 15:20:46 +080069};
70
71static const int cci_map[] = {
72 CCI400_SL_IFACE3_CLUSTER_IX,
73 CCI400_SL_IFACE4_CLUSTER_IX
74};
75
Victor Chong7d787f52017-08-16 13:53:56 +090076entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
Haojian Zhuang1b5c2252017-06-01 15:20:46 +080077{
78 entry_point_info_t *next_image_info;
79
80 next_image_info = (type == NON_SECURE) ? &bl33_ep_info : &bl32_ep_info;
81
82 /* None of the images on this platform can have 0x0 as the entrypoint */
83 if (next_image_info->pc)
84 return next_image_info;
85 return NULL;
86}
87
Antonio Nino Diaz582c2d72018-09-24 17:23:47 +010088void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
89 u_register_t arg2, u_register_t arg3)
Haojian Zhuang1b5c2252017-06-01 15:20:46 +080090{
91 unsigned int id, uart_base;
Antonio Nino Diaz582c2d72018-09-24 17:23:47 +010092 void *from_bl2;
93
94 from_bl2 = (void *) arg0;
Haojian Zhuang1b5c2252017-06-01 15:20:46 +080095
96 generic_delay_timer_init();
97 hikey960_read_boardid(&id);
98 if (id == 5300)
99 uart_base = PL011_UART5_BASE;
100 else
101 uart_base = PL011_UART6_BASE;
102
103 /* Initialize the console to provide early debug support */
Jerome Forissier3fb19df2018-11-08 09:59:29 +0100104 console_pl011_register(uart_base, PL011_UART_CLK_IN_HZ,
105 PL011_BAUDRATE, &console);
Haojian Zhuang1b5c2252017-06-01 15:20:46 +0800106
107 /* Initialize CCI driver */
108 cci_init(CCI400_REG_BASE, cci_map, ARRAY_SIZE(cci_map));
109 cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1()));
110
Victor Chong2d9a42d2017-08-17 15:21:10 +0900111 /*
112 * Check params passed from BL2 should not be NULL,
113 */
114 bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
115 assert(params_from_bl2 != NULL);
116 assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
117 assert(params_from_bl2->h.version >= VERSION_2);
118
119 bl_params_node_t *bl_params = params_from_bl2->head;
120
121 /*
122 * Copy BL33 and BL32 (if present), entry point information.
123 * They are stored in Secure RAM, in BL2's address space.
124 */
125 while (bl_params) {
126 if (bl_params->image_id == BL32_IMAGE_ID)
127 bl32_ep_info = *bl_params->ep_info;
128
129 if (bl_params->image_id == BL33_IMAGE_ID)
130 bl33_ep_info = *bl_params->ep_info;
131
132 bl_params = bl_params->next_params_info;
133 }
134
135 if (bl33_ep_info.pc == 0)
136 panic();
Haojian Zhuang1b5c2252017-06-01 15:20:46 +0800137}
138
139void bl31_plat_arch_setup(void)
140{
141 hikey960_init_mmu_el3(BL31_BASE,
142 BL31_LIMIT - BL31_BASE,
143 BL31_RO_BASE,
144 BL31_RO_LIMIT,
145 BL31_COHERENT_RAM_BASE,
146 BL31_COHERENT_RAM_LIMIT);
147}
148
Ryan Grachek44f8d652018-11-29 12:45:55 -0600149static void hikey960_edma_init(void)
150{
151 int i;
152 uint32_t non_secure;
153
154 non_secure = EDMAC_SEC_CTRL_INTR_SEC | EDMAC_SEC_CTRL_GLOBAL_SEC;
155 mmio_write_32(EDMAC_SEC_CTRL, non_secure);
156
157 for (i = 0; i < EDMAC_CHANNEL_NUMS; i++) {
158 mmio_write_32(EDMAC_AXI_CONF(i), (1 << 6) | (1 << 18));
159 }
160}
161
Haojian Zhuang1b5c2252017-06-01 15:20:46 +0800162void bl31_platform_setup(void)
163{
164 /* Initialize the GIC driver, cpu and distributor interfaces */
165 gicv2_driver_init(&hikey960_gic_data);
166 gicv2_distif_init();
167 gicv2_pcpu_distif_init();
168 gicv2_cpuif_enable();
169
Ryan Grachek44f8d652018-11-29 12:45:55 -0600170 hikey960_edma_init();
171
Haojian Zhuang1b5c2252017-06-01 15:20:46 +0800172 hisi_ipc_init();
173}
174
Leo Yanaf316a32018-01-22 12:40:25 +0800175#ifdef SPD_none
176static uint64_t hikey_debug_fiq_handler(uint32_t id,
177 uint32_t flags,
178 void *handle,
179 void *cookie)
180{
181 int intr, intr_raw;
182
183 /* Acknowledge interrupt */
184 intr_raw = plat_ic_acknowledge_interrupt();
185 intr = plat_ic_get_interrupt_id(intr_raw);
186 ERROR("Invalid interrupt: intr=%d\n", intr);
187 console_flush();
188 panic();
189
190 return 0;
191}
192#endif
193
Haojian Zhuang1b5c2252017-06-01 15:20:46 +0800194void bl31_plat_runtime_setup(void)
195{
Leo Yanaf316a32018-01-22 12:40:25 +0800196#ifdef SPD_none
197 uint32_t flags;
198 int32_t rc;
199
200 flags = 0;
201 set_interrupt_rm_flag(flags, NON_SECURE);
202 rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
203 hikey_debug_fiq_handler,
204 flags);
205 if (rc != 0)
206 panic();
207#endif
Haojian Zhuang1b5c2252017-06-01 15:20:46 +0800208}