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