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_SYS_H__
11 #define __CH56X_SYS_H__
12 
13 #include "soc.h"
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 #define sys_safe_access_enter(sys) \
20         do { \
21             sys->SAFE_ACCESS_SIG.reg = SAFE_ACCESS_SIG_1; \
22             sys->SAFE_ACCESS_SIG.reg = SAFE_ACCESS_SIG_2; \
23         } while(0)
24 
25 #define sys_safe_access_leave(sys) \
26         do sys->SAFE_ACCESS_SIG.reg = 0; while(0)
27 
28 union _sys_safe_access_sig
29 {
30     uint8_t reg;
31     struct
32     {
33         uint8_t safe_acc_mode   : 2;  // RO, current safe access, 11b => RWA ok
34         uint8_t resv_2          : 2;
35         uint8_t safe_acc_timer  : 3;  // RO, current safe access time count
36         uint8_t resv_7          : 1;
37     };
38 };
39 #define RB_SAFE_ACC_MODE        0x03
40 #define RB_SAFE_ACC_TIMER       0x70
41 
42 #define SAFE_ACCESS_SIG_1       0x57
43 #define SAFE_ACCESS_SIG_2       0xa8
44 
45 union _sys_glob_rom_cfg
46 {
47     uint8_t reg;
48     struct
49     {
50         uint8_t rom_ext_re      : 1;  // RO, allow programmer to read FlashROM
51         uint8_t code_ram_we     : 1;  // RWA, code SRAM writaboe
52         uint8_t rom_data_we     : 1;  // RWA, FlashROM data erasable/writable
53         uint8_t rom_code_we     : 1;  // RWA, FlashROM code erasable/writable
54         uint8_t rom_code_ofs    : 1;  // RWA, FlashROM offset for user code
55         uint8_t resv_5          : 3;
56     };
57 };
58 #define RB_ROM_EXT_RE           0x01
59 #define RB_CODE_RAM_WE          0x02
60 #define RB_ROM_DATA_WE          0x04
61 #define RB_ROM_CODE_WE          0x08
62 #define RB_ROM_CODE_OFS         0x10
63 
64 #define ROM_CODE_OFS_0x00000    0
65 #define ROM_CODE_OFS_0x04000    1
66 
67 union _sys_rst_boot_stat
68 {
69     uint8_t reg;
70     struct
71     {
72         uint8_t reset_flag      : 2;  // RO, last reset cause
73         uint8_t cfg_reset_en    : 1;  // RO, external reset pin (#RST) status
74         uint8_t cfg_boot_en     : 1;  // RO, reset as 1
75         uint8_t cfg_debug_en    : 1;  // RO
76         uint8_t boot_loader     : 1;  // RO
77         uint8_t resv_6          : 2;
78     };
79 };
80 #define RB_RESET_FLAG           0x03
81 #define RB_CFG_RESET_EN         0x04
82 #define RB_CFG_BOOT_EN          0x08
83 #define RB_CFG_DEBUG_EN         0x10
84 #define RB_BOOT_LOADER          0x20
85 
86 #define RESET_FLAG_IS_SOFT      0
87 #define RESET_FLAG_IS_POR       1
88 #define RESET_FLAG_IS_WDOG      2
89 #define RESET_FLAG_IS_RSTPIN    3
90 
91 union _sys_rst_wdog_ctrl
92 {
93     uint8_t reg;
94     struct
95     {
96         uint8_t software_reset  : 1;  // WA/WZ, system software reset, auto clear
97 #if defined(SOC_SERIES_CH569)
98         uint8_t wdog_rst_en     : 1;  // RWA, enable watchdog overflow to reset
99         uint8_t wdog_int_en     : 1;  // RWA, enable watchdog overflow interrupt
100         uint8_t wdog_int_flag   : 1;  // RW1, watchdog counter overflow
101 #else
102         uint8_t resv_2          : 3;
103 #endif
104         uint8_t resv_4          : 4;  // RO, B.7-6 must write 01b
105     };
106 };
107 #define RB_SOFTWARE_RESET       0x01
108 #ifdef SOC_SERIES_CH569
109 #define RB_WDOG_RST_EN          0x02
110 #define RB_WDOG_INT_EN          0x04
111 #define RB_WDOG_INT_FLAG        0x08
112 #endif
113 #define wdog_ctrl_wdat(v)       (0x40 | (v))
114 
115 union _sys_clk_pll_div
116 {
117     uint8_t reg;
118     struct
119     {
120         uint8_t pll_div         : 4;  // RWA, min 2
121         uint8_t resv_4          : 4;  // RWA, B.7-6 must write 01b
122     };
123 };
124 #define clk_pll_div_wdat(div)   (0x40 | (div))
125 
126 union _sys_clk_cfg_ctrl
127 {
128     uint8_t reg;
129     struct
130     {
131         uint8_t pll_sleep       : 1;  // RWA, PLL sleep control
132         uint8_t sel_pll         : 1;  // RWA, clock source select
133         uint8_t resv_6          : 6;  // RWA, must write 10b
134     };
135 };
136 #define RB_CLK_PLL_SLEEP        0x01
137 #define RB_CLK_SEL_PLL          0x02
138 
139 #define CLK_PLL_SLEEP_DISABLE   0
140 #define CLK_PLL_SLEEP_ENABLE    1
141 #define CLK_SEL_PLL_HSE_30M     0
142 #define CLK_SEL_PLL_USB_480M    1
143 #define clk_cfg_ctrl_wdat(v)    (0x80 | (v))
144 
145 union _sys_clk_mod_aux
146 {
147     uint8_t reg;
148     struct
149     {
150         uint8_t int_125m_en     : 1;  // RWA, USB PHY 125MHz to ETH
151         uint8_t ext_125m_en     : 1;  // RWA, external 125MHz to ETH
152         uint8_t mco_sel_msk     : 2;  // RWA, MCO output select
153         uint8_t mco_en          : 1;  // RWA, MCO output enable
154         uint8_t resv_5          : 3;
155     };
156 };
157 #define RB_INT_125M_EN          0x01
158 #define RB_EXT_125M_EN          0x02
159 #define RB_MCO_SEL_MSK          0x0c
160 #define RB_MCO_EN               0x10
161 
162 #define MCO_SEL_MSK_125M        0
163 #define MCO_SEL_MSK_25M         1
164 #define MCO_SEL_MSK_2_5M        2
165 
166 /* All bits are RWA (need safe_access_sig), 0/1 : clock on/off
167 */
168 union _sys_slp_clk_off0
169 {
170     uint8_t reg;
171     struct
172     {
173         uint8_t tmr0    : 1;
174         uint8_t tmr1    : 1;
175         uint8_t tmr2    : 1;
176         uint8_t pwmx    : 1;
177         uint8_t uart0   : 1;
178         uint8_t uart1   : 1;
179         uint8_t uart2   : 1;
180         uint8_t uart3   : 1;
181     };
182 };
183 #define RB_SLP_CLK_TMR0         0x01
184 #define RB_SLP_CLK_TMR1         0x02
185 #define RB_SLP_CLK_TMR2         0x04
186 #define RB_SLP_CLK_PWMX         0x08
187 #define RB_SLP_CLK_UART0        0x10
188 #define RB_SLP_CLK_UART1        0x20
189 #define RB_SLP_CLK_UART2        0x40
190 #define RB_SLP_CLK_UART3        0x80
191 
192 #define SYS_SLP_CLK_ON          0
193 #define SYS_SLP_CLK_OFF         1
194 
195 /* All writable bits are RWA (need safe_access_sig), 0/1 : clock on/off
196 */
197 union _sys_slp_clk_off1
198 {
199     uint8_t reg;
200     struct
201     {
202         uint8_t spi0    : 1;
203         uint8_t spi1    : 1;
204 #if defined(SOC_CH567)
205         uint8_t sdc     : 1;
206         uint8_t led     : 1;
207         uint8_t usb0    : 1;
208         uint8_t usb1    : 1;
209         uint8_t resv_6  : 1;
210 #elif defined(SOC_CH568)
211         uint8_t sdc     : 1;
212         uint8_t led     : 1;
213         uint8_t resv_4  : 1;
214         uint8_t usb1    : 1;
215         uint8_t sata    : 1;
216         uint8_t ecdc    : 1;
217 #else
218         uint8_t emmc    : 1;
219         uint8_t hspi    : 1;
220         uint8_t usbhs   : 1;
221         uint8_t usbss   : 1;
222         uint8_t serd    : 1;
223         uint8_t dvp     : 1;
224 #endif
225     };
226 };
227 #define RB_SLP_CLK_SPI0         0x01
228 #define RB_SLP_CLK_SPI1         0x02
229 #if defined(SOC_WCH_CH567)
230 #define RB_SLP_CLK_SDC          0x04
231 #define RB_SLP_CLK_LED          0x08
232 #define RB_SLP_CLK_USB0         0x10
233 #define RB_SLP_CLK_USB1         0x20
234 #define RB_SLP_CLK_ECDC         0x80
235 #elif defined(SOC_WCH_CH568)
236 #define RB_SLP_CLK_SDC          0x04
237 #define RB_SLP_CLK_LED          0x08
238 #define RB_SLP_CLK_USB1         0x20
239 #define RB_SLP_CLK_SATA         0x40
240 #define RB_SLP_CLK_ECDC         0x80
241 #else
242 #define RB_SLP_CLK_EMMC         0x04
243 #define RB_SLP_CLK_HSPI         0x08
244 #define RB_SLP_CLK_USBHS        0x10
245 #define RB_SLP_CLK_USBSS        0x20
246 #define RB_SLP_CLK_SERD         0x40
247 #define RB_SLP_CLK_DVP          0x80
248 #endif
249 
250 /* All writable bits are RWA (need safe_access_sig)
251 */
252 union _sys_slp_wake_ctrl
253 {
254     uint8_t reg;
255     struct
256     {
257 #if defined(SOC_WCH_CH567)
258         uint8_t usb0_wake       : 1;
259         uint8_t usb1_wake       : 1;
260         uint8_t resv_2          : 2;
261         uint8_t gpio_wake       : 1;
262         uint8_t resv_5          : 3;
263 #elif defined(SOC_WCH_CH568)
264         uint8_t resv_0          : 1;
265         uint8_t usb1_wake       : 1;
266         uint8_t sata_wake       : 1;
267         uint8_t resv_3          : 1;
268         uint8_t gpio_wake       : 1;
269         uint8_t resv_5          : 3;
270 #else
271         uint8_t usbhs_wake      : 1;
272         uint8_t usbss_wake      : 1;
273         uint8_t clk_eth         : 1;
274         uint8_t clk_ecdc        : 1;
275         uint8_t gpio_wake       : 1;
276         uint8_t eth_wake        : 1;
277         uint8_t resv_6          : 2;
278 #endif
279     };
280 };
281 #if defined(SOC_WCH_CH567)
282 #define RB_SLP_USB0_WAKE        0x01
283 #define RB_SLP_USB1_WAKE        0x02
284 #define RB_SLP_GPIO_WAKE        0x10
285 #elif defined(SOC_WCH_CH568)
286 #define RB_SLP_USB1_WAKE        0x02
287 #define RB_SLP_SATA_WAKE        0x04
288 #define RB_SLP_GPIO_WAKE        0x10
289 #else
290 #define RB_SLP_USBHS_WAKE       0x01
291 #define RB_SLP_USBSS_WAKE       0x02
292 #define RB_SLP_CLK_ETH          0x04
293 #define RB_SLP_CLK_ECDC         0x08
294 #define RB_SLP_GPIO_WAKE        0x10
295 #define RB_SLP_ETH_WAKE         0x20
296 #endif
297 
298 union _sys_slp_power_ctrl
299 {
300     uint8_t reg;
301     struct
302     {
303         uint8_t usbhs_pwrdn     : 1;  // RWA, USBHS power down (0:PWRUP)
304         uint8_t resv_2          : 7;
305     };
306 };
307 #define RB_SLP_USBHS_PWRDN      0x01
308 
309 union _sys_serd_ana_cfg1
310 {
311     uint16_t reg;
312     struct
313     {
314         uint8_t serd_pll_cfg;         // RWA, reset as 0x5a
315         uint8_t serd_30m_sel    : 1;  // RWA
316         uint8_t serd_dn_tst     : 1;  // RWA
317         uint8_t resv_10         : 6;
318     };
319 };
320 #define RB_SERD_PLL_CFG         0x0ff
321 #define RB_SERD_30M_SEL         0x100
322 #define RB_SERD_DN_TST          0x200
323 
324 union _sys_serd_ana_cfg2
325 {
326     uint32_t reg;
327     struct
328     {
329         uint32_t serd_trx_cfg   : 25;  // RWA, reset as 423015h
330         uint32_t resv_25        : 7;
331     };
332 };
333 #define RB_SERD_TRX_CFG         0x1000000
334 
335 /*
336  * 0x00  R8_SAFE_ACCESS_SIG: safe access signature register
337  * 0x01  R8_CHIP_ID:         RF, chip ID register
338  * 0x02  R8_SAFE_ACCESS_ID:  RF, read as 02h
339  * 0x03  R8_WDOG_COUNT       RW, watchdog counter
340  * 0x04  R8_GLOB_ROM_CFG:    ROM config register
341  * 0x05  R8_RST_BOOT_STAT:   RO, boot state register
342  * 0x06  R8_RST_WDOG_CTRL:   software reset & watchdog control register
343  * 0x07  R8_GLOB_RESET_KEEP: RW, only power-on-reset can clear this register
344  * 0x08  R8_CLK_PLL_DIV:     RWA, PLL output divisor register
345  * 0x0a  R8_CLK_CFG_CTRL:    RWA, clock config register
346  * 0x0b  R8_CLK_MOD_AUX:     RWA, clock auxiliary register
347  * 0x0c  R8_SLP_CLK_OFF0:    RWA, sleep control register 0
348  * 0x0d  R8_SLP_CLK_OFF1:    RWA, sleep control register 1
349  * 0x0e  R8_SLP_WAKE_CTRL:   RWA, wakeup control register
350  * 0x0f  R8_SLP_POWER_CTRL:  RWA, low power management register
351  * 0x20  R16_SERD_ANA_CFG1:  RWA, SerDes PHY analog param config register 1
352  * 0x24  R32_SERD_ANA_CFG2:  RWA, SerDes PHY analog param config register 2
353  *
354  * CAVEAT: gcc (as of 8.2.0) tends to read 32-bit word for bit field test.
355  * Be careful for those with side effect for read.
356  */
357 struct sys_registers
358 {
359     union _sys_safe_access_sig  SAFE_ACCESS_SIG;
360     uint8_t                     CHIP_ID;
361     uint8_t                     SAFE_ACCESS_ID;
362     uint8_t                     WDOG_COUNT;
363     union _sys_glob_rom_cfg     GLOB_ROM_CFG;
364     union _sys_rst_boot_stat    RST_BOOT_STAT;
365     union _sys_rst_wdog_ctrl    RST_WDOG_CTRL;
366     uint8_t                     GLOB_RESET_KEEP;
367     union _sys_clk_pll_div      CLK_PLL_DIV;
368     uint8_t                     resv_9;
369     union _sys_clk_cfg_ctrl     CLK_CFG_CTRL;
370     union _sys_clk_mod_aux      CLK_MOD_AUX;
371     union _sys_slp_clk_off0     SLP_CLK_OFF0;
372     union _sys_slp_clk_off1     SLP_CLK_OFF1;
373     union _sys_slp_wake_ctrl    SLP_WAKE_CTRL;
374     union _sys_slp_power_ctrl   SLP_POWER_CTRL;
375 #if defined(SOC_SERIES_CH569)
376     uint32_t                    resv_10[4];
377     union _sys_serd_ana_cfg1    SERD_ANA_CFG1;
378     uint16_t                    resv_22;
379     union _sys_serd_ana_cfg2    SERD_ANA_CFG2;
380 #endif
381 } __packed;
382 
383 CHECK_STRUCT_SIZE(struct sys_registers, 0x28);
384 
385 uint32_t sys_hclk_calc(void);
386 uint32_t sys_hclk_get(void);
387 int  sys_hclk_set(uint32_t freq);
388 int  sys_clk_off_by_irqn(uint8_t irqn, int off);
389 void sys_slp_clk_off0(uint8_t bits, int off);
390 void sys_slp_clk_off1(uint8_t bits, int off);
391 
392 #ifdef __cplusplus
393 }
394 #endif
395 
396 #endif
397