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