1 #include <linux/init.h>
2 #include <linux/module.h>
3 #include <linux/kernel.h>
4 #include <linux/spinlock.h>
5 #include <linux/suspend.h>
6 #include <linux/console.h>
9 #include <mach/sync_write.h>
10 #include <mach/mt_sleep.h>
11 #include <mach/mt_spm.h>
12 #include <mach/mt_spm_sleep.h>
13 #include <mach/mt_spm_mtcmos.h>
14 #include <mach/mt_clkmgr.h>
15 #include <mach/mt_gpio.h>
17 /**************************************
18 * only for internal debug
19 **************************************/
20 #ifdef CONFIG_MTK_LDVT
21 #define SLP_SLEEP_DPIDLE_EN 1
22 #define SLP_REPLACE_DEF_WAKESRC 1
23 #define SLP_SUSPEND_LOG_EN 1
25 #define SLP_SLEEP_DPIDLE_EN 1
26 #define SLP_REPLACE_DEF_WAKESRC 0
27 #define SLP_SUSPEND_LOG_EN 1
31 /**************************************
33 **************************************/
34 #define slp_read(addr) (*(volatile u32 *)(addr))
35 #define slp_write(addr, val) mt65xx_reg_sync_writel(val, addr)
37 #define slp_emerg(fmt, args...) printk(KERN_EMERG "[SLP] " fmt, ##args)
38 #define slp_alert(fmt, args...) printk(KERN_ALERT "[SLP] " fmt, ##args)
39 #define slp_crit(fmt, args...) printk(KERN_CRIT "[SLP] " fmt, ##args)
40 #define slp_error(fmt, args...) printk(KERN_ERR "[SLP] " fmt, ##args)
41 #define slp_warning(fmt, args...) printk(KERN_WARNING "[SLP] " fmt, ##args)
42 #define slp_notice(fmt, args...) printk(KERN_NOTICE "[SLP] " fmt, ##args)
43 #define slp_info(fmt, args...) printk(KERN_INFO "[SLP] " fmt, ##args)
44 #define slp_debug(fmt, args...) printk(KERN_DEBUG "[SLP] " fmt, ##args)
46 #define slp_crit2(fmt, args...) \
48 aee_sram_printk(fmt, ##args); \
49 slp_crit(fmt, ##args); \
52 extern void mt_power_gs_dump_suspend(void);
54 static DEFINE_SPINLOCK(slp_lock
);
56 static wake_reason_t slp_wake_reason
= WR_NONE
;
58 static bool slp_ck26m_on
= 0;
61 * SLEEP_DPIDLE_EN:1 && slp_ck26m_on=1
64 * SLEEP_DPIDLE_EN:0 || slp_ck26m_on=0
68 static bool slp_cpu_pdn
= 1;
71 * SLEEP_DPIDLE_EN:0 || slp_ck26m_on=0
72 * 1 = INFRA/DDRPHY power down
73 * 0 = keep INFRA/DDRPHY power
75 #ifndef MTK_ALPS_BOX_SUPPORT
76 static bool slp_infra_pdn
= 1;
78 static bool slp_infra_pdn
= 0;
81 * SLEEP_DPIDLE_EN:1 && slp_ck26m_on=1
85 static u16 slp_pwrlevel
= 0;
87 static int slp_pwake_time
= -1; /* sec */
89 static bool slp_chk_golden
= 0;
90 static bool slp_dump_gpio
= 0;
91 static bool slp_dump_regs
= 0;
93 static void slp_dump_pm_regs(void)
95 /* PLL/TOPCKGEN register */
96 slp_debug("AP_PLL_CON0 0x%x = 0x%x\n", AP_PLL_CON0
, slp_read(AP_PLL_CON0
));
97 slp_debug("AP_PLL_CON1 0x%x = 0x%x\n", AP_PLL_CON1
, slp_read(AP_PLL_CON1
));
98 slp_debug("AP_PLL_CON2 0x%x = 0x%x\n", AP_PLL_CON2
, slp_read(AP_PLL_CON2
));
99 slp_debug("UNIVPLL_CON0 0x%x = 0x%x\n", UNIVPLL_CON0
, slp_read(UNIVPLL_CON0
));
100 slp_debug("UNIVPLL_PWR_CON 0x%x = 0x%x\n", UNIVPLL_PWR_CON0
, slp_read(UNIVPLL_PWR_CON0
));
101 slp_debug("MMPLL_CON0 0x%x = 0x%x\n", MMPLL_CON0
, slp_read(MMPLL_CON0
));
102 slp_debug("MMPLL_PWR_CON 0x%x = 0x%x\n", MMPLL_PWR_CON0
, slp_read(MMPLL_PWR_CON0
));
103 slp_debug("CLK_SCP_CFG_0 0x%x = 0x%x\n", CLK_SCP_CFG_0
, slp_read(CLK_SCP_CFG_0
));
104 slp_debug("CLK_SCP_CFG_1 0x%x = 0x%x\n", CLK_SCP_CFG_1
, slp_read(CLK_SCP_CFG_1
));
106 /* INFRA/PERICFG register */
107 slp_debug("INFRA_PDN_STA 0x%x = 0x%x\n", INFRA_PDN_STA
, slp_read(INFRA_PDN_STA
));
108 slp_debug("PERI_PDN0_STA 0x%x = 0x%x\n", PERI_PDN0_STA
, slp_read(PERI_PDN0_STA
));
111 slp_debug("POWER_ON_VAL0 0x%x = 0x%x\n", SPM_POWER_ON_VAL0
, slp_read(SPM_POWER_ON_VAL0
));
112 slp_debug("POWER_ON_VAL1 0x%x = 0x%x\n", SPM_POWER_ON_VAL1
, slp_read(SPM_POWER_ON_VAL1
));
113 slp_debug("SPM_PCM_CON1 0x%x = 0x%x\n", SPM_PCM_CON1
, slp_read(SPM_PCM_CON1
));
114 slp_debug("PCM_PWR_IO_EN 0x%x = 0x%x\n", SPM_PCM_PWR_IO_EN
, slp_read(SPM_PCM_PWR_IO_EN
));
115 slp_debug("PCM_REG0_DATA 0x%x = 0x%x\n", SPM_PCM_REG0_DATA
, slp_read(SPM_PCM_REG0_DATA
));
116 slp_debug("PCM_REG7_DATA 0x%x = 0x%x\n", SPM_PCM_REG7_DATA
, slp_read(SPM_PCM_REG7_DATA
));
117 slp_debug("PCM_REG13_DATA 0x%x = 0x%x\n", SPM_PCM_REG13_DATA
, slp_read(SPM_PCM_REG13_DATA
));
118 slp_debug("CLK_CON 0x%x = 0x%x\n", SPM_CLK_CON
, slp_read(SPM_CLK_CON
));
119 slp_debug("AP_DVFS_CON 0x%x = 0x%x\n", SPM_AP_DVFS_CON_SET
, slp_read(SPM_AP_DVFS_CON_SET
));
120 slp_debug("PWR_STATUS 0x%x = 0x%x\n", SPM_PWR_STATUS
, slp_read(SPM_PWR_STATUS
));
121 slp_debug("SPM_PCM_SRC_REQ 0x%x = 0x%x\n", SPM_PCM_SRC_REQ
, slp_read(SPM_PCM_SRC_REQ
));
124 static int slp_suspend_ops_valid(suspend_state_t state
)
126 return state
== PM_SUSPEND_MEM
;
129 static int slp_suspend_ops_begin(suspend_state_t state
)
132 slp_notice("@@@@@@@@@@@@@@@@@@@@\n");
133 slp_notice("Chip_pm_begin(%u)(%u)\n", slp_cpu_pdn
, slp_infra_pdn
);
134 slp_notice("@@@@@@@@@@@@@@@@@@@@\n");
136 slp_wake_reason
= WR_NONE
;
141 static int slp_suspend_ops_prepare(void)
144 slp_notice("@@@@@@@@@@@@@@@@@@@@\n");
145 slp_crit2("Chip_pm_prepare\n");
146 slp_notice("@@@@@@@@@@@@@@@@@@@@\n");
149 mt_power_gs_dump_suspend();
154 static int slp_suspend_ops_enter(suspend_state_t state
)
157 slp_notice("@@@@@@@@@@@@@@@@@@@@\n");
158 slp_crit2("Chip_pm_enter\n");
159 slp_notice("@@@@@@@@@@@@@@@@@@@@\n");
167 if (!spm_cpusys_can_power_down()) {
168 slp_error("CANNOT SLEEP DUE TO CPU1/2/3 PON\n");
172 if (slp_infra_pdn
&& !slp_cpu_pdn
) {
173 slp_error("CANNOT SLEEP DUE TO INFRA PDN BUT CPU PON\n");
177 #if SLP_SLEEP_DPIDLE_EN
179 slp_wake_reason
= spm_go_to_sleep_dpidle(slp_cpu_pdn
, slp_pwrlevel
, slp_pwake_time
);
182 slp_wake_reason
= spm_go_to_sleep(slp_cpu_pdn
, slp_infra_pdn
, slp_pwake_time
);
187 static void slp_suspend_ops_finish(void)
190 slp_notice("@@@@@@@@@@@@@@@@@@@@\n");
191 slp_crit2("Chip_pm_finish\n");
192 slp_notice("@@@@@@@@@@@@@@@@@@@@\n");
195 static void slp_suspend_ops_end(void)
198 slp_notice("@@@@@@@@@@@@@@@@@@@@\n");
199 slp_notice("Chip_pm_end\n");
200 slp_notice("@@@@@@@@@@@@@@@@@@@@\n");
203 static struct platform_suspend_ops slp_suspend_ops
= {
204 .valid
= slp_suspend_ops_valid
,
205 .begin
= slp_suspend_ops_begin
,
206 .prepare
= slp_suspend_ops_prepare
,
207 .enter
= slp_suspend_ops_enter
,
208 .finish
= slp_suspend_ops_finish
,
209 .end
= slp_suspend_ops_end
,
213 * wakesrc : WAKE_SRC_XXX
214 * enable : enable or disable @wakesrc
215 * ck26m_on: if true, mean @wakesrc needs 26M to work
217 int slp_set_wakesrc(u32 wakesrc
, bool enable
, bool ck26m_on
)
222 slp_notice("wakesrc = 0x%x, enable = %u, ck26m_on = %u\n",
223 wakesrc
, enable
, ck26m_on
);
225 #if SLP_REPLACE_DEF_WAKESRC
226 if (wakesrc
& WAKE_SRC_CFG_KEY
)
228 if (!(wakesrc
& WAKE_SRC_CFG_KEY
))
232 spin_lock_irqsave(&slp_lock
, flags
);
233 #if SLP_REPLACE_DEF_WAKESRC
234 r
= spm_set_sleep_wakesrc(wakesrc
, enable
, true);
236 r
= spm_set_sleep_wakesrc(wakesrc
& ~WAKE_SRC_CFG_KEY
, enable
, false);
240 slp_ck26m_on
= ck26m_on
;
241 spin_unlock_irqrestore(&slp_lock
, flags
);
246 wake_reason_t
slp_get_wake_reason(void)
248 return slp_wake_reason
;
251 bool slp_will_infra_pdn(void)
253 return slp_infra_pdn
;
256 void slp_module_init(void)
258 spm_output_sleep_option();
260 slp_notice("SLEEP_DPIDLE_EN:%d, REPLACE_DEF_WAKESRC:%d, SUSPEND_LOG_EN:%d\n",
261 SLP_SLEEP_DPIDLE_EN
, SLP_REPLACE_DEF_WAKESRC
, SLP_SUSPEND_LOG_EN
);
263 suspend_set_ops(&slp_suspend_ops
);
265 #if SLP_SUSPEND_LOG_EN
266 console_suspend_enabled
= 0;
270 module_param(slp_ck26m_on
, bool, 0644);
272 module_param(slp_cpu_pdn
, bool, 0644);
273 module_param(slp_infra_pdn
, bool, 0644);
274 module_param(slp_pwrlevel
, ushort
, 0644);
276 module_param(slp_pwake_time
, int, 0644);
278 module_param(slp_chk_golden
, bool, 0644);
279 module_param(slp_dump_gpio
, bool, 0644);
280 module_param(slp_dump_regs
, bool, 0644);
282 MODULE_AUTHOR("Terry Chang <terry.chang@mediatek.com>");
283 MODULE_DESCRIPTION("Sleep Driver v0.4");