Line data Source code
1 0 : /*
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 1 : 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 1 : 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 1 : 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 1 : struct intel_adsp_ipc_msg {
55 : /** Header specific to platform. */
56 1 : uint32_t data;
57 :
58 : /** Extension specific to platform. */
59 1 : uint32_t ext_data;
60 :
61 : /** Timeout for sending synchronuous message. */
62 1 : 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 1 : struct intel_adsp_ipc_config {
129 : /** Pointer to hardware register block. */
130 1 : volatile struct intel_adsp_ipc *regs;
131 : };
132 :
133 : /**
134 : * Intel Audio DSP IPC service backend data struct.
135 : */
136 1 : struct intel_adsp_ipc_data {
137 : /** Semaphore used to wait for remote acknowledgment of sent message. */
138 1 : struct k_sem sem;
139 :
140 : /** General driver lock. */
141 1 : struct k_spinlock lock;
142 :
143 : /** Pending TX acknowlegement. */
144 1 : bool tx_ack_pending;
145 :
146 : /** Pointer to endpoint configuration. */
147 1 : 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 1 : struct intel_adsp_ipc_ept_priv_data {
182 : /** Callback return value (enum intel_adsp_cb_ret). */
183 1 : int cb_ret;
184 :
185 : /** Pointer to additional private data. */
186 1 : 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 */
|