ARM: rockchip: rename pm.c to rockchip_pm.c
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rockchip / rockchip_pm.c
1 #include <linux/kernel.h>
2 #include <linux/init.h>
3 #include <linux/suspend.h>
4 #include <asm/cacheflush.h>
5 #include <asm/tlbflush.h>
6 #include <asm/suspend.h>
7 #include <linux/delay.h>
8
9 #include <asm/io.h>
10 #include "pm.h"
11
12 /*************************dump reg********************************************/
13
14 void rkpm_ddr_reg_offset_dump(void __iomem * base_addr,u32 _offset)
15 {
16     rkpm_ddr_printhex(_offset);     
17     rkpm_ddr_printch('-');
18     rkpm_ddr_printhex(readl_relaxed((base_addr + _offset)));  
19 }
20
21 void  rkpm_ddr_regs_dump(void __iomem * base_addr,u32 start_offset,u32 end_offset)
22 {
23         u32 i;
24         u32 line=0;
25
26         rkpm_ddr_printascii("start from:");     
27         rkpm_ddr_printhex((u32)(base_addr +start_offset));       
28         rkpm_ddr_printch('\n');
29         
30         for(i=start_offset;i<=end_offset;)
31         {
32             rkpm_ddr_printhex(reg_readl((base_addr + i)));  
33             line++;
34             if((line%4==0)||i==end_offset)
35                 rkpm_ddr_printch('\n');
36             else              
37                 rkpm_ddr_printch('-');
38             i+=4;
39         } 
40     
41 }
42
43 static struct rkpm_ops pm_ops={NULL};
44
45 static struct rkpm_sram_ops *p_pm_sram_ops=NULL;//pie point for pm_sram_ops
46 static rkpm_sram_suspend_arg_cb p_suspend_pie_cb=NULL;
47
48 // for user setting
49 static u32   rkpm_ctrbits=0;
50 //for judging rkpm_ctrbits valid ,save ifself
51 static u32   rkpm_jdg_ctrbits=0;
52 static u32   rkpm_jdg_sram_ctrbits=0;
53
54 /**************************************ddr callback setting***************************************/
55
56 void rkpm_set_pie_info(struct rkpm_sram_ops *pm_sram_ops,rkpm_sram_suspend_arg_cb pie_cb)
57 {
58
59     p_pm_sram_ops=pm_sram_ops;
60     p_suspend_pie_cb=pie_cb;
61
62
63 }
64
65 void rkpm_set_ops_prepare_finish(rkpm_ops_void_callback prepare,rkpm_ops_void_callback finish)
66 {
67         pm_ops.prepare=prepare; 
68         pm_ops.finish=finish;   
69 }
70
71 void rkpm_set_ops_pwr_dmns(rkpm_ops_void_callback pwr_dmns,rkpm_ops_void_callback re_pwr_dmns)
72 {
73         pm_ops.pwr_dmns=pwr_dmns;       
74         pm_ops.re_pwr_dmns=re_pwr_dmns;
75 }
76
77 void rkpm_set_ops_gtclks(rkpm_ops_void_callback gtclks,rkpm_ops_void_callback re_gtclks)
78 {
79         pm_ops.gtclks=gtclks;   
80         pm_ops.re_gtclks=re_gtclks;
81 }
82
83
84 void rkpm_set_ops_plls(rkpm_ops_void_callback plls,rkpm_ops_void_callback re_plls)
85 {
86         pm_ops.plls=plls;       
87         pm_ops.re_plls=re_plls;
88 }
89
90
91 void rkpm_set_ops_gpios(rkpm_ops_void_callback gpios,rkpm_ops_void_callback re_gpios)
92 {
93         pm_ops.gpios=gpios;     
94         pm_ops.re_gpios=re_gpios;
95 }
96 void rkpm_set_ops_save_setting(rkpm_ops_paramter_u32_cb save_setting,rkpm_ops_void_callback re_save_setting)
97 {
98         pm_ops.save_setting=save_setting;       
99         pm_ops.re_save_setting=re_save_setting;
100 }
101
102
103
104 void rkpm_set_ops_printch(rkpm_ops_printch_callback printch)
105 {
106         pm_ops.printch=printch; 
107 }
108
109 void rkpm_set_ops_regs_pread(rkpm_ops_void_callback regs_pread)
110 {
111         pm_ops.regs_pread=regs_pread;   
112 }
113
114 void rkpm_set_ops_regs_sleep(rkpm_ops_void_callback slp_setting,rkpm_ops_void_callback re_last)
115 {       
116
117         pm_ops.slp_setting=slp_setting;    
118
119         pm_ops.slp_re_first=re_last;    
120 }
121
122
123 /**************************************sram callback setting***************************************/
124 void rkpm_set_sram_ops_volt(rkpm_ops_void_callback volts,rkpm_ops_void_callback re_volts)
125 {
126         if(p_pm_sram_ops)
127         {
128             p_pm_sram_ops->volts=volts; 
129             p_pm_sram_ops->re_volts=re_volts;
130         }
131 }
132
133 void rkpm_set_sram_ops_gtclks(rkpm_ops_void_callback gtclks,rkpm_ops_void_callback re_gtclks)
134 {
135          if(p_pm_sram_ops)
136         {
137                 p_pm_sram_ops->gtclks=gtclks;   
138                 p_pm_sram_ops->re_gtclks=re_gtclks;
139         }
140 }
141
142 void rkpm_set_sram_ops_sysclk(rkpm_ops_paramter_u32_cb sysclk,rkpm_ops_paramter_u32_cb re_sysclk)
143 {
144          if(p_pm_sram_ops)
145         {
146                 p_pm_sram_ops->sysclk=sysclk;   
147                 p_pm_sram_ops->re_sysclk=re_sysclk;
148         }
149 }
150
151 void rkpm_set_sram_ops_pmic(rkpm_ops_void_callback pmic,rkpm_ops_void_callback re_pmic)
152 {
153      if(p_pm_sram_ops)
154     {
155         p_pm_sram_ops->pmic=pmic;       
156         p_pm_sram_ops->re_pmic=re_pmic;
157     }
158 }
159
160 void rkpm_set_sram_ops_ddr(rkpm_ops_void_callback ddr,rkpm_ops_void_callback re_ddr)
161 {
162     if(p_pm_sram_ops)
163     {
164         p_pm_sram_ops->ddr=ddr; 
165         p_pm_sram_ops->re_ddr=re_ddr;
166     }
167 }
168 void rkpm_set_sram_ops_printch(rkpm_ops_printch_callback printch)
169 {  
170     if(p_pm_sram_ops)
171         p_pm_sram_ops->printch=printch; 
172 }
173
174 /******************for user ************************/
175 void inline rkpm_set_ctrbits(u32 bits)
176 {       
177         rkpm_ctrbits = bits;
178         
179 }
180 void inline rkpm_add_ctrbits(u32 bits)
181 {       
182         rkpm_ctrbits |= bits;
183         
184 }
185 u32  inline rkpm_get_ctrbits(void)
186 {       
187         return rkpm_ctrbits;
188 }
189
190 u32 inline  rkpm_chk_ctrbits(u32 bits)
191 {       
192         return (rkpm_ctrbits&bits);
193 }
194
195 //clear
196 void inline rkpm_clr_ctrbits(u32 bits)
197 {
198         rkpm_ctrbits&=~bits;
199 }
200
201 /****************** for pm.c************************/
202
203 static void inline rkpm_set_jdg_ctrbits(u32 bits)
204 {       
205         rkpm_jdg_ctrbits = bits;
206         
207 }
208 static u32  inline rkpm_get_jdg_ctrbits(void)
209 {       
210         return rkpm_jdg_ctrbits;
211 }
212
213 static void inline rkpm_add_jdg_ctrbits(int bit)
214 {       
215         rkpm_jdg_ctrbits|=bit;
216 }
217
218 #if 0
219 static u32 inline rkpm_chk_jdg_ctrbit(int bit)
220 {       
221         return (rkpm_jdg_ctrbits&bit);
222 }
223 #endif
224
225 static u32 inline rkpm_chk_jdg_ctrbits(int bits)
226 {       
227         return (rkpm_jdg_ctrbits&bits);
228 }
229 //clear
230 static void inline rkpm_clr_jdg_ctrbits(int bit)
231 {
232         rkpm_jdg_ctrbits&=~bit;
233 }
234
235
236 #define  RKPM_DDR_FUN(fun) \
237         if(pm_ops.fun)\
238                 (pm_ops.fun)()
239
240 // fun with paramater  param (p1,p2,p3)
241 #define  RKPM_DDR_PFUN(fun,param) \
242         if(pm_ops.fun) \
243             {(pm_ops.fun)param;} while(0)
244
245 #define  RKPM_BITCTR_DDR_FUN(ctr,fun) \
246         if(rkpm_chk_jdg_ctrbits(RKPM_CTR_##ctr)&&pm_ops.fun)\
247                 (pm_ops.fun)()
248
249 #define  RKPM_BITSCTR_DDR_FUN(bits,fun) \
250         if(rkpm_chk_jdg_ctrbits(bits)&&pm_ops.fun)\
251             (pm_ops.fun)()
252
253
254         
255 #define  RKPM_LPMD_BITSCTR_DDR_PFUN(bits,fun,param) \
256                 if(rkpm_chk_jdg_ctrbits(RKPM_CTRBITS_SOC_DLPMD)&&pm_ops.fun)\
257                     (pm_ops.fun)param
258
259 #define  RKPM_LPMD_BITSCTR_DDR_FUN(bits,fun) \
260                 if(rkpm_chk_jdg_ctrbits(RKPM_CTRBITS_SOC_DLPMD)&&pm_ops.fun)\
261                         (pm_ops.fun)()
262
263
264
265 void rkpm_ctrbits_prepare(void)
266 {
267         
268         //rkpm_sram_ctrbits=rkpm_ctrbits;
269         
270         rkpm_jdg_ctrbits=rkpm_ctrbits;
271
272         //if plls is no pd,clk rate is high, volts can not setting low,so we need to judge ctrbits
273         //if(rkpm_chk_jdg_ctrbits(RKPM_CTR_VOLTS))
274         {
275                 //rkpm_clr_jdg_ctrbits(RKPM_CTR_VOLTS);
276         }
277     
278         rkpm_jdg_sram_ctrbits=rkpm_jdg_ctrbits;
279         
280         //clk gating will gate ddr clk in sram
281         if(!rkpm_chk_val_ctrbits(rkpm_jdg_sram_ctrbits,RKPM_CTR_DDR))
282         {
283            // rkpm_clr_val_ctrbit(rkpm_jdg_sram_ctrbits,RKPM_CTR_GTCLKS);
284         }
285     
286 }
287
288 struct rk_soc_pm_info_st {
289     int offset;
290     char *name;
291 };
292
293 #define RK_SOC_PM_HELP_(id,NAME)\
294         {\
295         .offset= RKPM_CTR_##id,\
296         .name= NAME,\
297         }
298     
299 struct rk_soc_pm_info_st rk_soc_pm_helps[]={
300 #if 0
301     RK_SOC_PM_HELP_(NO_PD,"pd is not power dn"),
302     RK_SOC_PM_HELP_(NO_CLK_GATING,"clk is not gating"),
303     RK_SOC_PM_HELP_(NO_PLL,"pll is not power dn"),
304     RK_SOC_PM_HELP_(NO_VOLT,"volt is not set suspend"),
305     RK_SOC_PM_HELP_(NO_GPIO,"gpio is not control "),
306     //RK_SOC_PM_HELP_(NO_SRAM,"not enter sram code"),
307     RK_SOC_PM_HELP_(NO_DDR,"ddr is not reflash"),
308     RK_SOC_PM_HELP_(NO_PMIC,"pmic is not suspend"),
309     RK_SOC_PM_HELP_(RET_DIRT,"sys return from pm_enter directly"),
310     RK_SOC_PM_HELP_(SRAM_NO_WFI,"sys is not runing wfi in sram"),
311     RK_SOC_PM_HELP_(WAKE_UP_KEY,"send a power key to wake up lcd"),
312 #endif
313 };
314     
315 ssize_t rk_soc_pm_helps_sprintf(char *buf)
316 {
317     char *s = buf;
318     int i;
319
320     for(i=0;i<ARRAY_SIZE(rk_soc_pm_helps);i++)
321     {
322         s += sprintf(s, "bit(%d): %s\n", rk_soc_pm_helps[i].offset,rk_soc_pm_helps[i].name);
323     }
324
325     return (s-buf);
326 }   
327     
328 void rk_soc_pm_helps_printk(void)
329 {
330     int i;
331     printk("**************rkpm_ctr_bits bits help***********:\n");
332     for(i=0;i<ARRAY_SIZE(rk_soc_pm_helps);i++)
333     {
334         printk("bit(%d): %s\n", rk_soc_pm_helps[i].offset,rk_soc_pm_helps[i].name);
335     }
336 }   
337
338 #if 0
339 static int __init early_param_rk_soc_pm_ctr(char *str)
340 {
341     get_option(&str, &rkpm_ctrbits);
342     
343     printk("********rkpm_ctr_bits information is following:*********\n");
344     printk("rkpm_ctr_bits=%x\n",rkpm_ctrbits);
345     if(rkpm_ctrbits)
346     {
347         rk_soc_pm_helps_printk();
348     }
349     printk("********rkpm_ctr_bits information end*********\n");
350     return 0;
351 }
352 #endif
353
354 /*******************************************log*********************************************/
355
356
357 bool  pm_log;
358
359 extern void pm_emit_log_char(char c);
360
361 /********************************ddr print**********************************/
362 void rkpm_ddr_printch(char byte)
363 {
364         if(pm_ops.printch)
365             pm_ops.printch(byte);       
366         //if (byte == '\n')
367                 //rkpm_ddr_printch('\r');
368 }
369 void rkpm_ddr_printascii(const char *s)
370 {
371         while (*s) {
372                 rkpm_ddr_printch(*s);
373                 s++;
374         }
375 }
376
377 void  rkpm_ddr_printhex(unsigned int hex)
378 {
379         int i = 8;
380         rkpm_ddr_printch('0');
381         rkpm_ddr_printch('x');
382         while (i--) {
383                 unsigned char c = (hex & 0xF0000000) >> 28;
384                 rkpm_ddr_printch(c < 0xa ? c + '0' : c - 0xa + 'a');
385                 hex <<= 4;
386         }
387 }
388 static int rk_lpmode_enter(unsigned long arg)
389 {
390
391         //RKPM_DDR_PFUN(slp_setting(rkpm_jdg_sram_ctrbits),slp_setting); 
392     
393         RKPM_DDR_FUN(slp_setting); 
394                 
395         local_flush_tlb_all();
396         flush_cache_all();
397         outer_flush_all();
398         outer_disable();
399         cpu_proc_fin();
400         //outer_inv_all();// ???
401         //  l2x0_inv_all_pm(); //rk319x is not need
402         flush_cache_all();
403         
404         rkpm_ddr_printch('d');
405
406         //rkpm_udelay(3*10);
407
408         dsb();
409         wfi();  
410         
411         rkpm_ddr_printch('D');
412         return 0;
413 }
414
415
416 int cpu_suspend(unsigned long arg, int (*fn)(unsigned long));
417
418 static int rkpm_enter(suspend_state_t state)
419 {
420  
421         printk("%s\n",__FUNCTION__);
422
423         
424         RKPM_DDR_FUN(prepare);   
425         
426         printk(KERN_DEBUG "pm: ");
427
428         rkpm_ctrbits_prepare();
429          
430       //  if(rkpm_chk_jdg_ctrbits(RKPM_CTR_RET_DIRT))
431       //  return 0;
432       
433         rkpm_ddr_printch('0');
434
435         RKPM_BITCTR_DDR_FUN(PWR_DMNS,pwr_dmns);
436
437         rkpm_ddr_printch('1');
438
439         local_fiq_disable();
440     
441         RKPM_DDR_PFUN(save_setting,(rkpm_jdg_sram_ctrbits)); 
442         
443         rkpm_ddr_printch('2');
444         
445         RKPM_BITCTR_DDR_FUN(GTCLKS,gtclks);
446
447         rkpm_ddr_printch('3');
448
449         RKPM_BITCTR_DDR_FUN(PLLS,plls);
450
451         rkpm_ddr_printch('4');
452
453         RKPM_BITCTR_DDR_FUN(GPIOS,gpios);
454
455         RKPM_DDR_FUN(regs_pread);
456
457         rkpm_ddr_printch('5');
458
459         pm_log = false;
460
461         if(rkpm_chk_jdg_ctrbits(RKPM_CTRBITS_SOC_DLPMD))
462         {   
463             if(cpu_suspend(0,rk_lpmode_enter)==0)
464             {
465                 RKPM_DDR_FUN(slp_re_first);
466                 rkpm_ddr_printch('D');
467                 //rk_soc_pm_ctr_bits_prepare();
468             }                         
469             rkpm_ddr_printch('d');          
470         }
471         else if(rkpm_chk_jdg_ctrbits(RKPM_CTR_IDLESRAM_MD)&&p_suspend_pie_cb)
472         {
473             call_with_stack(p_suspend_pie_cb,&rkpm_jdg_sram_ctrbits, rockchip_sram_stack);
474         }
475         else
476         {
477             dsb();
478             wfi();
479         }
480
481         pm_log = true;
482
483         rkpm_ddr_printch('5');
484
485         RKPM_BITCTR_DDR_FUN(GPIOS,re_gpios);
486
487         rkpm_ddr_printch('4');
488
489         RKPM_BITCTR_DDR_FUN(PLLS,re_plls);
490
491         rkpm_ddr_printch('3');
492
493         RKPM_BITCTR_DDR_FUN(GTCLKS,re_gtclks);
494         
495         rkpm_ddr_printch('2');
496         
497         RKPM_DDR_FUN(re_save_setting); 
498
499         local_fiq_enable();
500         rkpm_ddr_printch('1');
501         
502
503
504         RKPM_BITCTR_DDR_FUN(PWR_DMNS,re_pwr_dmns);
505
506         rkpm_ddr_printch('0');
507
508
509         pm_log = false;
510
511         printk(KERN_CONT "\n");
512
513         rkpm_ddr_printch('\n');
514
515         RKPM_DDR_FUN(finish);
516         
517         return 0;
518 }
519
520 static int rkpm_enter_tst(void)
521 {
522
523        return rkpm_enter(0);
524
525 }
526
527 static int rkpm_suspend_prepare(void)
528 {
529         /* disable entering idle by disable_hlt() */
530         //disable_hlt();
531         return 0;
532 }
533
534 static void rkpm_suspend_finish(void)
535 {
536         //enable_hlt();
537         
538         #if 0 //def CONFIG_KEYS_RK29
539         if(rkpm_check_ctrbits(1<<RKPM_CTR_WAKE_UP_KEY))
540         {
541                 rk28_send_wakeup_key();
542                 printk("rk30_pm_finish rk28_send_wakeup_key\n");
543         }
544         #endif
545 }
546
547
548 static struct platform_suspend_ops rockchip_suspend_ops = {
549         .enter          = rkpm_enter,
550         .valid          = suspend_valid_only_mem,
551         .prepare        = rkpm_suspend_prepare,
552         .finish         = rkpm_suspend_finish,
553 };
554 void __init rockchip_suspend_init(void)
555 {
556     //printk("%s\n",__FUNCTION__);
557     suspend_set_ops(&rockchip_suspend_ops);
558     return;
559 }
560
561