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