1 /*
2 // Copyright (C) 2022 Beken Corporation
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <common/bk_include.h>
16 #include "bk_arm_arch.h"
17
18 #include "bk_misc.h"
19 #include "bk_sys_ctrl.h"
20 #include "bk_fake_clock.h"
21 #include "bk_drv_model.h"
22 #include <components/system.h>
23 #include "sys_driver.h"
24
25
26 /*******************************************************************************
27 * Function Implemantation
28 *******************************************************************************/
29 /*
30 MCLK:26MHz, delay(1): about 25us
31 delay(10):about 125us
32 delay(100):about 850us
33 */
delay(INT32 num)34 void delay(INT32 num)
35 {
36 volatile INT32 i, j;
37
38 for (i = 0; i < num; i ++) {
39 for (j = 0; j < 100; j ++)
40 ;
41 }
42 }
43
44
45
46 #if (CONFIG_SYSTEM_CTRL)
47 //RISC-V has mtimer which clock is 26M and it doesn't change frequency.
48 //as delay_us is just compare risc-v timer which block system runs, so the param
49 //of us should be not too big. F.E: < 100*000
delay_us(UINT32 us)50 void delay_us(UINT32 us)
51 {
52 extern u64 riscv_get_mtimer(void);
53
54 uint64_t tick_cnt = us * 26;
55 uint64_t start_tick = riscv_get_mtimer();
56
57 while((riscv_get_mtimer() - start_tick) < tick_cnt)
58 {
59 ;
60 }
61 }
62
63 //RISC-V each i++ consumes 30 cycles
64 //we should not use delay cycle to compute time as the CPU clock changes.
delay_cycle(INT32 num)65 void delay_cycle(INT32 num)
66 {
67 volatile INT32 i;
68
69 for (i = 0; i < num; i ++) {
70 ;
71 }
72 }
73
74 //RISC-V has mtimer which clock is 26M and it doesn't change frequency.
75 //as delay_ms is just compare risc-v timer which block system runs, so the param
76 //of ms_count should be not too big. F.E: < 100
delay_ms(UINT32 ms_count)77 void delay_ms(UINT32 ms_count)
78 {
79 #if 0 //we should not use delay cycle as the CPU clock changes.
80 UINT32 div;
81 UINT32 clk = 0;
82 UINT32 cell;
83
84 UINT32 mux = sys_drv_mclk_mux_get();
85 div = sys_drv_mclk_div_get();
86 switch (mux) {
87 case 0: //XTAL
88 clk = 26000000 / (1 + div);
89 break;
90
91 case 1: //DCO
92 clk = 26000000 / (1 + div);
93 break;
94
95 case 2: //320M
96 clk = 320000000 / (1 + div);
97 break;
98
99 case 3: //480M
100 clk = 480000000 / (1 + div);
101 break;
102
103 default:
104 break;
105 }
106
107 cell = clk / 18000;
108 delay_cycle(ms_count * cell);
109 #else
110 delay_us(1000 * ms_count);
111 #endif
112 }
113
delay_10us(UINT32 count)114 void delay_10us(UINT32 count)
115 {
116 #if 0 //we should not use delay cycle as the CPU clock changes.
117 UINT32 div;
118 UINT32 clk = 0;
119 UINT32 cell;
120
121 UINT32 mux = sys_drv_mclk_mux_get();
122 div = sys_drv_mclk_div_get();
123 switch (mux) {
124 case 0: //XTAL
125 clk = 26000000 / (1 + div);
126 break;
127
128 case 1: //DCO
129 clk = 26000000 / (1 + div);
130 break;
131
132 case 2: //320M
133 clk = 320000000 / (1 + div);
134 break;
135
136 case 3: //480M
137 clk = 480000000 / (1 + div);
138 break;
139
140 default:
141 break;
142 }
143
144 cell = (clk + 900000) / 1800000;
145 delay_cycle(count * cell);
146 #else
147 delay_us(10 * count);
148 #endif
149 }
150
151 #else
152 /*
153 when parameter is 1, the return result is approximately 1 ms;
154 */
delay_ms(UINT32 ms_count)155 void delay_ms(UINT32 ms_count)
156 {
157 UINT32 ret;
158 UINT32 div;
159 UINT32 clk = 0;
160 UINT32 cell;
161 SYS_CTRL_U param;
162
163 ret = sddev_control(DD_DEV_TYPE_SCTRL, CMD_GET_SCTRL_CONTROL, ¶m);
164 BK_ASSERT(SCTRL_SUCCESS == ret);
165
166 div = param.bits.mclk_div;
167 switch (param.bits.mclk_mux) {
168 case MCLK_MODE_DCO:
169 case MCLK_MODE_26M_XTAL:
170 clk = 26000000;
171 break;
172
173 case MCLK_MODE_DPLL:
174 clk = 480000000 / (2 << div);
175 break;
176
177 case MCLK_MODE_LPO:
178 clk = 32000;
179 break;
180
181 default:
182 break;
183 }
184
185 BK_ASSERT(clk);
186
187 cell = 100 * clk / 26000000;
188 delay(ms_count * cell);
189 }
190
delay_us(UINT32 ms_count)191 void delay_us(UINT32 ms_count)
192 {
193 UINT32 ret;
194 UINT32 div;
195 UINT32 clk = 0;
196 UINT32 cell;
197 SYS_CTRL_U param;
198
199 ret = sddev_control(DD_DEV_TYPE_SCTRL, CMD_GET_SCTRL_CONTROL, ¶m);
200 BK_ASSERT(SCTRL_SUCCESS == ret);
201
202 div = param.bits.mclk_div;
203 switch (param.bits.mclk_mux) {
204 case MCLK_MODE_DCO:
205 case MCLK_MODE_26M_XTAL:
206 clk = 26000000;
207 break;
208
209 case MCLK_MODE_DPLL:
210 clk = 480000000 / (2 << div);
211 break;
212
213 case MCLK_MODE_LPO:
214 clk = 32000;
215 break;
216
217 default:
218 break;
219 }
220
221 BK_ASSERT(clk);
222
223 cell = 100 * clk / 26000;
224 delay(ms_count * cell);
225 }
226 #endif
227
228
229 /*
230 [delay offset]worst case: delay about 1 second;
231 */
delay_sec(UINT32 ms_count)232 void delay_sec(UINT32 ms_count)
233 {
234 UINT32 t0;
235 UINT32 t1;
236
237 t0 = fclk_get_second();
238 while (1) {
239 t1 = fclk_get_second();
240 if (t1 - t0 >= 1)
241 break;
242 }
243 }
244
245 /*
246 [delay offset]worst case: delay about 1 tick;
247 */
delay_tick(UINT32 tick_count)248 void delay_tick(UINT32 tick_count)
249 {
250 UINT32 t0;
251 UINT32 t1;
252
253 t0 = bk_get_tick();
254 while (1) {
255 t1 = bk_get_tick();
256 if (t1 - t0 >= 1)
257 break;
258 }
259 }
260
261 // EOF
262
263