1 /*
2 * Copyright (c) 2021 Telink Semiconductor
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "sys.h"
8 #include "clock.h"
9 #include <zephyr/init.h>
10 #include <zephyr/devicetree.h>
11
12 /* Software reset defines */
13 #define reg_reset REG_ADDR8(0x1401ef)
14 #define SOFT_RESET 0x20u
15
16 /* List of supported CCLK frequencies */
17 #define CLK_16MHZ 16000000u
18 #define CLK_24MHZ 24000000u
19 #define CLK_32MHZ 32000000u
20 #define CLK_48MHZ 48000000u
21 #define CLK_64MHZ 64000000u
22 #define CLK_96MHZ 96000000u
23
24 /* Define 48 MHz and 96 MHz CCLK clock options (not present in HAL) */
25 #define CCLK_64M_HCLK_32M_PCLK_16M clock_init(PLL_CLK_192M, \
26 PAD_PLL_DIV, \
27 PLL_DIV3_TO_CCLK, \
28 CCLK_DIV2_TO_HCLK, \
29 HCLK_DIV2_TO_PCLK, \
30 PLL_DIV4_TO_MSPI_CLK)
31
32 #define CCLK_96M_HCLK_48M_PCLK_24M clock_init(PLL_CLK_192M, \
33 PAD_PLL_DIV, \
34 PLL_DIV2_TO_CCLK, \
35 CCLK_DIV2_TO_HCLK, \
36 HCLK_DIV2_TO_PCLK, \
37 PLL_DIV4_TO_MSPI_CLK)
38
39 /* Power Mode value */
40 #if DT_ENUM_IDX(DT_NODELABEL(power), power_mode) == 0
41 #define POWER_MODE LDO_1P4_LDO_1P8
42 #elif DT_ENUM_IDX(DT_NODELABEL(power), power_mode) == 1
43 #define POWER_MODE DCDC_1P4_LDO_1P8
44 #elif DT_ENUM_IDX(DT_NODELABEL(power), power_mode) == 2
45 #define POWER_MODE DCDC_1P4_DCDC_1P8
46 #else
47 #error "Wrong value for power-mode parameter"
48 #endif
49
50 /* Vbat Type value */
51 #if DT_ENUM_IDX(DT_NODELABEL(power), vbat_type) == 0
52 #define VBAT_TYPE VBAT_MAX_VALUE_LESS_THAN_3V6
53 #elif DT_ENUM_IDX(DT_NODELABEL(power), vbat_type) == 1
54 #define VBAT_TYPE VBAT_MAX_VALUE_GREATER_THAN_3V6
55 #else
56 #error "Wrong value for vbat-type parameter"
57 #endif
58
59 /* Check System Clock value. */
60 #if ((DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency) != CLK_16MHZ) && \
61 (DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency) != CLK_24MHZ) && \
62 (DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency) != CLK_32MHZ) && \
63 (DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency) != CLK_48MHZ) && \
64 (DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency) != CLK_64MHZ) && \
65 (DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency) != CLK_96MHZ))
66 #error "Unsupported clock-frequency. Supported values: 16, 24, 32, 48, 64 and 96 MHz"
67 #endif
68
69 /**
70 * @brief Perform basic initialization at boot.
71 *
72 * @return 0
73 */
soc_early_init_hook(void)74 void soc_early_init_hook(void)
75 {
76 unsigned int cclk = DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency);
77
78
79 /* system init */
80 sys_init(POWER_MODE, VBAT_TYPE);
81
82 /* clocks init: CCLK, HCLK, PCLK */
83 switch (cclk) {
84 case CLK_16MHZ:
85 CCLK_16M_HCLK_16M_PCLK_16M;
86 break;
87
88 case CLK_24MHZ:
89 CCLK_24M_HCLK_24M_PCLK_24M;
90 break;
91
92 case CLK_32MHZ:
93 CCLK_32M_HCLK_32M_PCLK_16M;
94 break;
95
96 case CLK_48MHZ:
97 CCLK_48M_HCLK_48M_PCLK_24M;
98 break;
99
100 case CLK_64MHZ:
101 CCLK_64M_HCLK_32M_PCLK_16M;
102 break;
103
104 case CLK_96MHZ:
105 CCLK_96M_HCLK_48M_PCLK_24M;
106 break;
107 }
108
109 /* Init Machine Timer source clock: 32 KHz RC */
110 clock_32k_init(CLK_32K_RC);
111 clock_cal_32k_rc();
112 }
113
114 /**
115 * @brief Reset the system.
116 */
sys_arch_reboot(int type)117 void sys_arch_reboot(int type)
118 {
119 ARG_UNUSED(type);
120
121 reg_reset = SOFT_RESET;
122 }
123