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