Skip to content

Commit cfb1ae4

Browse files
yongxu-wang15kartben
authored andcommitted
soc: nxp: imx95: set and restore wakeup irq mask in pm context
The CMC interface controls the entry and exit of the CPU's low-power mode and the identification of the wake-up source. To ensure the normal operation of the system's low-power timing sequence, when transfer IDLE_RUN to IDLE_SLEEP, it is necessary to ensure that the system is not awakened by the wake-up source during this stage. Therefore, an IRQ MASK needs to be set on the CMC Before the CPU enters the low power mode, a wake up mask needs to be set according to the situation where the interrupt controller is enabled at that time. After the cpu exits the low power mode, resume needs to be performed Signed-off-by: Yongxu Wang <[email protected]>
1 parent f94b3b9 commit cfb1ae4

File tree

1 file changed

+38
-1
lines changed
  • soc/nxp/imx/imx9/imx95/m7

1 file changed

+38
-1
lines changed

soc/nxp/imx/imx9/imx95/m7/soc.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ static int soc_init(void)
9191
void pm_state_before(void)
9292
{
9393
struct scmi_cpu_pd_lpm_config cpu_pd_lpm_cfg;
94+
struct scmi_cpu_irq_mask_config cpu_irq_mask_cfg;
9495

9596
/*
9697
* 1. Set M7 mix as power on state in suspend mode
@@ -114,8 +115,27 @@ void pm_state_before(void)
114115
cpu_pd_lpm_cfg.cfgs[1].ret_mask = 0;
115116

116117
scmi_cpu_pd_lpm_set(&cpu_pd_lpm_cfg);
117-
}
118118

119+
/* Set wakeup mask */
120+
uint32_t wake_mask[GPC_CMC_IRQ_WAKEUP_MASK_COUNT] = {
121+
[0 ... GPC_CMC_IRQ_WAKEUP_MASK_COUNT - 1] = 0xFFFFFFFFU
122+
};
123+
124+
/* IRQs enabled at NVIC level become GPC wake sources */
125+
for (uint32_t idx = 0; idx < 8; idx++) {
126+
wake_mask[idx] = ~(NVIC->ISER[idx]);
127+
}
128+
129+
cpu_irq_mask_cfg.cpu_id = CPU_IDX_M7P;
130+
cpu_irq_mask_cfg.mask_idx = 0;
131+
cpu_irq_mask_cfg.num_mask = GPC_CMC_IRQ_WAKEUP_MASK_COUNT;
132+
133+
for (uint8_t val = 0; val < GPC_CMC_IRQ_WAKEUP_MASK_COUNT; val++) {
134+
cpu_irq_mask_cfg.mask[val] = wake_mask[val];
135+
}
136+
137+
scmi_cpu_set_irq_mask(&cpu_irq_mask_cfg);
138+
}
119139

120140
void pm_state_set(enum pm_state state, uint8_t substate_id)
121141
{
@@ -167,6 +187,23 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
167187
{
168188
ARG_UNUSED(state);
169189

190+
struct scmi_cpu_irq_mask_config cpu_irq_mask_cfg;
191+
192+
/* Restore scmi cpu wake mask */
193+
uint32_t wake_mask[GPC_CMC_IRQ_WAKEUP_MASK_COUNT] = {
194+
[0 ... GPC_CMC_IRQ_WAKEUP_MASK_COUNT - 1] = 0x0U
195+
};
196+
197+
cpu_irq_mask_cfg.cpu_id = CPU_IDX_M7P;
198+
cpu_irq_mask_cfg.mask_idx = 0;
199+
cpu_irq_mask_cfg.num_mask = GPC_CMC_IRQ_WAKEUP_MASK_COUNT;
200+
201+
for (uint8_t val = 0; val < GPC_CMC_IRQ_WAKEUP_MASK_COUNT; val++) {
202+
cpu_irq_mask_cfg.mask[val] = wake_mask[val];
203+
}
204+
205+
scmi_cpu_set_irq_mask(&cpu_irq_mask_cfg);
206+
170207
struct scmi_cpu_sleep_mode_config cpu_cfg = {0};
171208
/* restore M7 core state into ACTIVE. */
172209
cpu_cfg.cpu_id = CPU_IDX_M7P;

0 commit comments

Comments
 (0)