1 /*
2 * Routines to access hardware
3 *
4 * Copyright (c) 2013 Realtek Semiconductor Corp.
5 *
6 * This module is a confidential and proprietary property of RealTek and
7 * possession or use of this module requires written permission of RealTek.
8 */
9
10 #include "ameba_soc.h"
11
12
13 CPU_PWR_SEQ SYSPLL_ON_SEQ[] = {
14 /* Enable SYS PLL */
15 {0x48000208, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 28)},
16 {0x48000280, CPU_PWRSEQ_CMD_WRITE, 0x00000000, 0x00000003},
17 {0x00000000, CPU_PWRSEQ_CMD_DELAY, 0x00000000, 4}, //delay 2us
18 {0x48000280, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 2)},
19 {0x480002B0, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 31)},
20 {0x00000000, CPU_PWRSEQ_CMD_DELAY, 0x00000000, 4}, //delay 400us
21 {0x48000264, CPU_PWRSEQ_CMD_WRITE, (0x01 << 29), 0x00000000},
22 {0x480002B0, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x03 << 29)},
23 {0x48000200, CPU_PWRSEQ_CMD_WRITE, (0x01 << 21), 0x00000000},
24 {0x480003F4, CPU_PWRSEQ_CMD_POLLING, (0x01 << 12), (0x01 << 12)}, /* temp use delay because FPGA dont have this function */
25 //{0x00000000, CPU_PWRSEQ_CMD_DELAY, 0x00000000, 100}, //delay 100us
26 {0x480002B0, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 8)},
27
28 /* End */
29 {0xFFFFFFFF, CPU_PWRSEQ_CMD_END, 0x00000000, 0x00000000},
30 };
31
32 CPU_PWR_SEQ SYSPLL_OFF_SEQ[] = {
33 /* Disable SYS PLL */
34 {0x480002B0, CPU_PWRSEQ_CMD_WRITE, (0x001 << 8), 0x00000000},
35 {0x48000200, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x001 << 21)},
36 {0x48000264, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x001 << 29)},
37 {0x480002B0, CPU_PWRSEQ_CMD_WRITE, (0x007 << 29), 0x00000000},
38
39 /* End */
40 {0xFFFFFFFF, CPU_PWRSEQ_CMD_END, 0x00000000, 0x00000000},
41 };
42
43 CPU_PWR_SEQ HSPWR_ON_SEQ[] = {
44 {0x00000000, CPU_PWRSEQ_CMD_LOGE, 0x00000000, 0x00000000/* or 1 */}, /* Enable LOG or not */
45
46 /* 1. Enable SWR */ //PMC
47 //{0x48000240, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 0)},
48 //{0x480003F4, CPU_PWRSEQ_CMD_POLLING, (0x01 << 11), (0x01 << 11)}, /* temp use delay because FPGA dont have this function */
49 //{0x00000000, CPU_PWRSEQ_CMD_DELAY, 0x00000000, 100}, //delay 100us
50 //{0x48000240, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 2)},
51
52 /* 2. Enable xtal/banggap */ //PMC
53 //{0x48000260, CPU_PWRSEQ_CMD_WRITE, 0x00000000, 0x03},
54 //{0x00000000, CPU_PWRSEQ_CMD_DELAY, 0x00000000, 750}, //delay 750us
55
56 /* 4. Enable HS power */
57 {0x48000200, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 1)},
58 {0x48000200, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 2)},
59 {0x00000000, CPU_PWRSEQ_CMD_DELAY, 0x00000000, 200}, //delay 100us
60 {0x48000200, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 3)},
61 {0x48000200, CPU_PWRSEQ_CMD_WRITE, (0x03 << 17), 0x00000000},
62
63 /* 5. Enable clock and reset */
64 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 0)},
65 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 4)},
66 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, (0x1FF << 16), (0x101 << 16)}, /* BIT24 is just for FPGA, ASIC dont need */
67 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x07 << 1)},
68 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, (0x07 << 25), 0x00000000}, //set KM4 200MHz
69
70 /* 1. Recover KM4 Memory power, the memory low power config in sleep_hsram_config[] */
71 {0x48000B08, CPU_PWRSEQ_CMD_WRITE, (0xFFFFFFFF), 0x00000000},
72
73 /* 6. Enable WIFI related */
74 {0x48000314, CPU_PWRSEQ_CMD_WRITE, 0x00000000, 0x00000001}, // enable HW auto response
75
76 /* 7. HS IPC Enable*/
77 {0x40000200, CPU_PWRSEQ_CMD_WRITE, 0x00000000, BIT_HS_IPC_FEN}, //function enable
78 {0x40000210, CPU_PWRSEQ_CMD_WRITE, 0x00000000, BIT_HS_IPC_CKE}, //clock enable
79
80 /* End */
81 {0xFFFFFFFF, CPU_PWRSEQ_CMD_END, 0x00000000, 0x00000000},
82 };
83
84 CPU_PWR_SEQ HSPWR_OFF_SEQ[] = {
85 /* 1. HSSYSON clock switch to 4M */
86 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 17)},
87
88 /* 2. Delay 20us for clock switch down*/
89 {0x00000000, CPU_PWRSEQ_CMD_DELAY, 0x00000000, 20},
90
91 /* 3. Gate CPU & Platform Clock */
92 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, (0x001 << 16), 0x00000000},
93 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, (0x001 << 24), 0x00000000}, /* BIT24 is just for FPGA, ASIC dont need */
94
95 /* 4. Reset CPU & Platform */
96 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, (0x01F << 0), 0x00000000},
97
98 /* 6. Disable HS Platform/HSSYSON power */
99 {0x48000200, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x003 << 17)},
100 {0x48000200, CPU_PWRSEQ_CMD_WRITE, (0x007 << 1), 0x00000000},
101
102 /* End */
103 {0xFFFFFFFF, CPU_PWRSEQ_CMD_END, 0x00000000, 0x00000000},
104 };
105
106 CPU_PWR_SEQ HSCLK_GATE_SEQ[] = {
107 /* 1. HSSYSON clock switch to 4M */
108 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 17)},
109
110 /* 2. Delay 20us for clock switch down*/
111 {0x00000000, CPU_PWRSEQ_CMD_DELAY, 0x00000000, 20},
112
113 /* 3. Gate CPU & Platform Clock */
114 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, (0x001 << 16), 0x00000000},
115 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, (0x001 << 24), 0x00000000}, /* BIT24 is just for FPGA, ASIC dont need */
116
117 /* 4. Disable clock generator*/
118 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, (0x001 << 4), 0x0000000F},
119
120 /* End */
121 {0xFFFFFFFF, CPU_PWRSEQ_CMD_END, 0x00000000, 0x00000000},
122 };
123
124 CPU_PWR_SEQ HSCLK_ON_SEQ[] = {
125 /* 1. Recover KM4 Memory power, the memory low power config in sleep_hsram_config[] */
126 {0x48000B08, CPU_PWRSEQ_CMD_WRITE, (0xFFFFFFFF), 0x00000000},
127
128 /* 3. Enable clock and reset */
129 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 4)},
130 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 24)},/* BIT24 is just for FPGA, ASIC dont need */
131 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 16)},
132 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, (0x01 << 17), 0x00000000},
133
134 /* End */
135 {0xFFFFFFFF, CPU_PWRSEQ_CMD_END, 0x00000000, 0x00000000},
136 };
137
138 /*It is different from HSPWR_OFF_SEQ[] for some peripheral to work in KM4 power gate mode*/
139 CPU_PWR_SEQ HSPWR_GATE_SEQ[] = {
140 /* 1. Disable SDIO dev func en off */
141 {0x40000208, CPU_PWRSEQ_CMD_WRITE, (0x01 << 1), 0x00000000},
142
143 /* 2. HSSYSON clock switch to 4M */
144 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 17)},
145
146 /* 3. Delay 20us for clock switch down*/
147 {0x00000000, CPU_PWRSEQ_CMD_DELAY, 0x00000000, 20},
148
149 /* 4. Gate CPU & Platform Clock */
150 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, (0x001 << 16), 0x00000000},
151 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, (0x001 << 24), 0x00000000}, /* BIT24 is just for FPGA, ASIC dont need */
152
153 /* 5. Reset CPU & Platform*/
154 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, (0x01F << 0), 0x00000001},
155
156 /* End */
157 {0xFFFFFFFF, CPU_PWRSEQ_CMD_END, 0x00000000, 0x00000000},
158 };
159
160 CPU_PWR_SEQ HSPWR_WAKE_SEQ[] = {
161 /* 1. Recover KM4 Memory power, the memory low power config in sleep_hsram_config[] */
162 {0x48000B08, CPU_PWRSEQ_CMD_WRITE, (0xFFFFFFFF), 0x00000000},
163
164 /* 2. Enable HS power */
165 {0x48000200, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 2)},
166 {0x00000000, CPU_PWRSEQ_CMD_DELAY, 0x00000000, 200}, //delay 100us
167 {0x48000200, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 3)},
168 {0x48000200, CPU_PWRSEQ_CMD_WRITE, (0x01 << 18), 0x00000000},
169
170 /* 3. Enable clock and reset */
171 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 4)},
172 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 24)},/* BIT24 is just for FPGA, ASIC dont need */
173 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 16)},
174 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, (0x01 << 17), 0x00000000},
175 {0x4800021C, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x07 << 1)},
176
177 /* 4. Enable SDIO dev func off */
178 {0x40000208, CPU_PWRSEQ_CMD_WRITE, 0x00000000, (0x01 << 1)},
179
180 /* End */
181 {0xFFFFFFFF, CPU_PWRSEQ_CMD_END, 0x00000000, 0x00000000},
182 };
183
184 u8 km4_sleep_type;
185 u32 km4_sleep_timeout = 0xffffffff;
186 u32 km4_wake_event;
187
km4_status_on(void)188 u32 km4_status_on(void)
189 {
190 u32 Temp = HAL_READ32(SYSTEM_CTRL_BASE_LP, REG_LP_KM4_CTRL);
191
192 if (Temp & BIT_LSYS_HPLAT_CKE){
193 return 1;
194 } else {
195 return 0;
196 }
197 }
198
km4_pm_init(void)199 void km4_pm_init(void)
200 {
201
202 }
203
km4_boot_on(void)204 void km4_boot_on(void)
205 {
206 u32 Temp;
207
208 pmu_acquire_wakelock(PMU_KM4_RUN);
209
210 /* Let KM4 RUN */
211 Temp = HAL_READ32(SYSTEM_CTRL_BASE, REG_LP_BOOT_CFG) | BIT_SOC_BOOT_PATCH_KM4_RUN;
212 HAL_WRITE32(SYSTEM_CTRL_BASE, REG_LP_BOOT_CFG, Temp);
213
214 BOOT_ROM_CM4PON((u32)HSPWR_ON_SEQ);
215
216 /*IPC table initialization*/
217 ipc_table_init();
218 }
219
km4_power_gate(void)220 void km4_power_gate(void)
221 {
222 u32 temp = 0;
223
224 if (!km4_status_on())
225 return;
226
227 DBG_PRINTF(MODULE_KM4, LEVEL_INFO, "M4G\n");
228
229 /* poll KM4 clock gate */
230 while (1) {
231 temp = HAL_READ32(SYSTEM_CTRL_BASE_HP, REG_HS_PLATFORM_PARA); /*get KM4 sleep status*/
232 if(temp & BIT_KM4_SLEEP_STATUS) {
233 break;
234 }
235 }
236
237 BOOT_ROM_CM4PON((u32)HSPWR_GATE_SEQ);
238
239 pmu_release_wakelock(PMU_KM4_RUN);
240 pmu_release_wakelock(PMU_OS);
241 }
242
km4_power_wake(void)243 void km4_power_wake(void)
244 {
245 u32 Temp = 0;
246
247 if (km4_status_on())
248 return;
249
250 DBG_PRINTF(MODULE_KM4, LEVEL_INFO, "M4W\n");
251
252 pmu_acquire_wakelock(PMU_KM4_RUN);
253
254 /* Let KM4 RUN */
255 Temp = HAL_READ32(SYSTEM_CTRL_BASE, REG_LP_BOOT_CFG) | BIT_SOC_BOOT_PATCH_KM4_RUN;
256 HAL_WRITE32(SYSTEM_CTRL_BASE, REG_LP_BOOT_CFG, Temp);
257
258 BOOT_ROM_CM4PON((u32)HSPWR_WAKE_SEQ);
259 }
260
km4_clock_gate(void)261 void km4_clock_gate(void)
262 {
263 u32 temp = 0;
264
265 if (!km4_status_on())
266 return;
267
268 DBG_PRINTF(MODULE_KM4, LEVEL_INFO, "M4CG\n");
269
270 /* poll KM4 clock gate */
271 while (1) {
272 temp = HAL_READ32(SYSTEM_CTRL_BASE_HP, REG_HS_PLATFORM_PARA); /*get KM4 sleep status*/
273 if(temp & BIT_KM4_SLEEP_STATUS) {
274 break;
275 }
276 }
277
278 BOOT_ROM_CM4PON((u32)HSCLK_GATE_SEQ);
279
280 DBG_PRINTF(MODULE_KM4, LEVEL_INFO, "M4CG-\n");
281
282 pmu_release_wakelock(PMU_KM4_RUN);
283 pmu_release_wakelock(PMU_OS);
284 }
285
km4_clock_on(void)286 void km4_clock_on(void)
287 {
288 if (km4_status_on())
289 return;
290
291 DBG_PRINTF(MODULE_KM4, LEVEL_INFO, "M4CW\n");
292
293 pmu_acquire_wakelock(PMU_KM4_RUN);
294
295 BOOT_ROM_CM4PON((u32)HSCLK_ON_SEQ);
296
297 /* tell KM4 wake */
298 asm volatile ("sev");
299
300 DBG_PRINTF(MODULE_KM4, LEVEL_INFO, "M4CW-\n");
301 }
302
km4_suspend(u32 type)303 u32 km4_suspend(u32 type)
304 {
305 u32 ret =_SUCCESS;
306 KM4SLEEP_ParamDef * sleep_param;
307 u32 duration = 0;
308
309 sleep_param = (KM4SLEEP_ParamDef *)ipc_get_message(IPC_INT_KM4_TICKLESS_INDICATION);
310 if(sleep_param != NULL)
311 duration = sleep_param->sleep_time;
312
313 if (duration > 0) {
314 /* used for resume delay */
315 km4_sleep_timeout = xTaskGetTickCount() + duration;
316 }
317
318 if (type == SLEEP_CG) {
319 km4_clock_gate();
320 } else {
321 km4_power_gate();
322 }
323
324 return ret;
325 }
326
km4_wake_event_update(void)327 void km4_wake_event_update(void)
328 {
329 /*the timer is used to control KM4 max sleep time*/
330 u32 current_tick = xTaskGetTickCount();
331 if (current_tick >= km4_sleep_timeout) {
332 km4_wake_event |=BIT_HP_WEVT_TIMER_STS;
333 km4_sleep_timeout = 0xffffffff;
334 }
335
336 /*when keyScan is used as a wake up source,*/
337 if ((ps_config.km0_enable_key_touch | BIT_KEY_ENABLE)
338 && KeyScan_GetINT(KEYSCAN_DEV))
339 km4_wake_event |=BIT_HP_WEVT_KEYSCAN_STS;
340
341 /*when CAPTOUCH is used as a wake up source,*/
342 if ((ps_config.km0_enable_key_touch | BIT_CAPTOUCH_ENABLE)
343 && CapTouch_GetISR(CAPTOUCH_DEV))
344 km4_wake_event |=BIT_HP_WEVT_CAPTOUCH_STS;
345
346 /*when GPIO is used as a wake up source,*/
347 //if ((ps_config.km0_enable_key_touch | BIT_GPIO_ENABLE)
348 // && GPIO trigger wake KM4)
349 // km4_wake_event |=BIT_HP_WEVT_GPIO_STS;
350
351 }
352
km4_set_wake_event(u32 wevt)353 void km4_set_wake_event(u32 wevt)
354 {
355 km4_wake_event |= wevt;
356 }
357
km4_get_wake_event(void)358 u32 km4_get_wake_event(void)
359 {
360 return km4_wake_event ;
361 }
362
km4_resume(void)363 void km4_resume(void)
364 {
365 if (km4_status_on())
366 goto exit;
367
368 pmu_acquire_wakelock(PMU_KM4_RUN);
369
370 if (km4_sleep_type == SLEEP_CG) {
371 km4_clock_on();
372 } else {
373 km4_power_wake();
374 }
375
376 /*set wake up status*/
377 HAL_WRITE32(SYSTEM_CTRL_BASE_HP, REG_HS_WAKE_EVENT_STATUS1, km4_wake_event);
378
379 SOCPS_AudioLDO(ENABLE);
380
381 exit:
382 km4_wake_event = 0;
383 }
384
km4_flash_highspeed_suspend(u32 Protection)385 void km4_flash_highspeed_suspend(u32 Protection)
386 {
387 FLASH_ClockSwitch(BIT_SHIFT_FLASH_CLK_XTAL, Protection);
388 BOOT_ROM_CM4PON((u32)SYSPLL_OFF_SEQ);
389 }
390
km4_flash_highspeed_init(void)391 void km4_flash_highspeed_init(void)
392 {
393 BOOT_ROM_CM4PON((u32)SYSPLL_ON_SEQ);
394 /* calibration high speed before KM4 run */
395 flash_operation_config();
396 }
397
km4_flash_highspeed_resume(u32 Protection)398 void km4_flash_highspeed_resume(u32 Protection)
399 {
400 BOOT_ROM_CM4PON((u32)SYSPLL_ON_SEQ);
401 FLASH_ClockSwitch(BIT_SHIFT_FLASH_CLK_PLL, Protection);
402 }
403
km4_tickless_ipc_int(VOID * Data,u32 IrqStatus,u32 ChanNum)404 void km4_tickless_ipc_int(VOID *Data, u32 IrqStatus, u32 ChanNum)
405 {
406 /* To avoid gcc warnings */
407 ( void ) Data;
408 ( void ) IrqStatus;
409 ( void ) ChanNum;
410
411 u32 Rtemp;
412 KM4SLEEP_ParamDef * psleep_param;
413
414 InterruptEn(UART_LOG_IRQ_LP, 10);
415 IPCM0_DEV->IPCx_USR[IPC_INT_CHAN_SHELL_SWITCH] = 0x00000000;
416
417 psleep_param = (KM4SLEEP_ParamDef *)ipc_get_message(IPC_INT_KM4_TICKLESS_INDICATION);
418 DCache_Invalidate((u32)psleep_param, sizeof(KM4SLEEP_ParamDef));
419
420 //set dlps
421 if (psleep_param->dlps_enable){
422 SOCPS_AONTimer(psleep_param->sleep_time);
423 if (psleep_param->sleep_time) {
424 SOCPS_AONTimerCmd(ENABLE);
425 }
426 SOCPS_DeepSleep_RAM();
427 }
428
429 km4_sleep_type = psleep_param->sleep_type;
430 switch (psleep_param->sleep_type) {
431 case SLEEP_PG:
432 if(_SUCCESS == km4_suspend(SLEEP_PG)) {
433
434 Rtemp = HAL_READ32(SYSTEM_CTRL_BASE_LP, REG_LP_BOOT_CFG);
435 Rtemp |= BIT_SOC_BOOT_WAKE_FROM_PS_HS;
436 HAL_WRITE32(SYSTEM_CTRL_BASE_LP, REG_LP_BOOT_CFG, Rtemp);
437 }
438 break;
439 case SLEEP_CG:
440 if(_SUCCESS ==km4_suspend(SLEEP_CG)) {
441 pmu_set_sysactive_time(2);
442 }
443 break;
444
445 default:
446 DBG_8195A("unknow sleep type\n");
447 }
448
449 }
450
451