xref: /openbmc/linux/sound/soc/intel/avs/ipc.c (revision fe4d0d5d)
1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
4 //
5 // Authors: Cezary Rojewski <cezary.rojewski@intel.com>
6 //          Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
7 //
8 
9 #include <linux/slab.h>
10 #include <sound/hdaudio_ext.h>
11 #include "avs.h"
12 #include "messages.h"
13 #include "registers.h"
14 
15 #define AVS_IPC_TIMEOUT_MS	300
16 
17 static void avs_dsp_receive_rx(struct avs_dev *adev, u64 header)
18 {
19 	struct avs_ipc *ipc = adev->ipc;
20 	union avs_reply_msg msg = AVS_MSG(header);
21 
22 	ipc->rx.header = header;
23 	/* Abort copying payload if request processing was unsuccessful. */
24 	if (!msg.status) {
25 		/* update size in case of LARGE_CONFIG_GET */
26 		if (msg.msg_target == AVS_MOD_MSG &&
27 		    msg.global_msg_type == AVS_MOD_LARGE_CONFIG_GET)
28 			ipc->rx.size = msg.ext.large_config.data_off_size;
29 
30 		memcpy_fromio(ipc->rx.data, avs_uplink_addr(adev), ipc->rx.size);
31 	}
32 }
33 
34 static void avs_dsp_process_notification(struct avs_dev *adev, u64 header)
35 {
36 	struct avs_notify_mod_data mod_data;
37 	union avs_notify_msg msg = AVS_MSG(header);
38 	size_t data_size = 0;
39 	void *data = NULL;
40 
41 	/* Ignore spurious notifications until handshake is established. */
42 	if (!adev->ipc->ready && msg.notify_msg_type != AVS_NOTIFY_FW_READY) {
43 		dev_dbg(adev->dev, "FW not ready, skip notification: 0x%08x\n", msg.primary);
44 		return;
45 	}
46 
47 	/* Calculate notification payload size. */
48 	switch (msg.notify_msg_type) {
49 	case AVS_NOTIFY_FW_READY:
50 		break;
51 
52 	case AVS_NOTIFY_PHRASE_DETECTED:
53 		data_size = sizeof(struct avs_notify_voice_data);
54 		break;
55 
56 	case AVS_NOTIFY_RESOURCE_EVENT:
57 		data_size = sizeof(struct avs_notify_res_data);
58 		break;
59 
60 	case AVS_NOTIFY_MODULE_EVENT:
61 		/* To know the total payload size, header needs to be read first. */
62 		memcpy_fromio(&mod_data, avs_uplink_addr(adev), sizeof(mod_data));
63 		data_size = sizeof(mod_data) + mod_data.data_size;
64 		break;
65 
66 	default:
67 		dev_info(adev->dev, "unknown notification: 0x%08x\n", msg.primary);
68 		break;
69 	}
70 
71 	if (data_size) {
72 		data = kmalloc(data_size, GFP_KERNEL);
73 		if (!data)
74 			return;
75 
76 		memcpy_fromio(data, avs_uplink_addr(adev), data_size);
77 	}
78 
79 	/* Perform notification-specific operations. */
80 	switch (msg.notify_msg_type) {
81 	case AVS_NOTIFY_FW_READY:
82 		dev_dbg(adev->dev, "FW READY 0x%08x\n", msg.primary);
83 		adev->ipc->ready = true;
84 		complete(&adev->fw_ready);
85 		break;
86 
87 	default:
88 		break;
89 	}
90 
91 	kfree(data);
92 }
93 
94 void avs_dsp_process_response(struct avs_dev *adev, u64 header)
95 {
96 	struct avs_ipc *ipc = adev->ipc;
97 
98 	/*
99 	 * Response may either be solicited - a reply for a request that has
100 	 * been sent beforehand - or unsolicited (notification).
101 	 */
102 	if (avs_msg_is_reply(header)) {
103 		/* Response processing is invoked from IRQ thread. */
104 		spin_lock_irq(&ipc->rx_lock);
105 		avs_dsp_receive_rx(adev, header);
106 		ipc->rx_completed = true;
107 		spin_unlock_irq(&ipc->rx_lock);
108 	} else {
109 		avs_dsp_process_notification(adev, header);
110 	}
111 
112 	complete(&ipc->busy_completion);
113 }
114 
115 irqreturn_t avs_dsp_irq_handler(int irq, void *dev_id)
116 {
117 	struct avs_dev *adev = dev_id;
118 	struct avs_ipc *ipc = adev->ipc;
119 	u32 adspis, hipc_rsp, hipc_ack;
120 	irqreturn_t ret = IRQ_NONE;
121 
122 	adspis = snd_hdac_adsp_readl(adev, AVS_ADSP_REG_ADSPIS);
123 	if (adspis == UINT_MAX || !(adspis & AVS_ADSP_ADSPIS_IPC))
124 		return ret;
125 
126 	hipc_ack = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCIE);
127 	hipc_rsp = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCT);
128 
129 	/* DSP acked host's request */
130 	if (hipc_ack & SKL_ADSP_HIPCIE_DONE) {
131 		/*
132 		 * As an extra precaution, mask done interrupt. Code executed
133 		 * due to complete() found below does not assume any masking.
134 		 */
135 		snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCCTL,
136 				      AVS_ADSP_HIPCCTL_DONE, 0);
137 
138 		complete(&ipc->done_completion);
139 
140 		/* tell DSP it has our attention */
141 		snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCIE,
142 				      SKL_ADSP_HIPCIE_DONE,
143 				      SKL_ADSP_HIPCIE_DONE);
144 		/* unmask done interrupt */
145 		snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCCTL,
146 				      AVS_ADSP_HIPCCTL_DONE,
147 				      AVS_ADSP_HIPCCTL_DONE);
148 		ret = IRQ_HANDLED;
149 	}
150 
151 	/* DSP sent new response to process */
152 	if (hipc_rsp & SKL_ADSP_HIPCT_BUSY) {
153 		/* mask busy interrupt */
154 		snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCCTL,
155 				      AVS_ADSP_HIPCCTL_BUSY, 0);
156 
157 		ret = IRQ_WAKE_THREAD;
158 	}
159 
160 	return ret;
161 }
162 
163 irqreturn_t avs_dsp_irq_thread(int irq, void *dev_id)
164 {
165 	struct avs_dev *adev = dev_id;
166 	union avs_reply_msg msg;
167 	u32 hipct, hipcte;
168 
169 	hipct = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCT);
170 	hipcte = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCTE);
171 
172 	/* ensure DSP sent new response to process */
173 	if (!(hipct & SKL_ADSP_HIPCT_BUSY))
174 		return IRQ_NONE;
175 
176 	msg.primary = hipct;
177 	msg.ext.val = hipcte;
178 	avs_dsp_process_response(adev, msg.val);
179 
180 	/* tell DSP we accepted its message */
181 	snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCT,
182 			      SKL_ADSP_HIPCT_BUSY, SKL_ADSP_HIPCT_BUSY);
183 	/* unmask busy interrupt */
184 	snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCCTL,
185 			      AVS_ADSP_HIPCCTL_BUSY, AVS_ADSP_HIPCCTL_BUSY);
186 
187 	return IRQ_HANDLED;
188 }
189 
190 static bool avs_ipc_is_busy(struct avs_ipc *ipc)
191 {
192 	struct avs_dev *adev = to_avs_dev(ipc->dev);
193 	u32 hipc_rsp;
194 
195 	hipc_rsp = snd_hdac_adsp_readl(adev, SKL_ADSP_REG_HIPCT);
196 	return hipc_rsp & SKL_ADSP_HIPCT_BUSY;
197 }
198 
199 static int avs_ipc_wait_busy_completion(struct avs_ipc *ipc, int timeout)
200 {
201 	u32 repeats_left = 128; /* to avoid infinite looping */
202 	int ret;
203 
204 again:
205 	ret = wait_for_completion_timeout(&ipc->busy_completion, msecs_to_jiffies(timeout));
206 
207 	/* DSP could be unresponsive at this point. */
208 	if (!ipc->ready)
209 		return -EPERM;
210 
211 	if (!ret) {
212 		if (!avs_ipc_is_busy(ipc))
213 			return -ETIMEDOUT;
214 		/*
215 		 * Firmware did its job, either notification or reply
216 		 * has been received - now wait until it's processed.
217 		 */
218 		wait_for_completion_killable(&ipc->busy_completion);
219 	}
220 
221 	/* Ongoing notification's bottom-half may cause early wakeup */
222 	spin_lock(&ipc->rx_lock);
223 	if (!ipc->rx_completed) {
224 		if (repeats_left) {
225 			/* Reply delayed due to notification. */
226 			repeats_left--;
227 			reinit_completion(&ipc->busy_completion);
228 			spin_unlock(&ipc->rx_lock);
229 			goto again;
230 		}
231 
232 		spin_unlock(&ipc->rx_lock);
233 		return -ETIMEDOUT;
234 	}
235 
236 	spin_unlock(&ipc->rx_lock);
237 	return 0;
238 }
239 
240 static void avs_ipc_msg_init(struct avs_ipc *ipc, struct avs_ipc_msg *reply)
241 {
242 	lockdep_assert_held(&ipc->rx_lock);
243 
244 	ipc->rx.header = 0;
245 	ipc->rx.size = reply ? reply->size : 0;
246 	ipc->rx_completed = false;
247 
248 	reinit_completion(&ipc->done_completion);
249 	reinit_completion(&ipc->busy_completion);
250 }
251 
252 static void avs_dsp_send_tx(struct avs_dev *adev, struct avs_ipc_msg *tx)
253 {
254 	tx->header |= SKL_ADSP_HIPCI_BUSY;
255 
256 	if (tx->size)
257 		memcpy_toio(avs_downlink_addr(adev), tx->data, tx->size);
258 	snd_hdac_adsp_writel(adev, SKL_ADSP_REG_HIPCIE, tx->header >> 32);
259 	snd_hdac_adsp_writel(adev, SKL_ADSP_REG_HIPCI, tx->header & UINT_MAX);
260 }
261 
262 static int avs_dsp_do_send_msg(struct avs_dev *adev, struct avs_ipc_msg *request,
263 			       struct avs_ipc_msg *reply, int timeout)
264 {
265 	struct avs_ipc *ipc = adev->ipc;
266 	int ret;
267 
268 	if (!ipc->ready)
269 		return -EPERM;
270 
271 	mutex_lock(&ipc->msg_mutex);
272 
273 	spin_lock(&ipc->rx_lock);
274 	avs_ipc_msg_init(ipc, reply);
275 	avs_dsp_send_tx(adev, request);
276 	spin_unlock(&ipc->rx_lock);
277 
278 	ret = avs_ipc_wait_busy_completion(ipc, timeout);
279 	if (ret) {
280 		if (ret == -ETIMEDOUT) {
281 			dev_crit(adev->dev, "communication severed: %d, rebooting dsp..\n", ret);
282 
283 			avs_ipc_block(ipc);
284 		}
285 		goto exit;
286 	}
287 
288 	ret = ipc->rx.rsp.status;
289 	if (reply) {
290 		reply->header = ipc->rx.header;
291 		if (reply->data && ipc->rx.size)
292 			memcpy(reply->data, ipc->rx.data, reply->size);
293 	}
294 
295 exit:
296 	mutex_unlock(&ipc->msg_mutex);
297 	return ret;
298 }
299 
300 int avs_dsp_send_msg_timeout(struct avs_dev *adev, struct avs_ipc_msg *request,
301 			     struct avs_ipc_msg *reply, int timeout)
302 {
303 	return avs_dsp_do_send_msg(adev, request, reply, timeout);
304 }
305 
306 int avs_dsp_send_msg(struct avs_dev *adev, struct avs_ipc_msg *request,
307 		     struct avs_ipc_msg *reply)
308 {
309 	return avs_dsp_send_msg_timeout(adev, request, reply, adev->ipc->default_timeout_ms);
310 }
311 
312 static int avs_dsp_do_send_rom_msg(struct avs_dev *adev, struct avs_ipc_msg *request, int timeout)
313 {
314 	struct avs_ipc *ipc = adev->ipc;
315 	int ret;
316 
317 	mutex_lock(&ipc->msg_mutex);
318 
319 	spin_lock(&ipc->rx_lock);
320 	avs_ipc_msg_init(ipc, NULL);
321 	avs_dsp_send_tx(adev, request);
322 	spin_unlock(&ipc->rx_lock);
323 
324 	/* ROM messages must be sent before main core is unstalled */
325 	ret = avs_dsp_op(adev, stall, AVS_MAIN_CORE_MASK, false);
326 	if (!ret) {
327 		ret = wait_for_completion_timeout(&ipc->done_completion, msecs_to_jiffies(timeout));
328 		ret = ret ? 0 : -ETIMEDOUT;
329 	}
330 
331 	mutex_unlock(&ipc->msg_mutex);
332 
333 	return ret;
334 }
335 
336 int avs_dsp_send_rom_msg_timeout(struct avs_dev *adev, struct avs_ipc_msg *request, int timeout)
337 {
338 	return avs_dsp_do_send_rom_msg(adev, request, timeout);
339 }
340 
341 int avs_dsp_send_rom_msg(struct avs_dev *adev, struct avs_ipc_msg *request)
342 {
343 	return avs_dsp_send_rom_msg_timeout(adev, request, adev->ipc->default_timeout_ms);
344 }
345 
346 void avs_dsp_interrupt_control(struct avs_dev *adev, bool enable)
347 {
348 	u32 value, mask;
349 
350 	/*
351 	 * No particular bit setting order. All of these are required
352 	 * to have a functional SW <-> FW communication.
353 	 */
354 	value = enable ? AVS_ADSP_ADSPIC_IPC : 0;
355 	snd_hdac_adsp_updatel(adev, AVS_ADSP_REG_ADSPIC, AVS_ADSP_ADSPIC_IPC, value);
356 
357 	mask = AVS_ADSP_HIPCCTL_DONE | AVS_ADSP_HIPCCTL_BUSY;
358 	value = enable ? mask : 0;
359 	snd_hdac_adsp_updatel(adev, SKL_ADSP_REG_HIPCCTL, mask, value);
360 }
361 
362 int avs_ipc_init(struct avs_ipc *ipc, struct device *dev)
363 {
364 	ipc->rx.data = devm_kzalloc(dev, AVS_MAILBOX_SIZE, GFP_KERNEL);
365 	if (!ipc->rx.data)
366 		return -ENOMEM;
367 
368 	ipc->dev = dev;
369 	ipc->ready = false;
370 	ipc->default_timeout_ms = AVS_IPC_TIMEOUT_MS;
371 	init_completion(&ipc->done_completion);
372 	init_completion(&ipc->busy_completion);
373 	spin_lock_init(&ipc->rx_lock);
374 	mutex_init(&ipc->msg_mutex);
375 
376 	return 0;
377 }
378 
379 void avs_ipc_block(struct avs_ipc *ipc)
380 {
381 	ipc->ready = false;
382 }
383