xref: /rk3399_ARM-atf/plat/nvidia/tegra/soc/t186/plat_setup.c (revision f893160690725fe79c8eb63fd90a945cc0374d90)
1 /*
2  * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
3  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include <assert.h>
9 
10 #include <arch_helpers.h>
11 #include <bl31/bl31.h>
12 #include <bl31/interrupt_mgmt.h>
13 #include <common/bl_common.h>
14 #include <common/debug.h>
15 #include <common/interrupt_props.h>
16 #include <context.h>
17 #include <cortex_a57.h>
18 #include <denver.h>
19 #include <drivers/arm/gic_common.h>
20 #include <drivers/arm/gicv2.h>
21 #include <drivers/console.h>
22 #include <lib/el3_runtime/context_mgmt.h>
23 #include <lib/xlat_tables/xlat_tables_v2.h>
24 #include <plat/common/platform.h>
25 
26 #include <mce.h>
27 #include <tegra_def.h>
28 #include <tegra_platform.h>
29 #include <tegra_private.h>
30 
31 /*******************************************************************************
32  * Tegra186 CPU numbers in cluster #0
33  *******************************************************************************
34  */
35 #define TEGRA186_CLUSTER0_CORE2		2U
36 #define TEGRA186_CLUSTER0_CORE3		3U
37 
38 /*******************************************************************************
39  * The Tegra power domain tree has a single system level power domain i.e. a
40  * single root node. The first entry in the power domain descriptor specifies
41  * the number of power domains at the highest power level.
42  *******************************************************************************
43  */
44 static const uint8_t tegra_power_domain_tree_desc[] = {
45 	/* No of root nodes */
46 	1,
47 	/* No of clusters */
48 	PLATFORM_CLUSTER_COUNT,
49 	/* No of CPU cores - cluster0 */
50 	PLATFORM_MAX_CPUS_PER_CLUSTER,
51 	/* No of CPU cores - cluster1 */
52 	PLATFORM_MAX_CPUS_PER_CLUSTER
53 };
54 
55 /*******************************************************************************
56  * This function returns the Tegra default topology tree information.
57  ******************************************************************************/
58 const uint8_t *plat_get_power_domain_tree_desc(void)
59 {
60 	return tegra_power_domain_tree_desc;
61 }
62 
63 /*
64  * Table of regions to map using the MMU.
65  */
66 static const mmap_region_t tegra_mmap[] = {
67 	MAP_REGION_FLAT(TEGRA_MISC_BASE, 0x10000U, /* 64KB */
68 			MT_DEVICE | MT_RW | MT_SECURE),
69 	MAP_REGION_FLAT(TEGRA_TSA_BASE, 0x20000U, /* 128KB */
70 			MT_DEVICE | MT_RW | MT_SECURE),
71 	MAP_REGION_FLAT(TEGRA_MC_STREAMID_BASE, 0x10000U, /* 64KB */
72 			MT_DEVICE | MT_RW | MT_SECURE),
73 	MAP_REGION_FLAT(TEGRA_MC_BASE, 0x10000U, /* 64KB */
74 			MT_DEVICE | MT_RW | MT_SECURE),
75 	MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000U, /* 128KB - UART A, B*/
76 			MT_DEVICE | MT_RW | MT_SECURE),
77 	MAP_REGION_FLAT(TEGRA_UARTC_BASE, 0x20000U, /* 128KB - UART C, G */
78 			MT_DEVICE | MT_RW | MT_SECURE),
79 	MAP_REGION_FLAT(TEGRA_UARTD_BASE, 0x30000U, /* 192KB - UART D, E, F */
80 			MT_DEVICE | MT_RW | MT_SECURE),
81 	MAP_REGION_FLAT(TEGRA_FUSE_BASE, 0x10000U, /* 64KB */
82 			MT_DEVICE | MT_RW | MT_SECURE),
83 	MAP_REGION_FLAT(TEGRA_GICD_BASE, 0x20000U, /* 128KB */
84 			MT_DEVICE | MT_RW | MT_SECURE),
85 	MAP_REGION_FLAT(TEGRA_SE0_BASE, 0x10000U, /* 64KB */
86 			MT_DEVICE | MT_RW | MT_SECURE),
87 	MAP_REGION_FLAT(TEGRA_PKA1_BASE, 0x10000U, /* 64KB */
88 			MT_DEVICE | MT_RW | MT_SECURE),
89 	MAP_REGION_FLAT(TEGRA_RNG1_BASE, 0x10000U, /* 64KB */
90 			MT_DEVICE | MT_RW | MT_SECURE),
91 	MAP_REGION_FLAT(TEGRA_CAR_RESET_BASE, 0x10000U, /* 64KB */
92 			MT_DEVICE | MT_RW | MT_SECURE),
93 	MAP_REGION_FLAT(TEGRA_PMC_BASE, 0x40000U, /* 256KB */
94 			MT_DEVICE | MT_RW | MT_SECURE),
95 	MAP_REGION_FLAT(TEGRA_TMRUS_BASE, 0x1000U, /* 4KB */
96 			MT_DEVICE | MT_RO | MT_SECURE),
97 	MAP_REGION_FLAT(TEGRA_SCRATCH_BASE, 0x10000U, /* 64KB */
98 			MT_DEVICE | MT_RW | MT_SECURE),
99 	MAP_REGION_FLAT(TEGRA_MMCRAB_BASE, 0x60000U, /* 384KB */
100 			MT_DEVICE | MT_RW | MT_SECURE),
101 	MAP_REGION_FLAT(TEGRA_ARM_ACTMON_CTR_BASE, 0x20000U, /* 128KB - ARM/Denver */
102 			MT_DEVICE | MT_RW | MT_SECURE),
103 	MAP_REGION_FLAT(TEGRA_SMMU0_BASE, 0x1000000U, /* 64KB */
104 			MT_DEVICE | MT_RW | MT_SECURE),
105 	{0}
106 };
107 
108 /*******************************************************************************
109  * Set up the pagetables as per the platform memory map & initialize the MMU
110  ******************************************************************************/
111 const mmap_region_t *plat_get_mmio_map(void)
112 {
113 	/* MMIO space */
114 	return tegra_mmap;
115 }
116 
117 /*******************************************************************************
118  * Handler to get the System Counter Frequency
119  ******************************************************************************/
120 uint32_t plat_get_syscnt_freq2(void)
121 {
122 	return 31250000;
123 }
124 
125 /*******************************************************************************
126  * Maximum supported UART controllers
127  ******************************************************************************/
128 #define TEGRA186_MAX_UART_PORTS		7
129 
130 /*******************************************************************************
131  * This variable holds the UART port base addresses
132  ******************************************************************************/
133 static uint32_t tegra186_uart_addresses[TEGRA186_MAX_UART_PORTS + 1] = {
134 	0,	/* undefined - treated as an error case */
135 	TEGRA_UARTA_BASE,
136 	TEGRA_UARTB_BASE,
137 	TEGRA_UARTC_BASE,
138 	TEGRA_UARTD_BASE,
139 	TEGRA_UARTE_BASE,
140 	TEGRA_UARTF_BASE,
141 	TEGRA_UARTG_BASE,
142 };
143 
144 /*******************************************************************************
145  * Enable console corresponding to the console ID
146  ******************************************************************************/
147 void plat_enable_console(int32_t id)
148 {
149 	static console_16550_t uart_console;
150 	uint32_t console_clock;
151 
152 	if ((id > 0) && (id < TEGRA186_MAX_UART_PORTS)) {
153 		/*
154 		 * Reference clock used by the FPGAs is a lot slower.
155 		 */
156 		if (tegra_platform_is_fpga()) {
157 			console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
158 		} else {
159 			console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
160 		}
161 
162 		(void)console_16550_register(tegra186_uart_addresses[id],
163 					     console_clock,
164 					     TEGRA_CONSOLE_BAUDRATE,
165 					     &uart_console);
166 		console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT |
167 			CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
168 	}
169 }
170 
171 /*******************************************************************************
172  * Handler for early platform setup
173  ******************************************************************************/
174 void plat_early_platform_setup(void)
175 {
176 	uint64_t impl, val;
177 	const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
178 
179 	/* sanity check MCE firmware compatibility */
180 	mce_verify_firmware_version();
181 
182 	impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
183 
184 	/*
185 	 * Enable ECC and Parity Protection for Cortex-A57 CPUs (Tegra186
186 	 * A02p and beyond).
187 	 */
188 	if ((plat_params->l2_ecc_parity_prot_dis != 1) &&
189 	    (impl != (uint64_t)DENVER_IMPL)) {
190 
191 		val = read_l2ctlr_el1();
192 		val |= CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
193 		write_l2ctlr_el1(val);
194 	}
195 }
196 
197 /*******************************************************************************
198  * Handler for late platform setup
199  ******************************************************************************/
200 void plat_late_platform_setup(void)
201 {
202 	; /* do nothing */
203 }
204 
205 /* Secure IRQs for Tegra186 */
206 static const interrupt_prop_t tegra186_interrupt_props[] = {
207 	INTR_PROP_DESC(TEGRA186_TOP_WDT_IRQ, GIC_HIGHEST_SEC_PRIORITY,
208 			GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
209 	INTR_PROP_DESC(TEGRA186_AON_WDT_IRQ, GIC_HIGHEST_SEC_PRIORITY,
210 			GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE)
211 };
212 
213 /*******************************************************************************
214  * Initialize the GIC and SGIs
215  ******************************************************************************/
216 void plat_gic_setup(void)
217 {
218 	tegra_gic_setup(tegra186_interrupt_props, ARRAY_SIZE(tegra186_interrupt_props));
219 	tegra_gic_init();
220 
221 	/*
222 	 * Initialize the FIQ handler only if the platform supports any
223 	 * FIQ interrupt sources.
224 	 */
225 	tegra_fiq_handler_setup();
226 }
227 
228 /*******************************************************************************
229  * Return pointer to the BL31 params from previous bootloader
230  ******************************************************************************/
231 struct tegra_bl31_params *plat_get_bl31_params(void)
232 {
233 	uint32_t val;
234 
235 	val = mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_BL31_PARAMS_ADDR);
236 
237 	return (struct tegra_bl31_params *)(uintptr_t)val;
238 }
239 
240 /*******************************************************************************
241  * Return pointer to the BL31 platform params from previous bootloader
242  ******************************************************************************/
243 plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
244 {
245 	uint32_t val;
246 
247 	val = mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_BL31_PLAT_PARAMS_ADDR);
248 
249 	return (plat_params_from_bl2_t *)(uintptr_t)val;
250 }
251 
252 /*******************************************************************************
253  * This function implements a part of the critical interface between the psci
254  * generic layer and the platform that allows the former to query the platform
255  * to convert an MPIDR to a unique linear index. An error code (-1) is returned
256  * in case the MPIDR is invalid.
257  ******************************************************************************/
258 int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
259 {
260 	u_register_t cluster_id, cpu_id, pos;
261 	int32_t ret;
262 
263 	cluster_id = (mpidr >> (u_register_t)MPIDR_AFF1_SHIFT) & (u_register_t)MPIDR_AFFLVL_MASK;
264 	cpu_id = (mpidr >> (u_register_t)MPIDR_AFF0_SHIFT) & (u_register_t)MPIDR_AFFLVL_MASK;
265 
266 	/*
267 	 * Validate cluster_id by checking whether it represents
268 	 * one of the two clusters present on the platform.
269 	 * Validate cpu_id by checking whether it represents a CPU in
270 	 * one of the two clusters present on the platform.
271 	 */
272 	if ((cluster_id >= (u_register_t)PLATFORM_CLUSTER_COUNT) ||
273 	    (cpu_id >= (u_register_t)PLATFORM_MAX_CPUS_PER_CLUSTER)) {
274 		ret = PSCI_E_NOT_PRESENT;
275 	} else {
276 		/* calculate the core position */
277 		pos = cpu_id + (cluster_id << 2U);
278 
279 		/* check for non-existent CPUs */
280 		if ((pos == TEGRA186_CLUSTER0_CORE2) || (pos == TEGRA186_CLUSTER0_CORE3)) {
281 			ret = PSCI_E_NOT_PRESENT;
282 		} else {
283 			ret = (int32_t)pos;
284 		}
285 	}
286 
287 	return ret;
288 }
289