xref: /rk3399_ARM-atf/plat/renesas/rcar_gen5/bl31_plat_setup.c (revision 7cab2c233b38cf2a63d37d31da73f1d82f5efc3c)
1 /*
2  * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
3  * Copyright (c) 2025, Renesas Electronics Corporation. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include <stddef.h>
9 
10 #include <arch.h>
11 #include <arch_helpers.h>
12 #include <bl31/bl31.h>
13 #include <common/bl_common.h>
14 #include <common/debug.h>
15 #include <drivers/arm/cci.h>
16 #include <drivers/console.h>
17 #include <lib/mmio.h>
18 #include <plat/arm/common/plat_arm.h>
19 #include <plat/common/platform.h>
20 #include "pwrc.h"
21 #include "timer.h"
22 
23 #include "rcar_def.h"
24 #include "rcar_private.h"
25 #include "rcar_version.h"
26 
27 #define SYSSS_TOP_Region_0			0xC6480000UL
28 #define SASYNCRTCKCR_OFFSET			0x1064UL
29 #define SASYNCRTCKCR				(SYSSS_TOP_Region_0 + SASYNCRTCKCR_OFFSET)
30 #define CKSTP_BIT				BIT_32(7)
31 
32 /* Base Address Macros */
33 #define CLK_CONTROL_SCP_BASE			0xC1330000UL // SYSSS_SCP_PS0_Region_0 base Address
34 #define CLK_CONTROL_PERE_BASE			0xC08F0000UL // SYSSS_PERE_Region_0 base Address
35 #define CLK_CONTROL_TOP_BASE			0xC6480000UL // SYSSS_TOP_Region_0 base Address
36 #define CLK_CONTROL_HSCS_BASE			0xDE200000UL // SYSSS_HSCS_Region_0 base Address
37 
38 /* Protection Register Macros */
39 #define CLK_CONTROL_CLKTOPPKCPROT0		(CLK_CONTROL_TOP_BASE + 0x00001370UL)
40 #define CLK_CONTROL_CLKPEREPKCPROT0		(CLK_CONTROL_PERE_BASE + 0x00001370UL)
41 #define CLK_CONTROL_CLKHSCSPKCPROT0		(CLK_CONTROL_HSCS_BASE + 0x00001370UL)
42 #define CLK_CONTROL_CLKSCPPKCPROT0		(CLK_CONTROL_SCP_BASE + 0x00001370UL)
43 
44 /* Mask and Key Code Macros */
45 #define CLK_CONTROL_BIT32_16_BASE_ADDRESS_MASK	0xFFFF0000UL
46 #define CLK_PKCPROT0_KCPROT_SET			0xA5A5A500UL
47 #define CLK_PKCPROT0_KCE_DISABLE_SET		0x00000000UL
48 #define CLK_PKCPROT0_KCE_ENABLE_SET		0x00000001UL
49 
50 /* Flag Macros */
51 #define FLAG_ON					0x5A5A0000U
52 #define FLAG_OFF				0xD4D47171U
53 
54 static u_register_t rcar_boot_mpidr;
55 
rd_write_clock_control_register(uint32_t reg_address,uint32_t set_value)56 void rd_write_clock_control_register(uint32_t reg_address, uint32_t set_value)
57 {
58 	uint32_t base_address;
59 	uint32_t base_address_check_flag;
60 	uint32_t pkc_prot_register;
61 	uint32_t write_key_code;
62 
63 	base_address = (CLK_CONTROL_BIT32_16_BASE_ADDRESS_MASK & reg_address);
64 
65 	/* Select the Protect register for Corresponding Power domain */
66 	switch (base_address) {
67 	case CLK_CONTROL_TOP_BASE:
68 		pkc_prot_register = CLK_CONTROL_CLKTOPPKCPROT0;
69 		base_address_check_flag = FLAG_OFF;
70 		break;
71 
72 	case CLK_CONTROL_PERE_BASE:
73 		pkc_prot_register = CLK_CONTROL_CLKPEREPKCPROT0;
74 		base_address_check_flag = FLAG_OFF;
75 		break;
76 
77 	case CLK_CONTROL_HSCS_BASE:
78 		pkc_prot_register = CLK_CONTROL_CLKHSCSPKCPROT0;
79 		base_address_check_flag = FLAG_OFF;
80 		break;
81 
82 	case CLK_CONTROL_SCP_BASE:
83 		pkc_prot_register = CLK_CONTROL_CLKSCPPKCPROT0;
84 		base_address_check_flag = FLAG_OFF;
85 		break;
86 
87 	default:
88 		pkc_prot_register = 0uL;
89 		base_address_check_flag = FLAG_ON;
90 		break;
91 	}
92 
93 	if (base_address_check_flag == FLAG_OFF) {
94 		write_key_code = (CLK_PKCPROT0_KCPROT_SET | CLK_PKCPROT0_KCE_ENABLE_SET);
95 		mmio_write_32(pkc_prot_register, write_key_code);
96 		mmio_write_32(reg_address, set_value);
97 		write_key_code = (CLK_PKCPROT0_KCPROT_SET | CLK_PKCPROT0_KCE_DISABLE_SET);
98 		mmio_write_32(pkc_prot_register, write_key_code);
99 	}
100 }
101 
enable_sasyncck_rt_clk(void)102 static void enable_sasyncck_rt_clk(void)
103 {
104 	uint32_t register_value;
105 
106 	/* Read the current register value */
107 	register_value = mmio_read_32(SASYNCRTCKCR);
108 
109 	/* Clear the CKSTP_BIT to enable the SASYNCCK_RT clock */
110 	register_value &= ~CKSTP_BIT;
111 
112 	/* Write the updated value back to the register using the wrapper */
113 	rd_write_clock_control_register(SASYNCRTCKCR, register_value);
114 }
115 
bl31_plat_get_next_image_ep_info(uint32_t type)116 struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type)
117 {
118 	bl2_to_bl31_params_mem_t *from_bl2 = (bl2_to_bl31_params_mem_t *)
119 					     PARAMS_BASE;
120 
121 	entry_point_info_t *next_image_info;
122 
123 	next_image_info = (type == NON_SECURE) ?
124 			  &from_bl2->bl33_ep_info :
125 			  &from_bl2->bl32_ep_info;
126 
127 	return (next_image_info->pc != 0U) ? next_image_info : NULL;
128 }
129 
bl31_early_platform_setup2(u_register_t arg0,u_register_t arg1,u_register_t arg2,u_register_t arg3)130 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
131 				u_register_t arg2, u_register_t arg3)
132 {
133 	rcar_console_boot_init();
134 	NOTICE("BL3-1 : Rev.%s\n", version_of_renesas);
135 }
136 
bl31_plat_arch_setup(void)137 void bl31_plat_arch_setup(void)
138 {
139 	static const uintptr_t BL31_RO_BASE = BL_CODE_BASE;
140 	static const uintptr_t BL31_RO_LIMIT = BL_CODE_END;
141 
142 	/* Enable SASYNCCK_RT gate clock */
143 	enable_sasyncck_rt_clk();
144 
145 	rcar_configure_mmu_el3(BL31_BASE,
146 			       BL31_LIMIT - BL31_BASE,
147 			       BL31_RO_BASE, BL31_RO_LIMIT);
148 }
149 
150 static const uintptr_t gicr_base_addrs[2] = {
151 	PLAT_ARM_GICR_BASE,	/* GICR Base address of the primary CPU */
152 	0U			/* Zero Termination */
153 };
154 
bl31_platform_setup(void)155 void bl31_platform_setup(void)
156 {
157 	/* Initialize generic timer */
158 	u_register_t reg_cntfid = RCAR_CNTC_EXTAL;
159 
160 	/* Update memory mapped and register based frequency */
161 	write_cntfrq_el0((u_register_t)reg_cntfid);
162 	mmio_write_32(ARM_SYS_CNTCTL_BASE + (uintptr_t)CNTFID_OFF, reg_cntfid);
163 
164 	/* enable the system level generic timer */
165 	mmio_write_32(RCAR_CNTC_BASE + CNTCR_OFF, CNTCR_FCREQ(0) | CNTCR_EN);
166 
167 	gic_set_gicr_frames(gicr_base_addrs);
168 
169 	/*
170 	 * Preserve plat_secondary_reset symbol for secondary CPU boot.
171 	 * Store function address to prevent linker dead code elimination.
172 	 */
173 	volatile uintptr_t secondary_reset_func = (uintptr_t)plat_secondary_reset;
174 	(void)secondary_reset_func;
175 
176 	plat_rcar_scmi_setup();
177 
178 	/*
179 	 * mask should match the kernel's MPIDR_HWID_BITMASK so the core can be
180 	 * identified during cpuhotplug (check the kernel's psci migrate set of
181 	 * functions
182 	 */
183 	rcar_boot_mpidr = read_mpidr_el1() & RCAR_MPIDR_AFFMASK;
184 }
185 
bl31_plat_runtime_setup(void)186 void bl31_plat_runtime_setup(void)
187 {
188 	rcar_console_runtime_init();
189 	console_switch_state(CONSOLE_FLAG_RUNTIME);
190 }
191