Merge tag lsk-v3.10-15.03-android
[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
180 void rkpm_set_sram_ops_bus(rkpm_ops_void_callback bus_idle_request)
181 {
182         if (p_pm_sram_ops)
183                 p_pm_sram_ops->bus_idle_request = bus_idle_request;
184 }
185 void rkpm_set_sram_ops_printch(rkpm_ops_printch_callback printch)
186 {  
187     if(p_pm_sram_ops)
188         p_pm_sram_ops->printch=printch; 
189 }
190
191 /******************for user ************************/
192 void rkpm_set_ctrbits(u32 bits)
193 {       
194         rkpm_ctrbits = bits;
195         
196 }
197 void rkpm_add_ctrbits(u32 bits)
198 {       
199         rkpm_ctrbits |= bits;
200         
201 }
202 u32 rkpm_get_ctrbits(void)
203 {       
204         return rkpm_ctrbits;
205 }
206
207 u32 rkpm_chk_ctrbits(u32 bits)
208 {       
209         return (rkpm_ctrbits&bits);
210 }
211
212 //clear
213 void rkpm_clr_ctrbits(u32 bits)
214 {
215         rkpm_ctrbits&=~bits;
216 }
217
218 /****************** for pm.c************************/
219
220 static void inline rkpm_set_jdg_ctrbits(u32 bits)
221 {       
222         rkpm_jdg_ctrbits = bits;
223         
224 }
225 static u32  inline rkpm_get_jdg_ctrbits(void)
226 {       
227         return rkpm_jdg_ctrbits;
228 }
229
230 static void inline rkpm_add_jdg_ctrbits(int bit)
231 {       
232         rkpm_jdg_ctrbits|=bit;
233 }
234
235 #if 0
236 static u32 inline rkpm_chk_jdg_ctrbit(int bit)
237 {       
238         return (rkpm_jdg_ctrbits&bit);
239 }
240 #endif
241
242 static u32 inline rkpm_chk_jdg_ctrbits(int bits)
243 {       
244         return (rkpm_jdg_ctrbits&bits);
245 }
246 //clear
247 static void inline rkpm_clr_jdg_ctrbits(int bit)
248 {
249         rkpm_jdg_ctrbits&=~bit;
250 }
251
252
253 #define  RKPM_DDR_FUN(fun) \
254         if(pm_ops.fun)\
255                 (pm_ops.fun)()
256
257 // fun with paramater  param (p1,p2,p3)
258 #define  RKPM_DDR_PFUN(fun,param) \
259         if(pm_ops.fun) \
260             {(pm_ops.fun)param;} while(0)
261
262 #define  RKPM_BITCTR_DDR_FUN(ctr,fun) \
263         if(rkpm_chk_jdg_ctrbits(RKPM_CTR_##ctr)&&pm_ops.fun)\
264                 (pm_ops.fun)()
265
266 #define  RKPM_BITSCTR_DDR_FUN(bits,fun) \
267         if(rkpm_chk_jdg_ctrbits(bits)&&pm_ops.fun)\
268             (pm_ops.fun)()
269
270
271         
272 #define  RKPM_LPMD_BITSCTR_DDR_PFUN(bits,fun,param) \
273                 if(rkpm_chk_jdg_ctrbits(RKPM_CTRBITS_SOC_DLPMD)&&pm_ops.fun)\
274                     (pm_ops.fun)param
275
276 #define  RKPM_LPMD_BITSCTR_DDR_FUN(bits,fun) \
277                 if(rkpm_chk_jdg_ctrbits(RKPM_CTRBITS_SOC_DLPMD)&&pm_ops.fun)\
278                         (pm_ops.fun)()
279
280
281
282 void rkpm_ctrbits_prepare(void)
283 {
284         
285         //rkpm_sram_ctrbits=rkpm_ctrbits;
286         
287         rkpm_jdg_ctrbits=rkpm_ctrbits;
288
289         //if plls is no pd,clk rate is high, volts can not setting low,so we need to judge ctrbits
290         //if(rkpm_chk_jdg_ctrbits(RKPM_CTR_VOLTS))
291         {
292                 //rkpm_clr_jdg_ctrbits(RKPM_CTR_VOLTS);
293         }
294     
295         rkpm_jdg_sram_ctrbits=rkpm_jdg_ctrbits;
296         
297         //clk gating will gate ddr clk in sram
298         if(!rkpm_chk_val_ctrbits(rkpm_jdg_sram_ctrbits,RKPM_CTR_DDR))
299         {
300            // rkpm_clr_val_ctrbit(rkpm_jdg_sram_ctrbits,RKPM_CTR_GTCLKS);
301         }
302     
303 }
304
305 struct rk_soc_pm_info_st {
306     int offset;
307     char *name;
308 };
309
310 #define RK_SOC_PM_HELP_(id,NAME)\
311         {\
312         .offset= RKPM_CTR_##id,\
313         .name= NAME,\
314         }
315     
316 struct rk_soc_pm_info_st rk_soc_pm_helps[]={
317 #if 0
318     RK_SOC_PM_HELP_(NO_PD,"pd is not power dn"),
319     RK_SOC_PM_HELP_(NO_CLK_GATING,"clk is not gating"),
320     RK_SOC_PM_HELP_(NO_PLL,"pll is not power dn"),
321     RK_SOC_PM_HELP_(NO_VOLT,"volt is not set suspend"),
322     RK_SOC_PM_HELP_(NO_GPIO,"gpio is not control "),
323     //RK_SOC_PM_HELP_(NO_SRAM,"not enter sram code"),
324     RK_SOC_PM_HELP_(NO_DDR,"ddr is not reflash"),
325     RK_SOC_PM_HELP_(NO_PMIC,"pmic is not suspend"),
326     RK_SOC_PM_HELP_(RET_DIRT,"sys return from pm_enter directly"),
327     RK_SOC_PM_HELP_(SRAM_NO_WFI,"sys is not runing wfi in sram"),
328     RK_SOC_PM_HELP_(WAKE_UP_KEY,"send a power key to wake up lcd"),
329 #endif
330 };
331     
332 ssize_t rk_soc_pm_helps_sprintf(char *buf)
333 {
334     char *s = buf;
335     int i;
336
337     for(i=0;i<ARRAY_SIZE(rk_soc_pm_helps);i++)
338     {
339         s += sprintf(s, "bit(%d): %s\n", rk_soc_pm_helps[i].offset,rk_soc_pm_helps[i].name);
340     }
341
342     return (s-buf);
343 }   
344     
345 void rk_soc_pm_helps_printk(void)
346 {
347     int i;
348     printk("**************rkpm_ctr_bits bits help***********:\n");
349     for(i=0;i<ARRAY_SIZE(rk_soc_pm_helps);i++)
350     {
351         printk("bit(%d): %s\n", rk_soc_pm_helps[i].offset,rk_soc_pm_helps[i].name);
352     }
353 }   
354
355 #if 0
356 static int __init early_param_rk_soc_pm_ctr(char *str)
357 {
358     get_option(&str, &rkpm_ctrbits);
359     
360     printk("********rkpm_ctr_bits information is following:*********\n");
361     printk("rkpm_ctr_bits=%x\n",rkpm_ctrbits);
362     if(rkpm_ctrbits)
363     {
364         rk_soc_pm_helps_printk();
365     }
366     printk("********rkpm_ctr_bits information end*********\n");
367     return 0;
368 }
369 #endif
370
371 /*******************************************log*********************************************/
372
373
374 bool  pm_log;
375
376 extern void pm_emit_log_char(char c);
377
378 /********************************ddr print**********************************/
379 void rkpm_ddr_printch(char byte)
380 {
381         if(pm_ops.printch)
382             pm_ops.printch(byte);       
383         //if (byte == '\n')
384                 //rkpm_ddr_printch('\r');
385 }
386 void rkpm_ddr_printascii(const char *s)
387 {
388         while (*s) {
389                 rkpm_ddr_printch(*s);
390                 s++;
391         }
392 }
393
394 void  rkpm_ddr_printhex(unsigned int hex)
395 {
396         int i = 8;
397         rkpm_ddr_printch('0');
398         rkpm_ddr_printch('x');
399         while (i--) {
400                 unsigned char c = (hex & 0xF0000000) >> 28;
401                 rkpm_ddr_printch(c < 0xa ? c + '0' : c - 0xa + 'a');
402                 hex <<= 4;
403         }
404 }
405
406 #ifdef CONFIG_ARM
407 void rk_sram_suspend(void)
408 {
409         RKPM_DDR_FUN(regs_pread);
410         rkpm_ddr_printascii("sram");
411         call_with_stack(p_suspend_pie_cb
412                 , &rkpm_jdg_sram_ctrbits, rockchip_sram_stack);
413 }
414 static int rk_lpmode_enter(unsigned long arg)
415 {
416
417         //RKPM_DDR_PFUN(slp_setting(rkpm_jdg_sram_ctrbits),slp_setting); 
418     
419         RKPM_DDR_FUN(slp_setting); 
420
421         local_flush_tlb_all();
422         flush_cache_all();
423         outer_flush_all();
424         outer_disable();
425         cpu_proc_fin();
426         //outer_inv_all();// ???
427         //  l2x0_inv_all_pm(); //rk319x is not need
428         flush_cache_all();
429
430          rkpm_ddr_printch('d');
431
432         //rkpm_udelay(3*10);
433
434         dsb();
435         wfi();  
436         
437         rkpm_ddr_printch('D');
438         return 0;
439 }
440
441 int cpu_suspend(unsigned long arg, int (*fn)(unsigned long));
442 #endif /* CONFIG_ARM */
443
444 static int rkpm_enter(suspend_state_t state)
445 {
446         //static u32 test_count=0;
447         // printk(KERN_DEBUG"pm: ");
448         printk("%s:\n",__FUNCTION__);
449         //printk("pm test times=%d\n",++test_count);
450        
451         RKPM_DDR_FUN(prepare);   
452         
453         rkpm_ctrbits_prepare();
454          
455         //  if(rkpm_chk_jdg_ctrbits(RKPM_CTR_RET_DIRT))
456         //  return 0;
457       
458         rkpm_ddr_printch('0');
459
460         RKPM_BITCTR_DDR_FUN(PWR_DMNS,pwr_dmns);
461
462         rkpm_ddr_printch('1');
463
464         local_fiq_disable();
465     
466         RKPM_DDR_PFUN(save_setting,(rkpm_jdg_sram_ctrbits)); 
467         
468         rkpm_ddr_printch('2');
469         
470         RKPM_BITCTR_DDR_FUN(GTCLKS,gtclks);
471
472         rkpm_ddr_printch('3');
473
474         RKPM_BITCTR_DDR_FUN(PLLS,plls);
475
476         rkpm_ddr_printch('4');
477
478         RKPM_BITCTR_DDR_FUN(GPIOS,gpios);
479
480         RKPM_DDR_FUN(regs_pread);
481
482         rkpm_ddr_printch('5');
483
484 #ifdef CONFIG_ARM
485         if(rkpm_chk_jdg_ctrbits(RKPM_CTRBITS_SOC_DLPMD))
486         {   
487             if(cpu_suspend(0,rk_lpmode_enter)==0)
488             {
489                 RKPM_DDR_FUN(slp_re_first);
490                 rkpm_ddr_printch('K');
491                 //rk_soc_pm_ctr_bits_prepare();
492             }                         
493             rkpm_ddr_printch('d');          
494         }
495         else if(rkpm_chk_jdg_ctrbits(RKPM_CTR_IDLESRAM_MD)&&p_suspend_pie_cb)
496         {
497             call_with_stack(p_suspend_pie_cb,&rkpm_jdg_sram_ctrbits, rockchip_sram_stack);
498         }
499         else
500         {
501             dsb();
502             wfi();
503         }
504 #else
505         flush_cache_all();
506         cpu_suspend(1);
507 #endif
508
509         rkpm_ddr_printch('5');
510
511         RKPM_BITCTR_DDR_FUN(GPIOS,re_gpios);
512
513         rkpm_ddr_printch('4');
514
515         RKPM_BITCTR_DDR_FUN(PLLS,re_plls);
516
517         rkpm_ddr_printch('3');
518
519         RKPM_BITCTR_DDR_FUN(GTCLKS,re_gtclks);
520         
521         rkpm_ddr_printch('2');
522         
523         RKPM_DDR_FUN(re_save_setting); 
524
525         local_fiq_enable();
526         rkpm_ddr_printch('1');
527         
528         RKPM_BITCTR_DDR_FUN(PWR_DMNS,re_pwr_dmns);
529
530         rkpm_ddr_printch('0');
531         rkpm_ddr_printch('\n');
532         
533         RKPM_DDR_FUN(finish);           
534         return 0;
535 }
536
537 #if 0
538 static int rkpm_enter_tst(void)
539 {
540
541        return rkpm_enter(0);
542
543 }
544 #endif
545
546 static int rkpm_suspend_prepare(void)
547 {
548         /* disable entering idle by disable_hlt() */
549         //disable_hlt();
550         return 0;
551 }
552
553 static void rkpm_suspend_finish(void)
554 {
555         //enable_hlt();
556         
557         #if 0 //def CONFIG_KEYS_RK29
558         if(rkpm_check_ctrbits(1<<RKPM_CTR_WAKE_UP_KEY))
559         {
560                 rk28_send_wakeup_key();
561                 printk("rk30_pm_finish rk28_send_wakeup_key\n");
562         }
563         #endif
564 }
565
566
567 static struct platform_suspend_ops rockchip_suspend_ops = {
568         .enter          = rkpm_enter,
569         .valid          = suspend_valid_only_mem,
570         .prepare        = rkpm_suspend_prepare,
571         .finish         = rkpm_suspend_finish,
572 };
573 void __init rockchip_suspend_init(void)
574 {
575     //printk("%s\n",__FUNCTION__);
576     suspend_set_ops(&rockchip_suspend_ops);
577     return;
578 }
579
580 #ifndef CONFIG_ARM
581 static int __init rockchip_init_suspend(void)
582 {
583         suspend_set_ops(&rockchip_suspend_ops);
584         return 0;
585 }
586 late_initcall_sync(rockchip_init_suspend);
587 #endif /* CONFIG_ARM */
588
589 static enum rockchip_pm_policy pm_policy;
590 static BLOCKING_NOTIFIER_HEAD(policy_notifier_list);
591
592 int rockchip_pm_policy_register_notifier(struct notifier_block *nb)
593 {
594         return blocking_notifier_chain_register(&policy_notifier_list, nb);
595 }
596
597 int rockchip_pm_policy_unregister_notifier(struct notifier_block *nb)
598 {
599         return blocking_notifier_chain_unregister(&policy_notifier_list, nb);
600 }
601
602 static int rockchip_pm_policy_notify(void)
603 {
604         return blocking_notifier_call_chain(&policy_notifier_list,
605                         pm_policy, NULL);
606 }
607
608 enum rockchip_pm_policy rockchip_pm_get_policy(void)
609 {
610         return pm_policy;
611 }
612
613 int rockchip_pm_set_policy(enum rockchip_pm_policy policy)
614 {
615         if (policy < ROCKCHIP_PM_NR_POLICYS && policy != pm_policy) {
616                 printk(KERN_INFO "pm policy %d -> %d\n", pm_policy, policy);
617                 pm_policy = policy;
618                 rockchip_pm_policy_notify();
619         }
620
621         return 0;
622 }
623
624 static unsigned int policy;
625
626 static int set_policy(const char *val, const struct kernel_param *kp)
627 {
628         int ret;
629
630         ret = param_set_uint(val, kp);
631         if (ret < 0)
632                 return ret;
633
634         rockchip_pm_set_policy(policy);
635         policy = rockchip_pm_get_policy();
636
637         return 0;
638 }
639
640 static struct kernel_param_ops policy_param_ops = {
641         .set = set_policy,
642         .get = param_get_uint,
643 };
644
645 module_param_cb(policy, &policy_param_ops, &policy, 0600);