Skip to content

Commit b4c4720

Browse files
committed
soc: intel_adsp: rework host IPC using IPC message service
This reworks the host IPC driver as a backend of the newly introduced IPC message service. This is the first step to rework IPC in SOF (Sound Open Firmware) into using a more generic IPC API instead of a SoC specific one. For now, it keeps the old interface to maintain usability as it is going to be a multiple process to rework IPC over there. Also, the structure of the new IPC backend resembles the SoC specific driver to make it easier to compare between them at this first iteration. Future optimizations will probably be needed once we start modifying the SOF side to utilize the new IPC message service API. Signed-off-by: Daniel Leung <daniel.leung@intel.com>
1 parent 77e3aa8 commit b4c4720

File tree

9 files changed

+798
-389
lines changed

9 files changed

+798
-389
lines changed
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
/*
2+
* Copyright (c) 2022, 2025 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
#ifndef ZEPHYR_INCLUDE_IPC_MSG_BACKEND_INTEL_ADSP_HOST_IPC_H
7+
#define ZEPHYR_INCLUDE_IPC_MSG_BACKEND_INTEL_ADSP_HOST_IPC_H
8+
9+
#include <intel_adsp_ipc_devtree.h>
10+
#include <zephyr/kernel.h>
11+
#include <zephyr/device.h>
12+
#include <zephyr/pm/device.h>
13+
14+
#include <zephyr/ipc/ipc_msg_service.h>
15+
16+
/* Enum for custom IPC message types. */
17+
enum intel_adsp_ipc_msg_types {
18+
/**
19+
* IPC message type.
20+
*
21+
* Use with struct intel_adsp_ipc_msg.
22+
*/
23+
INTEL_ADSP_IPC_MSG = IPC_MSG_TYPE_CUSTOM_START,
24+
25+
/**
26+
* IPC message type for synchronous send.
27+
*
28+
* Use with struct intel_adsp_ipc_msg_sync.
29+
*/
30+
INTEL_ADSP_IPC_MSG_SYNC,
31+
32+
/**
33+
* IPC message type for emergency send.
34+
*
35+
* Use with struct intel_adsp_ipc_msg_emergency.
36+
*/
37+
INTEL_ADSP_IPC_MSG_EMERGENCY,
38+
39+
/**
40+
* DONE message to acknowlege message from host has been processed.
41+
*
42+
* No data is associated with this message type.
43+
*/
44+
INTEL_ADSP_IPC_MSG_DONE,
45+
};
46+
47+
/* Enum for custom IPC event types. */
48+
enum intel_adsp_ipc_evt_types {
49+
/** IPC message event type for IPC done. */
50+
INTEL_ADSP_IPC_EVT_DONE = IPC_MSG_EVT_CUSTOM_START,
51+
};
52+
53+
/* Enum for return values for event callback. */
54+
enum intel_adsp_ipc_evt_returns {
55+
/** Return by event callback if external completion is performed. */
56+
INTEL_ADSP_IPC_EVT_RET_EXT_COMPELTE = 1,
57+
};
58+
59+
/* Enum for custom IPC query types. */
60+
enum intel_adsp_ipc_query_types {
61+
/**
62+
* Event type to query if host has completed processing the message.
63+
*
64+
* Returns 0 if completed, -EAGAIN if not.
65+
*/
66+
INTEL_ADSP_IPC_QUERY_IS_COMPLETE = IPC_MSG_QUERY_CUSTOM_START,
67+
};
68+
69+
/** Struct for message type INTEL_ADSP_IPC_MSG. */
70+
struct intel_adsp_ipc_msg {
71+
/** Data */
72+
uint32_t data;
73+
74+
/** Extended data*/
75+
uint32_t extdata;
76+
};
77+
78+
/** Struct for message type INTEL_ADSP_IPC_MSG_SYNC. */
79+
struct intel_adsp_ipc_msg_sync {
80+
/** Data */
81+
uint32_t data;
82+
83+
/** Extended data */
84+
uint32_t extdata;
85+
86+
/** Timeout to wait for host to finish processing the message. */
87+
k_timeout_t timeout;
88+
};
89+
90+
/** Struct for message type INTEL_ADSP_IPC_MSG_EMERGENCY. */
91+
struct intel_adsp_ipc_msg_emergency {
92+
/** Data */
93+
uint32_t data;
94+
95+
/** Extended data */
96+
uint32_t extdata;
97+
};
98+
99+
#ifdef CONFIG_INTEL_ADSP_IPC_OLD_INTERFACE
100+
101+
/**
102+
* @brief Intel ADSP IPC Message Handler Callback.
103+
*
104+
* This function, once registered via intel_adsp_ipc_set_message_handler(),
105+
* is invoked in interrupt context to service messages sent from the
106+
* foreign/connected IPC context. The message contents of the TDR and
107+
* TDD registers are provided in the data/ext_data argument.
108+
*
109+
* The function should return true if processing of the message is
110+
* complete and return notification to the other side (via the TDA
111+
* register) is desired immediately. Returning false means that no
112+
* return "DONE" interrupt will occur until intel_adsp_ipc_complete() is
113+
* called on this device at some point in the future.
114+
*
115+
* @note Further messages on the link will not be transmitted or
116+
* received while an in-progress message remains incomplete!
117+
*
118+
* @param dev IPC device.
119+
* @param arg Registered argument from intel_adsp_ipc_set_message_handler().
120+
* @param data Message data from other side (low bits of TDR register).
121+
* @param ext_dat Extended message data (TDD register).
122+
* @return true if the message is completely handled.
123+
*/
124+
typedef bool (*intel_adsp_ipc_handler_t)(const struct device *dev, void *arg, uint32_t data,
125+
uint32_t ext_data);
126+
127+
/**
128+
* @brief Intel ADSP IPC Message Complete Callback.
129+
*
130+
* This function, once registered via intel_adsp_ipc_set_done_handler(), is
131+
* invoked in interrupt context when a "DONE" return interrupt is
132+
* received from the other side of the connection (indicating that a
133+
* previously sent message is finished processing).
134+
*
135+
* @note On Intel ADSP hardware the DONE interrupt is transmitted
136+
* synchronously with the interrupt being cleared on the remote
137+
* device. It is not possible to delay processing. This callback
138+
* will still occur, but protocols which rely on notification of
139+
* asynchronous command processing will need modification.
140+
*
141+
* @param dev IPC device.
142+
* @param arg Registered argument from intel_adsp_ipc_set_done_handler().
143+
* @return True if IPC completion will be done externally, otherwise false.
144+
* @note Returning True will cause this API to skip writing IPC registers
145+
* signalling IPC message completion and those actions should be done by
146+
* external code manually. Returning false from the handler will perform
147+
* writing to IPC registers signalling message completion normally by this API.
148+
*/
149+
typedef bool (*intel_adsp_ipc_done_t)(const struct device *dev, void *arg);
150+
151+
#endif /* CONFIG_INTEL_ADSP_IPC_OLD_INTERFACE */
152+
153+
#ifdef CONFIG_PM_DEVICE
154+
typedef int (*intel_adsp_ipc_resume_handler_t)(const struct device *dev, void *arg);
155+
156+
typedef int (*intel_adsp_ipc_suspend_handler_t)(const struct device *dev, void *arg);
157+
#endif /* CONFIG_PM_DEVICE */
158+
159+
/**
160+
* Intel Audio DSP IPC message backend config struct
161+
*/
162+
struct intel_adsp_ipc_config {
163+
/** Pointer to hardware register block. */
164+
volatile struct intel_adsp_ipc *regs;
165+
};
166+
167+
/**
168+
* Intel Audio DSP IPC message backend data struct
169+
*/
170+
struct intel_adsp_ipc_data {
171+
/** Semaphore used to wait for remote acknowledgment of sent message. */
172+
struct k_sem sem;
173+
174+
/** General driver lock. */
175+
struct k_spinlock lock;
176+
177+
/** Pending TX acknowlegement. */
178+
bool tx_ack_pending;
179+
180+
/** Pointer to endpoint configuration. */
181+
const struct ipc_msg_ept_cfg *ept_cfg;
182+
183+
#ifdef CONFIG_INTEL_ADSP_IPC_OLD_INTERFACE
184+
/** Callback for message handler. */
185+
intel_adsp_ipc_handler_t handle_message;
186+
187+
/** Argument for message handler callback. */
188+
void *handler_arg;
189+
190+
/** Callback for done notification. */
191+
intel_adsp_ipc_done_t done_notify;
192+
193+
/** Argument for done notification callback. */
194+
void *done_arg;
195+
#endif /* CONFIG_INTEL_ADSP_IPC_OLD_INTERFACE */
196+
197+
#ifdef CONFIG_PM_DEVICE
198+
/** Pointer to resume handler. */
199+
intel_adsp_ipc_resume_handler_t resume_fn;
200+
201+
/** Argument for resume handler. */
202+
void *resume_fn_args;
203+
204+
/** Pointer to suspend handler. */
205+
intel_adsp_ipc_suspend_handler_t suspend_fn;
206+
207+
/** Argument for suspend handler. */
208+
void *suspend_fn_args;
209+
#endif /* CONFIG_PM_DEVICE */
210+
};
211+
212+
#ifdef CONFIG_PM_DEVICE
213+
214+
/**
215+
* @brief Registers resume callback handler used to resume Device from suspended state.
216+
*
217+
* @param dev IPC device.
218+
* @param fn Callback function.
219+
* @param arg Value to pass as the "arg" parameter to the function.
220+
*/
221+
void intel_adsp_ipc_set_resume_handler(const struct device *dev, intel_adsp_ipc_resume_handler_t fn,
222+
void *arg);
223+
224+
/**
225+
* @brief Registers suspend callback handler used to suspend active Device.
226+
*
227+
* @param dev IPC device.
228+
* @param fn Callback function.
229+
* @param arg Value to pass as the "arg" parameter to the function.
230+
*/
231+
void intel_adsp_ipc_set_suspend_handler(const struct device *dev,
232+
intel_adsp_ipc_suspend_handler_t fn, void *arg);
233+
234+
#endif /* CONFIG_PM_DEVICE */
235+
236+
#endif /* ZEPHYR_INCLUDE_IPC_MSG_BACKEND_INTEL_ADSP_HOST_IPC_H */

