blob: 6a03285eb7c68f6d1d78f5ae2fd99a8ca6132b13 [file] [log] [blame]
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +08001/*
2 * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7#include "FreeRTOS.h"
8#include <common.h>
9#include "util.h"
10#include "register.h"
11#include "uart.h"
12#include <task.h>
13#include <util.h>
14#include "timer_source.h"
15#include "./include/clk.h"
16#include "./include/clk_util.h"
17#include "./include/vad_suspend.h"
18#include "include/power_domain.h"
19
20void set_time(uint32_t val);
21uint32_t get_time(void);
22void alt_timebase(int use_clk_src);
23void set_sys_div_clk(int sel, int div);
24void set_axi_div_clk(int sel, int div);
25void clk_util_set_dsp_clk(uint32_t id, uint32_t freq_sel);
26void disable_pll(int id);
27void vCLK_resume(uint32_t st_f);
28void vCLK_suspend(uint32_t st_f);
29
30void set_time(uint32_t val)
31{
32#ifdef ARM_CPU
33 REG32(SYSCTRL_SEC_TIMERE) = 0x0;
34#else
35 REG32(SYSCTRL_TIMERF) = val;
36#endif
37}
38
39
40uint32_t get_time(void)
41{
42 uint64_t timerE = 0;
43
44#ifdef ARM_CPU
45 timerE = REG32(SYSCTRL_SEC_TIMERE);
46#else
47 timerE = REG32(SYSCTRL_TIMERF);
48#endif
49 return(timerE);
50}
51
52/*
53 * use_clk_src
54 * 0. osc_clk
55 * 1. sys_clk (rtc_pll) clk_div1
56 * 2. sys_clk (rtc_pll) clk_div2
57 * 3. rtc_clk
58 * Note:
59 * 1. If select sys_clk, tick clk of 1us/10us/100us/1ms/xtal3 are all same
60 * 2. If select rtc_clk, tick clk of 1us/10us/100us/1ms/xtal3 will actually
61 * be 1ms/10ms/100ms/1s/93.747us
62 */
63
64void alt_timebase(int use_clk_src)
65{
66 uint32_t clk_div = 0;
67 if (use_clk_src == 0)
68 //select osc_clk
69 REG32(CLKCTRL_TIMEBASE_CTRL0) = 0x20018;
70 else if (use_clk_src == 1) {
71 //select sys_clk (rtc_pll) clk_div1
72 //when sys_clk < 32MHz
73 //if sys_clk is 30MHz
74 clk_div = 30;
75 REG32(CLKCTRL_TIMEBASE_CTRL0) = (1 << 17) | (clk_div<<19) | (0x2aa<<6);
76 } else if (use_clk_src == 2) {
77 /* select sys_clk (rtc_pll) clk_div2
78 when sys_clk < 256MHz */
79 // if sys_clk is 122.88MHz
80 clk_div = 122;
81 REG32(CLKCTRL_TIMEBASE_CTRL0) = (1 << 17) | (clk_div<<24) | (0x3ff<<6);
82 } else {
83 //select rtc clk
84 // 32k/32 = 1k
85 REG32(CLKCTRL_TIMEBASE_CTRL0) = 0x20020;
86 }
87}
88
89/*
90 * This is function for axi clk setting:
91 * Includes axi_clk(AKA cpu_axi_clk/ACLK), axi_matrix, axi_sram
92 *
93 */
94void set_axi_div_clk(int sel, int div)
95{
96 uint32_t control;
97 uint32_t dyn_pre_mux;
98 uint32_t dyn_div;
99
100 // fclk_div4 = 500MHz
101 dyn_pre_mux = sel;
102 dyn_div = div;/* divide by 1 */
103
104 control = REG32(CLKCTRL_AXI_CLK_CTRL0);
105 if (control & (1 << 15)) {//default is preb, need use prea
106 control = (control & ~(0x3fff))
107 | ((1 << 13)
108 | (dyn_pre_mux << 10)
109 | (dyn_div << 0));
110 REG32(CLKCTRL_AXI_CLK_CTRL0) = control;
111 control = control & ~(1 << 15);
112 REG32(CLKCTRL_AXI_CLK_CTRL0) = control;
113 udelay(25);
114 } else {
115 //preb
116 control = (control & ~((0x3fff) << 16))
117 | ((1 << 29)
118 | (dyn_pre_mux << 26)
119 | (dyn_div << 16));
120 REG32(CLKCTRL_AXI_CLK_CTRL0) = control;
121 control = control | (1 << 15);
122 REG32(CLKCTRL_AXI_CLK_CTRL0) = control;
123 udelay(25);
124 }
125
126 return;
127}
128
129/*
130 * This is function for clk81 setting
131 *
132 */
133void set_sys_div_clk(int sel, int div)
134{
135 uint32_t control;
136 uint32_t dyn_pre_mux;
137 uint32_t dyn_div;
138
139 printf("Set sys clock to 167Mhz\n");
140
141 // fclk_div4 = 500MHz
142 dyn_pre_mux = sel;
143 dyn_div = div;/* divide by 3 */
144
145 control = REG32(CLKCTRL_SYS_CLK_CTRL0);
146
147 if (control & (1 << 15)) {//default is preb, need use prea
148 control = (control & ~(0x3fff))
149 | ((1 << 13)
150 | (dyn_pre_mux << 10)
151 | (dyn_div << 0));
152 REG32(CLKCTRL_SYS_CLK_CTRL0) = control;
153 control = control & ~(1 << 15);
154 REG32(CLKCTRL_SYS_CLK_CTRL0) = control;
155 udelay(25);
156 } else {
157 //preb
158 control = (control & ~((0x3fff) << 16))
159 | ((1 << 29)
160 | (dyn_pre_mux << 26)
161 | (dyn_div << 16));
162 REG32(CLKCTRL_SYS_CLK_CTRL0) = control;
163 control = control | (1 << 15);
164 REG32(CLKCTRL_SYS_CLK_CTRL0) = control;
165 udelay(25);
166 }
167
168
169 /* when bus switched from 24MHz to 166MHz,
170 * the clock tick used to generate OTP waveform
171 * needs 20us waiting time to switch to new clock tick
172 */
173 udelay(25);
174
175 return;
176}
177/*
178 * clk_util_set_dsp_clk
179 * freq_sel:
180 * 0:800MHz fclk_2p5
181 * 1:400MHz fclk_5
182 * 2:500MHz fclk_4
183 * 3:666MHz fclk_3
184 * 4:333Mhz fclk_3/2
185 * 5:250Mhz fclk_4/2
186 * 6:200Mhz fclk_5/2
187 * 7:100Mhz fclk_5/4
188 * 8:24Mhz oscin
189 * 10:3Mhz oscin/8
190 * others:400MHz fclk_5
191 *
192 *.clk0 (cts_oscin_clk ),
193 *.clk1 (fclk_div2p5 ),
194 *.clk2 (fclk_div3 ),
195 *.clk3 (rtc_pll_clk ),
196 *.clk4 (hifi_pll_clk ),
197 *.clk5 (fclk_div4 ),
198 *.clk6 (gp1_pll_clk ),
199 *.clk7 (cts_rtc_clk ),
200 */
201
202/* --------------------------------------------------
203 * clk_util_set_dsp_clk
204 * --------------------------------------------------
205 */
206
207void clk_util_set_dsp_clk(uint32_t id, uint32_t freq_sel)
208{
209 uint32_t control;
210 uint32_t clk_sel;
211 uint32_t clk_div;
212 uint32_t addr = CLKCTRL_DSPA_CLK_CTRL0;
213
214 switch (id) {
215 case 0: addr = CLKCTRL_DSPA_CLK_CTRL0; break;
216 //default : addr = CLKCTRL_DSPB_CLK_CTRL0; break;
217 default : printf("CLK_UTIL:Error, no dspb here\n"); break;
218 }
219
220 //Make sure not busy from last setting and we currently match the last setting
221 control = REG32(addr);
222
223 switch (freq_sel)
224 {
225 case 0:
226 clk_sel = 1;
227 clk_div = 0;
228 printf("CLK_UTIL:dsp[%d]:fclk2p5:800MHz\n", id);
229 break;
230 case 1:
231 clk_sel = 1;
232 clk_div = 1;
233 printf("CLK_UTIL:dsp[%d]:fclk5:400MHz\n", id);
234 break;
235 case 2:
236 clk_sel = 5;
237 clk_div = 0;
238 printf("CLK_UTIL:dsp[%d]:fclk4:500MHz\n", id);
239 break;
240 case 3:
241 clk_sel = 2;
242 clk_div = 0;
243 printf("CLK_UTIL:dsp[%d]:fclk/3:667MHz\n", id);
244 break;
245 case 4:
246 clk_sel = 2;
247 clk_div = 1;
248 printf("CLK_UTIL:dsp[%d]:fclk3/2:333MHz\n", id);
249 break;
250 case 5:
251 clk_sel = 5;
252 clk_div = 1;
253 printf("CLK_UTIL:dsp[%d]:fclk4/2:250MHz\n", id);
254 break;
255 case 6:
256 clk_sel = 1;
257 clk_div = 3;
258 printf("CLK_UTIL:dsp[%d]:fclk5/2:200MHz\n", id);
259 break;
260 case 7:
261 clk_sel = 1;
262 clk_div = 7;
263 printf("CLK_UTIL:dsp[%d]:fclk5/4:100MHz\n", id);
264 break;
265 case 8:
266 clk_sel = 0;
267 clk_div = 0;
268 printf("CLK_UTIL:dsp[%d]:oscin:24MHz\n", id);
269 break;
270 case 10:
271 clk_sel = 0;
272 clk_div = 7;
273 printf("CLK_UTIL:dsp[%d]:oscin/8:3MHz\n", id);
274 break;
275 case 11:
276 clk_sel = 3;
277 clk_div = 0;
278 printf("CLK_UTIL:dsp[%d]:rtc pll:122.88MHz\n", id);
279 break;
280 case 12:
281 clk_sel = 7;
282 clk_div = 0;
283 printf("CLK_UTIL:dsp[%d]:rtc clk:24MHz\n", id);
284 break;
285 default:
286 clk_sel = 1;
287 clk_div = 7;
288 printf("CLK_UTIL:dsp[%d]:fclk5:400MHz\n", id);
289 break;
290 }
291
292 //if sync_mux ==1, sel mux 0
293 if (control & (1 << 15))
294 control = (control & ~( ( 1<<15) | (0x3ff<<0) | (0x7 <<10) ) ) | (1<<13) |
295 (1<<29) | (clk_div<<0) | (clk_sel<<10);
296 else
297 control = (control & ~( ( 1<<15) | (0x3ff<<16) | (0x7 <<26) ) ) | (1<<13) |
298 (1<<29) | (clk_div<<16) | (clk_sel<<26) | (1<<15);
299
300 REG32(addr) = control;
301}
302
303void disable_pll(int id)
304{
305 switch (id) {
306 case PLL_SYS: REG32(ANACTRL_SYSPLL_CTRL0) = (1<<29); break;
307 case PLL_GP0: REG32(ANACTRL_GP0PLL_CTRL0) = (1<<29); break;
308 case PLL_GP1: REG32(ANACTRL_GP1PLL_CTRL0) = (1<<29); break;
309 case PLL_FIX: REG32(ANACTRL_FIXPLL_CTRL0) = (1<<29); break;
310 case PLL_HIFI: REG32(ANACTRL_HIFIPLL_CTRL0) = (1<<29); break;
311 case PLL_RTC: REG32(ANACTRL_RTCPLL_CTRL0) = (1<<29); break;
312 case PLL_DDR: REG32(AM_DDR_PLL_CNTL0) = (1<<29); break;
313 default: printf("Error: PLL is not in the list\n"); break;
314 }
315}
316
317int oscin_ctrl_reg = 0;
318void vCLK_resume(uint32_t st_f)
319{
320 if ((REG32(SYSCTRL_DEBUG_REG6) != WAIT_SWITCH_TO_RTC_PLL) &&
321 (REG32(SYSCTRL_DEBUG_REG6) != DSP_VAD_WAKUP_ARM))
322 printf("[AOCPU]:WARNING SYSCTRL_DEBUG_REG6's value is :0x%x!\n",
323 REG32(SYSCTRL_DEBUG_REG6));
324
325 if (REG32(SYSCTRL_DEBUG_REG6) == WAIT_SWITCH_TO_RTC_PLL)
326 REG32(SYSCTRL_DEBUG_REG6) = WAKEUP_FROM_OTHER_KEY;
327 /* switch osc_clk back*/
328 REG32(CLKCTRL_SYSOSCIN_CTRL) = 1;
329 REG32(CLKCTRL_OSCIN_CTRL) = oscin_ctrl_reg | (1<<31);
330 udelay(9000);
331
332 /* switching tick timer (using osc_clk) */
333 alt_timebase(0);
334
335 set_sys_div_clk(0, 0); // osc_clk
336 set_axi_div_clk(0, 0); // osc_clk
337
338 if ((REG32(SYSCTRL_DEBUG_REG6) != DSP_VAD_WAKUP_ARM) &&
339 (REG32(SYSCTRL_DEBUG_REG6) != WAKEUP_FROM_OTHER_KEY))
340 printf("[AOCPU]:WARNING SYSCTRL_DEBUG_REG6's value is :0x%x!\n",
341 REG32(SYSCTRL_DEBUG_REG6));
342
343 REG32(SYSCTRL_DEBUG_REG6) = WAIT_SWITCH_TO_24MHZ;
344
345 vTaskDelay(pdMS_TO_TICKS(90));
346// disable_pll(PLL_RTC);
347
348 if (st_f) {
349 power_switch_to_wraper(PWR_ON);
350 /* open mem_pd of srama and sramb */
351 REG32(PWRCTRL_MEM_PD2) = 0x0;
352 }
353
354 // In a55 boot code
355 REG32(PWRCTRL_ACCESS_CTRL) = 0x0; // default access pwrctrl
356}
357
358void vCLK_suspend(uint32_t st_f)
359{
360 if (st_f) {
361 /* close mem_pd of srama and sramb */
362 REG32(PWRCTRL_MEM_PD2) = 0xfffffffc;
363 /* poweroff wrapper */
364 power_switch_to_wraper(PWR_OFF);
365 }
366
367 udelay(2000);
368 /* switch to RTC pll */
369 set_sys_div_clk(6, 3); // rtc pll (30.72MHz)
370 set_axi_div_clk(6, 0); // rtc pll (122.88MHz)
371 alt_timebase(1); // 1us/10us/100us/1ms/xtal3 = 1 us tick 30.72/30
372
373 udelay(2000);
374
375 if (REG32(SYSCTRL_DEBUG_REG6) != 0)
376 printf("[AOCPU]:WARNING SYSCTRL_DEBUG_REG6's value is :0x%x!\n",
377 REG32(SYSCTRL_DEBUG_REG6));
378 REG32(SYSCTRL_DEBUG_REG6) = WAIT_SWITCH_TO_RTC_PLL;
379 vTaskDelay(pdMS_TO_TICKS(90));
380 /* power off osc_clk */
381 REG32(CLKCTRL_SYSOSCIN_CTRL) = 0;
382 oscin_ctrl_reg = REG32(CLKCTRL_OSCIN_CTRL);
383 REG32(CLKCTRL_OSCIN_CTRL) = 0;
384
385 printf("[AOCPU]: running at 30.72MHz, 24MHz osc clk power off.\n");
386 udelay(9000);
387
388 disable_pll(PLL_FIX);
389 disable_pll(PLL_GP0);
390 disable_pll(PLL_GP1);
391 disable_pll(PLL_HIFI);
392}
393