ipc: intel_adsp: Ensure IPC completion before runtime idle

Prevent the system from entering runtime idle state during IPC
transactions until the HOST acknowledgment is received.

This patch modifies the IPC mechanism to:
- Lock the runtime idle state immediately after sending an IPC message
  to the HOST, preventing the system from entering a low-power state.
- Unlock the runtime idle state once the IPC transaction is acknowledged
  by the HOST, allowing the system to enter low-power states if
  conditions permit.

The changes ensure that the DSP does not enter a power state that could
interrupt the IPC communication process, maintaining the integrity of
the IPC state machine.

Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
This commit is contained in:
Tomasz Leman 2024-03-04 14:49:55 +01:00 committed by Carles Cufí
parent a83d2dad8d
commit d5897a48aa

View file

@ -10,6 +10,7 @@
#include <zephyr/pm/state.h> #include <zephyr/pm/state.h>
#include <zephyr/pm/pm.h> #include <zephyr/pm/pm.h>
#include <zephyr/pm/device.h> #include <zephyr/pm/device.h>
#include <zephyr/pm/policy.h>
#include <errno.h> #include <errno.h>
void intel_adsp_ipc_set_message_handler(const struct device *dev, void intel_adsp_ipc_set_message_handler(const struct device *dev,
@ -73,6 +74,10 @@ void z_intel_adsp_ipc_isr(const void *devarg)
external_completion = devdata->done_notify(dev, devdata->done_arg); external_completion = devdata->done_notify(dev, devdata->done_arg);
} }
devdata->tx_ack_pending = false; devdata->tx_ack_pending = false;
/* Allow the system to enter the runtime idle state after the IPC acknowledgment
* is received.
*/
pm_policy_state_lock_get(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES);
k_sem_give(&devdata->sem); k_sem_give(&devdata->sem);
/* IPC completion registers will be set externally */ /* IPC completion registers will be set externally */
@ -158,6 +163,8 @@ int intel_adsp_ipc_send_message(const struct device *dev,
} }
k_sem_init(&devdata->sem, 0, 1); k_sem_init(&devdata->sem, 0, 1);
/* Prevent entering runtime idle state until IPC acknowledgment is received. */
pm_policy_state_lock_put(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES);
devdata->tx_ack_pending = true; devdata->tx_ack_pending = true;
config->regs->idd = ext_data; config->regs->idd = ext_data;
config->regs->idr = data | INTEL_ADSP_IPC_BUSY; config->regs->idr = data | INTEL_ADSP_IPC_BUSY;