1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2022-07-15 Emuzit first version
9 */
10 #ifndef __CH56X_PFIC_H__
11 #define __CH56X_PFIC_H__
12
13 #include "soc.h"
14
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18
19 /* IREG: IENR/IRER/IRSR/IPRR, make sure irqn be 12~59
20 */
21 #define PFIC_IREG1_MASK 0xfffff000
22 #define PFIC_IREG2_MASK 0x0fffffff
23 #define PFIC_MAX_IREG_BITS 60
24
25 #define _pfic_ireg_bit_get(pfic, IREG, irqn) \
26 ((pfic->IREG[(irqn) >> 5] >> ((irqn) & 0x1f)) & 1)
27
28 #define _pfic_ireg_bit_set(pfic, IREG, irqn) \
29 do pfic->IREG[(irqn) >> 5] = 1 << ((irqn) & 0x1f); while(0)
30
31 #define _pfic_irqn_enable(pfic, irqn) _pfic_ireg_bit_set(pfic, IENR, irqn)
32 #define _pfic_irqn_disable(pfic, irqn) _pfic_ireg_bit_set(pfic, IRER, irqn)
33
34 /* Note: `union _pfic_cfgr` is not used directly in the reg structure */
35 union _pfic_cfgr
36 {
37 uint32_t reg;
38 struct
39 {
40 uint32_t hwstkctrl : 1; // RW, hw stack push/pop control (0:enable)
41 uint32_t nestctrl : 1; // RW, nested intr enable control (0:enable)
42 uint32_t nmiset : 1; // WO, write 1 to set NMI pending
43 uint32_t nmireset : 1; // WO, write 1 to reset NMI pending
44 uint32_t excset : 1; // WO, write 1 to set exception pending
45 uint32_t excreset : 1; // WO, write 1 to reset exception pending
46 uint32_t pficreset : 1; // WO, write 1 to reset PFIC module, auto clear
47 uint32_t sysreset : 1; // WO, write 1 for a system reset, auto clear
48 uint32_t resv_8 : 8;
49 uint32_t keycode : 16; // WO, write protection keycode
50 };
51 };
52 #define PFIC_CFGR_KEY1 0xfa05 // for hwstkctrl & nestctrl
53 #define PFIC_CFGR_KEY2 0xbcaf // for nmi & exc set/reset
54 #define PFIC_CFGR_KEY3 0xbeef // for sysreset
55
56 #define PFIC_CFGR_NMISET (PFIC_CFGR_KEY2 << 16 | 1 << 2)
57 #define PFIC_CFGR_NMIRESET (PFIC_CFGR_KEY2 << 16 | 1 << 3)
58 #define PFIC_CFGR_EXCSET (PFIC_CFGR_KEY2 << 16 | 1 << 4)
59 #define PFIC_CFGR_EXCRESET (PFIC_CFGR_KEY2 << 16 | 1 << 5)
60 #define PFIC_CFGR_PFICRESET (1 << 6)
61 #define PFIC_CFGR_SYSRESET (PFIC_CFGR_KEY3 << 16 | 1 << 7)
62
63 #define CFGR_HWSTKCTRL_ENABLE (0 << 0)
64 #define CFGR_HWSTKCTRL_DISABLE (1 << 0)
65 #define CFGR_HWSTKCTRL_MASK (1 << 0)
66 #define CFGR_NESTCTRL_ENABLE (0 << 1)
67 #define CFGR_NESTCTRL_DISABLE (1 << 1)
68 #define CFGR_NESTCTRL_MASK (1 << 1)
69 #define cfgr_nest_hwstk(v) (PFIC_CFGR_KEY1 << 16 | (v))
70
71 union _pfic_gisr
72 {
73 uint32_t reg;
74 struct
75 {
76 uint32_t neststa : 8; // RO, nested interrupt state (0/1/2)
77 uint32_t gactsta : 1; // RO, global interrupt active status
78 uint32_t gpendsta : 1; // RO, global interrupt pending status
79 uint32_t resv_10 : 22;
80 };
81 };
82 #define PFIC_NESTSTA_NONE 0
83 #define PFIC_NESTSTA_L1 1
84 #define PFIC_NESTSTA_L2 2
85
86 union _pfic_fiofaddrr
87 {
88 uint32_t reg;
89 struct
90 {
91 uint32_t offaddr : 24; // RW
92 uint32_t irqid : 8; // RW
93 };
94 };
95
96 union _pfic_sctlr
97 {
98 uint32_t reg;
99 struct
100 {
101 uint32_t resv_0 : 1;
102 uint32_t sleeponexit : 1; // enter (deep) sleep mode on isr exiting
103 uint32_t sleepdeep : 1; // RW, 0/1 for sleep/deep-sleep mode
104 uint32_t wfitowfe : 1; // RW, treat WFI as WFE
105 uint32_t sevonpend : 1; // RW
106 uint32_t setevent : 1; // WO, set event for WFE
107 uint32_t resv_6 : 26;
108 };
109 };
110
111 /*
112 * 0x000 R32_PFIC_ISR1: PFIC interrupt enable status (# 12-31)
113 * 0x004 R32_PFIC_ISR2: PFIC interrupt enable status (# 32-59)
114 * 0x020 R32_PFIC_IPR1: PFIC interrupt pending status (# 12-31)
115 * 0x024 R32_PFIC_IPR2: PFIC interrupt pending status (# 32-59)
116 * 0x040 R32_PFIC_ITHRESDR: PFIC interrupt priority threshold (B.7-4)
117 * 0x044 R32_PFIC_FIBADDRR: PFIC fast intr base address (B.31-28)
118 * 0x048 R32_PFIC_CFGR: PFIC interrupt configuration register
119 * 0x04c R32_PFIC_GISR: PFIC global interrupt status register
120 * 0x060 R32_PFIC_FIOFADDRR0: PFIC fast intr 0 offset address (B.23-0)
121 * 0x064 R32_PFIC_FIOFADDRR1: PFIC fast intr 1 offset address (B.23-0)
122 * 0x068 R32_PFIC_FIOFADDRR2: PFIC fast intr 2 offset address (B.23-0)
123 * 0x06c R32_PFIC_FIOFADDRR3: PFIC fast intr 3 offset address (B.23-0)
124 * 0x100 R32_PFIC_IENR1: PFIC interrupt enable register (# 12-31)
125 * 0x104 R32_PFIC_IENR2: PFIC interrupt enable register (# 32-59)
126 * 0x180 R32_PFIC_IRER1: PFIC interrupt reset register (# 12-31)
127 * 0x184 R32_PFIC_IRER2: PFIC interrupt reset register (# 32-59)
128 * 0x200 R32_PFIC_IPSR1: PFIC interrupt pending set register (# 12-31)
129 * 0x204 R32_PFIC_IPSR2: PFIC interrupt pending set register (# 32-59)
130 * 0x280 R32_PFIC_IPRR1: PFIC interrupt pending reset register (# 12-31)
131 * 0x284 R32_PFIC_IPRR2: PFIC interrupt pending reset register (# 32-59)
132 * 0x300 R32_PFIC_IACTR1: PFIC interrupt active status register (# 12-31)
133 * 0x304 R32_PFIC_IACTR2: PFIC interrupt active status register (# 32-59)
134 * 0x400 R32_PFIC_IPRIORx: PFIC interrupt priority registers
135 * 0xd10 R32_PFIC_SCTLR: PFIC system control register
136 *
137 * CAVEAT: gcc (as of 8.2.0) tends to read 32-bit word for bit field test.
138 * Be careful for those with side effect for read.
139 */
140 struct pfic_registers
141 {
142 uint32_t ISR[2];
143 uint32_t resv_08[6];
144 uint32_t IPR[2];
145 uint32_t resv_28[6];
146 uint32_t ITHRESDR;
147 uint32_t FIBADDRR;
148 uint32_t CFGR;
149 union _pfic_gisr GISR;
150 uint32_t resv_50[4];
151 union _pfic_fiofaddrr FIOFADDRR[4];
152 uint32_t resv_70[36];
153 uint32_t IENR[2];
154 uint32_t resv_108[30];
155 uint32_t IRER[2];
156 uint32_t resv_188[30];
157 uint32_t IPSR[2];
158 uint32_t resv_208[30];
159 uint32_t IPRR[2];
160 uint32_t resv_288[30];
161 uint32_t IACTR[2];
162 uint32_t resv_308[62];
163 uint8_t IPRIOR[256];
164 uint32_t resv_500[516];
165 union _pfic_sctlr SCTLR;
166 } __packed;
167
168 CHECK_STRUCT_SIZE(struct pfic_registers, 0xd14);
169
170 union _systick_ctlr
171 {
172 uint32_t reg;
173 struct
174 {
175 uint32_t ste : 1; // RW, systick enable
176 uint32_t stie : 1; // RW, systick interrupt enable
177 uint32_t stclk : 1; // RW, systick clock source select
178 uint32_t resv_3 : 5;
179 uint32_t streload : 1; // W1, write 1 to reload systick
180 uint32_t resv_9 : 23;
181 };
182 };
183 #define RB_STKCTL_STE 0x001
184 #define RB_STKCTL_STIE 0x002
185 #define RB_STKCTL_STCLK 0x004
186 #define RB_STKCTL_STRELOAD 0x100
187
188 #define SYSTICK_SRC_HCLK_8 0
189 #define SYSTICK_SRC_HCLK 1
190
191 union _systick_cntfg
192 {
193 uint32_t reg;
194 struct
195 {
196 uint32_t swie : 1; // RW, software interrupt enable
197 uint32_t cntif : 1; // RW0, counter dec to 0 (write 0 to clear)
198 uint32_t resv_2 : 30;
199 };
200 };
201 #define RB_CNTFG_SWIE 0X01
202 #define RB_CNTFG_CNTIF 0X02
203
204 /*
205 * 0x00 R32_STK_CTLR: SysTick control register
206 * 0x04 R32_STK_CNTL: SysTick counter, Lo.32
207 * 0x08 R32_STK_CNTH: SysTick counter, Hi.32
208 * 0x0c R32_STK_CMPLR: SysTick compare-reload register, Lo.32
209 * 0x10 R32_STK_CMPHR: SysTick compare-reload register, Hi.32
210 * 0x14 R32_STK_CNTFG: SysTick counter flags
211 *
212 * CAVEAT: gcc (as of 8.2.0) tends to read 32-bit word for bit field test.
213 * Be careful for those with side effect for read.
214 */
215 struct systick_registers
216 {
217 union _systick_ctlr CTLR;
218 uint32_t CNTL;
219 uint32_t CNTH;
220 uint32_t CMPLR;
221 uint32_t CMPHR;
222 union _systick_cntfg CNTFG;
223 } __packed;
224
225 CHECK_STRUCT_SIZE(struct systick_registers, 0x18);
226
pfic_interrupt_umask(uint8_t irqn)227 rt_inline void pfic_interrupt_umask(uint8_t irqn)
228 {
229 volatile struct pfic_registers *pfic;
230
231 if (irqn < PFIC_MAX_IREG_BITS)
232 {
233 pfic = (void *)PFIC_REG_BASE;
234 _pfic_ireg_bit_set(pfic, IENR, irqn);
235 }
236 }
237
pfic_interrupt_mask(uint8_t irqn)238 rt_inline void pfic_interrupt_mask(uint8_t irqn)
239 {
240 volatile struct pfic_registers *pfic;
241
242 if (irqn < PFIC_MAX_IREG_BITS)
243 {
244 pfic = (void *)PFIC_REG_BASE;
245 _pfic_ireg_bit_set(pfic, IRER, irqn);
246 }
247 }
248
249 void pfic_swi_pendset(void);
250 void pfic_swi_pendreset(void);
251 void pfic_cfgr_set(uint32_t key_bit);
252 void systick_init(uint32_t count);
253
254 #ifdef __cplusplus
255 }
256 #endif
257
258 #endif
259