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