intel_adsp: ipc: pm action in busy state
Currently SOF has disabled CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE option and use pm_suspend_devices() to suspend and resume IPC device during D3 power flow. The pm_suspend_devices() function skips suspending devices that are busy. In very rare cases, the IPC device is busy during the power state transition, which results in the device not being restored during reboot. This happens when FW sends a message to the HOST and waits for ACK, and the HOST simultaneously sends a SET_DX message to the DSP. This suspend/resume logic in IPC driver does not work well when the system enters the D3 state because it is not a suspend state, but rather a power-off. IPC does not require suspending, only reinitialization when exiting D3. We cannot avoid this one missing ACK and it cannot block the DSP from turning off. When FW receives a SET_DX message it checks whether it can enter the D3 state and then returns an error (via IPC) or calls the pm_state_force function. Success response is sent directly from power_down assembly and not via ipc driver. This is because after receiving the response, the HOST will turn off the DSP. In order for the transition to D3 to take place, only the primary core can be active, all pipes must be stopped (and therefore all modules in FW). The only active thread at this time is the Idle thread. Driver on the host will not send another ipc because is still waiting for response. FW can try to send only two notification: - FW exception: from this place there is no return to continue the power transition, - log buffer status: skipped, they remain in the queue without being sent. I'm moving pm_device_busy_clear(dev) from IRQ handler to intel_adsp_ipc_send_message function so the pending ACK does not block power transition. Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
This commit is contained in:
parent
747991d528
commit
d7af6f3710
1 changed files with 1 additions and 1 deletions
|
@ -82,7 +82,6 @@ void z_intel_adsp_ipc_isr(const void *devarg)
|
|||
}
|
||||
|
||||
regs->ida = INTEL_ADSP_IPC_DONE;
|
||||
pm_device_busy_clear(dev);
|
||||
}
|
||||
|
||||
k_spin_unlock(&devdata->lock, key);
|
||||
|
@ -163,6 +162,7 @@ int intel_adsp_ipc_send_message(const struct device *dev,
|
|||
config->regs->idd = ext_data;
|
||||
config->regs->idr = data | INTEL_ADSP_IPC_BUSY;
|
||||
k_spin_unlock(&devdata->lock, key);
|
||||
pm_device_busy_clear(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue