• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &param);
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, &param);
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