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