blob: 7ca65dd060df1fec3f9600d76e8111c7d60c65ce [file] [log] [blame]
Varun Wadekar41612552018-04-09 17:48:58 -07001/*
2 * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch_helpers.h>
8#include <assert.h>
9#include <bl31/bl31.h>
10#include <common/bl_common.h>
11#include <common/interrupt_props.h>
12#include <drivers/console.h>
13#include <context.h>
14#include <lib/el3_runtime/context_mgmt.h>
15#include <cortex_a57.h>
16#include <common/debug.h>
17#include <denver.h>
18#include <drivers/arm/gic_common.h>
19#include <drivers/arm/gicv2.h>
20#include <bl31/interrupt_mgmt.h>
21#include <mce.h>
22#include <plat/common/platform.h>
23#include <tegra_def.h>
24#include <tegra_platform.h>
25#include <tegra_private.h>
26#include <lib/xlat_tables/xlat_tables_v2.h>
27
28DEFINE_RENAME_SYSREG_RW_FUNCS(l2ctlr_el1, L2CTLR_EL1)
29extern uint64_t tegra_enable_l2_ecc_parity_prot;
30
31/*******************************************************************************
32 * The Tegra power domain tree has a single system level power domain i.e. a
33 * single root node. The first entry in the power domain descriptor specifies
34 * the number of power domains at the highest power level.
35 *******************************************************************************
36 */
37const unsigned char tegra_power_domain_tree_desc[] = {
38 /* No of root nodes */
39 1,
40 /* No of clusters */
41 PLATFORM_CLUSTER_COUNT,
42 /* No of CPU cores - cluster0 */
43 PLATFORM_MAX_CPUS_PER_CLUSTER,
44 /* No of CPU cores - cluster1 */
45 PLATFORM_MAX_CPUS_PER_CLUSTER
46};
47
Varun Wadekar42de0382017-04-28 08:45:53 -070048/*******************************************************************************
49 * This function returns the Tegra default topology tree information.
50 ******************************************************************************/
51const unsigned char *plat_get_power_domain_tree_desc(void)
52{
53 return tegra_power_domain_tree_desc;
54}
55
Varun Wadekar41612552018-04-09 17:48:58 -070056/*
57 * Table of regions to map using the MMU.
58 */
59static const mmap_region_t tegra_mmap[] = {
60 MAP_REGION_FLAT(TEGRA_MISC_BASE, 0x10000, /* 64KB */
61 MT_DEVICE | MT_RW | MT_SECURE),
62 MAP_REGION_FLAT(TEGRA_TSA_BASE, 0x20000, /* 128KB */
63 MT_DEVICE | MT_RW | MT_SECURE),
64 MAP_REGION_FLAT(TEGRA_MC_STREAMID_BASE, 0x10000, /* 64KB */
65 MT_DEVICE | MT_RW | MT_SECURE),
66 MAP_REGION_FLAT(TEGRA_MC_BASE, 0x10000, /* 64KB */
67 MT_DEVICE | MT_RW | MT_SECURE),
68 MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000, /* 128KB - UART A, B*/
69 MT_DEVICE | MT_RW | MT_SECURE),
70 MAP_REGION_FLAT(TEGRA_UARTC_BASE, 0x20000, /* 128KB - UART C, G */
71 MT_DEVICE | MT_RW | MT_SECURE),
72 MAP_REGION_FLAT(TEGRA_UARTD_BASE, 0x30000, /* 192KB - UART D, E, F */
73 MT_DEVICE | MT_RW | MT_SECURE),
74 MAP_REGION_FLAT(TEGRA_FUSE_BASE, 0x10000, /* 64KB */
75 MT_DEVICE | MT_RW | MT_SECURE),
76 MAP_REGION_FLAT(TEGRA_GICD_BASE, 0x20000, /* 128KB */
77 MT_DEVICE | MT_RW | MT_SECURE),
78 MAP_REGION_FLAT(TEGRA_SE0_BASE, 0x10000, /* 64KB */
79 MT_DEVICE | MT_RW | MT_SECURE),
80 MAP_REGION_FLAT(TEGRA_PKA1_BASE, 0x10000, /* 64KB */
81 MT_DEVICE | MT_RW | MT_SECURE),
82 MAP_REGION_FLAT(TEGRA_RNG1_BASE, 0x10000, /* 64KB */
83 MT_DEVICE | MT_RW | MT_SECURE),
84 MAP_REGION_FLAT(TEGRA_CAR_RESET_BASE, 0x10000, /* 64KB */
85 MT_DEVICE | MT_RW | MT_SECURE),
86 MAP_REGION_FLAT(TEGRA_PMC_BASE, 0x40000, /* 256KB */
87 MT_DEVICE | MT_RW | MT_SECURE),
88 MAP_REGION_FLAT(TEGRA_SCRATCH_BASE, 0x10000, /* 64KB */
89 MT_DEVICE | MT_RW | MT_SECURE),
90 MAP_REGION_FLAT(TEGRA_MMCRAB_BASE, 0x60000, /* 384KB */
91 MT_DEVICE | MT_RW | MT_SECURE),
Pritesh Raithatha0ea88812017-01-24 14:16:07 +053092 MAP_REGION_FLAT(TEGRA_SMMU0_BASE, 0x1000000, /* 64KB */
93 MT_DEVICE | MT_RW | MT_SECURE),
94 MAP_REGION_FLAT(TEGRA_SMMU1_BASE, 0x1000000, /* 64KB */
95 MT_DEVICE | MT_RW | MT_SECURE),
96 MAP_REGION_FLAT(TEGRA_SMMU2_BASE, 0x1000000, /* 64KB */
Varun Wadekar41612552018-04-09 17:48:58 -070097 MT_DEVICE | MT_RW | MT_SECURE),
98 {0}
99};
100
101/*******************************************************************************
102 * Set up the pagetables as per the platform memory map & initialize the MMU
103 ******************************************************************************/
104const mmap_region_t *plat_get_mmio_map(void)
105{
106 /* MMIO space */
107 return tegra_mmap;
108}
109
110/*******************************************************************************
111 * Handler to get the System Counter Frequency
112 ******************************************************************************/
113unsigned int plat_get_syscnt_freq2(void)
114{
115 return 31250000;
116}
117
118/*******************************************************************************
119 * Maximum supported UART controllers
120 ******************************************************************************/
121#define TEGRA186_MAX_UART_PORTS 7
122
123/*******************************************************************************
124 * This variable holds the UART port base addresses
125 ******************************************************************************/
126static uint32_t tegra186_uart_addresses[TEGRA186_MAX_UART_PORTS + 1] = {
127 0, /* undefined - treated as an error case */
128 TEGRA_UARTA_BASE,
129 TEGRA_UARTB_BASE,
130 TEGRA_UARTC_BASE,
131 TEGRA_UARTD_BASE,
132 TEGRA_UARTE_BASE,
133 TEGRA_UARTF_BASE,
134 TEGRA_UARTG_BASE,
135};
136
137/*******************************************************************************
138 * Retrieve the UART controller base to be used as the console
139 ******************************************************************************/
140uint32_t plat_get_console_from_id(int id)
141{
142 if (id > TEGRA186_MAX_UART_PORTS)
143 return 0;
144
145 return tegra186_uart_addresses[id];
146}
147
148/* represent chip-version as concatenation of major (15:12), minor (11:8) and subrev (7:0) */
149#define TEGRA186_VER_A02P 0x1201
150
151/*******************************************************************************
152 * Handler for early platform setup
153 ******************************************************************************/
154void plat_early_platform_setup(void)
155{
156 int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
157 uint32_t chip_subrev, val;
158
159 /* sanity check MCE firmware compatibility */
160 mce_verify_firmware_version();
161
162 /*
163 * Enable ECC and Parity Protection for Cortex-A57 CPUs
164 * for Tegra A02p SKUs
165 */
166 if (impl != DENVER_IMPL) {
167
168 /* get the major, minor and sub-version values */
169 chip_subrev = mmio_read_32(TEGRA_FUSE_BASE + OPT_SUBREVISION) &
170 SUBREVISION_MASK;
171
172 /* prepare chip version number */
173 val = (tegra_get_chipid_major() << 12) |
174 (tegra_get_chipid_minor() << 8) |
175 chip_subrev;
176
177 /* enable L2 ECC for Tegra186 A02P and beyond */
178 if (val >= TEGRA186_VER_A02P) {
179
180 val = read_l2ctlr_el1();
181 val |= L2_ECC_PARITY_PROTECTION_BIT;
182 write_l2ctlr_el1(val);
183
184 /*
185 * Set the flag to enable ECC/Parity Protection
186 * when we exit System Suspend or Cluster Powerdn
187 */
188 tegra_enable_l2_ecc_parity_prot = 1;
189 }
190 }
191}
192
193/* Secure IRQs for Tegra186 */
194static const irq_sec_cfg_t tegra186_sec_irqs[] = {
195 [0] = {
196 TEGRA186_BPMP_WDT_IRQ,
197 TEGRA186_SEC_IRQ_TARGET_MASK,
198 INTR_TYPE_EL3,
199 },
200 [1] = {
201 TEGRA186_BPMP_WDT_IRQ,
202 TEGRA186_SEC_IRQ_TARGET_MASK,
203 INTR_TYPE_EL3,
204 },
205 [2] = {
206 TEGRA186_SPE_WDT_IRQ,
207 TEGRA186_SEC_IRQ_TARGET_MASK,
208 INTR_TYPE_EL3,
209 },
210 [3] = {
211 TEGRA186_SCE_WDT_IRQ,
212 TEGRA186_SEC_IRQ_TARGET_MASK,
213 INTR_TYPE_EL3,
214 },
215 [4] = {
216 TEGRA186_TOP_WDT_IRQ,
217 TEGRA186_SEC_IRQ_TARGET_MASK,
218 INTR_TYPE_EL3,
219 },
220 [5] = {
221 TEGRA186_AON_WDT_IRQ,
222 TEGRA186_SEC_IRQ_TARGET_MASK,
223 INTR_TYPE_EL3,
224 },
225};
226
227/*******************************************************************************
228 * Initialize the GIC and SGIs
229 ******************************************************************************/
230void plat_gic_setup(void)
231{
232 tegra_gic_setup(tegra186_sec_irqs,
233 sizeof(tegra186_sec_irqs) / sizeof(tegra186_sec_irqs[0]));
234
235 /*
236 * Initialize the FIQ handler only if the platform supports any
237 * FIQ interrupt sources.
238 */
239 if (sizeof(tegra186_sec_irqs) > 0)
240 tegra_fiq_handler_setup();
241}
242
243/*******************************************************************************
244 * Return pointer to the BL31 params from previous bootloader
245 ******************************************************************************/
246struct tegra_bl31_params *plat_get_bl31_params(void)
247{
248 uint32_t val;
249
250 val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_LO);
251
252 return (struct tegra_bl31_params *)(uintptr_t)val;
253}
254
255/*******************************************************************************
256 * Return pointer to the BL31 platform params from previous bootloader
257 ******************************************************************************/
258plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
259{
260 uint32_t val;
261
262 val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_HI);
263
264 return (plat_params_from_bl2_t *)(uintptr_t)val;
265}