1 /******************************************************************************
2  * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *   http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************/
18 
19 /********************************************************************************************************
20  * @file	clock.h
21  *
22  * @brief	This is the header file for B91
23  *
24  * @author	Driver Group
25  *
26  *******************************************************************************************************/
27 /**	@page CLOCK
28  *
29  *	Introduction
30  *	===============
31  *	TLSRB91 clock setting.
32  *
33  *	API Reference
34  *	===============
35  *	Header File: clock.h
36  */
37 
38 #ifndef CLOCK_H_
39 #define CLOCK_H_
40 
41 #include "reg_include/register_b91.h"
42 #include "compiler.h"
43 
44 /**********************************************************************************************************************
45  *                                         global constants                                                           *
46  *********************************************************************************************************************/
47 
48 /**********************************************************************************************************************
49  *                                           global macro                                                             *
50  *********************************************************************************************************************/
51 #define  	CCLK_16M_HCLK_16M_PCLK_16M		clock_init(PLL_CLK_192M, PAD_PLL_DIV, PLL_DIV12_TO_CCLK, CCLK_DIV1_TO_HCLK, HCLK_DIV1_TO_PCLK, PLL_DIV4_TO_MSPI_CLK)
52 #define		CCLK_24M_HCLK_24M_PCLK_24M		clock_init(PLL_CLK_192M, PAD_PLL_DIV, PLL_DIV8_TO_CCLK, CCLK_DIV1_TO_HCLK, HCLK_DIV1_TO_PCLK, PLL_DIV4_TO_MSPI_CLK)
53 #define		CCLK_32M_HCLK_32M_PCLK_16M		clock_init(PLL_CLK_192M, PAD_PLL_DIV, PLL_DIV6_TO_CCLK, CCLK_DIV1_TO_HCLK, HCLK_DIV2_TO_PCLK, PLL_DIV4_TO_MSPI_CLK)
54 #define		CCLK_48M_HCLK_48M_PCLK_24M		clock_init(PLL_CLK_192M, PAD_PLL_DIV, PLL_DIV4_TO_CCLK, CCLK_DIV1_TO_HCLK, HCLK_DIV2_TO_PCLK, PLL_DIV4_TO_MSPI_CLK)
55 
56 /**********************************************************************************************************************
57  *                                         global data type                                                           *
58  *********************************************************************************************************************/
59 
60 /**
61  *  @brief  Define sys_clk struct.
62  */
63 typedef struct {
64 	unsigned short pll_clk;		/**< pll clk */
65 	unsigned char cclk;			/**< cpu clk */
66 	unsigned char hclk;			/**< hclk */
67 	unsigned char pclk;			/**< pclk */
68 	unsigned char mspi_clk;		/**< mspi_clk */
69 }sys_clk_t;
70 
71 
72 /**
73  * @brief system clock type
74  * |           |              |               |
75  * | :-------- | :----------- | :------------ |
76  * |   <1:0>   |     <6:2>    |    <15:8>     |
77  * |ana_09<3:2>|analog_80<4:0>|      clk      |
78  */
79 typedef enum{
80 	PLL_CLK_48M 	= (0 | (16 << 2) | (48 << 8)),
81 	PLL_CLK_54M 	= (0 | (17 << 2) | (54 << 8)),
82 	PLL_CLK_60M 	= (0 | (18 << 2) | (54 << 8)),
83 	PLL_CLK_66M 	= (0 | (19 << 2) | (66 << 8)),
84 	PLL_CLK_96M 	= (1 | (16 << 2) | (96 << 8)),
85 	PLL_CLK_108M 	= (1 | (17 << 2) | (108 << 8)),
86 	PLL_CLK_120M 	= (1 | (18 << 2) | (120 << 8)),
87 	PLL_CLK_132M 	= (1 | (19 << 2) | (132 << 8)),
88 	PLL_CLK_192M 	= (2 | (16 << 2) | (192 << 8)),
89 	PLL_CLK_216M 	= (2 | (17 << 2) | (216 << 8)),
90 	PLL_CLK_240M 	= (2 | (18 << 2) | (240 << 8)),
91 	PLL_CLK_264M 	= (2 | (19 << 2) | (264 << 8)),
92 }sys_pll_clk_e;
93 
94 /**
95  * @brief system clock type.
96  */
97 typedef enum{
98 	RC24M,
99 	PAD24M,
100 	PAD_PLL_DIV,
101 	PAD_PLL,
102 }sys_clock_src_e;
103 
104 /**
105  * @brief 32K clock type.
106  */
107 typedef enum{
108 	CLK_32K_RC   =0,
109 	CLK_32K_XTAL =1,
110 }clk_32k_type_e;
111 
112 /**
113  * @brief pll div to cclk.
114  */
115 typedef enum{
116 	PLL_DIV2_TO_CCLK    =    2,
117 	PLL_DIV3_TO_CCLK    =    3,
118 	PLL_DIV4_TO_CCLK    =    4,
119 	PLL_DIV5_TO_CCLK    =    5,
120 	PLL_DIV6_TO_CCLK    =    6,
121 	PLL_DIV7_TO_CCLK    =    7,
122 	PLL_DIV8_TO_CCLK    =    8,
123 	PLL_DIV9_TO_CCLK    =    9,
124 	PLL_DIV10_TO_CCLK   =    10,
125 	PLL_DIV11_TO_CCLK   =    11,
126 	PLL_DIV12_TO_CCLK   =    12,
127 	PLL_DIV13_TO_CCLK   =    13,
128 	PLL_DIV14_TO_CCLK   =    14,
129 	PLL_DIV15_TO_CCLK   =    15,
130 }sys_pll_div_to_cclk_e;
131 
132 /**
133  * @brief cclk/pll_div to mspi clk.
134  */
135 typedef enum{
136 	CCLK_TO_MSPI_CLK       	=    1,
137 	PLL_DIV2_TO_MSPI_CLK    =    2,
138 	PLL_DIV3_TO_MSPI_CLK    =    3,
139 	PLL_DIV4_TO_MSPI_CLK    =    4,
140 	PLL_DIV5_TO_MSPI_CLK    =    5,
141 	PLL_DIV6_TO_MSPI_CLK    =    6,
142 	PLL_DIV7_TO_MSPI_CLK    =    7,
143 	PLL_DIV8_TO_MSPI_CLK    =    8,
144 	PLL_DIV9_TO_MSPI_CLK    =    9,
145 	PLL_DIV10_TO_MSPI_CLK   =    10,
146 	PLL_DIV11_TO_MSPI_CLK   =    11,
147 	PLL_DIV12_TO_MSPI_CLK   =    12,
148 	PLL_DIV13_TO_MSPI_CLK   =    13,
149 	PLL_DIV14_TO_MSPI_CLK   =    14,
150 	PLL_DIV15_TO_MSPI_CLK   =    15,
151 }sys_pll_div_to_mspi_clk_e;
152 
153 /**
154  * @brief hclk div to pclk.
155  */
156 typedef enum{
157 	HCLK_DIV1_TO_PCLK    =    1,
158 	HCLK_DIV2_TO_PCLK    =    2,
159 	HCLK_DIV4_TO_PCLK    =    4,
160 }sys_hclk_div_to_pclk_e;
161 
162 /**
163  * @brief cclk div to hclk.
164  */
165 typedef enum{
166 	CCLK_DIV1_TO_HCLK    =    1,
167 	CCLK_DIV2_TO_HCLK    =    2,  /*< can not use in A0. if use reboot when hclk = 1/2cclk will cause problem */
168 }sys_cclk_div_to_hclk_e;
169 
170 /**
171  *  @brief  Define rc_24M_cal enable/disable.
172  */
173 typedef enum {
174 	RC_24M_CAL_DISABLE=0,
175 	RC_24M_CAL_ENABLE,
176 
177 }rc_24M_cal_e;
178 
179 
180 /**********************************************************************************************************************
181  *                                     global variable declaration                                                    *
182  *********************************************************************************************************************/
183 extern sys_clk_t sys_clk;
184 extern clk_32k_type_e g_clk_32k_src;
185 
186 /**********************************************************************************************************************
187  *                                      global function prototype                                                     *
188  *********************************************************************************************************************/
189 
190 /**
191  * @brief       This function use to select the system clock source.
192  * @param[in]   pll - pll clock.
193  * @param[in]	src - cclk source.
194  * @param[in]	cclk_div - the cclk divide from pll.it is useless if src is not PAD_PLL_DIV. cclk max is 96M
195  * @param[in]	hclk_div - the hclk divide from cclk.hclk max is 48M.
196  * @param[in]	pclk_div - the pclk divide from hclk.pclk max is 24M.
197  * @param[in]	mspi_clk_div - mspi_clk has two source. pll div and hclk.mspi max is 64M.
198  * @return      none
199  */
200 _attribute_ram_code_sec_noinline_ void clock_init(sys_pll_clk_e pll,
201 		sys_clock_src_e src,
202 		sys_pll_div_to_cclk_e cclk_div,
203 		sys_cclk_div_to_hclk_e hclk_div,
204 		sys_hclk_div_to_pclk_e pclk_div,
205 		sys_pll_div_to_mspi_clk_e mspi_clk_div);
206 
207 /**
208  * @brief   	This function serves to set 32k clock source.
209  * @param[in]   src - variable of 32k type.
210  * @return  	none.
211  */
212 void clock_32k_init(clk_32k_type_e src);
213 
214 /**
215  * @brief   	This function serves to kick 32k xtal.
216  * @param[in]   xtal_times - kick times.
217  * @return  	1 success, 0 error.
218  */
219 unsigned char clock_kick_32k_xtal(unsigned char xtal_times);
220 
221 /**
222  * @brief     	This function performs to select 24M as the system clock source.
223  * @return		none.
224  */
225 _attribute_ram_code_sec_noinline_ void clock_cal_24m_rc (void);
226 
227 /**
228  * @brief     This function performs to select 32K as the system clock source.
229  * @return    none.
230  */
231 void clock_cal_32k_rc (void);
232 
233 /**
234  * @brief  This function serves to get the 32k tick.
235  * @return none.
236  */
237 _attribute_ram_code_sec_noinline_  unsigned int clock_get_32k_tick (void);
238 
239 /**
240  * @brief  This function serves to set the 32k tick.
241  * @param  tick - the value of to be set to 32k.
242  * @return none.
243  */
244 _attribute_ram_code_sec_noinline_ void clock_set_32k_tick(unsigned int tick);
245 #endif
246 
247