soc/intel/intel_adsp/Kconfig

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ config SOC_FAMILY_INTEL_ADSP
1111
select ARCH_HAS_USERSPACE if XTENSA_MMU
1212
imply XTENSA_MMU_DOUBLE_MAP
1313
select CPU_CACHE_INCOHERENT
14+
select IPC_MSG_SERVICE if DT_HAS_INTEL_ADSP_HOST_IPC_ENABLED
1415

1516
if SOC_FAMILY_INTEL_ADSP
1617

@@ -32,14 +33,20 @@ config INTEL_ADSP_SIM_NO_SECONDARY_CORE_FLOW
3233

3334
endif # INTEL_ADSP_SIM
3435

35-
DT_COMPAT_INTEL_ADSP_HOST_IPC := intel,adsp-host-ipc
36-
3736
config INTEL_ADSP_IPC
38-
bool "Driver for the host IPC interrupt delivery"
39-
default $(dt_compat_enabled,$(DT_COMPAT_INTEL_ADSP_HOST_IPC)) if !SOF
37+
bool "Driver for the host IPC interrupt delivery (Deprecated)"
38+
select DEPRECATED
39+
help
40+
Deprecated config for IPC. Will be removed in the future.
41+
42+
config INTEL_ADSP_IPC_OLD_INTERFACE
43+
bool "Expose old interface for the IPC"
44+
depends on IPC_MSG_BACKEND_INTEL_ADSP_IPC
45+
default y
46+
select INTEL_ADSP_IPC
4047
help
41-
Driver for the host IPC interrupt delivery mechanism.
42-
Currently SOF has its own driver for this hardware.
48+
Expose the old IPC interface (intel_adsp_ipc_* functions) to
49+
maintain backward compatibility.
4350

4451
config MEMORY_WIN_0_SIZE
4552
int "Size of memory window 0"

soc/intel/intel_adsp/common/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ zephyr_library_named(intel_adsp_common)
99
zephyr_include_directories(include)
1010
zephyr_library_include_directories(${ZEPHYR_BASE}/drivers)
1111

12-
zephyr_library_sources_ifdef(CONFIG_INTEL_ADSP_IPC ipc.c)
12+
zephyr_library_sources_ifdef(CONFIG_INTEL_ADSP_IPC_OLD_INTERFACE ipc.c)
1313

1414
zephyr_library_sources_ifdef(CONFIG_GDBSTUB
1515
gdbstub_backend_sram.c

0 commit comments

Comments
 (0)