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