Intel® Quark™ Microcontroller Software Interface 1.4.0 Intel® Quark™ Microcontroller BSP

- Main Page
- Modules
- Data Structures
- Files

- File List

power_states.c
1 /*
2 * {% copyright %}
3 */
4
5 #include "power_states.h"
6 #include "vreg.h"
7
8 #if (QM_SENSOR)
9 #include "qm_sensor_regs.h"
10 #endif
11 #include "soc_watch.h"
12
13 void qm_power_soc_sleep()
14 {
15 /* Go to sleep */
16 QM_SCSS_PMU->slp_cfg &= ~QM_SCSS_SLP_CFG_LPMODE_EN;
17
18 SOC_WATCH_LOG_EVENT(SOCW_EVENT_REGISTER, SOCW_REG_SLP_CFG);
19 SOC_WATCH_LOG_EVENT(SOCW_EVENT_SLEEP, 0);
20 QM_SCSS_PMU->pm1c |= QM_SCSS_PM1C_SLPEN;
21 }
22
23 void qm_power_soc_deep_sleep()
24 {
25 /* Switch to linear regulators.
26 * For low power deep sleep mode, it is a requirement that the platform
27 * voltage regulators are not in switching mode.
28 */
29 vreg_plat1p8_set_mode(VREG_MODE_LINEAR);
30 vreg_plat3p3_set_mode(VREG_MODE_LINEAR);
31
32 /* Enable low power sleep mode */
33 QM_SCSS_PMU->slp_cfg |= QM_SCSS_SLP_CFG_LPMODE_EN;
34 SOC_WATCH_LOG_EVENT(SOCW_EVENT_REGISTER, SOCW_REG_SLP_CFG);
35 SOC_WATCH_LOG_EVENT(SOCW_EVENT_SLEEP, 0);
36 QM_SCSS_PMU->pm1c |= QM_SCSS_PM1C_SLPEN;
37 }
38
39 #if (ENABLE_RESTORE_CONTEXT) && (!QM_SENSOR)
40 /*
41 * The restore trap address is stored in the variable __x86_restore_info.
42 * The variable __x86_restore_info is defined in the linker script as a new
43 * and independent memory segment.
44 */
45 extern uint32_t *__x86_restore_info;
46 /*
47 * The stack pointer is saved in the global variable sp_restore_storage
48 * by qm_x86_save_context() before sleep and it is restored by
49 * qm_x86_restore_context() after wake up.
50 */
51 uint32_t sp_restore_storage;
52 void qm_power_soc_sleep_restore()
53 {
54 /*
55 * Save x86 restore trap address.
56 * The first parameter in this macro represents the label defined in
57 * the qm_x86_restore_context() macro, which is actually the restore
58 * trap address.
59 */
60 qm_x86_set_resume_vector(sleep_restore_trap, __x86_restore_info);
61
62 /* Save x86 execution context. */
63 qm_x86_save_context(sp_restore_storage);
64
65 /* Set restore flags. */
66 qm_power_soc_set_x86_restore_flag();
67
68 /* Enter sleep. */
69 qm_power_soc_sleep();
70
71 /*
72 * Restore x86 execution context.
73 * The bootloader code will jump to this location after waking up from
74 * sleep. The restore trap address is the label defined in the macro.
75 * That label is exposed here through the first parameter.
76 */
77 qm_x86_restore_context(sleep_restore_trap, sp_restore_storage);
78 }
79
80 void qm_power_soc_deep_sleep_restore()
81 {
82 /*
83 * Save x86 restore trap address.
84 * The first parameter in this macro represents the label defined in
85 * the qm_x86_restore_context() macro, which is actually the restore
86 * trap address.
87 */
88 qm_x86_set_resume_vector(deep_sleep_restore_trap, __x86_restore_info);
89
90 /* Save x86 execution context. */
91 qm_x86_save_context(sp_restore_storage);
92
93 /* Set restore flags. */
94 qm_power_soc_set_x86_restore_flag();
95
96 /* Enter sleep. */
97 qm_power_soc_deep_sleep();
98
99 /*
100 * Restore x86 execution context.
101 * The bootloader code will jump to this location after waking up from
102 * sleep. The restore trap address is the label defined in the macro.
103 * That label is exposed here through the first parameter.
104 */
105 qm_x86_restore_context(deep_sleep_restore_trap, sp_restore_storage);
106 }
107
108 void qm_power_sleep_wait()
109 {
110 /*
111 * Save x86 restore trap address.
112 * The first parameter in this macro represents the label defined in
113 * the qm_x86_restore_context() macro, which is actually the restore
114 * trap address.
115 */
116 qm_x86_set_resume_vector(sleep_restore_trap, __x86_restore_info);
117
118 /* Save x86 execution context. */
119 qm_x86_save_context(sp_restore_storage);
120
121 /* Set restore flags. */
122 qm_power_soc_set_x86_restore_flag();
123
124 /* Enter C2 and stay in it until sleep and wake-up. */
125 while (1) {
126 qm_power_cpu_c2();
127 }
128
129 /*
130 * Restore x86 execution context.
131 * The bootloader code will jump to this location after waking up from
132 * sleep. The restore trap address is the label defined in the macro.
133 * That label is exposed here through the first parameter.
134 */
135 qm_x86_restore_context(sleep_restore_trap, sp_restore_storage);
136 }
137
138 void qm_power_soc_set_x86_restore_flag(void)
139 {
140 QM_SCSS_GP->gps0 |= BIT(QM_GPS0_BIT_X86_WAKEUP);
141 }
142 #endif /* ENABLE_RESTORE_CONTEXT */
143
144 #if (!QM_SENSOR)
145 void qm_power_cpu_c1()
146 {
147 SOC_WATCH_LOG_EVENT(SOCW_EVENT_HALT, 0);
148 /*
149 * STI sets the IF flag. After the IF flag is set,
150 * the core begins responding to external,
151 * maskable interrupts after the next instruction is executed.
152 * When this function is called with interrupts disabled,
153 * this guarantees that an interrupt is caught only
154 * after the processor has transitioned into HLT.
155 */
156 __asm__ __volatile__("sti\n\t"
157 "hlt\n\t");
158 }
159
160 void qm_power_cpu_c2()
161 {
162 QM_SCSS_CCU->ccu_lp_clk_ctl &= ~QM_SCSS_CCU_C2_LP_EN;
163 SOC_WATCH_LOG_EVENT(SOCW_EVENT_REGISTER, SOCW_REG_CCU_LP_CLK_CTL);
164
165 /* Read P_LVL2 to trigger a C2 request */
166 SOC_WATCH_LOG_EVENT(SOCW_EVENT_SLEEP, 0);
167 QM_SCSS_PMU->p_lvl2;
168 }
169
170 void qm_power_cpu_c2lp()
171 {
172 QM_SCSS_CCU->ccu_lp_clk_ctl |= QM_SCSS_CCU_C2_LP_EN;
173 SOC_WATCH_LOG_EVENT(SOCW_EVENT_REGISTER, SOCW_REG_CCU_LP_CLK_CTL);
174
175 /* Read P_LVL2 to trigger a C2 request */
176 SOC_WATCH_LOG_EVENT(SOCW_EVENT_SLEEP, 0);
177 QM_SCSS_PMU->p_lvl2;
178 }
179 #endif
SOCW_EVENT_REGISTER
SOC register altered.
Definition: soc_watch.h:40
SOCW_EVENT_SLEEP
Sleep mode entered.
Definition: soc_watch.h:39
qm_power_cpu_c1
void qm_power_cpu_c1()
Enter Host C1 state.
Definition: power_states.c:145
vreg_plat3p3_set_mode
int vreg_plat3p3_set_mode(const vreg_mode_t mode)
Set Platform 3P3 Voltage Regulator mode.
Definition: vreg.c:53
SOCW_REG_CCU_LP_CLK_CTL
0x02C Clock Control register.
Definition: soc_watch.h:74
qm_power_soc_deep_sleep
void qm_power_soc_deep_sleep(const qm_power_wake_event_t wake_event)
Put SoC to deep sleep.
Definition: power_states.c:180
qm_power_cpu_c2lp
void qm_power_cpu_c2lp()
Enter Host C2LP state or SoC LPSS state.
Definition: power_states.c:170
SOCW_EVENT_HALT
CPU Halt.
Definition: soc_watch.h:37
vreg_plat1p8_set_mode
int vreg_plat1p8_set_mode(const vreg_mode_t mode)
Set Platform 1P8 Voltage Regulator mode.
Definition: vreg.c:59
qm_power_soc_deep_sleep_restore
void qm_power_soc_deep_sleep_restore(void)
Enter SoC deep sleep state and restore after wake up.
Definition: power_states.c:304
qm_power_soc_sleep
void qm_power_soc_sleep(void)
Put SoC to sleep.
Definition: power_states.c:59
SOCW_REG_SLP_CFG
0x550 Sleep Configuration.
Definition: soc_watch.h:99
qm_power_soc_sleep_restore
void qm_power_soc_sleep_restore(void)
Enter SoC sleep state and restore after wake up.
Definition: power_states.c:135
qm_power_soc_set_x86_restore_flag
void qm_power_soc_set_x86_restore_flag(void)
Enable the x86 startup restore flag, see GPS0 #define in qm_soc_regs.h.
Definition: power_states.c:138
qm_power_sleep_wait
void qm_power_sleep_wait()
Save context, enter x86 C2 power save state and restore after wake up.
Definition: power_states.c:108
qm_power_cpu_c2
void qm_power_cpu_c2()
Enter Host C2 state or SoC LPSS state.
Definition: power_states.c:160