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

- Main Page
- Modules
- Data Structures
- Files

- File List

ss_power_states.c
1 /*
2 * {% copyright %}
3 */
4
5 #include "power_states.h"
6 #include "ss_power_states.h"
7 #include "qm_isr.h"
8 #include "qm_sensor_regs.h"
9 #include "soc_watch.h"
10 #include "qm_common.h"
11
12 /* Sensor Subsystem sleep operand definition.
13 * Only a subset applies as internal sensor RTC
14 * is not available.
15 *
16 * OP | Core | Timers | RTC
17 * 000 | 0 | 1 | 1 <-- used for SS1
18 * 001 | 0 | 0 | 1
19 * 010 | 0 | 1 | 0
20 * 011 | 0 | 0 | 0 <-- used for SS2
21 * 100 | 0 | 0 | 0
22 * 101 | 0 | 0 | 0
23 * 110 | 0 | 0 | 0
24 * 111 | 0 | 0 | 0
25 *
26 * sleep opcode argument:
27 * - [7:5] : Sleep Operand
28 * - [4] : Interrupt enable
29 * - [3:0] : Interrupt threshold value
30 */
31
32 #define SLEEP_INT_EN BIT(4)
33 #define SLEEP_TIMER_ON (0x0)
34 #define SLEEP_TIMER_OFF (0x20)
35 #define SLEEP_TIMER_RTC_OFF (0x60)
36
37 #define SS_STATE_1_TIMER_ON (SLEEP_TIMER_ON | SLEEP_INT_EN)
38 #define SS_STATE_1_TIMER_OFF (SLEEP_TIMER_OFF | SLEEP_INT_EN)
39 #define SS_STATE_2 (SLEEP_TIMER_RTC_OFF | SLEEP_INT_EN)
40
41 void qm_ss_power_soc_lpss_enable()
42 {
43 uint32_t creg_mst0_ctrl = 0;
44
45 creg_mst0_ctrl = __builtin_arc_lr(QM_SS_CREG_BASE);
46
47 /*
48 * Clock gate the sensor peripherals at CREG level.
49 * This clock gating is independent of the peripheral-specific clock
50 * gating provided in ss_clk.h .
51 */
52 creg_mst0_ctrl |= (QM_SS_IO_CREG_MST0_CTRL_ADC_CLK_GATE |
53 QM_SS_IO_CREG_MST0_CTRL_I2C1_CLK_GATE |
54 QM_SS_IO_CREG_MST0_CTRL_I2C0_CLK_GATE |
55 QM_SS_IO_CREG_MST0_CTRL_SPI1_CLK_GATE |
56 QM_SS_IO_CREG_MST0_CTRL_SPI0_CLK_GATE);
57
58 __builtin_arc_sr(creg_mst0_ctrl, QM_SS_CREG_BASE);
59
60 QM_SCSS_CCU->ccu_lp_clk_ctl |= QM_SCSS_CCU_SS_LPS_EN;
61 SOC_WATCH_LOG_EVENT(SOCW_EVENT_REGISTER, SOCW_REG_CCU_LP_CLK_CTL);
62 }
63
64 void qm_ss_power_soc_lpss_disable()
65 {
66 uint32_t creg_mst0_ctrl = 0;
67
68 creg_mst0_ctrl = __builtin_arc_lr(QM_SS_CREG_BASE);
69
70 /*
71 * Restore clock gate of the sensor peripherals at CREG level.
72 * CREG is not used anywhere else so we can safely restore
73 * the configuration to its POR default.
74 */
75 creg_mst0_ctrl &= ~(QM_SS_IO_CREG_MST0_CTRL_ADC_CLK_GATE |
76 QM_SS_IO_CREG_MST0_CTRL_I2C1_CLK_GATE |
77 QM_SS_IO_CREG_MST0_CTRL_I2C0_CLK_GATE |
78 QM_SS_IO_CREG_MST0_CTRL_SPI1_CLK_GATE |
79 QM_SS_IO_CREG_MST0_CTRL_SPI0_CLK_GATE);
80
81 __builtin_arc_sr(creg_mst0_ctrl, QM_SS_CREG_BASE);
82
83 QM_SCSS_CCU->ccu_lp_clk_ctl &= ~QM_SCSS_CCU_SS_LPS_EN;
84 SOC_WATCH_LOG_EVENT(SOCW_EVENT_REGISTER, SOCW_REG_CCU_LP_CLK_CTL);
85 }
86
87 /* Enter SS1 :
88 * SLEEP + sleep operand
89 * __builtin_arc_sleep is not used here as it does not propagate sleep operand.
90 */
91 void qm_ss_power_cpu_ss1(const qm_ss_power_cpu_ss1_mode_t mode)
92 {
93 uint32_t priority;
94
95 priority =
96 (__builtin_arc_lr(QM_SS_AUX_STATUS32) & QM_SS_STATUS32_E_MASK) >> 1;
97
98 SOC_WATCH_LOG_EVENT(SOCW_ARC_EVENT_SS1, 0);
99
100 /* Enter SS1 */
101 switch (mode) {
102 case QM_SS_POWER_CPU_SS1_TIMER_OFF:
103 __asm__ __volatile__("sleep %0"
104 :
105 : "r"(SS_STATE_1_TIMER_OFF | priority)
106 : "memory", "cc");
107 break;
108 case QM_SS_POWER_CPU_SS1_TIMER_ON:
109 default:
110 __asm__ __volatile__("sleep %0"
111 :
112 : "r"(SS_STATE_1_TIMER_ON | priority)
113 : "memory", "cc");
114 break;
115 }
116 }
117
118 /* Enter SS2 :
119 * SLEEP + sleep operand
120 * __builtin_arc_sleep is not used here as it does not propagate sleep operand.
121 */
122 void qm_ss_power_cpu_ss2(void)
123 {
124 uint32_t priority;
125
126 priority =
127 (__builtin_arc_lr(QM_SS_AUX_STATUS32) & QM_SS_STATUS32_E_MASK) >> 1;
128
129 SOC_WATCH_LOG_EVENT(SOCW_ARC_EVENT_SS2, 0);
130
131 /* Enter SS2 */
132 __asm__ __volatile__("sleep %0"
133 :
134 : "r"(SS_STATE_2 | priority)
135 : "memory", "cc");
136 }
137
138 #if (ENABLE_RESTORE_CONTEXT)
139 extern uint32_t arc_restore_addr;
140 uint32_t cpu_context[33];
141 void qm_ss_power_soc_sleep_restore(void)
142 {
143 /*
144 * Save sensor restore trap address.
145 * The first parameter in this macro represents the label defined in
146 * the qm_ss_restore_context() macro, which is actually the restore
147 * trap address.
148 */
149 qm_ss_set_resume_vector(sleep_restore_trap, arc_restore_addr);
150
151 /* Save ARC execution context. */
152 qm_ss_save_context(cpu_context);
153
154 /* Set restore flags. */
155 qm_power_soc_set_ss_restore_flag();
156
157 /* Enter sleep. */
158 qm_power_soc_sleep();
159
160 /*
161 * Restore sensor execution context.
162 * The sensor startup code will jump to this location after waking up
163 * from sleep. The restore trap address is the label defined in the
164 * macro and the label is exposed here through the first parameter.
165 */
166 qm_ss_restore_context(sleep_restore_trap, cpu_context);
167 }
168 void qm_ss_power_soc_deep_sleep_restore(void)
169 {
170 /*
171 * Save sensor restore trap address.
172 * The first parameter in this macro represents the label defined in
173 * the qm_ss_restore_context() macro, which is actually the restore
174 * trap address.
175 */
176 qm_ss_set_resume_vector(deep_sleep_restore_trap, arc_restore_addr);
177
178 /* Save ARC execution context. */
179 qm_ss_save_context(cpu_context);
180
181 /* Set restore flags. */
182 qm_power_soc_set_ss_restore_flag();
183
184 /* Enter sleep. */
185 qm_power_soc_deep_sleep();
186
187 /*
188 * Restore sensor execution context.
189 * The sensor startup code will jump to this location after waking up
190 * from sleep. The restore trap address is the label defined in the
191 * macro and the label is exposed here through the first parameter.
192 */
193 qm_ss_restore_context(deep_sleep_restore_trap, cpu_context);
194 }
195
196 void qm_ss_power_sleep_wait(void)
197 {
198 /*
199 * Save sensor restore trap address.
200 * The first parameter in this macro represents the label defined in
201 * the qm_ss_restore_context() macro, which is actually the restore
202 * trap address.
203 */
204 qm_ss_set_resume_vector(sleep_restore_trap, arc_restore_addr);
205
206 /* Save ARC execution context. */
207 qm_ss_save_context(cpu_context);
208
209 /* Set restore flags. */
210 qm_power_soc_set_ss_restore_flag();
211
212 /* Enter SS1 and stay in it until sleep and wake-up. */
213 while (1) {
214 qm_ss_power_cpu_ss1(QM_SS_POWER_CPU_SS1_TIMER_ON);
215 }
216
217 /*
218 * Restore sensor execution context.
219 * The sensor startup code will jump to this location after waking up
220 * from sleep. The restore trap address is the label defined in the
221 * macro and the label is exposed here through the first parameter.
222 */
223 qm_ss_restore_context(sleep_restore_trap, cpu_context);
224 }
225
226 void qm_power_soc_set_ss_restore_flag(void)
227 {
228 QM_SCSS_GP->gps0 |= BIT(QM_GPS0_BIT_SENSOR_WAKEUP);
229 }
230
231 #endif /* ENABLE_RESTORE_CONTEXT */
qm_ss_power_cpu_ss1
void qm_ss_power_cpu_ss1(const qm_ss_power_cpu_ss1_mode_t mode)
Enter Sensor SS1 state.
Definition: ss_power_states.c:91
qm_ss_power_cpu_ss2
void qm_ss_power_cpu_ss2(void)
Enter Sensor SS2 state or SoC LPSS state.
Definition: ss_power_states.c:122
qm_ss_power_sleep_wait
void qm_ss_power_sleep_wait(void)
Save context, enter ARC SS1 power save state and restore after wake up.
Definition: ss_power_states.c:196
SOCW_EVENT_REGISTER
SOC register altered.
Definition: soc_watch.h:40
qm_power_soc_set_ss_restore_flag
void qm_power_soc_set_ss_restore_flag(void)
Enable the SENSOR startup restore flag.
Definition: ss_power_states.c:226
SOCW_REG_CCU_LP_CLK_CTL
0x02C Clock Control register.
Definition: soc_watch.h:74
QM_SS_POWER_CPU_SS1_TIMER_OFF
Disable SS Timers in SS1.
Definition: ss_power_states.h:22
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_ss_power_soc_sleep_restore
void qm_ss_power_soc_sleep_restore(void)
Enter SoC sleep state and restore after wake up.
Definition: ss_power_states.c:141
qm_ss_power_soc_lpss_disable
void qm_ss_power_soc_lpss_disable()
Disable LPSS state entry.
Definition: ss_power_states.c:64
qm_ss_power_cpu_ss1_mode_t
qm_ss_power_cpu_ss1_mode_t
Sensor Subsystem SS1 Timers mode type.
Definition: ss_power_states.h:21
QM_SS_POWER_CPU_SS1_TIMER_ON
Keep SS Timers enabled in SS1.
Definition: ss_power_states.h:23
qm_ss_power_soc_lpss_enable
void qm_ss_power_soc_lpss_enable()
Enable LPSS state entry.
Definition: ss_power_states.c:41
qm_power_soc_sleep
void qm_power_soc_sleep(void)
Put SoC to sleep.
Definition: power_states.c:59
qm_ss_power_soc_deep_sleep_restore
void qm_ss_power_soc_deep_sleep_restore(void)
Enter SoC sleep state and restore after wake up.
Definition: ss_power_states.c:168