1 /*
2  * Copyright (c) 2024 Ian Morris
3  * Copyright (c) 2024 TOKITA Hiroshi
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 /**
9  * @file
10  * @brief System/hardware module for Renesas RA4M1 family processor
11  */
12 
13 #include <zephyr/device.h>
14 #include <zephyr/init.h>
15 #include <zephyr/kernel.h>
16 #include <zephyr/arch/cpu.h>
17 #include <cmsis_core.h>
18 #include <zephyr/arch/arm/nmi.h>
19 #include <zephyr/irq.h>
20 #include <zephyr/logging/log.h>
21 LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL);
22 
23 #include "bsp_cfg.h"
24 #include <bsp_api.h>
25 
26 #define HOCO_FREQ DT_PROP(DT_PATH(clocks, clock_hoco), clock_frequency)
27 
28 #if HOCO_FREQ == MHZ(24)
29 #define OFS1_HOCO_FREQ 0
30 #elif HOCO_FREQ == MHZ(32)
31 #define OFS1_HOCO_FREQ 2
32 #elif HOCO_FREQ == MHZ(48)
33 #define OFS1_HOCO_FREQ 4
34 #elif HOCO_FREQ == MHZ(64)
35 #define OFS1_HOCO_FREQ 5
36 #else
37 #error "Unsupported HOCO frequency"
38 #endif
39 
40 struct ofs0_reg {
41 	uint32_t RSVD1: 1;
42 	uint32_t IWDTSTRT: 1;
43 	uint32_t IWDTTOPS: 2;
44 	uint32_t IWDTCKS: 4;
45 	uint32_t IWDTRPES: 2;
46 	uint32_t IWDTRPSS: 2;
47 	uint32_t IWDTRSTIRQS: 1;
48 	uint32_t RSVD2: 1;
49 	uint32_t IWDTSTPCTL: 1;
50 	uint32_t RSVD3: 2;
51 	uint32_t WDTSTRT: 1;
52 	uint32_t WDTTOPS: 2;
53 	uint32_t WDTCKS: 4;
54 	uint32_t WDTRPES: 2;
55 	uint32_t WDTRPSS: 2;
56 	uint32_t WDTRSTIRQS: 1;
57 	uint32_t RSVD4: 1;
58 	uint32_t WDTSTPCTL: 1;
59 	uint32_t RSVD5: 1;
60 };
61 
62 struct ofs1_reg {
63 	uint32_t RSVD1: 2;
64 	uint32_t LVDAS: 1;
65 	uint32_t VDSEL1: 3;
66 	uint32_t RSVD2: 2;
67 	uint32_t HOCOEN: 1;
68 	uint32_t RSVD3: 3;
69 	uint32_t HOCOFRQ1: 3;
70 	uint32_t RSVD4: 17;
71 };
72 
73 struct mpu_regs {
74 	uint32_t SECMPUPCSO;
75 	uint32_t SECMPUPCEO;
76 	uint32_t SECMPUPCS1;
77 	uint32_t SECMPUPCE1;
78 	uint32_t SECMPUS0;
79 	uint32_t SECMPUE0;
80 	uint32_t SECMPUS1;
81 	uint32_t SECMPUE1;
82 	uint32_t SECMPUS2;
83 	uint32_t SECMPUE2;
84 	uint32_t SECMPUS3;
85 	uint32_t SECMPUE3;
86 	uint32_t SECMPUAC;
87 };
88 
89 struct opt_set_mem {
90 	struct ofs0_reg ofs0;
91 	struct ofs1_reg ofs1;
92 	struct mpu_regs mpu;
93 };
94 
95 #ifdef CONFIG_SOC_OPTION_SETTING_MEMORY
96 Z_GENERIC_SECTION(".rom_registers")
97 const struct opt_set_mem ops = {
98 	/*
99 	 * Initial settings for watchdog timers. Set all fields to 1,
100 	 * disabling watchdog functionality as config options have not
101 	 * yet been implemented.
102 	 */
103 	.ofs0 = {.RSVD1 = 0x1,
104 		 .IWDTSTRT = 0x1, /* Disable independent watchdog timer */
105 		 .IWDTTOPS = 0x3,
106 		 .IWDTCKS = 0xf,
107 		 .IWDTRPES = 0x3,
108 		 .IWDTRPSS = 0x3,
109 		 .IWDTRSTIRQS = 0x1,
110 		 .RSVD2 = 0x1,
111 		 .IWDTSTPCTL = 0x1,
112 		 .RSVD3 = 0x3,
113 		 /* Stop watchdog timer following reset */
114 		 .WDTSTRT = !IS_ENABLED(CONFIG_WDT_RENESAS_RA_START_IN_BOOT),
115 		 .WDTTOPS = 0x3,
116 		 .WDTCKS = 0xf,
117 		 .WDTRPES = 0x3,
118 		 .WDTRPSS = 0x3,
119 		 .WDTRSTIRQS = 0x1,
120 		 .RSVD4 = 0x1,
121 		 .WDTSTPCTL = 0x1,
122 		 .RSVD5 = 0x1},
123 	.ofs1 = {.RSVD1 = 0x3,
124 		 .LVDAS = 0x1, /* Disable voltage monitor 0 following reset */
125 		 .VDSEL1 = 0x3,
126 		 .RSVD2 = 0x3,
127 		 .HOCOEN = !DT_NODE_HAS_STATUS(DT_PATH(clocks, clock_hoco), okay),
128 		 .RSVD3 = 0x7,
129 		 .HOCOFRQ1 = OFS1_HOCO_FREQ,
130 		 .RSVD4 = 0x1ffff},
131 	/*
132 	 * Initial settings for MPU. Set all areas to maximum values
133 	 * essentially disabling MPU functionality as config options
134 	 * have not yet been implemented.
135 	 */
136 	.mpu = {.SECMPUPCSO = 0x00fffffc,
137 		.SECMPUPCEO = 0x00ffffff,
138 		.SECMPUPCS1 = 0x00fffffc,
139 		.SECMPUPCE1 = 0x00ffffff,
140 		.SECMPUS0 = 0x00fffffc,
141 		.SECMPUE0 = 0x00ffffff,
142 		.SECMPUS1 = 0x200ffffc,
143 		.SECMPUE1 = 0x200fffff,
144 		.SECMPUS2 = 0x407ffffc,
145 		.SECMPUE2 = 0x407fffff,
146 		.SECMPUS3 = 0x40dffffc,
147 		.SECMPUE3 = 0x40dfffff,
148 		.SECMPUAC = 0xffffffff}};
149 #endif
150 
151 uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT;
152 
153 volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT;
154 
155 #ifdef CONFIG_RUNTIME_NMI
156 extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[];
157 extern void NMI_Handler(void);
158 #endif /* CONFIG_RUNTIME_NMI */
159 
160 /**
161  * @brief Perform basic hardware initialization at boot.
162  *
163  * This needs to be run from the very beginning.
164  */
soc_early_init_hook(void)165 void soc_early_init_hook(void)
166 {
167 	uint32_t key;
168 
169 	key = irq_lock();
170 
171 	SystemCoreClock = BSP_MOCO_HZ;
172 	g_protect_pfswe_counter = 0;
173 
174 #ifdef CONFIG_RUNTIME_NMI
175 	for (uint32_t i = 0; i < 16; i++) {
176 		g_bsp_group_irq_sources[i] = 0;
177 	}
178 
179 	z_arm_nmi_set_handler(NMI_Handler);
180 #endif /* CONFIG_RUNTIME_NMI */
181 
182 	irq_unlock(key);
183 }
184