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