Skip to content

Commit cf7e2e6

Browse files
dcpleungcfriedt
authored andcommitted
soc: intel_adsp: rework host IPC using IPC service
This reworks the Intel audio DSP host IPC driver as a backend of the IPC 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 IPC interface. Signed-off-by: Daniel Leung <[email protected]>
1 parent ec28731 commit cf7e2e6

File tree

9 files changed

+789
-382
lines changed

9 files changed

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

soc/intel/intel_adsp/Kconfig

Lines changed: 12 additions & 5 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_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
3837
bool "Driver for the host IPC interrupt delivery"
39-
default $(dt_compat_enabled,$(DT_COMPAT_INTEL_ADSP_HOST_IPC)) if !SOF
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_SERVICE_BACKEND_INTEL_ADSP_HOST_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)