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