Intel® Quark™ Microcontroller Software Interface  1.4.0
Intel® Quark™ Microcontroller BSP
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 
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 
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  */
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) {
103  __asm__ __volatile__("sleep %0"
104  :
105  : "r"(SS_STATE_1_TIMER_OFF | priority)
106  : "memory", "cc");
107  break;
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  */
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];
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. */
156 
157  /* Enter 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 }
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. */
183 
184  /* Enter 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 
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. */
211 
212  /* Enter SS1 and stay in it until sleep and wake-up. */
213  while (1) {
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 
227 {
228  QM_SCSS_GP->gps0 |= BIT(QM_GPS0_BIT_SENSOR_WAKEUP);
229 }
230 
231 #endif /* ENABLE_RESTORE_CONTEXT */
void qm_ss_power_cpu_ss1(const qm_ss_power_cpu_ss1_mode_t mode)
Enter Sensor SS1 state.
void qm_ss_power_cpu_ss2(void)
Enter Sensor SS2 state or SoC LPSS state.
void qm_ss_power_sleep_wait(void)
Save context, enter ARC SS1 power save state and restore after wake up.
SOC register altered.
Definition: soc_watch.h:40
void qm_power_soc_set_ss_restore_flag(void)
Enable the SENSOR startup restore flag.
0x02C Clock Control register.
Definition: soc_watch.h:74
Disable SS Timers in SS1.
void qm_power_soc_deep_sleep(const qm_power_wake_event_t wake_event)
Put SoC to deep sleep.
Definition: power_states.c:180
void qm_ss_power_soc_sleep_restore(void)
Enter SoC sleep state and restore after wake up.
void qm_ss_power_soc_lpss_disable()
Disable LPSS state entry.
qm_ss_power_cpu_ss1_mode_t
Sensor Subsystem SS1 Timers mode type.
Keep SS Timers enabled in SS1.
void qm_ss_power_soc_lpss_enable()
Enable LPSS state entry.
void qm_power_soc_sleep(void)
Put SoC to sleep.
Definition: power_states.c:59
void qm_ss_power_soc_deep_sleep_restore(void)
Enter SoC sleep state and restore after wake up.