ARM: rockchip: rk3228: implement function rk3228_restart
[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 #include <asm/psci.h>
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((unsigned long)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_PSCI
407 static bool psci_suspend_available(void)
408 {
409         return (psci_ops.cpu_suspend != NULL);
410 }
411 #else
412 static inline bool psci_suspend_available(void)
413 {
414         return false;
415 }
416 #endif
417
418 #ifdef CONFIG_ARM
419 void rk_sram_suspend(void)
420 {
421         RKPM_DDR_FUN(regs_pread);
422         rkpm_ddr_printascii("sram");
423         call_with_stack(p_suspend_pie_cb
424                 , &rkpm_jdg_sram_ctrbits, rockchip_sram_stack);
425 }
426
427 static int rk_lpmode_enter(unsigned long arg)
428 {
429 #ifdef CONFIG_ARM_PSCI
430         const struct psci_power_state ps = {
431                 .type = PSCI_POWER_STATE_TYPE_POWER_DOWN,
432         };
433
434         if (psci_suspend_available())
435                 return psci_ops.cpu_suspend(ps, virt_to_phys(cpu_resume));
436 #endif
437         //RKPM_DDR_PFUN(slp_setting(rkpm_jdg_sram_ctrbits),slp_setting); 
438     
439         RKPM_DDR_FUN(slp_setting); 
440
441         local_flush_tlb_all();
442         flush_cache_all();
443         outer_flush_all();
444         outer_disable();
445         cpu_proc_fin();
446         //outer_inv_all();// ???
447         //  l2x0_inv_all_pm(); //rk319x is not need
448         flush_cache_all();
449
450          rkpm_ddr_printch('d');
451
452         //rkpm_udelay(3*10);
453
454         dsb();
455         wfi();  
456         
457         rkpm_ddr_printch('D');
458         return 0;
459 }
460
461 int cpu_suspend(unsigned long arg, int (*fn)(unsigned long));
462 #endif /* CONFIG_ARM */
463
464 static int rkpm_enter(suspend_state_t state)
465 {
466         //static u32 test_count=0;
467         // printk(KERN_DEBUG"pm: ");
468         printk("%s:\n",__FUNCTION__);
469         //printk("pm test times=%d\n",++test_count);
470
471 #ifdef CONFIG_ARM_PSCI
472         if (psci_suspend_available()) {
473                 cpu_suspend(0, rk_lpmode_enter);
474                 return 0;
475         }
476 #endif
477         RKPM_DDR_FUN(prepare);   
478         
479         rkpm_ctrbits_prepare();
480          
481         //  if(rkpm_chk_jdg_ctrbits(RKPM_CTR_RET_DIRT))
482         //  return 0;
483       
484         rkpm_ddr_printch('0');
485
486         RKPM_BITCTR_DDR_FUN(PWR_DMNS,pwr_dmns);
487
488         rkpm_ddr_printch('1');
489
490         local_fiq_disable();
491     
492         RKPM_DDR_PFUN(save_setting,(rkpm_jdg_sram_ctrbits)); 
493         
494         rkpm_ddr_printch('2');
495         
496         RKPM_BITCTR_DDR_FUN(GTCLKS,gtclks);
497
498         rkpm_ddr_printch('3');
499
500         RKPM_BITCTR_DDR_FUN(PLLS,plls);
501
502         rkpm_ddr_printch('4');
503
504         RKPM_BITCTR_DDR_FUN(GPIOS,gpios);
505
506         RKPM_DDR_FUN(regs_pread);
507
508         rkpm_ddr_printch('5');
509
510 #ifdef CONFIG_ARM
511         if(rkpm_chk_jdg_ctrbits(RKPM_CTRBITS_SOC_DLPMD))
512         {   
513             if(cpu_suspend(0,rk_lpmode_enter)==0)
514             {
515                 RKPM_DDR_FUN(slp_re_first);
516                 rkpm_ddr_printch('K');
517                 //rk_soc_pm_ctr_bits_prepare();
518             }                         
519             rkpm_ddr_printch('d');          
520         }
521         else if(rkpm_chk_jdg_ctrbits(RKPM_CTR_IDLESRAM_MD)&&p_suspend_pie_cb)
522         {
523             call_with_stack(p_suspend_pie_cb,&rkpm_jdg_sram_ctrbits, rockchip_sram_stack);
524         }
525         else
526         {
527             dsb();
528             wfi();
529         }
530 #else
531         flush_cache_all();
532         cpu_suspend(1);
533 #endif
534
535         rkpm_ddr_printch('5');
536
537         RKPM_BITCTR_DDR_FUN(GPIOS,re_gpios);
538
539         rkpm_ddr_printch('4');
540
541         RKPM_BITCTR_DDR_FUN(PLLS,re_plls);
542
543         rkpm_ddr_printch('3');
544
545         RKPM_BITCTR_DDR_FUN(GTCLKS,re_gtclks);
546         
547         rkpm_ddr_printch('2');
548         
549         RKPM_DDR_FUN(re_save_setting); 
550
551         local_fiq_enable();
552         rkpm_ddr_printch('1');
553         
554         RKPM_BITCTR_DDR_FUN(PWR_DMNS,re_pwr_dmns);
555
556         rkpm_ddr_printch('0');
557         rkpm_ddr_printch('\n');
558         
559         RKPM_DDR_FUN(finish);           
560         return 0;
561 }
562
563 #if 0
564 static int rkpm_enter_tst(void)
565 {
566
567        return rkpm_enter(0);
568
569 }
570 #endif
571
572 static int rkpm_suspend_prepare(void)
573 {
574         /* disable entering idle by disable_hlt() */
575         //disable_hlt();
576         return 0;
577 }
578
579 static void rkpm_suspend_finish(void)
580 {
581         //enable_hlt();
582         
583         #if 0 //def CONFIG_KEYS_RK29
584         if(rkpm_check_ctrbits(1<<RKPM_CTR_WAKE_UP_KEY))
585         {
586                 rk28_send_wakeup_key();
587                 printk("rk30_pm_finish rk28_send_wakeup_key\n");
588         }
589         #endif
590 }
591
592
593 static struct platform_suspend_ops rockchip_suspend_ops = {
594         .enter          = rkpm_enter,
595         .valid          = suspend_valid_only_mem,
596         .prepare        = rkpm_suspend_prepare,
597         .finish         = rkpm_suspend_finish,
598 };
599 void __init rockchip_suspend_init(void)
600 {
601     //printk("%s\n",__FUNCTION__);
602     suspend_set_ops(&rockchip_suspend_ops);
603     return;
604 }
605
606 #ifndef CONFIG_ARM
607 static int __init rockchip_init_suspend(void)
608 {
609         suspend_set_ops(&rockchip_suspend_ops);
610         return 0;
611 }
612 late_initcall_sync(rockchip_init_suspend);
613 #endif /* CONFIG_ARM */
614
615 static enum rockchip_pm_policy pm_policy;
616 static BLOCKING_NOTIFIER_HEAD(policy_notifier_list);
617
618 int rockchip_pm_policy_register_notifier(struct notifier_block *nb)
619 {
620         return blocking_notifier_chain_register(&policy_notifier_list, nb);
621 }
622
623 int rockchip_pm_policy_unregister_notifier(struct notifier_block *nb)
624 {
625         return blocking_notifier_chain_unregister(&policy_notifier_list, nb);
626 }
627
628 static int rockchip_pm_policy_notify(void)
629 {
630         return blocking_notifier_call_chain(&policy_notifier_list,
631                         pm_policy, NULL);
632 }
633
634 enum rockchip_pm_policy rockchip_pm_get_policy(void)
635 {
636         return pm_policy;
637 }
638
639 int rockchip_pm_set_policy(enum rockchip_pm_policy policy)
640 {
641         if (policy < ROCKCHIP_PM_NR_POLICYS && policy != pm_policy) {
642                 printk(KERN_INFO "pm policy %d -> %d\n", pm_policy, policy);
643                 pm_policy = policy;
644                 rockchip_pm_policy_notify();
645         }
646
647         return 0;
648 }
649
650 static unsigned int policy;
651
652 static int set_policy(const char *val, const struct kernel_param *kp)
653 {
654         int ret;
655
656         ret = param_set_uint(val, kp);
657         if (ret < 0)
658                 return ret;
659
660         rockchip_pm_set_policy(policy);
661         policy = rockchip_pm_get_policy();
662
663         return 0;
664 }
665
666 static struct kernel_param_ops policy_param_ops = {
667         .set = set_policy,
668         .get = param_get_uint,
669 };
670
671 module_param_cb(policy, &policy_param_ops, &policy, 0600);