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 const struct opt_set_mem ops __attribute__((section(".rom_registers"))) = {
97 .ofs0 = {
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 .RSVD1 = 0x1, .IWDTSTRT = 0x1, /* Disable independent watchdog timer
104 */
105 .IWDTTOPS = 0x3, .IWDTCKS = 0xf, .IWDTRPES = 0x3, .IWDTRPSS = 0x3,
106 .IWDTRSTIRQS = 0x1, .RSVD2 = 0x1, .IWDTSTPCTL = 0x1, .RSVD3 = 0x3,
107 .WDTSTRT = 0x1, /* Stop watchdog timer following reset */
108 .WDTTOPS = 0x3, .WDTCKS = 0xf, .WDTRPES = 0x3, .WDTRPSS = 0x3,
109 .WDTRSTIRQS = 0x1, .RSVD4 = 0x1, .WDTSTPCTL = 0x1, .RSVD5 = 0x1,
110 },
111 .ofs1 = {
112 .RSVD1 = 0x3,
113 .LVDAS = 0x1, /* Disable voltage monitor 0 following reset */
114 .VDSEL1 = 0x3,
115 .RSVD2 = 0x3,
116 .HOCOEN = !DT_NODE_HAS_STATUS(DT_PATH(clocks, clock_hoco), okay),
117 .RSVD3 = 0x7,
118 .HOCOFRQ1 = OFS1_HOCO_FREQ,
119 .RSVD4 = 0x1ffff,
120 },
121 .mpu = {
122 /*
123 * Initial settings for MPU. Set all areas to maximum values
124 * essentially disabling MPU functionality as config options
125 * have not yet been implemented.
126 */
127 .SECMPUPCSO = 0x00fffffc,
128 .SECMPUPCEO = 0x00ffffff,
129 .SECMPUPCS1 = 0x00fffffc,
130 .SECMPUPCE1 = 0x00ffffff,
131 .SECMPUS0 = 0x00fffffc,
132 .SECMPUE0 = 0x00ffffff,
133 .SECMPUS1 = 0x200ffffc,
134 .SECMPUE1 = 0x200fffff,
135 .SECMPUS2 = 0x407ffffc,
136 .SECMPUE2 = 0x407fffff,
137 .SECMPUS3 = 0x40dffffc,
138 .SECMPUE3 = 0x40dfffff,
139 .SECMPUAC = 0xffffffff,
140 }};
141 #endif
142
143 uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT;
144
145 volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT;
146
147 /**
148 * @brief Perform basic hardware initialization at boot.
149 *
150 * This needs to be run from the very beginning.
151 */
soc_early_init_hook(void)152 void soc_early_init_hook(void)
153 {
154 uint32_t key;
155
156 key = irq_lock();
157
158 SystemCoreClock = BSP_MOCO_HZ;
159 g_protect_pfswe_counter = 0;
160
161 irq_unlock(key);
162 }
163