• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <stdbool.h>
9 
10 #include <platform_def.h>
11 
12 #include <arch_helpers.h>
13 #include <context.h>
14 #include <common/bl_common.h>
15 #include <common/debug.h>
16 #include <drivers/arm/cci.h>
17 #include <drivers/console.h>
18 #include <lib/el3_runtime/context_mgmt.h>
19 #include <lib/mmio.h>
20 #include <lib/xlat_tables/xlat_tables.h>
21 #include <plat/common/platform.h>
22 
23 #include <imx8qm_pads.h>
24 #include <imx8_iomux.h>
25 #include <imx8_lpuart.h>
26 #include <plat_imx8.h>
27 #include <sci/sci.h>
28 #include <sec_rsrc.h>
29 
30 static const unsigned long BL31_COHERENT_RAM_START	= BL_COHERENT_RAM_BASE;
31 static const unsigned long BL31_COHERENT_RAM_END	= BL_COHERENT_RAM_END;
32 static const unsigned long BL31_RO_START		= BL_CODE_BASE;
33 static const unsigned long BL31_RO_END			= BL_CODE_END;
34 static const unsigned long BL31_RW_END			= BL_END;
35 
36 IMPORT_SYM(unsigned long, __RW_START__, BL31_RW_START);
37 
38 static entry_point_info_t bl32_image_ep_info;
39 static entry_point_info_t bl33_image_ep_info;
40 
41 #define UART_PAD_CTRL	(PADRING_IFMUX_EN_MASK | PADRING_GP_EN_MASK | \
42 			(SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \
43 			(SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \
44 			(SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | \
45 			(SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT))
46 
47 #if defined(IMX_USE_UART0)
48 #define IMX_RES_UART			SC_R_UART_0
49 #define IMX_PAD_UART_RX			SC_P_UART0_RX
50 #define IMX_PAD_UART_TX			SC_P_UART0_TX
51 #define IMX_PAD_UART_RTS_B		SC_P_UART0_RTS_B
52 #define IMX_PAD_UART_CTS_B		SC_P_UART0_CTS_B
53 #elif defined(IMX_USE_UART1)
54 #define IMX_RES_UART			SC_R_UART_1
55 #define IMX_PAD_UART_RX			SC_P_UART1_RX
56 #define IMX_PAD_UART_TX			SC_P_UART1_TX
57 #define IMX_PAD_UART_RTS_B		SC_P_UART1_RTS_B
58 #define IMX_PAD_UART_CTS_B		SC_P_UART1_CTS_B
59 #else
60 #error "Provide proper UART number in IMX_DEBUG_UART"
61 #endif
62 
63 const static int imx8qm_cci_map[] = {
64 	CLUSTER0_CCI_SLVAE_IFACE,
65 	CLUSTER1_CCI_SLVAE_IFACE
66 };
67 
68 static const mmap_region_t imx_mmap[] = {
69 	MAP_REGION_FLAT(IMX_REG_BASE, IMX_REG_SIZE, MT_DEVICE | MT_RW),
70 	{0}
71 };
72 
get_spsr_for_bl33_entry(void)73 static uint32_t get_spsr_for_bl33_entry(void)
74 {
75 	unsigned long el_status;
76 	unsigned long mode;
77 	uint32_t spsr;
78 
79 	/* figure out what mode we enter the non-secure world */
80 	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
81 	el_status &= ID_AA64PFR0_ELX_MASK;
82 
83 	mode = (el_status) ? MODE_EL2 : MODE_EL1;
84 	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
85 
86 	return spsr;
87 }
88 
89 #if DEBUG_CONSOLE_A53
lpuart32_serial_setbrg(unsigned int base,int baudrate)90 static void lpuart32_serial_setbrg(unsigned int base, int baudrate)
91 {
92 	unsigned int sbr, osr, baud_diff, tmp_osr, tmp_sbr;
93 	unsigned int diff1, diff2, tmp, rate;
94 
95 	if (baudrate == 0)
96 		panic();
97 
98 	sc_pm_get_clock_rate(ipc_handle, IMX_RES_UART, 2, &rate);
99 
100 	baud_diff = baudrate;
101 	osr = 0;
102 	sbr = 0;
103 	for (tmp_osr = 4; tmp_osr <= 32; tmp_osr++) {
104 		tmp_sbr = (rate / (baudrate * tmp_osr));
105 		if (tmp_sbr == 0)
106 			tmp_sbr = 1;
107 
108 		/* calculate difference in actual baud w/ current values */
109 		diff1 = rate / (tmp_osr * tmp_sbr) - baudrate;
110 		diff2 = rate / (tmp_osr * (tmp_sbr + 1));
111 
112 		/* select best values between sbr and sbr+1 */
113 		if (diff1 > (baudrate - diff2)) {
114 			diff1 = baudrate - diff2;
115 			tmp_sbr++;
116 		}
117 
118 		if (diff1 <= baud_diff) {
119 			baud_diff = diff1;
120 			osr = tmp_osr;
121 			sbr = tmp_sbr;
122 		}
123 	}
124 
125 	tmp = mmio_read_32(IMX_BOOT_UART_BASE + BAUD);
126 
127 	if ((osr > 3) && (osr < 8))
128 		tmp |= LPUART_BAUD_BOTHEDGE_MASK;
129 
130 	tmp &= ~LPUART_BAUD_OSR_MASK;
131 	tmp |= LPUART_BAUD_OSR(osr - 1);
132 	tmp &= ~LPUART_BAUD_SBR_MASK;
133 	tmp |= LPUART_BAUD_SBR(sbr);
134 
135 	/* explicitly disable 10 bit mode & set 1 stop bit */
136 	tmp &= ~(LPUART_BAUD_M10_MASK | LPUART_BAUD_SBNS_MASK);
137 
138 	mmio_write_32(IMX_BOOT_UART_BASE + BAUD, tmp);
139 }
140 
lpuart32_serial_init(unsigned int base)141 static int lpuart32_serial_init(unsigned int base)
142 {
143 	unsigned int tmp;
144 
145 	/* disable TX & RX before enabling clocks */
146 	tmp = mmio_read_32(IMX_BOOT_UART_BASE + CTRL);
147 	tmp &= ~(CTRL_TE | CTRL_RE);
148 	mmio_write_32(IMX_BOOT_UART_BASE + CTRL, tmp);
149 
150 	mmio_write_32(IMX_BOOT_UART_BASE + MODIR, 0);
151 	mmio_write_32(IMX_BOOT_UART_BASE + FIFO, ~(FIFO_TXFE | FIFO_RXFE));
152 
153 	mmio_write_32(IMX_BOOT_UART_BASE + MATCH, 0);
154 
155 	/* provide data bits, parity, stop bit, etc */
156 	lpuart32_serial_setbrg(base, IMX_BOOT_UART_BAUDRATE);
157 
158 	/* eight data bits no parity bit */
159 	tmp = mmio_read_32(IMX_BOOT_UART_BASE + CTRL);
160 	tmp &= ~(LPUART_CTRL_PE_MASK | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK);
161 	mmio_write_32(IMX_BOOT_UART_BASE + CTRL, tmp);
162 
163 	mmio_write_32(IMX_BOOT_UART_BASE + CTRL, CTRL_RE | CTRL_TE);
164 
165 	mmio_write_32(IMX_BOOT_UART_BASE + DATA, 0x55);
166 	mmio_write_32(IMX_BOOT_UART_BASE + DATA, 0x55);
167 	mmio_write_32(IMX_BOOT_UART_BASE + DATA, 0x0A);
168 
169 	return 0;
170 }
171 #endif
172 
mx8_partition_resources(void)173 void mx8_partition_resources(void)
174 {
175 	sc_rm_pt_t secure_part, os_part;
176 	sc_rm_mr_t mr, mr_record = 64;
177 	sc_faddr_t start, end;
178 	bool owned, owned2;
179 	sc_err_t err;
180 	int i;
181 
182 	err = sc_rm_get_partition(ipc_handle, &secure_part);
183 
184 	err = sc_rm_partition_alloc(ipc_handle, &os_part, false, false,
185 		false, false, false);
186 
187 	err = sc_rm_set_parent(ipc_handle, os_part, secure_part);
188 
189 	/* set secure resources to NOT-movable */
190 	for (i = 0; i < ARRAY_SIZE(secure_rsrcs); i++) {
191 		err = sc_rm_set_resource_movable(ipc_handle, secure_rsrcs[i],
192 			secure_rsrcs[i], false);
193 		if (err)
194 			ERROR("sc_rm_set_resource_movable: rsrc %u, ret %u\n",
195 				secure_rsrcs[i], err);
196 	}
197 
198 	owned = sc_rm_is_resource_owned(ipc_handle, SC_R_M4_0_PID0);
199 	if (owned) {
200 		err = sc_rm_set_resource_movable(ipc_handle, SC_R_M4_0_PID0,
201 				SC_R_M4_0_PID0, false);
202 		if (err)
203 			ERROR("sc_rm_set_resource_movable: rsrc %u, ret %u\n",
204 				SC_R_M4_0_PID0, err);
205 	}
206 
207 	owned2 = sc_rm_is_resource_owned(ipc_handle, SC_R_M4_1_PID0);
208 	if (owned2) {
209 		err = sc_rm_set_resource_movable(ipc_handle, SC_R_M4_1_PID0,
210 				SC_R_M4_1_PID0, false);
211 		if (err)
212 			ERROR("sc_rm_set_resource_movable: rsrc %u, ret %u\n",
213 				SC_R_M4_1_PID0, err);
214 	}
215 	/* move all movable resources and pins to non-secure partition */
216 	err = sc_rm_move_all(ipc_handle, secure_part, os_part, true, true);
217 	if (err)
218 		ERROR("sc_rm_move_all: %u\n", err);
219 
220 	/* iterate through peripherals to give NS OS part access */
221 	for (i = 0; i < ARRAY_SIZE(ns_access_allowed); i++) {
222 		err = sc_rm_set_peripheral_permissions(ipc_handle, ns_access_allowed[i],
223 			os_part, SC_RM_PERM_FULL);
224 		if (err)
225 			ERROR("sc_rm_set_peripheral_permissions: rsrc %u, \
226 				ret %u\n", ns_access_allowed[i], err);
227 	}
228 
229 	if (owned) {
230 		err = sc_rm_set_resource_movable(ipc_handle, SC_R_M4_0_PID0,
231 				SC_R_M4_0_PID0, true);
232 		if (err)
233 			ERROR("sc_rm_set_resource_movable: rsrc %u, ret %u\n",
234 				SC_R_M4_0_PID0, err);
235 		err = sc_rm_assign_resource(ipc_handle, os_part, SC_R_M4_0_PID0);
236 		if (err)
237 			ERROR("sc_rm_assign_resource: rsrc %u, ret %u\n",
238 				SC_R_M4_0_PID0, err);
239 	}
240 	if (owned2) {
241 		err = sc_rm_set_resource_movable(ipc_handle, SC_R_M4_1_PID0,
242 				SC_R_M4_1_PID0, true);
243 		if (err)
244 			ERROR("sc_rm_set_resource_movable: rsrc %u, ret %u\n",
245 				SC_R_M4_1_PID0, err);
246 		err = sc_rm_assign_resource(ipc_handle, os_part, SC_R_M4_1_PID0);
247 		if (err)
248 			ERROR("sc_rm_assign_resource: rsrc %u, ret %u\n",
249 				SC_R_M4_1_PID0, err);
250 	}
251 
252 	/*
253 	 * sc_rm_set_peripheral_permissions
254 	 * sc_rm_set_memreg_permissions
255 	 * sc_rm_set_pin_movable
256 	 */
257 
258 	for (mr = 0; mr < 64; mr++) {
259 		owned = sc_rm_is_memreg_owned(ipc_handle, mr);
260 		if (owned) {
261 			err = sc_rm_get_memreg_info(ipc_handle, mr, &start, &end);
262 			if (err)
263 				ERROR("Memreg get info failed, %u\n", mr);
264 			NOTICE("Memreg %u 0x%llx -- 0x%llx\n", mr, start, end);
265 			if (BL31_BASE >= start && (BL31_LIMIT - 1) <= end) {
266 				mr_record = mr; /* Record the mr for ATF running */
267 			} else {
268 				err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
269 				if (err)
270 					ERROR("Memreg assign failed, 0x%llx -- 0x%llx, \
271 						err %d\n", start, end, err);
272 			}
273 		}
274 	}
275 
276 	if (mr_record != 64) {
277 		err = sc_rm_get_memreg_info(ipc_handle, mr_record, &start, &end);
278 		if (err)
279 			ERROR("Memreg get info failed, %u\n", mr_record);
280 		if ((BL31_LIMIT - 1) < end) {
281 			err = sc_rm_memreg_alloc(ipc_handle, &mr, BL31_LIMIT, end);
282 			if (err)
283 				ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n",
284 					(sc_faddr_t)BL31_LIMIT, end);
285 			err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
286 			if (err)
287 				ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n",
288 					(sc_faddr_t)BL31_LIMIT, end);
289 		}
290 
291 		if (start < (BL31_BASE - 1)) {
292 			err = sc_rm_memreg_alloc(ipc_handle, &mr, start, BL31_BASE - 1);
293 			if (err)
294 				ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n",
295 					start, (sc_faddr_t)BL31_BASE - 1);
296 			err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
297 				if (err)
298 					ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n",
299 						start, (sc_faddr_t)BL31_BASE - 1);
300 		}
301 	}
302 
303 	if (err)
304 		NOTICE("Partitioning Failed\n");
305 	else
306 		NOTICE("Non-secure Partitioning Succeeded\n");
307 
308 }
309 
bl31_early_platform_setup2(u_register_t arg0,u_register_t arg1,u_register_t arg2,u_register_t arg3)310 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
311 				u_register_t arg2, u_register_t arg3)
312 {
313 #if DEBUG_CONSOLE
314 	static console_t console;
315 #endif
316 	if (sc_ipc_open(&ipc_handle, SC_IPC_BASE) != SC_ERR_NONE)
317 		panic();
318 
319 #if DEBUG_CONSOLE_A53
320 	sc_pm_set_resource_power_mode(ipc_handle, IMX_RES_UART,
321 				      SC_PM_PW_MODE_ON);
322 	sc_pm_clock_rate_t rate = 80000000;
323 	sc_pm_set_clock_rate(ipc_handle, IMX_RES_UART, 2, &rate);
324 	sc_pm_clock_enable(ipc_handle, IMX_RES_UART, 2, true, false);
325 
326 	/* configure UART pads */
327 	sc_pad_set(ipc_handle, IMX_PAD_UART_RX, UART_PAD_CTRL);
328 	sc_pad_set(ipc_handle, IMX_PAD_UART_TX, UART_PAD_CTRL);
329 	sc_pad_set(ipc_handle, IMX_PAD_UART_RTS_B, UART_PAD_CTRL);
330 	sc_pad_set(ipc_handle, IMX_PAD_UART_CTS_B, UART_PAD_CTRL);
331 	lpuart32_serial_init(IMX_BOOT_UART_BASE);
332 #endif
333 
334 #if DEBUG_CONSOLE
335 	console_lpuart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
336 		     IMX_CONSOLE_BAUDRATE, &console);
337 #endif
338 
339 	/* turn on MU1 for non-secure OS/Hypervisor */
340 	sc_pm_set_resource_power_mode(ipc_handle, SC_R_MU_1A, SC_PM_PW_MODE_ON);
341 	/* Turn on GPT_0's power & clock for non-secure OS/Hypervisor */
342 	sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_ON);
343 	sc_pm_clock_enable(ipc_handle, SC_R_GPT_0, SC_PM_CLK_PER, true, 0);
344 	mmio_write_32(IMX_GPT_LPCG_BASE, mmio_read_32(IMX_GPT_LPCG_BASE) | (1 << 25));
345 
346 	/*
347 	 * create new partition for non-secure OS/Hypervisor
348 	 * uses global structs defined in sec_rsrc.h
349 	 */
350 	mx8_partition_resources();
351 
352 	bl33_image_ep_info.pc = PLAT_NS_IMAGE_OFFSET;
353 	bl33_image_ep_info.spsr = get_spsr_for_bl33_entry();
354 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
355 
356 	/* init the first cluster's cci slave interface */
357 	cci_init(PLAT_CCI_BASE, imx8qm_cci_map, PLATFORM_CLUSTER_COUNT);
358 	cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1()));
359 }
360 
bl31_plat_arch_setup(void)361 void bl31_plat_arch_setup(void)
362 {
363 	unsigned long ro_start = BL31_RO_START;
364 	unsigned long ro_size = BL31_RO_END - BL31_RO_START;
365 	unsigned long rw_start = BL31_RW_START;
366 	unsigned long rw_size = BL31_RW_END - BL31_RW_START;
367 #if USE_COHERENT_MEM
368 	unsigned long coh_start = BL31_COHERENT_RAM_START;
369 	unsigned long coh_size = BL31_COHERENT_RAM_END - BL31_COHERENT_RAM_START;
370 #endif
371 
372 	mmap_add_region(ro_start, ro_start, ro_size,
373 		MT_RO | MT_MEMORY | MT_SECURE);
374 	mmap_add_region(rw_start, rw_start, rw_size,
375 		MT_RW | MT_MEMORY | MT_SECURE);
376 	mmap_add(imx_mmap);
377 
378 #if USE_COHERENT_MEM
379 	mmap_add_region(coh_start, coh_start, coh_size,
380 			MT_DEVICE | MT_RW | MT_SECURE);
381 #endif
382 
383 	/* setup xlat table */
384 	init_xlat_tables();
385 	/* enable the MMU */
386 	enable_mmu_el3(0);
387 }
388 
bl31_platform_setup(void)389 void bl31_platform_setup(void)
390 {
391 	plat_gic_driver_init();
392 	plat_gic_init();
393 }
394 
bl31_plat_get_next_image_ep_info(unsigned int type)395 entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
396 {
397 	if (type == NON_SECURE)
398 		return &bl33_image_ep_info;
399 	if (type == SECURE)
400 		return &bl32_image_ep_info;
401 
402 	return NULL;
403 }
404 
plat_get_syscnt_freq2(void)405 unsigned int plat_get_syscnt_freq2(void)
406 {
407 	return COUNTER_FREQUENCY;
408 }
409 
bl31_plat_runtime_setup(void)410 void bl31_plat_runtime_setup(void)
411 {
412 	return;
413 }
414