xref: /rk3399_ARM-atf/plat/nvidia/tegra/soc/t194/plat_setup.c (revision 0ea8881ea3c776491ab9b1326798b1283f0cec1f)
141612559SVarun Wadekar /*
241612559SVarun Wadekar  * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
341612559SVarun Wadekar  *
441612559SVarun Wadekar  * SPDX-License-Identifier: BSD-3-Clause
541612559SVarun Wadekar  */
641612559SVarun Wadekar 
741612559SVarun Wadekar #include <arch_helpers.h>
841612559SVarun Wadekar #include <assert.h>
941612559SVarun Wadekar #include <bl31/bl31.h>
1041612559SVarun Wadekar #include <common/bl_common.h>
1141612559SVarun Wadekar #include <common/interrupt_props.h>
1241612559SVarun Wadekar #include <drivers/console.h>
1341612559SVarun Wadekar #include <context.h>
1441612559SVarun Wadekar #include <lib/el3_runtime/context_mgmt.h>
1541612559SVarun Wadekar #include <cortex_a57.h>
1641612559SVarun Wadekar #include <common/debug.h>
1741612559SVarun Wadekar #include <denver.h>
1841612559SVarun Wadekar #include <drivers/arm/gic_common.h>
1941612559SVarun Wadekar #include <drivers/arm/gicv2.h>
2041612559SVarun Wadekar #include <bl31/interrupt_mgmt.h>
2141612559SVarun Wadekar #include <mce.h>
2241612559SVarun Wadekar #include <plat/common/platform.h>
2341612559SVarun Wadekar #include <tegra_def.h>
2441612559SVarun Wadekar #include <tegra_platform.h>
2541612559SVarun Wadekar #include <tegra_private.h>
2641612559SVarun Wadekar #include <lib/xlat_tables/xlat_tables_v2.h>
2741612559SVarun Wadekar 
2841612559SVarun Wadekar DEFINE_RENAME_SYSREG_RW_FUNCS(l2ctlr_el1, L2CTLR_EL1)
2941612559SVarun Wadekar extern uint64_t tegra_enable_l2_ecc_parity_prot;
3041612559SVarun Wadekar 
3141612559SVarun Wadekar /*******************************************************************************
3241612559SVarun Wadekar  * The Tegra power domain tree has a single system level power domain i.e. a
3341612559SVarun Wadekar  * single root node. The first entry in the power domain descriptor specifies
3441612559SVarun Wadekar  * the number of power domains at the highest power level.
3541612559SVarun Wadekar  *******************************************************************************
3641612559SVarun Wadekar  */
3741612559SVarun Wadekar const unsigned char tegra_power_domain_tree_desc[] = {
3841612559SVarun Wadekar 	/* No of root nodes */
3941612559SVarun Wadekar 	1,
4041612559SVarun Wadekar 	/* No of clusters */
4141612559SVarun Wadekar 	PLATFORM_CLUSTER_COUNT,
4241612559SVarun Wadekar 	/* No of CPU cores - cluster0 */
4341612559SVarun Wadekar 	PLATFORM_MAX_CPUS_PER_CLUSTER,
4441612559SVarun Wadekar 	/* No of CPU cores - cluster1 */
4541612559SVarun Wadekar 	PLATFORM_MAX_CPUS_PER_CLUSTER
4641612559SVarun Wadekar };
4741612559SVarun Wadekar 
4841612559SVarun Wadekar /*
4941612559SVarun Wadekar  * Table of regions to map using the MMU.
5041612559SVarun Wadekar  */
5141612559SVarun Wadekar static const mmap_region_t tegra_mmap[] = {
5241612559SVarun Wadekar 	MAP_REGION_FLAT(TEGRA_MISC_BASE, 0x10000, /* 64KB */
5341612559SVarun Wadekar 			MT_DEVICE | MT_RW | MT_SECURE),
5441612559SVarun Wadekar 	MAP_REGION_FLAT(TEGRA_TSA_BASE, 0x20000, /* 128KB */
5541612559SVarun Wadekar 			MT_DEVICE | MT_RW | MT_SECURE),
5641612559SVarun Wadekar 	MAP_REGION_FLAT(TEGRA_MC_STREAMID_BASE, 0x10000, /* 64KB */
5741612559SVarun Wadekar 			MT_DEVICE | MT_RW | MT_SECURE),
5841612559SVarun Wadekar 	MAP_REGION_FLAT(TEGRA_MC_BASE, 0x10000, /* 64KB */
5941612559SVarun Wadekar 			MT_DEVICE | MT_RW | MT_SECURE),
6041612559SVarun Wadekar 	MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000, /* 128KB - UART A, B*/
6141612559SVarun Wadekar 			MT_DEVICE | MT_RW | MT_SECURE),
6241612559SVarun Wadekar 	MAP_REGION_FLAT(TEGRA_UARTC_BASE, 0x20000, /* 128KB - UART C, G */
6341612559SVarun Wadekar 			MT_DEVICE | MT_RW | MT_SECURE),
6441612559SVarun Wadekar 	MAP_REGION_FLAT(TEGRA_UARTD_BASE, 0x30000, /* 192KB - UART D, E, F */
6541612559SVarun Wadekar 			MT_DEVICE | MT_RW | MT_SECURE),
6641612559SVarun Wadekar 	MAP_REGION_FLAT(TEGRA_FUSE_BASE, 0x10000, /* 64KB */
6741612559SVarun Wadekar 			MT_DEVICE | MT_RW | MT_SECURE),
6841612559SVarun Wadekar 	MAP_REGION_FLAT(TEGRA_GICD_BASE, 0x20000, /* 128KB */
6941612559SVarun Wadekar 			MT_DEVICE | MT_RW | MT_SECURE),
7041612559SVarun Wadekar 	MAP_REGION_FLAT(TEGRA_SE0_BASE, 0x10000, /* 64KB */
7141612559SVarun Wadekar 			MT_DEVICE | MT_RW | MT_SECURE),
7241612559SVarun Wadekar 	MAP_REGION_FLAT(TEGRA_PKA1_BASE, 0x10000, /* 64KB */
7341612559SVarun Wadekar 			MT_DEVICE | MT_RW | MT_SECURE),
7441612559SVarun Wadekar 	MAP_REGION_FLAT(TEGRA_RNG1_BASE, 0x10000, /* 64KB */
7541612559SVarun Wadekar 			MT_DEVICE | MT_RW | MT_SECURE),
7641612559SVarun Wadekar 	MAP_REGION_FLAT(TEGRA_CAR_RESET_BASE, 0x10000, /* 64KB */
7741612559SVarun Wadekar 			MT_DEVICE | MT_RW | MT_SECURE),
7841612559SVarun Wadekar 	MAP_REGION_FLAT(TEGRA_PMC_BASE, 0x40000, /* 256KB */
7941612559SVarun Wadekar 			MT_DEVICE | MT_RW | MT_SECURE),
8041612559SVarun Wadekar 	MAP_REGION_FLAT(TEGRA_SCRATCH_BASE, 0x10000, /* 64KB */
8141612559SVarun Wadekar 			MT_DEVICE | MT_RW | MT_SECURE),
8241612559SVarun Wadekar 	MAP_REGION_FLAT(TEGRA_MMCRAB_BASE, 0x60000, /* 384KB */
8341612559SVarun Wadekar 			MT_DEVICE | MT_RW | MT_SECURE),
84*0ea8881eSPritesh Raithatha 	MAP_REGION_FLAT(TEGRA_SMMU0_BASE, 0x1000000, /* 64KB */
85*0ea8881eSPritesh Raithatha 			MT_DEVICE | MT_RW | MT_SECURE),
86*0ea8881eSPritesh Raithatha 	MAP_REGION_FLAT(TEGRA_SMMU1_BASE, 0x1000000, /* 64KB */
87*0ea8881eSPritesh Raithatha 			MT_DEVICE | MT_RW | MT_SECURE),
88*0ea8881eSPritesh Raithatha 	MAP_REGION_FLAT(TEGRA_SMMU2_BASE, 0x1000000, /* 64KB */
8941612559SVarun Wadekar 			MT_DEVICE | MT_RW | MT_SECURE),
9041612559SVarun Wadekar 	{0}
9141612559SVarun Wadekar };
9241612559SVarun Wadekar 
9341612559SVarun Wadekar /*******************************************************************************
9441612559SVarun Wadekar  * Set up the pagetables as per the platform memory map & initialize the MMU
9541612559SVarun Wadekar  ******************************************************************************/
9641612559SVarun Wadekar const mmap_region_t *plat_get_mmio_map(void)
9741612559SVarun Wadekar {
9841612559SVarun Wadekar 	/* MMIO space */
9941612559SVarun Wadekar 	return tegra_mmap;
10041612559SVarun Wadekar }
10141612559SVarun Wadekar 
10241612559SVarun Wadekar /*******************************************************************************
10341612559SVarun Wadekar  * Handler to get the System Counter Frequency
10441612559SVarun Wadekar  ******************************************************************************/
10541612559SVarun Wadekar unsigned int plat_get_syscnt_freq2(void)
10641612559SVarun Wadekar {
10741612559SVarun Wadekar 	return 31250000;
10841612559SVarun Wadekar }
10941612559SVarun Wadekar 
11041612559SVarun Wadekar /*******************************************************************************
11141612559SVarun Wadekar  * Maximum supported UART controllers
11241612559SVarun Wadekar  ******************************************************************************/
11341612559SVarun Wadekar #define TEGRA186_MAX_UART_PORTS		7
11441612559SVarun Wadekar 
11541612559SVarun Wadekar /*******************************************************************************
11641612559SVarun Wadekar  * This variable holds the UART port base addresses
11741612559SVarun Wadekar  ******************************************************************************/
11841612559SVarun Wadekar static uint32_t tegra186_uart_addresses[TEGRA186_MAX_UART_PORTS + 1] = {
11941612559SVarun Wadekar 	0,	/* undefined - treated as an error case */
12041612559SVarun Wadekar 	TEGRA_UARTA_BASE,
12141612559SVarun Wadekar 	TEGRA_UARTB_BASE,
12241612559SVarun Wadekar 	TEGRA_UARTC_BASE,
12341612559SVarun Wadekar 	TEGRA_UARTD_BASE,
12441612559SVarun Wadekar 	TEGRA_UARTE_BASE,
12541612559SVarun Wadekar 	TEGRA_UARTF_BASE,
12641612559SVarun Wadekar 	TEGRA_UARTG_BASE,
12741612559SVarun Wadekar };
12841612559SVarun Wadekar 
12941612559SVarun Wadekar /*******************************************************************************
13041612559SVarun Wadekar  * Retrieve the UART controller base to be used as the console
13141612559SVarun Wadekar  ******************************************************************************/
13241612559SVarun Wadekar uint32_t plat_get_console_from_id(int id)
13341612559SVarun Wadekar {
13441612559SVarun Wadekar 	if (id > TEGRA186_MAX_UART_PORTS)
13541612559SVarun Wadekar 		return 0;
13641612559SVarun Wadekar 
13741612559SVarun Wadekar 	return tegra186_uart_addresses[id];
13841612559SVarun Wadekar }
13941612559SVarun Wadekar 
14041612559SVarun Wadekar /* represent chip-version as concatenation of major (15:12), minor (11:8) and subrev (7:0) */
14141612559SVarun Wadekar #define TEGRA186_VER_A02P	0x1201
14241612559SVarun Wadekar 
14341612559SVarun Wadekar /*******************************************************************************
14441612559SVarun Wadekar  * Handler for early platform setup
14541612559SVarun Wadekar  ******************************************************************************/
14641612559SVarun Wadekar void plat_early_platform_setup(void)
14741612559SVarun Wadekar {
14841612559SVarun Wadekar 	int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
14941612559SVarun Wadekar 	uint32_t chip_subrev, val;
15041612559SVarun Wadekar 
15141612559SVarun Wadekar 	/* sanity check MCE firmware compatibility */
15241612559SVarun Wadekar 	mce_verify_firmware_version();
15341612559SVarun Wadekar 
15441612559SVarun Wadekar 	/*
15541612559SVarun Wadekar 	 * Enable ECC and Parity Protection for Cortex-A57 CPUs
15641612559SVarun Wadekar 	 * for Tegra A02p SKUs
15741612559SVarun Wadekar 	 */
15841612559SVarun Wadekar 	if (impl != DENVER_IMPL) {
15941612559SVarun Wadekar 
16041612559SVarun Wadekar 		/* get the major, minor and sub-version values */
16141612559SVarun Wadekar 		chip_subrev = mmio_read_32(TEGRA_FUSE_BASE + OPT_SUBREVISION) &
16241612559SVarun Wadekar 			      SUBREVISION_MASK;
16341612559SVarun Wadekar 
16441612559SVarun Wadekar 		/* prepare chip version number */
16541612559SVarun Wadekar 		val = (tegra_get_chipid_major() << 12) |
16641612559SVarun Wadekar 		      (tegra_get_chipid_minor() << 8) |
16741612559SVarun Wadekar 		       chip_subrev;
16841612559SVarun Wadekar 
16941612559SVarun Wadekar 		/* enable L2 ECC for Tegra186 A02P and beyond */
17041612559SVarun Wadekar 		if (val >= TEGRA186_VER_A02P) {
17141612559SVarun Wadekar 
17241612559SVarun Wadekar 			val = read_l2ctlr_el1();
17341612559SVarun Wadekar 			val |= L2_ECC_PARITY_PROTECTION_BIT;
17441612559SVarun Wadekar 			write_l2ctlr_el1(val);
17541612559SVarun Wadekar 
17641612559SVarun Wadekar 			/*
17741612559SVarun Wadekar 			 * Set the flag to enable ECC/Parity Protection
17841612559SVarun Wadekar 			 * when we exit System Suspend or Cluster Powerdn
17941612559SVarun Wadekar 			 */
18041612559SVarun Wadekar 			tegra_enable_l2_ecc_parity_prot = 1;
18141612559SVarun Wadekar 		}
18241612559SVarun Wadekar 	}
18341612559SVarun Wadekar }
18441612559SVarun Wadekar 
18541612559SVarun Wadekar /* Secure IRQs for Tegra186 */
18641612559SVarun Wadekar static const irq_sec_cfg_t tegra186_sec_irqs[] = {
18741612559SVarun Wadekar 	[0] = {
18841612559SVarun Wadekar 		TEGRA186_BPMP_WDT_IRQ,
18941612559SVarun Wadekar 		TEGRA186_SEC_IRQ_TARGET_MASK,
19041612559SVarun Wadekar 		INTR_TYPE_EL3,
19141612559SVarun Wadekar 	},
19241612559SVarun Wadekar 	[1] = {
19341612559SVarun Wadekar 		TEGRA186_BPMP_WDT_IRQ,
19441612559SVarun Wadekar 		TEGRA186_SEC_IRQ_TARGET_MASK,
19541612559SVarun Wadekar 		INTR_TYPE_EL3,
19641612559SVarun Wadekar 	},
19741612559SVarun Wadekar 	[2] = {
19841612559SVarun Wadekar 		TEGRA186_SPE_WDT_IRQ,
19941612559SVarun Wadekar 		TEGRA186_SEC_IRQ_TARGET_MASK,
20041612559SVarun Wadekar 		INTR_TYPE_EL3,
20141612559SVarun Wadekar 	},
20241612559SVarun Wadekar 	[3] = {
20341612559SVarun Wadekar 		TEGRA186_SCE_WDT_IRQ,
20441612559SVarun Wadekar 		TEGRA186_SEC_IRQ_TARGET_MASK,
20541612559SVarun Wadekar 		INTR_TYPE_EL3,
20641612559SVarun Wadekar 	},
20741612559SVarun Wadekar 	[4] = {
20841612559SVarun Wadekar 		TEGRA186_TOP_WDT_IRQ,
20941612559SVarun Wadekar 		TEGRA186_SEC_IRQ_TARGET_MASK,
21041612559SVarun Wadekar 		INTR_TYPE_EL3,
21141612559SVarun Wadekar 	},
21241612559SVarun Wadekar 	[5] = {
21341612559SVarun Wadekar 		TEGRA186_AON_WDT_IRQ,
21441612559SVarun Wadekar 		TEGRA186_SEC_IRQ_TARGET_MASK,
21541612559SVarun Wadekar 		INTR_TYPE_EL3,
21641612559SVarun Wadekar 	},
21741612559SVarun Wadekar };
21841612559SVarun Wadekar 
21941612559SVarun Wadekar /*******************************************************************************
22041612559SVarun Wadekar  * Initialize the GIC and SGIs
22141612559SVarun Wadekar  ******************************************************************************/
22241612559SVarun Wadekar void plat_gic_setup(void)
22341612559SVarun Wadekar {
22441612559SVarun Wadekar 	tegra_gic_setup(tegra186_sec_irqs,
22541612559SVarun Wadekar 		sizeof(tegra186_sec_irqs) / sizeof(tegra186_sec_irqs[0]));
22641612559SVarun Wadekar 
22741612559SVarun Wadekar 	/*
22841612559SVarun Wadekar 	 * Initialize the FIQ handler only if the platform supports any
22941612559SVarun Wadekar 	 * FIQ interrupt sources.
23041612559SVarun Wadekar 	 */
23141612559SVarun Wadekar 	if (sizeof(tegra186_sec_irqs) > 0)
23241612559SVarun Wadekar 		tegra_fiq_handler_setup();
23341612559SVarun Wadekar }
23441612559SVarun Wadekar 
23541612559SVarun Wadekar /*******************************************************************************
23641612559SVarun Wadekar  * Return pointer to the BL31 params from previous bootloader
23741612559SVarun Wadekar  ******************************************************************************/
23841612559SVarun Wadekar struct tegra_bl31_params *plat_get_bl31_params(void)
23941612559SVarun Wadekar {
24041612559SVarun Wadekar 	uint32_t val;
24141612559SVarun Wadekar 
24241612559SVarun Wadekar 	val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_LO);
24341612559SVarun Wadekar 
24441612559SVarun Wadekar 	return (struct tegra_bl31_params *)(uintptr_t)val;
24541612559SVarun Wadekar }
24641612559SVarun Wadekar 
24741612559SVarun Wadekar /*******************************************************************************
24841612559SVarun Wadekar  * Return pointer to the BL31 platform params from previous bootloader
24941612559SVarun Wadekar  ******************************************************************************/
25041612559SVarun Wadekar plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
25141612559SVarun Wadekar {
25241612559SVarun Wadekar 	uint32_t val;
25341612559SVarun Wadekar 
25441612559SVarun Wadekar 	val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_HI);
25541612559SVarun Wadekar 
25641612559SVarun Wadekar 	return (plat_params_from_bl2_t *)(uintptr_t)val;
25741612559SVarun Wadekar }
258