xref: /rk3399_ARM-atf/plat/qti/msm8916/msm8916_bl31_setup.c (revision af6447315c8534331513ca6b6556af661e0ba88b)
1dddba19aSStephan Gerhold /*
2dddba19aSStephan Gerhold  * Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
3dddba19aSStephan Gerhold  *
4dddba19aSStephan Gerhold  * SPDX-License-Identifier: BSD-3-Clause
5dddba19aSStephan Gerhold  */
6dddba19aSStephan Gerhold 
7dddba19aSStephan Gerhold #include <assert.h>
8dddba19aSStephan Gerhold 
9dddba19aSStephan Gerhold #include <arch.h>
10dddba19aSStephan Gerhold #include <common/debug.h>
11dddba19aSStephan Gerhold #include <drivers/console.h>
12dddba19aSStephan Gerhold #include <drivers/generic_delay_timer.h>
13dddba19aSStephan Gerhold #include <lib/mmio.h>
14dddba19aSStephan Gerhold #include <lib/xlat_tables/xlat_mmu_helpers.h>
15dddba19aSStephan Gerhold #include <lib/xlat_tables/xlat_tables_v2.h>
16dddba19aSStephan Gerhold #include <plat/common/platform.h>
17dddba19aSStephan Gerhold 
18*af644731SStephan Gerhold #include "msm8916_gicv2.h"
19dddba19aSStephan Gerhold #include <msm8916_mmap.h>
20dddba19aSStephan Gerhold #include <platform_def.h>
21dddba19aSStephan Gerhold #include <uartdm_console.h>
22dddba19aSStephan Gerhold 
23dddba19aSStephan Gerhold static const mmap_region_t msm8916_mmap[] = {
24dddba19aSStephan Gerhold 	MAP_REGION_FLAT(PCNOC_BASE, PCNOC_SIZE,
25dddba19aSStephan Gerhold 			MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER),
26dddba19aSStephan Gerhold 	MAP_REGION_FLAT(APCS_BASE, APCS_SIZE,
27dddba19aSStephan Gerhold 			MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER),
28dddba19aSStephan Gerhold 	{},
29dddba19aSStephan Gerhold };
30dddba19aSStephan Gerhold 
31dddba19aSStephan Gerhold static struct {
32dddba19aSStephan Gerhold 	entry_point_info_t bl32;
33dddba19aSStephan Gerhold 	entry_point_info_t bl33;
34dddba19aSStephan Gerhold } image_ep_info = {
35dddba19aSStephan Gerhold 	/* BL32 entry point */
36dddba19aSStephan Gerhold 	SET_STATIC_PARAM_HEAD(bl32, PARAM_EP, VERSION_1,
37dddba19aSStephan Gerhold 			      entry_point_info_t, SECURE),
38dddba19aSStephan Gerhold 	.bl32.pc = BL32_BASE,
39dddba19aSStephan Gerhold 
40dddba19aSStephan Gerhold 	/* BL33 entry point */
41dddba19aSStephan Gerhold 	SET_STATIC_PARAM_HEAD(bl33, PARAM_EP, VERSION_1,
42dddba19aSStephan Gerhold 			      entry_point_info_t, NON_SECURE),
43dddba19aSStephan Gerhold 	.bl33.pc = PRELOADED_BL33_BASE,
44dddba19aSStephan Gerhold 	.bl33.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS),
45dddba19aSStephan Gerhold };
46dddba19aSStephan Gerhold 
47dddba19aSStephan Gerhold static console_t console;
48dddba19aSStephan Gerhold 
49dddba19aSStephan Gerhold unsigned int plat_get_syscnt_freq2(void)
50dddba19aSStephan Gerhold {
51dddba19aSStephan Gerhold 	return PLAT_SYSCNT_FREQ;
52dddba19aSStephan Gerhold }
53dddba19aSStephan Gerhold 
54dddba19aSStephan Gerhold #define CLK_ENABLE			BIT_32(0)
55dddba19aSStephan Gerhold #define CLK_OFF				BIT_32(31)
56dddba19aSStephan Gerhold 
57dddba19aSStephan Gerhold #define GPIO_BLSP_UART2_TX		4
58dddba19aSStephan Gerhold #define GPIO_BLSP_UART2_RX		5
59dddba19aSStephan Gerhold #define GPIO_CFG_FUNC_BLSP_UART2	(U(0x2) << 2)
60dddba19aSStephan Gerhold #define GPIO_CFG_DRV_STRENGTH_16MA	(U(0x7) << 6)
61dddba19aSStephan Gerhold 
62dddba19aSStephan Gerhold #define GCC_BLSP1_AHB_CBCR		(GCC_BASE + 0x01008)
63dddba19aSStephan Gerhold #define GCC_BLSP1_UART2_APPS_CBCR	(GCC_BASE + 0x0302c)
64dddba19aSStephan Gerhold #define GCC_APCS_CLOCK_BRANCH_ENA_VOTE	(GCC_BASE + 0x45004)
65dddba19aSStephan Gerhold #define BLSP1_AHB_CLK_ENA		BIT_32(10)
66dddba19aSStephan Gerhold 
67dddba19aSStephan Gerhold /*
68dddba19aSStephan Gerhold  * The previous boot stage seems to disable most of the UART setup before exit
69dddba19aSStephan Gerhold  * so it must be enabled here again before the UART console can be used.
70dddba19aSStephan Gerhold  */
71dddba19aSStephan Gerhold static void msm8916_enable_blsp_uart2(void)
72dddba19aSStephan Gerhold {
73dddba19aSStephan Gerhold 	/* Route GPIOs to BLSP UART2 */
74dddba19aSStephan Gerhold 	mmio_write_32(TLMM_GPIO_CFG(GPIO_BLSP_UART2_TX),
75dddba19aSStephan Gerhold 		      GPIO_CFG_FUNC_BLSP_UART2 | GPIO_CFG_DRV_STRENGTH_16MA);
76dddba19aSStephan Gerhold 	mmio_write_32(TLMM_GPIO_CFG(GPIO_BLSP_UART2_RX),
77dddba19aSStephan Gerhold 		      GPIO_CFG_FUNC_BLSP_UART2 | GPIO_CFG_DRV_STRENGTH_16MA);
78dddba19aSStephan Gerhold 
79dddba19aSStephan Gerhold 	/* Enable AHB clock */
80dddba19aSStephan Gerhold 	mmio_setbits_32(GCC_APCS_CLOCK_BRANCH_ENA_VOTE, BLSP1_AHB_CLK_ENA);
81dddba19aSStephan Gerhold 	while (mmio_read_32(GCC_BLSP1_AHB_CBCR) & CLK_OFF)
82dddba19aSStephan Gerhold 		;
83dddba19aSStephan Gerhold 
84dddba19aSStephan Gerhold 	/* Enable BLSP UART2 clock */
85dddba19aSStephan Gerhold 	mmio_setbits_32(GCC_BLSP1_UART2_APPS_CBCR, CLK_ENABLE);
86dddba19aSStephan Gerhold 	while (mmio_read_32(GCC_BLSP1_UART2_APPS_CBCR) & CLK_OFF)
87dddba19aSStephan Gerhold 		;
88dddba19aSStephan Gerhold }
89dddba19aSStephan Gerhold 
90dddba19aSStephan Gerhold void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
91dddba19aSStephan Gerhold 				u_register_t arg2, u_register_t arg3)
92dddba19aSStephan Gerhold {
93dddba19aSStephan Gerhold 	/* Initialize the debug console as early as possible */
94dddba19aSStephan Gerhold 	msm8916_enable_blsp_uart2();
95dddba19aSStephan Gerhold 	console_uartdm_register(&console, BLSP_UART2_BASE);
96dddba19aSStephan Gerhold }
97dddba19aSStephan Gerhold 
98dddba19aSStephan Gerhold void bl31_plat_arch_setup(void)
99dddba19aSStephan Gerhold {
100dddba19aSStephan Gerhold 	mmap_add_region(BL31_BASE, BL31_BASE, BL31_END - BL31_BASE,
101dddba19aSStephan Gerhold 			MT_RW_DATA | MT_SECURE);
102dddba19aSStephan Gerhold 	mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
103dddba19aSStephan Gerhold 			BL_CODE_END - BL_CODE_BASE,
104dddba19aSStephan Gerhold 			MT_CODE | MT_SECURE);
105dddba19aSStephan Gerhold 	mmap_add_region(BL_RO_DATA_BASE, BL_RO_DATA_BASE,
106dddba19aSStephan Gerhold 			BL_RO_DATA_END - BL_RO_DATA_BASE,
107dddba19aSStephan Gerhold 			MT_RO_DATA | MT_SECURE);
108dddba19aSStephan Gerhold 	mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
109dddba19aSStephan Gerhold 			BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
110dddba19aSStephan Gerhold 			MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER);
111dddba19aSStephan Gerhold 
112dddba19aSStephan Gerhold 	mmap_add(msm8916_mmap);
113dddba19aSStephan Gerhold 	init_xlat_tables();
114dddba19aSStephan Gerhold 	enable_mmu_el3(0);
115dddba19aSStephan Gerhold }
116dddba19aSStephan Gerhold 
117*af644731SStephan Gerhold static void msm8916_configure_timer(void)
118*af644731SStephan Gerhold {
119*af644731SStephan Gerhold 	/* Set timer frequency */
120*af644731SStephan Gerhold 	mmio_write_32(APCS_QTMR + CNTCTLBASE_CNTFRQ, plat_get_syscnt_freq2());
121*af644731SStephan Gerhold 
122*af644731SStephan Gerhold 	/* Make frame 0 available to non-secure world */
123*af644731SStephan Gerhold 	mmio_write_32(APCS_QTMR + CNTNSAR, BIT_32(CNTNSAR_NS_SHIFT(0)));
124*af644731SStephan Gerhold 	mmio_write_32(APCS_QTMR + CNTACR_BASE(0),
125*af644731SStephan Gerhold 		      BIT_32(CNTACR_RPCT_SHIFT) | BIT_32(CNTACR_RVCT_SHIFT) |
126*af644731SStephan Gerhold 		      BIT_32(CNTACR_RFRQ_SHIFT) | BIT_32(CNTACR_RVOFF_SHIFT) |
127*af644731SStephan Gerhold 		      BIT_32(CNTACR_RWVT_SHIFT) | BIT_32(CNTACR_RWPT_SHIFT));
128*af644731SStephan Gerhold }
129*af644731SStephan Gerhold 
130*af644731SStephan Gerhold /*
131*af644731SStephan Gerhold  * The APCS register regions always start with a SECURE register that should
132*af644731SStephan Gerhold  * be cleared to 0 to only allow secure access. Since BL31 handles most of
133*af644731SStephan Gerhold  * the CPU power management, most of them can be cleared to secure access only.
134*af644731SStephan Gerhold  */
135*af644731SStephan Gerhold #define APCS_GLB_SECURE_STS_NS		BIT_32(0)
136*af644731SStephan Gerhold #define APCS_GLB_SECURE_PWR_NS		BIT_32(1)
137*af644731SStephan Gerhold 
138*af644731SStephan Gerhold static void msm8916_configure_cpu_pm(void)
139*af644731SStephan Gerhold {
140*af644731SStephan Gerhold 	unsigned int cpu;
141*af644731SStephan Gerhold 
142*af644731SStephan Gerhold 	/* Disallow non-secure access to boot remapper / TCM registers */
143*af644731SStephan Gerhold 	mmio_write_32(APCS_CFG, 0);
144*af644731SStephan Gerhold 
145*af644731SStephan Gerhold 	/*
146*af644731SStephan Gerhold 	 * Disallow non-secure access to power management registers.
147*af644731SStephan Gerhold 	 * However, allow STS and PWR since those also seem to control access
148*af644731SStephan Gerhold 	 * to CPU frequency related registers (e.g. APCS_CMD_RCGR). If these
149*af644731SStephan Gerhold 	 * bits are not set, CPU frequency control fails in the non-secure world.
150*af644731SStephan Gerhold 	 */
151*af644731SStephan Gerhold 	mmio_write_32(APCS_GLB, APCS_GLB_SECURE_STS_NS | APCS_GLB_SECURE_PWR_NS);
152*af644731SStephan Gerhold 
153*af644731SStephan Gerhold 	/* Disallow non-secure access to L2 SAW2 */
154*af644731SStephan Gerhold 	mmio_write_32(APCS_L2_SAW2, 0);
155*af644731SStephan Gerhold 
156*af644731SStephan Gerhold 	/* Disallow non-secure access to CPU ACS and SAW2 */
157*af644731SStephan Gerhold 	for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) {
158*af644731SStephan Gerhold 		mmio_write_32(APCS_ALIAS_ACS(cpu), 0);
159*af644731SStephan Gerhold 		mmio_write_32(APCS_ALIAS_SAW2(cpu), 0);
160*af644731SStephan Gerhold 	}
161*af644731SStephan Gerhold }
162*af644731SStephan Gerhold 
163*af644731SStephan Gerhold /*
164*af644731SStephan Gerhold  * MSM8916 has a special "interrupt aggregation logic" in the APPS SMMU,
165*af644731SStephan Gerhold  * which allows routing context bank interrupts to one of 3 interrupt numbers
166*af644731SStephan Gerhold  * ("TZ/HYP/NS"). Route all interrupts to the non-secure interrupt number
167*af644731SStephan Gerhold  * by default to avoid special setup on the non-secure side.
168*af644731SStephan Gerhold  */
169*af644731SStephan Gerhold #define GCC_SMMU_CFG_CBCR			(GCC_BASE + 0x12038)
170*af644731SStephan Gerhold #define GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE	(GCC_BASE + 0x4500c)
171*af644731SStephan Gerhold #define SMMU_CFG_CLK_ENA			BIT_32(12)
172*af644731SStephan Gerhold #define APPS_SMMU_INTR_SEL_NS			(APPS_SMMU_QCOM + 0x2000)
173*af644731SStephan Gerhold #define APPS_SMMU_INTR_SEL_NS_EN_ALL		U(0xffffffff)
174*af644731SStephan Gerhold 
175*af644731SStephan Gerhold static void msm8916_configure_smmu(void)
176*af644731SStephan Gerhold {
177*af644731SStephan Gerhold 	/* Enable SMMU configuration clock to enable register access */
178*af644731SStephan Gerhold 	mmio_setbits_32(GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE, SMMU_CFG_CLK_ENA);
179*af644731SStephan Gerhold 	while (mmio_read_32(GCC_SMMU_CFG_CBCR) & CLK_OFF)
180*af644731SStephan Gerhold 		;
181*af644731SStephan Gerhold 
182*af644731SStephan Gerhold 	/* Route all context bank interrupts to non-secure interrupt */
183*af644731SStephan Gerhold 	mmio_write_32(APPS_SMMU_INTR_SEL_NS, APPS_SMMU_INTR_SEL_NS_EN_ALL);
184*af644731SStephan Gerhold 
185*af644731SStephan Gerhold 	/* Disable configuration clock again */
186*af644731SStephan Gerhold 	mmio_clrbits_32(GCC_APCS_SMMU_CLOCK_BRANCH_ENA_VOTE, SMMU_CFG_CLK_ENA);
187*af644731SStephan Gerhold }
188*af644731SStephan Gerhold 
189dddba19aSStephan Gerhold void bl31_platform_setup(void)
190dddba19aSStephan Gerhold {
191*af644731SStephan Gerhold 	INFO("BL31: Platform setup start\n");
192dddba19aSStephan Gerhold 	generic_delay_timer_init();
193*af644731SStephan Gerhold 	msm8916_configure_timer();
194*af644731SStephan Gerhold 	msm8916_gicv2_init();
195*af644731SStephan Gerhold 	msm8916_configure_cpu_pm();
196*af644731SStephan Gerhold 	msm8916_configure_smmu();
197*af644731SStephan Gerhold 	INFO("BL31: Platform setup done\n");
198dddba19aSStephan Gerhold }
199dddba19aSStephan Gerhold 
200dddba19aSStephan Gerhold entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
201dddba19aSStephan Gerhold {
202dddba19aSStephan Gerhold 	switch (type) {
203dddba19aSStephan Gerhold 	case SECURE:
204dddba19aSStephan Gerhold 		return &image_ep_info.bl32;
205dddba19aSStephan Gerhold 	case NON_SECURE:
206dddba19aSStephan Gerhold 		return &image_ep_info.bl33;
207dddba19aSStephan Gerhold 	default:
208dddba19aSStephan Gerhold 		assert(sec_state_is_valid(type));
209dddba19aSStephan Gerhold 		return NULL;
210dddba19aSStephan Gerhold 	}
211dddba19aSStephan Gerhold }
212