3 #include <linux/init.h>
4 #include <linux/kernel.h>
5 #include <linux/module.h>
8 #include <linux/types.h>
9 #include <linux/string.h>
10 #include <mach/mt_cirq.h>
11 #include <asm/system_misc.h>
13 #include <mach/mt_typedefs.h>
14 #include <mach/sync_write.h>
15 #include <mach/mt_clkmgr.h>
16 #include <mach/mt_dcm.h>
17 #include <mach/mt_gpt.h>
18 #include <mach/mt_spm_idle.h>
19 #include <mach/mt_spm_sleep.h>
20 #include <mach/hotplug.h>
21 #include <mach/mt_cpufreq.h>
22 #include <mach/mt_power_gs.h>
23 #include <mach/mt_ptp.h>
25 #include <mach/mt_idle.h>
30 #include <linux/xlog.h>
32 #define TAG "Power/swap"
34 #define idle_err(fmt, args...) \
35 xlog_printk(ANDROID_LOG_ERROR, TAG, fmt, ##args)
36 #define idle_warn(fmt, args...) \
37 xlog_printk(ANDROID_LOG_WARN, TAG, fmt, ##args)
38 #define idle_info(fmt, args...) \
39 xlog_printk(ANDROID_LOG_INFO, TAG, fmt, ##args)
40 #define idle_dbg(fmt, args...) \
41 xlog_printk(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
42 #define idle_ver(fmt, args...) \
43 xlog_printk(ANDROID_LOG_VERBOSE, TAG, fmt, ##args)
45 #else /* !USING_XLOG */
47 #define TAG "[Power/swap] "
49 #define idle_err(fmt, args...) \
50 pr_err(TAG fmt, ##args)
51 #define idle_warn(fmt, args...) \
52 pr_warn(TAG fmt, ##args)
53 #define idle_info(fmt, args...) \
54 pr_notice(TAG fmt, ##args)
55 #define idle_dbg(fmt, args...) \
56 pr_info(TAG fmt, ##args)
57 #define idle_ver(fmt, args...) \
58 pr_debug(TAG fmt, ##args)
63 #define idle_readl(addr) \
66 #define idle_writel(addr, val) \
67 mt65xx_reg_sync_writel(val, addr)
69 #define idle_setl(addr, val) \
70 mt65xx_reg_sync_writel(idle_readl(addr) | (val), addr)
72 #define idle_clrl(addr, val) \
73 mt65xx_reg_sync_writel(idle_readl(addr) & ~(val), addr)
76 #define INVALID_GRP_ID(grp) (grp < 0 || grp >= NR_GRPS)
77 bool __attribute__((weak
))
78 clkmgr_idle_can_enter(unsigned int *condition_mask
, unsigned int *block_mask
)
100 static const char *idle_name
[NR_TYPES
] = {
107 static const char *reason_name
[NR_REASONS
] = {
115 static int idle_switch
[NR_TYPES
] = {
116 1, /* soidle switch */
117 1, /* dpidle switch */
118 1, /* slidle switch */
119 1, /* rgidle switch */
122 /************************************************
124 ************************************************/
125 #ifdef SPM_SODI_ENABLED
127 static unsigned int soidle_gpt_percpu
[NR_CPUS
] = {
134 static unsigned int soidle_condition_mask
[NR_GRPS
] = {
135 0x11eee5c1, /* PERI0: */
136 0x00000007, /* PERI1: */
137 0x00000000, /* INFRA: */
138 0x00000000, /* TOPCK: */
139 0x000a4cc4, /* DISP0: */
140 0x00000000, /* DISP1: */
141 0x000003e1, /* IMAGE: */
142 0x00000001, /* MFG: */
143 0x00000040, /* AUDIO: */
144 0x00000000, /* VDEC0: */
145 0x00000001, /* VDEC1: */
148 static unsigned int soidle_block_mask
[NR_GRPS
] = {0x0};
150 static unsigned int soidle_timer_left
[NR_CPUS
];
151 static unsigned int soidle_timer_left2
[NR_CPUS
];
152 static unsigned int soidle_time_critera
= 13000; /* 1ms */
155 static unsigned long soidle_cnt
[NR_CPUS
] = {0};
156 static unsigned long soidle_block_cnt
[NR_CPUS
][NR_REASONS
] = { {0} };
158 static DEFINE_MUTEX(soidle_locked
);
160 static void enable_soidle_by_mask(int grp
, unsigned int mask
)
162 mutex_lock(&soidle_locked
);
163 soidle_condition_mask
[grp
] &= ~mask
;
164 mutex_unlock(&soidle_locked
);
167 static void disable_soidle_by_mask(int grp
, unsigned int mask
)
169 mutex_lock(&soidle_locked
);
170 soidle_condition_mask
[grp
] |= mask
;
171 mutex_unlock(&soidle_locked
);
174 void enable_soidle_by_bit(int id
)
176 int grp
= clk_id_to_grp_id(id
);
177 unsigned int mask
= clk_id_to_mask(id
);
178 BUG_ON(INVALID_GRP_ID(grp
));
179 enable_soidle_by_mask(grp
, mask
);
181 EXPORT_SYMBOL(enable_soidle_by_bit
);
183 void disable_soidle_by_bit(int id
)
185 int grp
= clk_id_to_grp_id(id
);
186 unsigned int mask
= clk_id_to_mask(id
);
187 BUG_ON(INVALID_GRP_ID(grp
));
188 disable_soidle_by_mask(grp
, mask
);
190 EXPORT_SYMBOL(disable_soidle_by_bit
);
193 bool soidle_can_enter(int cpu
)
195 int reason
= NR_REASONS
;
199 if (TRUE
== gSpm_IsLcmVideoMode
) {
204 if (gSPM_SODI_EN
!= 0) {
209 /*if hotplug-ing, can't enter sodi avoid bootslave corrupt*/
210 if (atomic_read(&is_in_hotplug
) >= 1) {
215 if (atomic_read(&hotplug_cpu_count
) != 1) {
221 memset(soidle_block_mask
, 0, NR_GRPS
* sizeof(unsigned int));
222 if (!clkmgr_idle_can_enter(soidle_condition_mask
, soidle_block_mask
)) {
228 soidle_timer_left
[cpu
] = localtimer_get_counter();
229 if (soidle_timer_left
[cpu
] < soidle_time_critera
||
230 ((int)soidle_timer_left
[cpu
]) < 0) {
236 if (reason
< NR_REASONS
) {
237 soidle_block_cnt
[cpu
][reason
]++;
243 void soidle_before_wfi(int cpu
)
246 unsigned int id
= soidle_gpt_percpu
[cpu
];
249 err
= request_gpt(id
, GPT_ONE_SHOT
, GPT_CLK_SRC_SYS
, GPT_CLK_DIV_1
,
250 0, NULL
, GPT_NOAUTOEN
);
252 idle_info("[%s]fail to request GPT4\n", __func__
);
254 soidle_timer_left2
[cpu
] = localtimer_get_counter();
257 if ((int)soidle_timer_left2
[cpu
] <= 0)
258 gpt_set_cmp(id
, 1); /* Trigger GPT4 Timerout imediately */
260 gpt_set_cmp(id
, soidle_timer_left2
[cpu
]);
266 void soidle_after_wfi(int cpu
)
268 unsigned int id
= soidle_gpt_percpu
[cpu
];
270 if (gpt_check_and_ack_irq(id
))
271 localtimer_set_next_event(1);
273 /* waked up by other wakeup source */
274 unsigned int cnt
, cmp
;
275 gpt_get_cnt(id
, &cnt
);
276 gpt_get_cmp(id
, &cmp
);
277 if (unlikely(cmp
< cnt
)) {
278 idle_err("[%s]GPT%d: counter = %10u, compare = %10u\n", __func__
,
283 localtimer_set_next_event(cmp
-cnt
);
290 #endif /* SPM_SODI_ENABLED */
292 /************************************************
294 ************************************************/
295 static unsigned int dpidle_condition_mask
[NR_GRPS
] = {
296 0x1bfd0ffd, /* PERI0: */
297 0x00000007, /* PERI1: */
298 0x0000a080, /* INFRA: */
299 0x00000000, /* TOPCK: */
300 0x001fffff, /* DISP0: */
301 0x00003fff, /* DISP1: */
302 0x000003e1, /* IMAGE: */
303 0x00000001, /* MFG: */
304 0x00000000, /* AUDIO: */
305 0x00000001, /* VDEC0: */
306 0x00000001, /* VDEC1: */
309 static unsigned int dpidle_block_mask
[NR_GRPS
] = {0x0};
312 static unsigned int dpidle_timer_left
;
313 static unsigned int dpidle_timer_left2
;
314 static unsigned int dpidle_time_critera
= 26000;
316 static unsigned long dpidle_cnt
[NR_CPUS
] = {0};
317 static unsigned long dpidle_block_cnt
[NR_REASONS
] = {0};
319 static DEFINE_MUTEX(dpidle_locked
);
321 static void enable_dpidle_by_mask(int grp
, unsigned int mask
)
323 mutex_lock(&dpidle_locked
);
324 dpidle_condition_mask
[grp
] &= ~mask
;
325 mutex_unlock(&dpidle_locked
);
328 static void disable_dpidle_by_mask(int grp
, unsigned int mask
)
330 mutex_lock(&dpidle_locked
);
331 dpidle_condition_mask
[grp
] |= mask
;
332 mutex_unlock(&dpidle_locked
);
335 void enable_dpidle_by_bit(int id
)
337 int grp
= clk_id_to_grp_id(id
);
338 unsigned int mask
= clk_id_to_mask(id
);
339 BUG_ON(INVALID_GRP_ID(grp
));
340 enable_dpidle_by_mask(grp
, mask
);
342 EXPORT_SYMBOL(enable_dpidle_by_bit
);
344 void disable_dpidle_by_bit(int id
)
346 int grp
= clk_id_to_grp_id(id
);
347 unsigned int mask
= clk_id_to_mask(id
);
348 BUG_ON(INVALID_GRP_ID(grp
));
349 disable_dpidle_by_mask(grp
, mask
);
351 EXPORT_SYMBOL(disable_dpidle_by_bit
);
354 static bool dpidle_can_enter(void)
356 int reason
= NR_REASONS
;
358 #ifdef SPM_SODI_ENABLED
359 if (gSPM_SODI_EN
!= 0) {
365 if (!mt_cpufreq_earlysuspend_status_get()) {
370 if (atomic_read(&hotplug_cpu_count
) != 1) {
375 memset(dpidle_block_mask
, 0, NR_GRPS
* sizeof(unsigned int));
376 if (!clkmgr_idle_can_enter(dpidle_condition_mask
, dpidle_block_mask
)) {
381 dpidle_timer_left
= localtimer_get_counter();
382 if (dpidle_timer_left
< dpidle_time_critera
||
383 ((int)dpidle_timer_left
) < 0) {
389 if (reason
< NR_REASONS
) {
390 dpidle_block_cnt
[reason
]++;
396 static unsigned int clk_cfg_3
;
398 #define faudintbus_pll2sq() \
400 clk_cfg_3 = idle_readl(CLK_CFG_3); \
401 idle_writel(CLK_CFG_3, clk_cfg_3 & 0xF8FFFFFF); \
404 #define faudintbus_sq2pll() \
405 idle_writel(CLK_CFG_3, clk_cfg_3)
408 void spm_dpidle_before_wfi(void)
411 mt_power_gs_dump_dpidle();
418 dpidle_timer_left
= localtimer_get_counter();
419 gpt_set_cmp(GPT4
, dpidle_timer_left
);
421 dpidle_timer_left2
= localtimer_get_counter();
422 gpt_set_cmp(GPT4
, dpidle_timer_left2
);
428 void spm_dpidle_after_wfi(void)
431 idle_info("[%s]timer_left=%u, timer_left2=%u, delta=%u\n",
432 dpidle_timer_left
, dpidle_timer_left2
, dpidle_timer_left
-dpidle_timer_left2
);
435 if (gpt_check_and_ack_irq(GPT4
)) {
436 /* waked up by WAKEUP_GPT */
437 localtimer_set_next_event(1);
439 /* waked up by other wakeup source */
440 unsigned int cnt
, cmp
;
441 gpt_get_cnt(GPT4
, &cnt
);
442 gpt_get_cmp(GPT4
, &cmp
);
443 if (unlikely(cmp
< cnt
)) {
444 idle_err("[%s]GPT%d: counter = %10u, compare = %10u\n", __func__
,
449 localtimer_set_next_event(cmp
-cnt
);
461 /************************************************
463 ************************************************/
464 static unsigned int slidle_condition_mask
[NR_GRPS
] = {
465 0x11e01000, /* PERI0: */
466 0x00000000, /* PERI1: */
467 0x00000000, /* INFRA: */
468 0x00000000, /* TOPCK: */
469 0x00000000, /* DISP0: */
470 0x00000000, /* DISP1: */
471 0x00000000, /* IMAGE: */
472 0x00000000, /* MFG: */
473 0x00000000, /* AUDIO: */
474 0x00000000, /* VDEC0: */
475 0x00000000, /* VDEC1: */
478 static unsigned int slidle_block_mask
[NR_GRPS
] = {0x0};
480 static unsigned long slidle_cnt
[NR_CPUS
] = {0};
481 static unsigned long slidle_block_cnt
[NR_REASONS
] = {0};
483 static DEFINE_MUTEX(slidle_locked
);
486 static void enable_slidle_by_mask(int grp
, unsigned int mask
)
488 mutex_lock(&slidle_locked
);
489 slidle_condition_mask
[grp
] &= ~mask
;
490 mutex_unlock(&slidle_locked
);
493 static void disable_slidle_by_mask(int grp
, unsigned int mask
)
495 mutex_lock(&slidle_locked
);
496 slidle_condition_mask
[grp
] |= mask
;
497 mutex_unlock(&slidle_locked
);
500 void enable_slidle_by_bit(int id
)
502 int grp
= clk_id_to_grp_id(id
);
503 unsigned int mask
= clk_id_to_mask(id
);
504 BUG_ON(INVALID_GRP_ID(grp
));
505 enable_slidle_by_mask(grp
, mask
);
507 EXPORT_SYMBOL(enable_slidle_by_bit
);
509 void disable_slidle_by_bit(int id
)
511 int grp
= clk_id_to_grp_id(id
);
512 unsigned int mask
= clk_id_to_mask(id
);
513 BUG_ON(INVALID_GRP_ID(grp
));
514 disable_slidle_by_mask(grp
, mask
);
516 EXPORT_SYMBOL(disable_slidle_by_bit
);
518 static bool slidle_can_enter(void)
520 int reason
= NR_REASONS
;
521 if (atomic_read(&hotplug_cpu_count
) != 1) {
526 memset(slidle_block_mask
, 0, NR_GRPS
* sizeof(unsigned int));
527 if (!clkmgr_idle_can_enter(slidle_condition_mask
, slidle_block_mask
)) {
540 if (reason
< NR_REASONS
) {
541 slidle_block_cnt
[reason
]++;
548 static void slidle_before_wfi(int cpu
)
553 static void slidle_after_wfi(int cpu
)
560 static void go_to_slidle(int cpu
)
562 slidle_before_wfi(cpu
);
565 __asm__
__volatile__("wfi" : : : "memory");
567 slidle_after_wfi(cpu
);
571 /************************************************
573 ************************************************/
574 static unsigned long rgidle_cnt
[NR_CPUS
] = {0};
576 static void rgidle_before_wfi(int cpu
)
578 mt_power_gs_dump_idle();
581 static void rgidle_after_wfi(int cpu
)
586 static noinline
void go_to_rgidle(int cpu
)
588 rgidle_before_wfi(cpu
);
591 __asm__
__volatile__("wfi" : : : "memory");
593 rgidle_after_wfi(cpu
);
596 /************************************************
597 * idle task flow part
598 ************************************************/
601 * xxidle_handler return 1 if enter and exit the low power state
603 #ifdef SPM_SODI_ENABLED
605 static int sodi_cpu_pdn
= 1;
606 static inline int soidle_handler(int cpu
)
608 if (idle_switch
[IDLE_TYPE_SO
]) {
609 if (soidle_can_enter(cpu
)) {
610 spm_go_to_sodi(sodi_cpu_pdn
);
618 static inline int soidle_handler(int cpu
)
624 static int dpidle_cpu_pdn
= 1;
626 static inline int dpidle_handler(int cpu
)
629 if (idle_switch
[IDLE_TYPE_DP
]) {
630 if (dpidle_can_enter()) {
631 spm_go_to_dpidle(dpidle_cpu_pdn
, 0);
639 static inline int slidle_handler(int cpu
)
642 if (idle_switch
[IDLE_TYPE_SL
]) {
643 if (slidle_can_enter()) {
652 static inline int rgidle_handler(int cpu
)
655 if (idle_switch
[IDLE_TYPE_RG
]) {
663 static int (*idle_handlers
[NR_TYPES
])(int) = {
673 int cpu
= smp_processor_id();
676 for (i
= 0; i
< NR_TYPES
; i
++) {
677 if (idle_handlers
[i
](cpu
))
682 #define idle_attr(_name) \
683 static struct kobj_attribute _name##_attr = { \
685 .name = __stringify(_name), \
688 .show = _name##_show, \
689 .store = _name##_store, \
693 #ifdef SPM_SODI_ENABLED
694 static ssize_t
soidle_state_show(struct kobject
*kobj
,
695 struct kobj_attribute
*attr
, char *buf
)
702 p
+= sprintf(p
, "*********** screen on idle state ************\n");
703 p
+= sprintf(p
, "soidle_time_critera=%u\n", soidle_time_critera
);
705 for (cpus
= 0; cpus
< nr_cpu_ids
; cpus
++) {
706 p
+= sprintf(p
, "cpu:%d\n", cpus
);
707 for (reason
= 0; reason
< NR_REASONS
; reason
++) {
708 p
+= sprintf(p
, "[%d]soidle_block_cnt[%s]=%lu\n", reason
,
709 reason_name
[reason
], soidle_block_cnt
[cpus
][reason
]);
711 p
+= sprintf(p
, "\n");
714 for (i
= 0; i
< NR_GRPS
; i
++) {
715 p
+= sprintf(p
, "[%02d]soidle_condition_mask[%-8s]=0x%08x\t\tsoidle_block_mask[%-8s]=0x%08x\n", i
,
716 grp_get_name(i
), soidle_condition_mask
[i
],
717 grp_get_name(i
), soidle_block_mask
[i
]);
720 p
+= sprintf(p
, "\n********** soidle command help **********\n");
721 p
+= sprintf(p
, "soidle help: cat /sys/power/soidle_state\n");
722 p
+= sprintf(p
, "switch on/off: echo [soidle] 1/0 > /sys/power/soidle_state\n");
723 p
+= sprintf(p
, "en_so_by_bit: echo enable id > /sys/power/soidle_state\n");
724 p
+= sprintf(p
, "dis_so_by_bit: echo disable id > /sys/power/soidle_state\n");
725 p
+= sprintf(p
, "modify tm_cri: echo time value(dec) > /sys/power/soidle_state\n");
731 static ssize_t
soidle_state_store(struct kobject
*kobj
,
732 struct kobj_attribute
*attr
, const char *buf
, size_t n
)
737 if (sscanf(buf
, "%s %d", cmd
, ¶m
) == 2) {
738 if (!strcmp(cmd
, "soidle"))
739 idle_switch
[IDLE_TYPE_SO
] = param
;
740 else if (!strcmp(cmd
, "enable"))
741 enable_soidle_by_bit(param
);
742 else if (!strcmp(cmd
, "disable"))
743 disable_soidle_by_bit(param
);
744 else if (!strcmp(cmd
, "time"))
745 soidle_time_critera
= param
;
748 } else if (sscanf(buf
, "%d", ¶m
) == 1) {
749 idle_switch
[IDLE_TYPE_SO
] = param
;
755 idle_attr(soidle_state
);
758 static ssize_t
dpidle_state_show(struct kobject
*kobj
,
759 struct kobj_attribute
*attr
, char *buf
)
766 p
+= sprintf(p
, "*********** deep idle state ************\n");
767 p
+= sprintf(p
, "dpidle_cpu_pdn = %d\n", dpidle_cpu_pdn
);
768 p
+= sprintf(p
, "dpidle_time_critera=%u\n", dpidle_time_critera
);
770 for (i
= 0; i
< NR_REASONS
; i
++) {
771 p
+= sprintf(p
, "[%d]dpidle_block_cnt[%s]=%lu\n", i
, reason_name
[i
],
772 dpidle_block_cnt
[i
]);
775 p
+= sprintf(p
, "\n");
777 for (i
= 0; i
< NR_GRPS
; i
++) {
778 p
+= sprintf(p
, "[%02d]dpidle_condition_mask[%-8s]=0x%08x\t\tdpidle_block_mask[%-8s]=0x%08x\n", i
,
779 grp_get_name(i
), dpidle_condition_mask
[i
],
780 grp_get_name(i
), dpidle_block_mask
[i
]);
783 p
+= sprintf(p
, "\n*********** dpidle command help ************\n");
784 p
+= sprintf(p
, "dpidle help: cat /sys/power/dpidle_state\n");
785 p
+= sprintf(p
, "switch on/off: echo [dpidle] 1/0 > /sys/power/dpidle_state\n");
786 p
+= sprintf(p
, "cpupdn on/off: echo cpupdn 1/0 > /sys/power/dpidle_state\n");
787 p
+= sprintf(p
, "en_dp_by_bit: echo enable id > /sys/power/dpidle_state\n");
788 p
+= sprintf(p
, "dis_dp_by_bit: echo disable id > /sys/power/dpidle_state\n");
789 p
+= sprintf(p
, "modify tm_cri: echo time value(dec) > /sys/power/dpidle_state\n");
795 static ssize_t
dpidle_state_store(struct kobject
*kobj
,
796 struct kobj_attribute
*attr
, const char *buf
, size_t n
)
801 if (sscanf(buf
, "%s %d", cmd
, ¶m
) == 2) {
802 if (!strcmp(cmd
, "dpidle"))
803 idle_switch
[IDLE_TYPE_DP
] = param
;
804 else if (!strcmp(cmd
, "enable"))
805 enable_dpidle_by_bit(param
);
806 else if (!strcmp(cmd
, "disable"))
807 disable_dpidle_by_bit(param
);
808 else if (!strcmp(cmd
, "cpupdn"))
809 dpidle_cpu_pdn
= !!param
;
810 else if (!strcmp(cmd
, "time"))
811 dpidle_time_critera
= param
;
814 } else if (sscanf(buf
, "%d", ¶m
) == 1) {
815 idle_switch
[IDLE_TYPE_DP
] = param
;
821 idle_attr(dpidle_state
);
823 static ssize_t
slidle_state_show(struct kobject
*kobj
,
824 struct kobj_attribute
*attr
, char *buf
)
831 p
+= sprintf(p
, "*********** slow idle state ************\n");
832 for (i
= 0; i
< NR_REASONS
; i
++) {
833 p
+= sprintf(p
, "[%d]slidle_block_cnt[%s]=%lu\n",
834 i
, reason_name
[i
], slidle_block_cnt
[i
]);
837 p
+= sprintf(p
, "\n");
839 for (i
= 0; i
< NR_GRPS
; i
++) {
840 p
+= sprintf(p
, "[%02d]slidle_condition_mask[%-8s]=0x%08x\t\tslidle_block_mask[%-8s]=0x%08x\n", i
,
841 grp_get_name(i
), slidle_condition_mask
[i
],
842 grp_get_name(i
), slidle_block_mask
[i
]);
846 p
+= sprintf(p
, "\n********** slidle command help **********\n");
847 p
+= sprintf(p
, "slidle help: cat /sys/power/slidle_state\n");
848 p
+= sprintf(p
, "switch on/off: echo [slidle] 1/0 > /sys/power/slidle_state\n");
854 static ssize_t
slidle_state_store(struct kobject
*kobj
,
855 struct kobj_attribute
*attr
, const char *buf
, size_t n
)
860 if (sscanf(buf
, "%s %d", cmd
, ¶m
) == 2) {
861 if (!strcmp(cmd
, "slidle"))
862 idle_switch
[IDLE_TYPE_SL
] = param
;
863 else if (!strcmp(cmd
, "enable"))
864 enable_slidle_by_bit(param
);
865 else if (!strcmp(cmd
, "disable"))
866 disable_slidle_by_bit(param
);
869 } else if (sscanf(buf
, "%d", ¶m
) == 1) {
870 idle_switch
[IDLE_TYPE_SL
] = param
;
876 idle_attr(slidle_state
);
878 static ssize_t
rgidle_state_show(struct kobject
*kobj
,
879 struct kobj_attribute
*attr
, char *buf
)
884 p
+= sprintf(p
, "*********** regular idle state ************\n");
885 p
+= sprintf(p
, "\n********** rgidle command help **********\n");
886 p
+= sprintf(p
, "rgidle help: cat /sys/power/rgidle_state\n");
887 p
+= sprintf(p
, "switch on/off: echo [rgidle] 1/0 > /sys/power/rgidle_state\n");
893 static ssize_t
rgidle_state_store(struct kobject
*kobj
,
894 struct kobj_attribute
*attr
, const char *buf
, size_t n
)
899 if (sscanf(buf
, "%s %d", cmd
, ¶m
) == 2) {
900 if (!strcmp(cmd
, "rgidle"))
901 idle_switch
[IDLE_TYPE_RG
] = param
;
904 } else if (sscanf(buf
, "%d", ¶m
) == 1) {
905 idle_switch
[IDLE_TYPE_RG
] = param
;
911 idle_attr(rgidle_state
);
913 static ssize_t
idle_state_show(struct kobject
*kobj
,
914 struct kobj_attribute
*attr
, char *buf
)
921 p
+= sprintf(p
, "********** idle state dump **********\n");
922 #ifdef SPM_SODI_ENABLED
923 for (i
= 0; i
< nr_cpu_ids
; i
++) {
924 p
+= sprintf(p
, "soidle_cnt[%d]=%lu, dpidle_cnt[%d]=%lu, slidle_cnt[%d]=%lu, rgidle_cnt[%d]=%lu\n",
925 i
, soidle_cnt
[i
], i
, dpidle_cnt
[i
],
926 i
, slidle_cnt
[i
], i
, rgidle_cnt
[i
]);
929 for (i
= 0; i
< nr_cpu_ids
; i
++) {
930 p
+= sprintf(p
, "dpidle_cnt[%d]=%lu, slidle_cnt[%d]=%lu, rgidle_cnt[%d]=%lu\n",
931 i
, dpidle_cnt
[i
], i
, slidle_cnt
[i
], i
, rgidle_cnt
[i
]);
935 p
+= sprintf(p
, "\n********** variables dump **********\n");
936 for (i
= 0; i
< NR_TYPES
; i
++)
937 p
+= sprintf(p
, "%s_switch=%d, ", idle_name
[i
], idle_switch
[i
]);
938 p
+= sprintf(p
, "\n");
940 p
+= sprintf(p
, "\n********** idle command help **********\n");
941 p
+= sprintf(p
, "status help: cat /sys/power/idle_state\n");
942 p
+= sprintf(p
, "switch on/off: echo switch mask > /sys/power/idle_state\n");
944 #ifdef SPM_SODI_ENABLED
945 p
+= sprintf(p
, "soidle help: cat /sys/power/soidle_state\n");
947 p
+= sprintf(p
, "soidle help: soidle is unavailable\n");
949 p
+= sprintf(p
, "dpidle help: cat /sys/power/dpidle_state\n");
950 p
+= sprintf(p
, "slidle help: cat /sys/power/slidle_state\n");
951 p
+= sprintf(p
, "rgidle help: cat /sys/power/rgidle_state\n");
957 static ssize_t
idle_state_store(struct kobject
*kobj
,
958 struct kobj_attribute
*attr
, const char *buf
, size_t n
)
964 if (sscanf(buf
, "%s %x", cmd
, ¶m
) == 2) {
965 if (!strcmp(cmd
, "switch")) {
966 for (idx
= 0; idx
< NR_TYPES
; idx
++) {
967 #ifndef SPM_SODI_ENABLED
968 if (idx
== IDLE_TYPE_SO
)
971 idle_switch
[idx
] = (param
& (1U << idx
)) ? 1 : 0;
979 idle_attr(idle_state
);
982 void mt_idle_init(void)
986 idle_info("[%s]entry!!\n", __func__
);
987 arm_pm_idle
= arch_idle
;
989 #ifndef SPM_SODI_ENABLED
990 idle_switch
[IDLE_TYPE_SO
] = 0;
993 err
= free_gpt(GPT1
);
995 idle_info("[%s]fail to free GPT1\n", __func__
);
997 err
= request_gpt(GPT1
, GPT_ONE_SHOT
, GPT_CLK_SRC_SYS
, GPT_CLK_DIV_1
,
998 0, NULL
, GPT_NOAUTOEN
);
1000 idle_info("[%s]fail to request GPT1\n", __func__
);
1002 err
= request_gpt(GPT4
, GPT_ONE_SHOT
, GPT_CLK_SRC_SYS
, GPT_CLK_DIV_1
,
1003 0, NULL
, GPT_NOAUTOEN
);
1005 idle_info("[%s]fail to request GPT4\n", __func__
);
1007 err
= request_gpt(GPT5
, GPT_ONE_SHOT
, GPT_CLK_SRC_SYS
, GPT_CLK_DIV_1
,
1008 0, NULL
, GPT_NOAUTOEN
);
1010 idle_info("[%s]fail to request GPT5\n", __func__
);
1012 err
= sysfs_create_file(power_kobj
, &idle_state_attr
.attr
);
1013 #ifdef SPM_SODI_ENABLED
1014 err
|= sysfs_create_file(power_kobj
, &soidle_state_attr
.attr
);
1016 err
|= sysfs_create_file(power_kobj
, &dpidle_state_attr
.attr
);
1017 err
|= sysfs_create_file(power_kobj
, &slidle_state_attr
.attr
);
1018 err
|= sysfs_create_file(power_kobj
, &rgidle_state_attr
.attr
);
1021 idle_err("[%s]: fail to create sysfs\n", __func__
);