1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * skl-sst-ipc.c - Intel skl IPC Support
4  *
5  * Copyright (C) 2014-15, Intel Corporation.
6  */
7 #include <linux/device.h>
8 
9 #include "../common/sst-dsp.h"
10 #include "../common/sst-dsp-priv.h"
11 #include "skl.h"
12 #include "skl-sst-dsp.h"
13 #include "skl-sst-ipc.h"
14 #include "sound/hdaudio_ext.h"
15 
16 
17 #define IPC_IXC_STATUS_BITS		24
18 
19 /* Global Message - Generic */
20 #define IPC_GLB_TYPE_SHIFT		24
21 #define IPC_GLB_TYPE_MASK		(0xf << IPC_GLB_TYPE_SHIFT)
22 #define IPC_GLB_TYPE(x)			((x) << IPC_GLB_TYPE_SHIFT)
23 
24 /* Global Message - Reply */
25 #define IPC_GLB_REPLY_STATUS_SHIFT	24
26 #define IPC_GLB_REPLY_STATUS_MASK	((0x1 << IPC_GLB_REPLY_STATUS_SHIFT) - 1)
27 #define IPC_GLB_REPLY_STATUS(x)		((x) << IPC_GLB_REPLY_STATUS_SHIFT)
28 
29 #define IPC_GLB_REPLY_TYPE_SHIFT	29
30 #define IPC_GLB_REPLY_TYPE_MASK		0x1F
31 #define IPC_GLB_REPLY_TYPE(x)		(((x) >> IPC_GLB_REPLY_TYPE_SHIFT) \
32 					& IPC_GLB_RPLY_TYPE_MASK)
33 
34 #define IPC_TIMEOUT_MSECS		3000
35 
36 #define IPC_EMPTY_LIST_SIZE		8
37 
38 #define IPC_MSG_TARGET_SHIFT		30
39 #define IPC_MSG_TARGET_MASK		0x1
40 #define IPC_MSG_TARGET(x)		(((x) & IPC_MSG_TARGET_MASK) \
41 					<< IPC_MSG_TARGET_SHIFT)
42 
43 #define IPC_MSG_DIR_SHIFT		29
44 #define IPC_MSG_DIR_MASK		0x1
45 #define IPC_MSG_DIR(x)			(((x) & IPC_MSG_DIR_MASK) \
46 					<< IPC_MSG_DIR_SHIFT)
47 /* Global Notification Message */
48 #define IPC_GLB_NOTIFY_TYPE_SHIFT	16
49 #define IPC_GLB_NOTIFY_TYPE_MASK	0xFF
50 #define IPC_GLB_NOTIFY_TYPE(x)		(((x) >> IPC_GLB_NOTIFY_TYPE_SHIFT) \
51 					& IPC_GLB_NOTIFY_TYPE_MASK)
52 
53 #define IPC_GLB_NOTIFY_MSG_TYPE_SHIFT	24
54 #define IPC_GLB_NOTIFY_MSG_TYPE_MASK	0x1F
55 #define IPC_GLB_NOTIFY_MSG_TYPE(x)	(((x) >> IPC_GLB_NOTIFY_MSG_TYPE_SHIFT)	\
56 						& IPC_GLB_NOTIFY_MSG_TYPE_MASK)
57 
58 #define IPC_GLB_NOTIFY_RSP_SHIFT	29
59 #define IPC_GLB_NOTIFY_RSP_MASK		0x1
60 #define IPC_GLB_NOTIFY_RSP_TYPE(x)	(((x) >> IPC_GLB_NOTIFY_RSP_SHIFT) \
61 					& IPC_GLB_NOTIFY_RSP_MASK)
62 
63 /* Pipeline operations */
64 
65 /* Create pipeline message */
66 #define IPC_PPL_MEM_SIZE_SHIFT		0
67 #define IPC_PPL_MEM_SIZE_MASK		0x7FF
68 #define IPC_PPL_MEM_SIZE(x)		(((x) & IPC_PPL_MEM_SIZE_MASK) \
69 					<< IPC_PPL_MEM_SIZE_SHIFT)
70 
71 #define IPC_PPL_TYPE_SHIFT		11
72 #define IPC_PPL_TYPE_MASK		0x1F
73 #define IPC_PPL_TYPE(x)			(((x) & IPC_PPL_TYPE_MASK) \
74 					<< IPC_PPL_TYPE_SHIFT)
75 
76 #define IPC_INSTANCE_ID_SHIFT		16
77 #define IPC_INSTANCE_ID_MASK		0xFF
78 #define IPC_INSTANCE_ID(x)		(((x) & IPC_INSTANCE_ID_MASK) \
79 					<< IPC_INSTANCE_ID_SHIFT)
80 
81 #define IPC_PPL_LP_MODE_SHIFT           0
82 #define IPC_PPL_LP_MODE_MASK            0x1
83 #define IPC_PPL_LP_MODE(x)              (((x) & IPC_PPL_LP_MODE_MASK) \
84 					<< IPC_PPL_LP_MODE_SHIFT)
85 
86 /* Set pipeline state message */
87 #define IPC_PPL_STATE_SHIFT		0
88 #define IPC_PPL_STATE_MASK		0x1F
89 #define IPC_PPL_STATE(x)		(((x) & IPC_PPL_STATE_MASK) \
90 					<< IPC_PPL_STATE_SHIFT)
91 
92 /* Module operations primary register */
93 #define IPC_MOD_ID_SHIFT		0
94 #define IPC_MOD_ID_MASK		0xFFFF
95 #define IPC_MOD_ID(x)		(((x) & IPC_MOD_ID_MASK) \
96 					<< IPC_MOD_ID_SHIFT)
97 
98 #define IPC_MOD_INSTANCE_ID_SHIFT	16
99 #define IPC_MOD_INSTANCE_ID_MASK	0xFF
100 #define IPC_MOD_INSTANCE_ID(x)	(((x) & IPC_MOD_INSTANCE_ID_MASK) \
101 					<< IPC_MOD_INSTANCE_ID_SHIFT)
102 
103 /* Init instance message extension register */
104 #define IPC_PARAM_BLOCK_SIZE_SHIFT	0
105 #define IPC_PARAM_BLOCK_SIZE_MASK	0xFFFF
106 #define IPC_PARAM_BLOCK_SIZE(x)		(((x) & IPC_PARAM_BLOCK_SIZE_MASK) \
107 					<< IPC_PARAM_BLOCK_SIZE_SHIFT)
108 
109 #define IPC_PPL_INSTANCE_ID_SHIFT	16
110 #define IPC_PPL_INSTANCE_ID_MASK	0xFF
111 #define IPC_PPL_INSTANCE_ID(x)		(((x) & IPC_PPL_INSTANCE_ID_MASK) \
112 					<< IPC_PPL_INSTANCE_ID_SHIFT)
113 
114 #define IPC_CORE_ID_SHIFT		24
115 #define IPC_CORE_ID_MASK		0x1F
116 #define IPC_CORE_ID(x)			(((x) & IPC_CORE_ID_MASK) \
117 					<< IPC_CORE_ID_SHIFT)
118 
119 #define IPC_DOMAIN_SHIFT                28
120 #define IPC_DOMAIN_MASK                 0x1
121 #define IPC_DOMAIN(x)                   (((x) & IPC_DOMAIN_MASK) \
122 					<< IPC_DOMAIN_SHIFT)
123 
124 /* Bind/Unbind message extension register */
125 #define IPC_DST_MOD_ID_SHIFT		0
126 #define IPC_DST_MOD_ID(x)		(((x) & IPC_MOD_ID_MASK) \
127 					<< IPC_DST_MOD_ID_SHIFT)
128 
129 #define IPC_DST_MOD_INSTANCE_ID_SHIFT 16
130 #define IPC_DST_MOD_INSTANCE_ID(x)	(((x) & IPC_MOD_INSTANCE_ID_MASK) \
131 					<< IPC_DST_MOD_INSTANCE_ID_SHIFT)
132 
133 #define IPC_DST_QUEUE_SHIFT		24
134 #define IPC_DST_QUEUE_MASK		0x7
135 #define IPC_DST_QUEUE(x)		(((x) & IPC_DST_QUEUE_MASK) \
136 					<< IPC_DST_QUEUE_SHIFT)
137 
138 #define IPC_SRC_QUEUE_SHIFT		27
139 #define IPC_SRC_QUEUE_MASK		0x7
140 #define IPC_SRC_QUEUE(x)		(((x) & IPC_SRC_QUEUE_MASK) \
141 					<< IPC_SRC_QUEUE_SHIFT)
142 /* Load Module count */
143 #define IPC_LOAD_MODULE_SHIFT		0
144 #define IPC_LOAD_MODULE_MASK		0xFF
145 #define IPC_LOAD_MODULE_CNT(x)		(((x) & IPC_LOAD_MODULE_MASK) \
146 					<< IPC_LOAD_MODULE_SHIFT)
147 
148 /* Save pipeline messgae extension register */
149 #define IPC_DMA_ID_SHIFT		0
150 #define IPC_DMA_ID_MASK			0x1F
151 #define IPC_DMA_ID(x)			(((x) & IPC_DMA_ID_MASK) \
152 					<< IPC_DMA_ID_SHIFT)
153 /* Large Config message extension register */
154 #define IPC_DATA_OFFSET_SZ_SHIFT	0
155 #define IPC_DATA_OFFSET_SZ_MASK		0xFFFFF
156 #define IPC_DATA_OFFSET_SZ(x)		(((x) & IPC_DATA_OFFSET_SZ_MASK) \
157 					<< IPC_DATA_OFFSET_SZ_SHIFT)
158 #define IPC_DATA_OFFSET_SZ_CLEAR	~(IPC_DATA_OFFSET_SZ_MASK \
159 					  << IPC_DATA_OFFSET_SZ_SHIFT)
160 
161 #define IPC_LARGE_PARAM_ID_SHIFT	20
162 #define IPC_LARGE_PARAM_ID_MASK		0xFF
163 #define IPC_LARGE_PARAM_ID(x)		(((x) & IPC_LARGE_PARAM_ID_MASK) \
164 					<< IPC_LARGE_PARAM_ID_SHIFT)
165 
166 #define IPC_FINAL_BLOCK_SHIFT		28
167 #define IPC_FINAL_BLOCK_MASK		0x1
168 #define IPC_FINAL_BLOCK(x)		(((x) & IPC_FINAL_BLOCK_MASK) \
169 					<< IPC_FINAL_BLOCK_SHIFT)
170 
171 #define IPC_INITIAL_BLOCK_SHIFT		29
172 #define IPC_INITIAL_BLOCK_MASK		0x1
173 #define IPC_INITIAL_BLOCK(x)		(((x) & IPC_INITIAL_BLOCK_MASK) \
174 					<< IPC_INITIAL_BLOCK_SHIFT)
175 #define IPC_INITIAL_BLOCK_CLEAR		~(IPC_INITIAL_BLOCK_MASK \
176 					  << IPC_INITIAL_BLOCK_SHIFT)
177 /* Set D0ix IPC extension register */
178 #define IPC_D0IX_WAKE_SHIFT		0
179 #define IPC_D0IX_WAKE_MASK		0x1
180 #define IPC_D0IX_WAKE(x)		(((x) & IPC_D0IX_WAKE_MASK) \
181 					<< IPC_D0IX_WAKE_SHIFT)
182 
183 #define IPC_D0IX_STREAMING_SHIFT	1
184 #define IPC_D0IX_STREAMING_MASK		0x1
185 #define IPC_D0IX_STREAMING(x)		(((x) & IPC_D0IX_STREAMING_MASK) \
186 					<< IPC_D0IX_STREAMING_SHIFT)
187 
188 
189 enum skl_ipc_msg_target {
190 	IPC_FW_GEN_MSG = 0,
191 	IPC_MOD_MSG = 1
192 };
193 
194 enum skl_ipc_msg_direction {
195 	IPC_MSG_REQUEST = 0,
196 	IPC_MSG_REPLY = 1
197 };
198 
199 /* Global Message Types */
200 enum skl_ipc_glb_type {
201 	IPC_GLB_GET_FW_VERSION = 0, /* Retrieves firmware version */
202 	IPC_GLB_LOAD_MULTIPLE_MODS = 15,
203 	IPC_GLB_UNLOAD_MULTIPLE_MODS = 16,
204 	IPC_GLB_CREATE_PPL = 17,
205 	IPC_GLB_DELETE_PPL = 18,
206 	IPC_GLB_SET_PPL_STATE = 19,
207 	IPC_GLB_GET_PPL_STATE = 20,
208 	IPC_GLB_GET_PPL_CONTEXT_SIZE = 21,
209 	IPC_GLB_SAVE_PPL = 22,
210 	IPC_GLB_RESTORE_PPL = 23,
211 	IPC_GLB_LOAD_LIBRARY = 24,
212 	IPC_GLB_NOTIFY = 26,
213 	IPC_GLB_MAX_IPC_MSG_NUMBER = 31 /* Maximum message number */
214 };
215 
216 enum skl_ipc_glb_reply {
217 	IPC_GLB_REPLY_SUCCESS = 0,
218 
219 	IPC_GLB_REPLY_UNKNOWN_MSG_TYPE = 1,
220 	IPC_GLB_REPLY_ERROR_INVALID_PARAM = 2,
221 
222 	IPC_GLB_REPLY_BUSY = 3,
223 	IPC_GLB_REPLY_PENDING = 4,
224 	IPC_GLB_REPLY_FAILURE = 5,
225 	IPC_GLB_REPLY_INVALID_REQUEST = 6,
226 
227 	IPC_GLB_REPLY_OUT_OF_MEMORY = 7,
228 	IPC_GLB_REPLY_OUT_OF_MIPS = 8,
229 
230 	IPC_GLB_REPLY_INVALID_RESOURCE_ID = 9,
231 	IPC_GLB_REPLY_INVALID_RESOURCE_STATE = 10,
232 
233 	IPC_GLB_REPLY_MOD_MGMT_ERROR = 100,
234 	IPC_GLB_REPLY_MOD_LOAD_CL_FAILED = 101,
235 	IPC_GLB_REPLY_MOD_LOAD_INVALID_HASH = 102,
236 
237 	IPC_GLB_REPLY_MOD_UNLOAD_INST_EXIST = 103,
238 	IPC_GLB_REPLY_MOD_NOT_INITIALIZED = 104,
239 
240 	IPC_GLB_REPLY_INVALID_CONFIG_PARAM_ID = 120,
241 	IPC_GLB_REPLY_INVALID_CONFIG_DATA_LEN = 121,
242 	IPC_GLB_REPLY_GATEWAY_NOT_INITIALIZED = 140,
243 	IPC_GLB_REPLY_GATEWAY_NOT_EXIST = 141,
244 	IPC_GLB_REPLY_SCLK_ALREADY_RUNNING = 150,
245 	IPC_GLB_REPLY_MCLK_ALREADY_RUNNING = 151,
246 
247 	IPC_GLB_REPLY_PPL_NOT_INITIALIZED = 160,
248 	IPC_GLB_REPLY_PPL_NOT_EXIST = 161,
249 	IPC_GLB_REPLY_PPL_SAVE_FAILED = 162,
250 	IPC_GLB_REPLY_PPL_RESTORE_FAILED = 163,
251 
252 	IPC_MAX_STATUS = ((1<<IPC_IXC_STATUS_BITS)-1)
253 };
254 
255 enum skl_ipc_notification_type {
256 	IPC_GLB_NOTIFY_GLITCH = 0,
257 	IPC_GLB_NOTIFY_OVERRUN = 1,
258 	IPC_GLB_NOTIFY_UNDERRUN = 2,
259 	IPC_GLB_NOTIFY_END_STREAM = 3,
260 	IPC_GLB_NOTIFY_PHRASE_DETECTED = 4,
261 	IPC_GLB_NOTIFY_RESOURCE_EVENT = 5,
262 	IPC_GLB_NOTIFY_LOG_BUFFER_STATUS = 6,
263 	IPC_GLB_NOTIFY_TIMESTAMP_CAPTURED = 7,
264 	IPC_GLB_NOTIFY_FW_READY = 8
265 };
266 
267 /* Module Message Types */
268 enum skl_ipc_module_msg {
269 	IPC_MOD_INIT_INSTANCE = 0,
270 	IPC_MOD_CONFIG_GET = 1,
271 	IPC_MOD_CONFIG_SET = 2,
272 	IPC_MOD_LARGE_CONFIG_GET = 3,
273 	IPC_MOD_LARGE_CONFIG_SET = 4,
274 	IPC_MOD_BIND = 5,
275 	IPC_MOD_UNBIND = 6,
276 	IPC_MOD_SET_DX = 7,
277 	IPC_MOD_SET_D0IX = 8
278 };
279 
280 void skl_ipc_tx_data_copy(struct ipc_message *msg, char *tx_data,
281 		size_t tx_size)
282 {
283 	if (tx_size)
284 		memcpy(msg->tx_data, tx_data, tx_size);
285 }
286 
287 static bool skl_ipc_is_dsp_busy(struct sst_dsp *dsp)
288 {
289 	u32 hipci;
290 
291 	hipci = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCI);
292 	return (hipci & SKL_ADSP_REG_HIPCI_BUSY);
293 }
294 
295 /* Lock to be held by caller */
296 static void skl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
297 {
298 	struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->header);
299 
300 	if (msg->tx_size)
301 		sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size);
302 	sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCIE,
303 						header->extension);
304 	sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCI,
305 		header->primary | SKL_ADSP_REG_HIPCI_BUSY);
306 }
307 
308 int skl_ipc_check_D0i0(struct sst_dsp *dsp, bool state)
309 {
310 	int ret;
311 
312 	/* check D0i3 support */
313 	if (!dsp->fw_ops.set_state_D0i0)
314 		return 0;
315 
316 	/* Attempt D0i0 or D0i3 based on state */
317 	if (state)
318 		ret = dsp->fw_ops.set_state_D0i0(dsp);
319 	else
320 		ret = dsp->fw_ops.set_state_D0i3(dsp);
321 
322 	return ret;
323 }
324 
325 static struct ipc_message *skl_ipc_reply_get_msg(struct sst_generic_ipc *ipc,
326 				u64 ipc_header)
327 {
328 	struct ipc_message *msg =  NULL;
329 	struct skl_ipc_header *header = (struct skl_ipc_header *)(&ipc_header);
330 
331 	if (list_empty(&ipc->rx_list)) {
332 		dev_err(ipc->dev, "ipc: rx list is empty but received 0x%x\n",
333 			header->primary);
334 		goto out;
335 	}
336 
337 	msg = list_first_entry(&ipc->rx_list, struct ipc_message, list);
338 
339 out:
340 	return msg;
341 
342 }
343 
344 int skl_ipc_process_notification(struct sst_generic_ipc *ipc,
345 		struct skl_ipc_header header)
346 {
347 	struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc);
348 
349 	if (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
350 		switch (IPC_GLB_NOTIFY_TYPE(header.primary)) {
351 
352 		case IPC_GLB_NOTIFY_UNDERRUN:
353 			dev_err(ipc->dev, "FW Underrun %x\n", header.primary);
354 			break;
355 
356 		case IPC_GLB_NOTIFY_RESOURCE_EVENT:
357 			dev_err(ipc->dev, "MCPS Budget Violation: %x\n",
358 						header.primary);
359 			break;
360 
361 		case IPC_GLB_NOTIFY_FW_READY:
362 			skl->boot_complete = true;
363 			wake_up(&skl->boot_wait);
364 			break;
365 
366 		case IPC_GLB_NOTIFY_PHRASE_DETECTED:
367 			dev_dbg(ipc->dev, "***** Phrase Detected **********\n");
368 
369 			/*
370 			 * Per HW recomendation, After phrase detection,
371 			 * clear the CGCTL.MISCBDCGE.
372 			 *
373 			 * This will be set back on stream closure
374 			 */
375 			skl->enable_miscbdcge(ipc->dev, false);
376 			skl->miscbdcg_disabled = true;
377 			break;
378 
379 		default:
380 			dev_err(ipc->dev, "ipc: Unhandled error msg=%x\n",
381 						header.primary);
382 			break;
383 		}
384 	}
385 
386 	return 0;
387 }
388 
389 struct skl_ipc_err_map {
390 	const char *msg;
391 	enum skl_ipc_glb_reply reply;
392 	int err;
393 };
394 
395 static struct skl_ipc_err_map skl_err_map[] = {
396 	{"DSP out of memory", IPC_GLB_REPLY_OUT_OF_MEMORY, -ENOMEM},
397 	{"DSP busy", IPC_GLB_REPLY_BUSY, -EBUSY},
398 	{"SCLK already running", IPC_GLB_REPLY_SCLK_ALREADY_RUNNING,
399 			IPC_GLB_REPLY_SCLK_ALREADY_RUNNING},
400 	{"MCLK already running", IPC_GLB_REPLY_MCLK_ALREADY_RUNNING,
401 			IPC_GLB_REPLY_MCLK_ALREADY_RUNNING},
402 };
403 
404 static int skl_ipc_set_reply_error_code(struct sst_generic_ipc *ipc, u32 reply)
405 {
406 	int i;
407 
408 	for (i = 0; i < ARRAY_SIZE(skl_err_map); i++) {
409 		if (skl_err_map[i].reply == reply)
410 			break;
411 	}
412 
413 	if (i == ARRAY_SIZE(skl_err_map)) {
414 		dev_err(ipc->dev, "ipc FW reply: %d FW Error Code: %u\n",
415 				reply,
416 				ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
417 		return -EINVAL;
418 	}
419 
420 	if (skl_err_map[i].err < 0)
421 		dev_err(ipc->dev, "ipc FW reply: %s FW Error Code: %u\n",
422 				skl_err_map[i].msg,
423 				ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
424 	else
425 		dev_info(ipc->dev, "ipc FW reply: %s FW Error Code: %u\n",
426 				skl_err_map[i].msg,
427 				ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
428 
429 	return skl_err_map[i].err;
430 }
431 
432 void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
433 		struct skl_ipc_header header)
434 {
435 	struct ipc_message *msg;
436 	u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK;
437 	u64 *ipc_header = (u64 *)(&header);
438 	struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc);
439 	unsigned long flags;
440 
441 	spin_lock_irqsave(&ipc->dsp->spinlock, flags);
442 	msg = skl_ipc_reply_get_msg(ipc, *ipc_header);
443 	spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
444 	if (msg == NULL) {
445 		dev_dbg(ipc->dev, "ipc: rx list is empty\n");
446 		return;
447 	}
448 
449 	/* first process the header */
450 	if (reply == IPC_GLB_REPLY_SUCCESS) {
451 		dev_dbg(ipc->dev, "ipc FW reply %x: success\n", header.primary);
452 		/* copy the rx data from the mailbox */
453 		sst_dsp_inbox_read(ipc->dsp, msg->rx_data, msg->rx_size);
454 		switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
455 		case IPC_GLB_LOAD_MULTIPLE_MODS:
456 		case IPC_GLB_LOAD_LIBRARY:
457 			skl->mod_load_complete = true;
458 			skl->mod_load_status = true;
459 			wake_up(&skl->mod_load_wait);
460 			break;
461 
462 		default:
463 			break;
464 
465 		}
466 	} else {
467 		msg->errno = skl_ipc_set_reply_error_code(ipc, reply);
468 		switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
469 		case IPC_GLB_LOAD_MULTIPLE_MODS:
470 		case IPC_GLB_LOAD_LIBRARY:
471 			skl->mod_load_complete = true;
472 			skl->mod_load_status = false;
473 			wake_up(&skl->mod_load_wait);
474 			break;
475 
476 		default:
477 			break;
478 
479 		}
480 	}
481 
482 	spin_lock_irqsave(&ipc->dsp->spinlock, flags);
483 	list_del(&msg->list);
484 	sst_ipc_tx_msg_reply_complete(ipc, msg);
485 	spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
486 }
487 
488 irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context)
489 {
490 	struct sst_dsp *dsp = context;
491 	struct skl_sst *skl = sst_dsp_get_thread_context(dsp);
492 	struct sst_generic_ipc *ipc = &skl->ipc;
493 	struct skl_ipc_header header = {0};
494 	u32 hipcie, hipct, hipcte;
495 	int ipc_irq = 0;
496 
497 	if (dsp->intr_status & SKL_ADSPIS_CL_DMA)
498 		skl_cldma_process_intr(dsp);
499 
500 	/* Here we handle IPC interrupts only */
501 	if (!(dsp->intr_status & SKL_ADSPIS_IPC))
502 		return IRQ_NONE;
503 
504 	hipcie = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCIE);
505 	hipct = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCT);
506 
507 	/* reply message from DSP */
508 	if (hipcie & SKL_ADSP_REG_HIPCIE_DONE) {
509 		sst_dsp_shim_update_bits(dsp, SKL_ADSP_REG_HIPCCTL,
510 			SKL_ADSP_REG_HIPCCTL_DONE, 0);
511 
512 		/* clear DONE bit - tell DSP we have completed the operation */
513 		sst_dsp_shim_update_bits_forced(dsp, SKL_ADSP_REG_HIPCIE,
514 			SKL_ADSP_REG_HIPCIE_DONE, SKL_ADSP_REG_HIPCIE_DONE);
515 
516 		ipc_irq = 1;
517 
518 		/* unmask Done interrupt */
519 		sst_dsp_shim_update_bits(dsp, SKL_ADSP_REG_HIPCCTL,
520 			SKL_ADSP_REG_HIPCCTL_DONE, SKL_ADSP_REG_HIPCCTL_DONE);
521 	}
522 
523 	/* New message from DSP */
524 	if (hipct & SKL_ADSP_REG_HIPCT_BUSY) {
525 		hipcte = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCTE);
526 		header.primary = hipct;
527 		header.extension = hipcte;
528 		dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x\n",
529 						header.primary);
530 		dev_dbg(dsp->dev, "IPC irq: Firmware respond extension:%x\n",
531 						header.extension);
532 
533 		if (IPC_GLB_NOTIFY_RSP_TYPE(header.primary)) {
534 			/* Handle Immediate reply from DSP Core */
535 			skl_ipc_process_reply(ipc, header);
536 		} else {
537 			dev_dbg(dsp->dev, "IPC irq: Notification from firmware\n");
538 			skl_ipc_process_notification(ipc, header);
539 		}
540 		/* clear  busy interrupt */
541 		sst_dsp_shim_update_bits_forced(dsp, SKL_ADSP_REG_HIPCT,
542 			SKL_ADSP_REG_HIPCT_BUSY, SKL_ADSP_REG_HIPCT_BUSY);
543 		ipc_irq = 1;
544 	}
545 
546 	if (ipc_irq == 0)
547 		return IRQ_NONE;
548 
549 	skl_ipc_int_enable(dsp);
550 
551 	/* continue to send any remaining messages... */
552 	schedule_work(&ipc->kwork);
553 
554 	return IRQ_HANDLED;
555 }
556 
557 void skl_ipc_int_enable(struct sst_dsp *ctx)
558 {
559 	sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_ADSPIC,
560 			SKL_ADSPIC_IPC, SKL_ADSPIC_IPC);
561 }
562 
563 void skl_ipc_int_disable(struct sst_dsp *ctx)
564 {
565 	sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPIC,
566 			SKL_ADSPIC_IPC, 0);
567 }
568 
569 void skl_ipc_op_int_enable(struct sst_dsp *ctx)
570 {
571 	/* enable IPC DONE interrupt */
572 	sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_HIPCCTL,
573 		SKL_ADSP_REG_HIPCCTL_DONE, SKL_ADSP_REG_HIPCCTL_DONE);
574 
575 	/* Enable IPC BUSY interrupt */
576 	sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_HIPCCTL,
577 		SKL_ADSP_REG_HIPCCTL_BUSY, SKL_ADSP_REG_HIPCCTL_BUSY);
578 }
579 
580 void skl_ipc_op_int_disable(struct sst_dsp *ctx)
581 {
582 	/* disable IPC DONE interrupt */
583 	sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_HIPCCTL,
584 					SKL_ADSP_REG_HIPCCTL_DONE, 0);
585 
586 	/* Disable IPC BUSY interrupt */
587 	sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_HIPCCTL,
588 					SKL_ADSP_REG_HIPCCTL_BUSY, 0);
589 
590 }
591 
592 bool skl_ipc_int_status(struct sst_dsp *ctx)
593 {
594 	return sst_dsp_shim_read_unlocked(ctx,
595 			SKL_ADSP_REG_ADSPIS) & SKL_ADSPIS_IPC;
596 }
597 
598 int skl_ipc_init(struct device *dev, struct skl_sst *skl)
599 {
600 	struct sst_generic_ipc *ipc;
601 	int err;
602 
603 	ipc = &skl->ipc;
604 	ipc->dsp = skl->dsp;
605 	ipc->dev = dev;
606 
607 	ipc->tx_data_max_size = SKL_ADSP_W1_SZ;
608 	ipc->rx_data_max_size = SKL_ADSP_W0_UP_SZ;
609 
610 	err = sst_ipc_init(ipc);
611 	if (err)
612 		return err;
613 
614 	ipc->ops.tx_msg = skl_ipc_tx_msg;
615 	ipc->ops.tx_data_copy = skl_ipc_tx_data_copy;
616 	ipc->ops.is_dsp_busy = skl_ipc_is_dsp_busy;
617 
618 	return 0;
619 }
620 
621 void skl_ipc_free(struct sst_generic_ipc *ipc)
622 {
623 	/* Disable IPC DONE interrupt */
624 	sst_dsp_shim_update_bits(ipc->dsp, SKL_ADSP_REG_HIPCCTL,
625 		SKL_ADSP_REG_HIPCCTL_DONE, 0);
626 
627 	/* Disable IPC BUSY interrupt */
628 	sst_dsp_shim_update_bits(ipc->dsp, SKL_ADSP_REG_HIPCCTL,
629 		SKL_ADSP_REG_HIPCCTL_BUSY, 0);
630 
631 	sst_ipc_fini(ipc);
632 }
633 
634 int skl_ipc_create_pipeline(struct sst_generic_ipc *ipc,
635 		u16 ppl_mem_size, u8 ppl_type, u8 instance_id, u8 lp_mode)
636 {
637 	struct skl_ipc_header header = {0};
638 	u64 *ipc_header = (u64 *)(&header);
639 	int ret;
640 
641 	header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
642 	header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
643 	header.primary |= IPC_GLB_TYPE(IPC_GLB_CREATE_PPL);
644 	header.primary |= IPC_INSTANCE_ID(instance_id);
645 	header.primary |= IPC_PPL_TYPE(ppl_type);
646 	header.primary |= IPC_PPL_MEM_SIZE(ppl_mem_size);
647 
648 	header.extension = IPC_PPL_LP_MODE(lp_mode);
649 
650 	dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
651 	ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
652 	if (ret < 0) {
653 		dev_err(ipc->dev, "ipc: create pipeline fail, err: %d\n", ret);
654 		return ret;
655 	}
656 
657 	return ret;
658 }
659 EXPORT_SYMBOL_GPL(skl_ipc_create_pipeline);
660 
661 int skl_ipc_delete_pipeline(struct sst_generic_ipc *ipc, u8 instance_id)
662 {
663 	struct skl_ipc_header header = {0};
664 	u64 *ipc_header = (u64 *)(&header);
665 	int ret;
666 
667 	header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
668 	header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
669 	header.primary |= IPC_GLB_TYPE(IPC_GLB_DELETE_PPL);
670 	header.primary |= IPC_INSTANCE_ID(instance_id);
671 
672 	dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
673 	ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
674 	if (ret < 0) {
675 		dev_err(ipc->dev, "ipc: delete pipeline failed, err %d\n", ret);
676 		return ret;
677 	}
678 
679 	return 0;
680 }
681 EXPORT_SYMBOL_GPL(skl_ipc_delete_pipeline);
682 
683 int skl_ipc_set_pipeline_state(struct sst_generic_ipc *ipc,
684 		u8 instance_id, enum skl_ipc_pipeline_state state)
685 {
686 	struct skl_ipc_header header = {0};
687 	u64 *ipc_header = (u64 *)(&header);
688 	int ret;
689 
690 	header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
691 	header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
692 	header.primary |= IPC_GLB_TYPE(IPC_GLB_SET_PPL_STATE);
693 	header.primary |= IPC_INSTANCE_ID(instance_id);
694 	header.primary |= IPC_PPL_STATE(state);
695 
696 	dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
697 	ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
698 	if (ret < 0) {
699 		dev_err(ipc->dev, "ipc: set pipeline state failed, err: %d\n", ret);
700 		return ret;
701 	}
702 	return ret;
703 }
704 EXPORT_SYMBOL_GPL(skl_ipc_set_pipeline_state);
705 
706 int
707 skl_ipc_save_pipeline(struct sst_generic_ipc *ipc, u8 instance_id, int dma_id)
708 {
709 	struct skl_ipc_header header = {0};
710 	u64 *ipc_header = (u64 *)(&header);
711 	int ret;
712 
713 	header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
714 	header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
715 	header.primary |= IPC_GLB_TYPE(IPC_GLB_SAVE_PPL);
716 	header.primary |= IPC_INSTANCE_ID(instance_id);
717 
718 	header.extension = IPC_DMA_ID(dma_id);
719 	dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
720 	ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
721 	if (ret < 0) {
722 		dev_err(ipc->dev, "ipc: save pipeline failed, err: %d\n", ret);
723 		return ret;
724 	}
725 
726 	return ret;
727 }
728 EXPORT_SYMBOL_GPL(skl_ipc_save_pipeline);
729 
730 int skl_ipc_restore_pipeline(struct sst_generic_ipc *ipc, u8 instance_id)
731 {
732 	struct skl_ipc_header header = {0};
733 	u64 *ipc_header = (u64 *)(&header);
734 	int ret;
735 
736 	header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
737 	header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
738 	header.primary |= IPC_GLB_TYPE(IPC_GLB_RESTORE_PPL);
739 	header.primary |= IPC_INSTANCE_ID(instance_id);
740 
741 	dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
742 	ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
743 	if (ret < 0) {
744 		dev_err(ipc->dev, "ipc: restore  pipeline failed, err: %d\n", ret);
745 		return ret;
746 	}
747 
748 	return ret;
749 }
750 EXPORT_SYMBOL_GPL(skl_ipc_restore_pipeline);
751 
752 int skl_ipc_set_dx(struct sst_generic_ipc *ipc, u8 instance_id,
753 		u16 module_id, struct skl_ipc_dxstate_info *dx)
754 {
755 	struct skl_ipc_header header = {0};
756 	u64 *ipc_header = (u64 *)(&header);
757 	int ret;
758 
759 	header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
760 	header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
761 	header.primary |= IPC_GLB_TYPE(IPC_MOD_SET_DX);
762 	header.primary |= IPC_MOD_INSTANCE_ID(instance_id);
763 	header.primary |= IPC_MOD_ID(module_id);
764 
765 	dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
766 			 header.primary, header.extension);
767 	ret = sst_ipc_tx_message_wait(ipc, *ipc_header,
768 				dx, sizeof(*dx), NULL, 0);
769 	if (ret < 0) {
770 		dev_err(ipc->dev, "ipc: set dx failed, err %d\n", ret);
771 		return ret;
772 	}
773 
774 	return ret;
775 }
776 EXPORT_SYMBOL_GPL(skl_ipc_set_dx);
777 
778 int skl_ipc_init_instance(struct sst_generic_ipc *ipc,
779 		struct skl_ipc_init_instance_msg *msg, void *param_data)
780 {
781 	struct skl_ipc_header header = {0};
782 	u64 *ipc_header = (u64 *)(&header);
783 	int ret;
784 	u32 *buffer = (u32 *)param_data;
785 	 /* param_block_size must be in dwords */
786 	u16 param_block_size = msg->param_data_size / sizeof(u32);
787 
788 	print_hex_dump_debug("Param data:", DUMP_PREFIX_NONE,
789 		16, 4, buffer, param_block_size, false);
790 
791 	header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
792 	header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
793 	header.primary |= IPC_GLB_TYPE(IPC_MOD_INIT_INSTANCE);
794 	header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
795 	header.primary |= IPC_MOD_ID(msg->module_id);
796 
797 	header.extension = IPC_CORE_ID(msg->core_id);
798 	header.extension |= IPC_PPL_INSTANCE_ID(msg->ppl_instance_id);
799 	header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size);
800 	header.extension |= IPC_DOMAIN(msg->domain);
801 
802 	dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
803 			 header.primary, header.extension);
804 	ret = sst_ipc_tx_message_wait(ipc, *ipc_header, param_data,
805 			msg->param_data_size, NULL, 0);
806 
807 	if (ret < 0) {
808 		dev_err(ipc->dev, "ipc: init instance failed\n");
809 		return ret;
810 	}
811 
812 	return ret;
813 }
814 EXPORT_SYMBOL_GPL(skl_ipc_init_instance);
815 
816 int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc,
817 		struct skl_ipc_bind_unbind_msg *msg)
818 {
819 	struct skl_ipc_header header = {0};
820 	u64 *ipc_header = (u64 *)(&header);
821 	u8 bind_unbind = msg->bind ? IPC_MOD_BIND : IPC_MOD_UNBIND;
822 	int ret;
823 
824 	header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
825 	header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
826 	header.primary |= IPC_GLB_TYPE(bind_unbind);
827 	header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
828 	header.primary |= IPC_MOD_ID(msg->module_id);
829 
830 	header.extension = IPC_DST_MOD_ID(msg->dst_module_id);
831 	header.extension |= IPC_DST_MOD_INSTANCE_ID(msg->dst_instance_id);
832 	header.extension |= IPC_DST_QUEUE(msg->dst_queue);
833 	header.extension |= IPC_SRC_QUEUE(msg->src_queue);
834 
835 	dev_dbg(ipc->dev, "In %s hdr=%x ext=%x\n", __func__, header.primary,
836 			 header.extension);
837 	ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
838 	if (ret < 0) {
839 		dev_err(ipc->dev, "ipc: bind/unbind failed\n");
840 		return ret;
841 	}
842 
843 	return ret;
844 }
845 EXPORT_SYMBOL_GPL(skl_ipc_bind_unbind);
846 
847 /*
848  * In order to load a module we need to send IPC to initiate that. DMA will
849  * performed to load the module memory. The FW supports multiple module load
850  * at single shot, so we can send IPC with N modules represented by
851  * module_cnt
852  */
853 int skl_ipc_load_modules(struct sst_generic_ipc *ipc,
854 				u8 module_cnt, void *data)
855 {
856 	struct skl_ipc_header header = {0};
857 	u64 *ipc_header = (u64 *)(&header);
858 	int ret;
859 
860 	header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
861 	header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
862 	header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_MULTIPLE_MODS);
863 	header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
864 
865 	ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, data,
866 				(sizeof(u16) * module_cnt));
867 	if (ret < 0)
868 		dev_err(ipc->dev, "ipc: load modules failed :%d\n", ret);
869 
870 	return ret;
871 }
872 EXPORT_SYMBOL_GPL(skl_ipc_load_modules);
873 
874 int skl_ipc_unload_modules(struct sst_generic_ipc *ipc, u8 module_cnt,
875 							void *data)
876 {
877 	struct skl_ipc_header header = {0};
878 	u64 *ipc_header = (u64 *)(&header);
879 	int ret;
880 
881 	header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
882 	header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
883 	header.primary |= IPC_GLB_TYPE(IPC_GLB_UNLOAD_MULTIPLE_MODS);
884 	header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
885 
886 	ret = sst_ipc_tx_message_wait(ipc, *ipc_header, data,
887 				(sizeof(u16) * module_cnt), NULL, 0);
888 	if (ret < 0)
889 		dev_err(ipc->dev, "ipc: unload modules failed :%d\n", ret);
890 
891 	return ret;
892 }
893 EXPORT_SYMBOL_GPL(skl_ipc_unload_modules);
894 
895 int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
896 		struct skl_ipc_large_config_msg *msg, u32 *param)
897 {
898 	struct skl_ipc_header header = {0};
899 	u64 *ipc_header = (u64 *)(&header);
900 	int ret = 0;
901 	size_t sz_remaining, tx_size, data_offset;
902 
903 	header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
904 	header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
905 	header.primary |= IPC_GLB_TYPE(IPC_MOD_LARGE_CONFIG_SET);
906 	header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
907 	header.primary |= IPC_MOD_ID(msg->module_id);
908 
909 	header.extension = IPC_DATA_OFFSET_SZ(msg->param_data_size);
910 	header.extension |= IPC_LARGE_PARAM_ID(msg->large_param_id);
911 	header.extension |= IPC_FINAL_BLOCK(0);
912 	header.extension |= IPC_INITIAL_BLOCK(1);
913 
914 	sz_remaining = msg->param_data_size;
915 	data_offset = 0;
916 	while (sz_remaining != 0) {
917 		tx_size = sz_remaining > SKL_ADSP_W1_SZ
918 				? SKL_ADSP_W1_SZ : sz_remaining;
919 		if (tx_size == sz_remaining)
920 			header.extension |= IPC_FINAL_BLOCK(1);
921 
922 		dev_dbg(ipc->dev, "In %s primary=%#x ext=%#x\n", __func__,
923 			header.primary, header.extension);
924 		dev_dbg(ipc->dev, "transmitting offset: %#x, size: %#x\n",
925 			(unsigned)data_offset, (unsigned)tx_size);
926 		ret = sst_ipc_tx_message_wait(ipc, *ipc_header,
927 					  ((char *)param) + data_offset,
928 					  tx_size, NULL, 0);
929 		if (ret < 0) {
930 			dev_err(ipc->dev,
931 				"ipc: set large config fail, err: %d\n", ret);
932 			return ret;
933 		}
934 		sz_remaining -= tx_size;
935 		data_offset = msg->param_data_size - sz_remaining;
936 
937 		/* clear the fields */
938 		header.extension &= IPC_INITIAL_BLOCK_CLEAR;
939 		header.extension &= IPC_DATA_OFFSET_SZ_CLEAR;
940 		/* fill the fields */
941 		header.extension |= IPC_INITIAL_BLOCK(0);
942 		header.extension |= IPC_DATA_OFFSET_SZ(data_offset);
943 	}
944 
945 	return ret;
946 }
947 EXPORT_SYMBOL_GPL(skl_ipc_set_large_config);
948 
949 int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
950 		struct skl_ipc_large_config_msg *msg, u32 *param)
951 {
952 	struct skl_ipc_header header = {0};
953 	u64 *ipc_header = (u64 *)(&header);
954 	int ret = 0;
955 	size_t sz_remaining, rx_size, data_offset;
956 
957 	header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
958 	header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
959 	header.primary |= IPC_GLB_TYPE(IPC_MOD_LARGE_CONFIG_GET);
960 	header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
961 	header.primary |= IPC_MOD_ID(msg->module_id);
962 
963 	header.extension = IPC_DATA_OFFSET_SZ(msg->param_data_size);
964 	header.extension |= IPC_LARGE_PARAM_ID(msg->large_param_id);
965 	header.extension |= IPC_FINAL_BLOCK(1);
966 	header.extension |= IPC_INITIAL_BLOCK(1);
967 
968 	sz_remaining = msg->param_data_size;
969 	data_offset = 0;
970 
971 	while (sz_remaining != 0) {
972 		rx_size = sz_remaining > SKL_ADSP_W1_SZ
973 				? SKL_ADSP_W1_SZ : sz_remaining;
974 		if (rx_size == sz_remaining)
975 			header.extension |= IPC_FINAL_BLOCK(1);
976 
977 		ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0,
978 					      ((char *)param) + data_offset,
979 					      msg->param_data_size);
980 		if (ret < 0) {
981 			dev_err(ipc->dev,
982 				"ipc: get large config fail, err: %d\n", ret);
983 			return ret;
984 		}
985 		sz_remaining -= rx_size;
986 		data_offset = msg->param_data_size - sz_remaining;
987 
988 		/* clear the fields */
989 		header.extension &= IPC_INITIAL_BLOCK_CLEAR;
990 		header.extension &= IPC_DATA_OFFSET_SZ_CLEAR;
991 		/* fill the fields */
992 		header.extension |= IPC_INITIAL_BLOCK(1);
993 		header.extension |= IPC_DATA_OFFSET_SZ(data_offset);
994 	}
995 
996 	return ret;
997 }
998 EXPORT_SYMBOL_GPL(skl_ipc_get_large_config);
999 
1000 int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
1001 				u8 dma_id, u8 table_id, bool wait)
1002 {
1003 	struct skl_ipc_header header = {0};
1004 	u64 *ipc_header = (u64 *)(&header);
1005 	int ret = 0;
1006 
1007 	header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
1008 	header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
1009 	header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_LIBRARY);
1010 	header.primary |= IPC_MOD_INSTANCE_ID(table_id);
1011 	header.primary |= IPC_MOD_ID(dma_id);
1012 
1013 	if (wait)
1014 		ret = sst_ipc_tx_message_wait(ipc, *ipc_header,
1015 					NULL, 0, NULL, 0);
1016 	else
1017 		ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, NULL, 0);
1018 
1019 	if (ret < 0)
1020 		dev_err(ipc->dev, "ipc: load lib failed\n");
1021 
1022 	return ret;
1023 }
1024 EXPORT_SYMBOL_GPL(skl_sst_ipc_load_library);
1025 
1026 int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg)
1027 {
1028 	struct skl_ipc_header header = {0};
1029 	u64 *ipc_header = (u64 *)(&header);
1030 	int ret;
1031 
1032 	header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
1033 	header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
1034 	header.primary |= IPC_GLB_TYPE(IPC_MOD_SET_D0IX);
1035 	header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
1036 	header.primary |= IPC_MOD_ID(msg->module_id);
1037 
1038 	header.extension = IPC_D0IX_WAKE(msg->wake);
1039 	header.extension |= IPC_D0IX_STREAMING(msg->streaming);
1040 
1041 	dev_dbg(ipc->dev, "In %s primary=%x ext=%x\n", __func__,
1042 			header.primary,	header.extension);
1043 
1044 	/*
1045 	 * Use the nopm IPC here as we dont want it checking for D0iX
1046 	 */
1047 	ret = sst_ipc_tx_message_nopm(ipc, *ipc_header, NULL, 0, NULL, 0);
1048 	if (ret < 0)
1049 		dev_err(ipc->dev, "ipc: set d0ix failed, err %d\n", ret);
1050 
1051 	return ret;
1052 }
1053 EXPORT_SYMBOL_GPL(skl_ipc_set_d0ix);
1054