1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (C) 2017 Timesys Corporation.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <arm32.h>
30 #include <console.h>
31 #include <drivers/atmel_saic.h>
32 #include <drivers/atmel_uart.h>
33 #include <io.h>
34 #include <kernel/boot.h>
35 #include <kernel/interrupt.h>
36 #include <kernel/misc.h>
37 #include <kernel/panic.h>
38 #include <kernel/tz_ssvce_def.h>
39 #include <matrix.h>
40 #include <mm/core_mmu.h>
41 #include <mm/core_memprot.h>
42 #include <platform_config.h>
43 #include <sama5d2.h>
44 #include <stdint.h>
45 #include <sm/optee_smc.h>
46 #include <tz_matrix.h>
47 
48 static struct atmel_uart_data console_data;
49 register_phys_mem_pgdir(MEM_AREA_IO_SEC, CONSOLE_UART_BASE,
50 			CORE_MMU_PGDIR_SIZE);
51 
console_init(void)52 void console_init(void)
53 {
54 	atmel_uart_init(&console_data, CONSOLE_UART_BASE);
55 	register_serial_console(&console_data.chip);
56 }
57 
58 register_phys_mem_pgdir(MEM_AREA_IO_SEC, AT91C_BASE_MATRIX32,
59 			CORE_MMU_PGDIR_SIZE);
60 register_phys_mem_pgdir(MEM_AREA_IO_SEC, AT91C_BASE_MATRIX64,
61 			CORE_MMU_PGDIR_SIZE);
62 
matrix32_base(void)63 vaddr_t matrix32_base(void)
64 {
65 	static void *va;
66 
67 	if (cpu_mmu_enabled()) {
68 		if (!va)
69 			va = phys_to_virt(AT91C_BASE_MATRIX32, MEM_AREA_IO_SEC,
70 					  1);
71 		return (vaddr_t)va;
72 	}
73 	return AT91C_BASE_MATRIX32;
74 }
75 
matrix64_base(void)76 vaddr_t matrix64_base(void)
77 {
78 	static void *va;
79 
80 	if (cpu_mmu_enabled()) {
81 		if (!va)
82 			va = phys_to_virt(AT91C_BASE_MATRIX64, MEM_AREA_IO_SEC,
83 					  1);
84 		return (vaddr_t)va;
85 	}
86 	return AT91C_BASE_MATRIX64;
87 }
88 
matrix_configure_slave_h64mx(void)89 static void matrix_configure_slave_h64mx(void)
90 {
91 	unsigned int ddr_port;
92 	unsigned int ssr_setting;
93 	unsigned int sasplit_setting;
94 	unsigned int srtop_setting;
95 
96 	/*
97 	 * 0: Bridge from H64MX to AXIMX
98 	 * (Internal ROM, Crypto Library, PKCC RAM): Always Secured
99 	 */
100 
101 	/* 1: H64MX Peripheral Bridge: SDMMC0, SDMMC1 Non-Secure */
102 	srtop_setting =	MATRIX_SRTOP(1, MATRIX_SRTOP_VALUE_128M)
103 			| MATRIX_SRTOP(2, MATRIX_SRTOP_VALUE_128M);
104 	sasplit_setting = MATRIX_SASPLIT(1, MATRIX_SASPLIT_VALUE_128M)
105 			| MATRIX_SASPLIT(2, MATRIX_SASPLIT_VALUE_128M);
106 	ssr_setting = (MATRIX_LANSECH_NS(1)
107 			| MATRIX_LANSECH_NS(2)
108 			| MATRIX_RDNSECH_NS(1)
109 			| MATRIX_RDNSECH_NS(2)
110 			| MATRIX_WRNSECH_NS(1)
111 			| MATRIX_WRNSECH_NS(2));
112 	matrix_configure_slave_security(matrix64_base(),
113 					H64MX_SLAVE_PERI_BRIDGE,
114 					srtop_setting,
115 					sasplit_setting,
116 					ssr_setting);
117 
118 	/*
119 	 * Matrix DDR configuration is hardcoded here and is difficult to
120 	 * generate at runtime. Since this configuration expect the secure
121 	 * DRAM to be at start of RAM and 8M of size, enforce it here.
122 	 */
123 	COMPILE_TIME_ASSERT(CFG_TZDRAM_START == AT91C_BASE_DDRCS);
124 	COMPILE_TIME_ASSERT(CFG_TZDRAM_SIZE == 0x800000);
125 
126 	/* 2 ~ 9 DDR2 Port1 ~ 7: Non-Secure, except op-tee tee/ta memory */
127 	srtop_setting = MATRIX_SRTOP(0, MATRIX_SRTOP_VALUE_128M);
128 	sasplit_setting = (MATRIX_SASPLIT(0, MATRIX_SASPLIT_VALUE_8M)
129 				| MATRIX_SASPLIT(1, MATRIX_SASPLIT_VALUE_128M)
130 				| MATRIX_SASPLIT(2, MATRIX_SASPLIT_VALUE_128M)
131 				| MATRIX_SASPLIT(3, MATRIX_SASPLIT_VALUE_128M));
132 	ssr_setting = (MATRIX_LANSECH_S(0)
133 			| MATRIX_LANSECH_NS(1)
134 			| MATRIX_LANSECH_NS(2)
135 			| MATRIX_LANSECH_NS(3)
136 			| MATRIX_RDNSECH_S(0)
137 			| MATRIX_RDNSECH_NS(1)
138 			| MATRIX_RDNSECH_NS(2)
139 			| MATRIX_RDNSECH_NS(3)
140 			| MATRIX_WRNSECH_S(0)
141 			| MATRIX_WRNSECH_NS(1)
142 			| MATRIX_WRNSECH_NS(2)
143 			| MATRIX_WRNSECH_NS(3));
144 	/* DDR port 0 not used from NWd */
145 	for (ddr_port = 1; ddr_port < 8; ddr_port++) {
146 		matrix_configure_slave_security(matrix64_base(),
147 					(H64MX_SLAVE_DDR2_PORT_0 + ddr_port),
148 					srtop_setting,
149 					sasplit_setting,
150 					ssr_setting);
151 	}
152 
153 	/*
154 	 * 10: Internal SRAM 128K:
155 	 * - First 64K are reserved for suspend code in Secure World
156 	 * - Last 64K are for Non-Secure world (used by CAN)
157 	 */
158 	srtop_setting = MATRIX_SRTOP(0, MATRIX_SRTOP_VALUE_128K);
159 	sasplit_setting = MATRIX_SASPLIT(0, MATRIX_SRTOP_VALUE_64K);
160 	ssr_setting = (MATRIX_LANSECH_S(0) | MATRIX_RDNSECH_S(0) |
161 		       MATRIX_WRNSECH_S(0));
162 	matrix_configure_slave_security(matrix64_base(),
163 					H64MX_SLAVE_INTERNAL_SRAM,
164 					srtop_setting, sasplit_setting,
165 					ssr_setting);
166 
167 	/* 11:  Internal SRAM 128K (Cache L2): Default */
168 
169 	/* 12:  QSPI0: Normal world */
170 	/* 13:  QSPI1: Normal world */
171 	srtop_setting = MATRIX_SRTOP(0, MATRIX_SRTOP_VALUE_128M);
172 	sasplit_setting = MATRIX_SASPLIT(0, MATRIX_SASPLIT_VALUE_128M);
173 	ssr_setting = MATRIX_LANSECH_NS(0) | MATRIX_RDNSECH_NS(0) |
174 		      MATRIX_WRNSECH_NS(0);
175 
176 	matrix_configure_slave_security(matrix64_base(), H64MX_SLAVE_QSPI0,
177 					srtop_setting, sasplit_setting,
178 					ssr_setting);
179 	matrix_configure_slave_security(matrix64_base(), H64MX_SLAVE_QSPI1,
180 					srtop_setting, sasplit_setting,
181 					ssr_setting);
182 	/* 14:  AESB: Default */
183 }
184 
matrix_configure_slave_h32mx(void)185 static void matrix_configure_slave_h32mx(void)
186 {
187 	unsigned int ssr_setting;
188 	unsigned int sasplit_setting;
189 	unsigned int srtop_setting;
190 
191 	/* 0: Bridge from H32MX to H64MX: Not Secured */
192 	/* 1: H32MX Peripheral Bridge 0: Not Secured */
193 	/* 2: H32MX Peripheral Bridge 1: Not Secured */
194 
195 	/*
196 	 * 3: External Bus Interface
197 	 * EBI CS0 Memory(256M) ----> Slave Region 0, 1
198 	 * EBI CS1 Memory(256M) ----> Slave Region 2, 3
199 	 * EBI CS2 Memory(256M) ----> Slave Region 4, 5
200 	 * EBI CS3 Memory(128M) ----> Slave Region 6
201 	 * NFC Command Registers(128M) -->Slave Region 7
202 	 * NANDFlash(EBI CS3) --> Slave Region 6: Non-Secure
203 	 */
204 	srtop_setting =	MATRIX_SRTOP(6, MATRIX_SRTOP_VALUE_128M);
205 	srtop_setting |= MATRIX_SRTOP(7, MATRIX_SRTOP_VALUE_128M);
206 	sasplit_setting = MATRIX_SASPLIT(6, MATRIX_SASPLIT_VALUE_128M);
207 	sasplit_setting |= MATRIX_SASPLIT(7, MATRIX_SASPLIT_VALUE_128M);
208 	ssr_setting = (MATRIX_LANSECH_NS(6)
209 			| MATRIX_RDNSECH_NS(6)
210 			| MATRIX_WRNSECH_NS(6));
211 	ssr_setting |= (MATRIX_LANSECH_NS(7)
212 			| MATRIX_RDNSECH_NS(7)
213 			| MATRIX_WRNSECH_NS(7));
214 	matrix_configure_slave_security(matrix32_base(),
215 					H32MX_EXTERNAL_EBI,
216 					srtop_setting,
217 					sasplit_setting,
218 					ssr_setting);
219 
220 	/* 4: NFC SRAM (4K): Non-Secure */
221 	srtop_setting = MATRIX_SRTOP(0, MATRIX_SRTOP_VALUE_8K);
222 	sasplit_setting = MATRIX_SASPLIT(0, MATRIX_SASPLIT_VALUE_8K);
223 	ssr_setting = (MATRIX_LANSECH_NS(0)
224 			| MATRIX_RDNSECH_NS(0)
225 			| MATRIX_WRNSECH_NS(0));
226 	matrix_configure_slave_security(matrix32_base(),
227 					H32MX_NFC_SRAM,
228 					srtop_setting,
229 					sasplit_setting,
230 					ssr_setting);
231 
232 	/* 5:
233 	 * USB Device High Speed Dual Port RAM (DPR): 1M
234 	 * USB Host OHCI registers: 1M
235 	 * USB Host EHCI registers: 1M
236 	 */
237 	srtop_setting = (MATRIX_SRTOP(0, MATRIX_SRTOP_VALUE_1M)
238 			| MATRIX_SRTOP(1, MATRIX_SRTOP_VALUE_1M)
239 			| MATRIX_SRTOP(2, MATRIX_SRTOP_VALUE_1M));
240 	sasplit_setting = (MATRIX_SASPLIT(0, MATRIX_SASPLIT_VALUE_1M)
241 			| MATRIX_SASPLIT(1, MATRIX_SASPLIT_VALUE_1M)
242 			| MATRIX_SASPLIT(2, MATRIX_SASPLIT_VALUE_1M));
243 	ssr_setting = (MATRIX_LANSECH_NS(0)
244 			| MATRIX_LANSECH_NS(1)
245 			| MATRIX_LANSECH_NS(2)
246 			| MATRIX_RDNSECH_NS(0)
247 			| MATRIX_RDNSECH_NS(1)
248 			| MATRIX_RDNSECH_NS(2)
249 			| MATRIX_WRNSECH_NS(0)
250 			| MATRIX_WRNSECH_NS(1)
251 			| MATRIX_WRNSECH_NS(2));
252 	matrix_configure_slave_security(matrix32_base(),
253 					H32MX_USB,
254 					srtop_setting,
255 					sasplit_setting,
256 					ssr_setting);
257 }
258 
259 static unsigned int security_ps_peri_id[] = {
260 	AT91C_ID_PMC,
261 	AT91C_ID_ARM,
262 	AT91C_ID_PIT,
263 	AT91C_ID_WDT,
264 	AT91C_ID_GMAC,
265 	AT91C_ID_XDMAC0,
266 	AT91C_ID_XDMAC1,
267 	AT91C_ID_ICM,
268 	AT91C_ID_AES,
269 	AT91C_ID_AESB,
270 	AT91C_ID_TDES,
271 	AT91C_ID_SHA,
272 	AT91C_ID_MPDDRC,
273 	AT91C_ID_HSMC,
274 	AT91C_ID_FLEXCOM0,
275 	AT91C_ID_FLEXCOM1,
276 	AT91C_ID_FLEXCOM2,
277 	AT91C_ID_FLEXCOM3,
278 	AT91C_ID_FLEXCOM4,
279 	AT91C_ID_UART0,
280 	AT91C_ID_UART1,
281 	AT91C_ID_UART2,
282 	AT91C_ID_UART3,
283 	AT91C_ID_UART4,
284 	AT91C_ID_TWI0,
285 	AT91C_ID_TWI1,
286 	AT91C_ID_SDMMC0,
287 	AT91C_ID_SDMMC1,
288 	AT91C_ID_SPI0,
289 	AT91C_ID_SPI1,
290 	AT91C_ID_TC0,
291 	AT91C_ID_TC1,
292 	AT91C_ID_PWM,
293 	AT91C_ID_ADC,
294 	AT91C_ID_UHPHS,
295 	AT91C_ID_UDPHS,
296 	AT91C_ID_SSC0,
297 	AT91C_ID_SSC1,
298 	AT91C_ID_LCDC,
299 	AT91C_ID_ISI,
300 	AT91C_ID_TRNG,
301 	AT91C_ID_PDMIC,
302 	AT91C_ID_SFC,
303 	AT91C_ID_QSPI0,
304 	AT91C_ID_QSPI1,
305 	AT91C_ID_I2SC0,
306 	AT91C_ID_I2SC1,
307 	AT91C_ID_CAN0_INT0,
308 	AT91C_ID_CAN1_INT0,
309 	AT91C_ID_CLASSD,
310 	AT91C_ID_SFR,
311 	AT91C_ID_L2CC,
312 	AT91C_ID_CAN0_INT1,
313 	AT91C_ID_CAN1_INT1,
314 	AT91C_ID_GMAC_Q1,
315 	AT91C_ID_GMAC_Q2,
316 	AT91C_ID_SDMMC0_TIMER,
317 	AT91C_ID_SDMMC1_TIMER,
318 	AT91C_ID_SYS,
319 	AT91C_ID_ACC,
320 	AT91C_ID_RXLP,
321 	AT91C_ID_SFRBU,
322 	AT91C_ID_CHIPID,
323 };
324 
matrix_init(void)325 static int matrix_init(void)
326 {
327 	matrix_write_protect_disable(matrix64_base());
328 	matrix_write_protect_disable(matrix32_base());
329 
330 	matrix_configure_slave_h64mx();
331 	matrix_configure_slave_h32mx();
332 
333 	return matrix_configure_periph_non_secure(security_ps_peri_id,
334 					      ARRAY_SIZE(security_ps_peri_id));
335 }
336 
plat_primary_init_early(void)337 void plat_primary_init_early(void)
338 {
339 	matrix_init();
340 }
341 
itr_core_handler(void)342 void itr_core_handler(void)
343 {
344 	atmel_saic_it_handle();
345 }
346 
main_init_gic(void)347 void main_init_gic(void)
348 {
349 	if (atmel_saic_setup())
350 		panic("Failed to init interrupts\n");
351 }
352