arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / sound / soc / intel / skylake / skl-sst-ipc.c
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->tx.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         list_del(&msg->list);
340 out:
341         return msg;
342
343 }
344
345 int skl_ipc_process_notification(struct sst_generic_ipc *ipc,
346                 struct skl_ipc_header header)
347 {
348         struct skl_dev *skl = container_of(ipc, struct skl_dev, ipc);
349
350         if (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
351                 switch (IPC_GLB_NOTIFY_TYPE(header.primary)) {
352
353                 case IPC_GLB_NOTIFY_UNDERRUN:
354                         dev_err(ipc->dev, "FW Underrun %x\n", header.primary);
355                         break;
356
357                 case IPC_GLB_NOTIFY_RESOURCE_EVENT:
358                         dev_err(ipc->dev, "MCPS Budget Violation: %x\n",
359                                                 header.primary);
360                         break;
361
362                 case IPC_GLB_NOTIFY_FW_READY:
363                         skl->boot_complete = true;
364                         wake_up(&skl->boot_wait);
365                         break;
366
367                 case IPC_GLB_NOTIFY_PHRASE_DETECTED:
368                         dev_dbg(ipc->dev, "***** Phrase Detected **********\n");
369
370                         /*
371                          * Per HW recomendation, After phrase detection,
372                          * clear the CGCTL.MISCBDCGE.
373                          *
374                          * This will be set back on stream closure
375                          */
376                         skl->enable_miscbdcge(ipc->dev, false);
377                         skl->miscbdcg_disabled = true;
378                         break;
379
380                 default:
381                         dev_err(ipc->dev, "ipc: Unhandled error msg=%x\n",
382                                                 header.primary);
383                         break;
384                 }
385         }
386
387         return 0;
388 }
389
390 struct skl_ipc_err_map {
391         const char *msg;
392         enum skl_ipc_glb_reply reply;
393         int err;
394 };
395
396 static struct skl_ipc_err_map skl_err_map[] = {
397         {"DSP out of memory", IPC_GLB_REPLY_OUT_OF_MEMORY, -ENOMEM},
398         {"DSP busy", IPC_GLB_REPLY_BUSY, -EBUSY},
399         {"SCLK already running", IPC_GLB_REPLY_SCLK_ALREADY_RUNNING,
400                         IPC_GLB_REPLY_SCLK_ALREADY_RUNNING},
401         {"MCLK already running", IPC_GLB_REPLY_MCLK_ALREADY_RUNNING,
402                         IPC_GLB_REPLY_MCLK_ALREADY_RUNNING},
403 };
404
405 static int skl_ipc_set_reply_error_code(struct sst_generic_ipc *ipc, u32 reply)
406 {
407         int i;
408
409         for (i = 0; i < ARRAY_SIZE(skl_err_map); i++) {
410                 if (skl_err_map[i].reply == reply)
411                         break;
412         }
413
414         if (i == ARRAY_SIZE(skl_err_map)) {
415                 dev_err(ipc->dev, "ipc FW reply: %d FW Error Code: %u\n",
416                                 reply,
417                                 ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
418                 return -EINVAL;
419         }
420
421         if (skl_err_map[i].err < 0)
422                 dev_err(ipc->dev, "ipc FW reply: %s FW Error Code: %u\n",
423                                 skl_err_map[i].msg,
424                                 ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
425         else
426                 dev_info(ipc->dev, "ipc FW reply: %s FW Error Code: %u\n",
427                                 skl_err_map[i].msg,
428                                 ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
429
430         return skl_err_map[i].err;
431 }
432
433 void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
434                 struct skl_ipc_header header)
435 {
436         struct ipc_message *msg;
437         u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK;
438         u64 *ipc_header = (u64 *)(&header);
439         struct skl_dev *skl = container_of(ipc, struct skl_dev, ipc);
440         unsigned long flags;
441
442         spin_lock_irqsave(&ipc->dsp->spinlock, flags);
443         msg = skl_ipc_reply_get_msg(ipc, *ipc_header);
444         spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
445         if (msg == NULL) {
446                 dev_dbg(ipc->dev, "ipc: rx list is empty\n");
447                 return;
448         }
449
450         msg->rx.header = *ipc_header;
451         /* first process the header */
452         if (reply == IPC_GLB_REPLY_SUCCESS) {
453                 dev_dbg(ipc->dev, "ipc FW reply %x: success\n", header.primary);
454                 /* copy the rx data from the mailbox */
455                 sst_dsp_inbox_read(ipc->dsp, msg->rx.data, msg->rx.size);
456                 switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
457                 case IPC_GLB_LOAD_MULTIPLE_MODS:
458                 case IPC_GLB_LOAD_LIBRARY:
459                         skl->mod_load_complete = true;
460                         skl->mod_load_status = true;
461                         wake_up(&skl->mod_load_wait);
462                         break;
463
464                 default:
465                         break;
466
467                 }
468         } else {
469                 msg->errno = skl_ipc_set_reply_error_code(ipc, reply);
470                 switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
471                 case IPC_GLB_LOAD_MULTIPLE_MODS:
472                 case IPC_GLB_LOAD_LIBRARY:
473                         skl->mod_load_complete = true;
474                         skl->mod_load_status = false;
475                         wake_up(&skl->mod_load_wait);
476                         break;
477
478                 default:
479                         break;
480
481                 }
482         }
483
484         spin_lock_irqsave(&ipc->dsp->spinlock, flags);
485         sst_ipc_tx_msg_reply_complete(ipc, msg);
486         spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
487 }
488
489 irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context)
490 {
491         struct sst_dsp *dsp = context;
492         struct skl_dev *skl = dsp->thread_context;
493         struct sst_generic_ipc *ipc = &skl->ipc;
494         struct skl_ipc_header header = {0};
495         u32 hipcie, hipct, hipcte;
496         int ipc_irq = 0;
497
498         if (dsp->intr_status & SKL_ADSPIS_CL_DMA)
499                 skl_cldma_process_intr(dsp);
500
501         /* Here we handle IPC interrupts only */
502         if (!(dsp->intr_status & SKL_ADSPIS_IPC))
503                 return IRQ_NONE;
504
505         hipcie = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCIE);
506         hipct = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCT);
507         hipcte = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCTE);
508
509         /* reply message from DSP */
510         if (hipcie & SKL_ADSP_REG_HIPCIE_DONE) {
511                 sst_dsp_shim_update_bits(dsp, SKL_ADSP_REG_HIPCCTL,
512                         SKL_ADSP_REG_HIPCCTL_DONE, 0);
513
514                 /* clear DONE bit - tell DSP we have completed the operation */
515                 sst_dsp_shim_update_bits_forced(dsp, SKL_ADSP_REG_HIPCIE,
516                         SKL_ADSP_REG_HIPCIE_DONE, SKL_ADSP_REG_HIPCIE_DONE);
517
518                 ipc_irq = 1;
519
520                 /* unmask Done interrupt */
521                 sst_dsp_shim_update_bits(dsp, SKL_ADSP_REG_HIPCCTL,
522                         SKL_ADSP_REG_HIPCCTL_DONE, SKL_ADSP_REG_HIPCCTL_DONE);
523         }
524
525         /* New message from DSP */
526         if (hipct & SKL_ADSP_REG_HIPCT_BUSY) {
527                 header.primary = hipct;
528                 header.extension = hipcte;
529                 dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x\n",
530                                                 header.primary);
531                 dev_dbg(dsp->dev, "IPC irq: Firmware respond extension:%x\n",
532                                                 header.extension);
533
534                 if (IPC_GLB_NOTIFY_RSP_TYPE(header.primary)) {
535                         /* Handle Immediate reply from DSP Core */
536                         skl_ipc_process_reply(ipc, header);
537                 } else {
538                         dev_dbg(dsp->dev, "IPC irq: Notification from firmware\n");
539                         skl_ipc_process_notification(ipc, header);
540                 }
541                 /* clear  busy interrupt */
542                 sst_dsp_shim_update_bits_forced(dsp, SKL_ADSP_REG_HIPCT,
543                         SKL_ADSP_REG_HIPCT_BUSY, SKL_ADSP_REG_HIPCT_BUSY);
544                 ipc_irq = 1;
545         }
546
547         if (ipc_irq == 0)
548                 return IRQ_NONE;
549
550         skl_ipc_int_enable(dsp);
551
552         /* continue to send any remaining messages... */
553         schedule_work(&ipc->kwork);
554
555         return IRQ_HANDLED;
556 }
557
558 void skl_ipc_int_enable(struct sst_dsp *ctx)
559 {
560         sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_ADSPIC,
561                         SKL_ADSPIC_IPC, SKL_ADSPIC_IPC);
562 }
563
564 void skl_ipc_int_disable(struct sst_dsp *ctx)
565 {
566         sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPIC,
567                         SKL_ADSPIC_IPC, 0);
568 }
569
570 void skl_ipc_op_int_enable(struct sst_dsp *ctx)
571 {
572         /* enable IPC DONE interrupt */
573         sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_HIPCCTL,
574                 SKL_ADSP_REG_HIPCCTL_DONE, SKL_ADSP_REG_HIPCCTL_DONE);
575
576         /* Enable IPC BUSY interrupt */
577         sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_HIPCCTL,
578                 SKL_ADSP_REG_HIPCCTL_BUSY, SKL_ADSP_REG_HIPCCTL_BUSY);
579 }
580
581 void skl_ipc_op_int_disable(struct sst_dsp *ctx)
582 {
583         /* disable IPC DONE interrupt */
584         sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_HIPCCTL,
585                                         SKL_ADSP_REG_HIPCCTL_DONE, 0);
586
587         /* Disable IPC BUSY interrupt */
588         sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_HIPCCTL,
589                                         SKL_ADSP_REG_HIPCCTL_BUSY, 0);
590
591 }
592
593 bool skl_ipc_int_status(struct sst_dsp *ctx)
594 {
595         return sst_dsp_shim_read_unlocked(ctx,
596                         SKL_ADSP_REG_ADSPIS) & SKL_ADSPIS_IPC;
597 }
598
599 int skl_ipc_init(struct device *dev, struct skl_dev *skl)
600 {
601         struct sst_generic_ipc *ipc;
602         int err;
603
604         ipc = &skl->ipc;
605         ipc->dsp = skl->dsp;
606         ipc->dev = dev;
607
608         ipc->tx_data_max_size = SKL_ADSP_W1_SZ;
609         ipc->rx_data_max_size = SKL_ADSP_W0_UP_SZ;
610
611         err = sst_ipc_init(ipc);
612         if (err)
613                 return err;
614
615         ipc->ops.tx_msg = skl_ipc_tx_msg;
616         ipc->ops.tx_data_copy = skl_ipc_tx_data_copy;
617         ipc->ops.is_dsp_busy = skl_ipc_is_dsp_busy;
618
619         return 0;
620 }
621
622 void skl_ipc_free(struct sst_generic_ipc *ipc)
623 {
624         /* Disable IPC DONE interrupt */
625         sst_dsp_shim_update_bits(ipc->dsp, SKL_ADSP_REG_HIPCCTL,
626                 SKL_ADSP_REG_HIPCCTL_DONE, 0);
627
628         /* Disable IPC BUSY interrupt */
629         sst_dsp_shim_update_bits(ipc->dsp, SKL_ADSP_REG_HIPCCTL,
630                 SKL_ADSP_REG_HIPCCTL_BUSY, 0);
631
632         sst_ipc_fini(ipc);
633 }
634
635 int skl_ipc_create_pipeline(struct sst_generic_ipc *ipc,
636                 u16 ppl_mem_size, u8 ppl_type, u8 instance_id, u8 lp_mode)
637 {
638         struct skl_ipc_header header = {0};
639         struct sst_ipc_message request = {0};
640         int ret;
641
642         header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
643         header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
644         header.primary |= IPC_GLB_TYPE(IPC_GLB_CREATE_PPL);
645         header.primary |= IPC_INSTANCE_ID(instance_id);
646         header.primary |= IPC_PPL_TYPE(ppl_type);
647         header.primary |= IPC_PPL_MEM_SIZE(ppl_mem_size);
648
649         header.extension = IPC_PPL_LP_MODE(lp_mode);
650         request.header = *(u64 *)(&header);
651
652         dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
653         ret = sst_ipc_tx_message_wait(ipc, request, NULL);
654         if (ret < 0) {
655                 dev_err(ipc->dev, "ipc: create pipeline fail, err: %d\n", ret);
656                 return ret;
657         }
658
659         return ret;
660 }
661 EXPORT_SYMBOL_GPL(skl_ipc_create_pipeline);
662
663 int skl_ipc_delete_pipeline(struct sst_generic_ipc *ipc, u8 instance_id)
664 {
665         struct skl_ipc_header header = {0};
666         struct sst_ipc_message request = {0};
667         int ret;
668
669         header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
670         header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
671         header.primary |= IPC_GLB_TYPE(IPC_GLB_DELETE_PPL);
672         header.primary |= IPC_INSTANCE_ID(instance_id);
673         request.header = *(u64 *)(&header);
674
675         dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
676         ret = sst_ipc_tx_message_wait(ipc, request, NULL);
677         if (ret < 0) {
678                 dev_err(ipc->dev, "ipc: delete pipeline failed, err %d\n", ret);
679                 return ret;
680         }
681
682         return 0;
683 }
684 EXPORT_SYMBOL_GPL(skl_ipc_delete_pipeline);
685
686 int skl_ipc_set_pipeline_state(struct sst_generic_ipc *ipc,
687                 u8 instance_id, enum skl_ipc_pipeline_state state)
688 {
689         struct skl_ipc_header header = {0};
690         struct sst_ipc_message request = {0};
691         int ret;
692
693         header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
694         header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
695         header.primary |= IPC_GLB_TYPE(IPC_GLB_SET_PPL_STATE);
696         header.primary |= IPC_INSTANCE_ID(instance_id);
697         header.primary |= IPC_PPL_STATE(state);
698         request.header = *(u64 *)(&header);
699
700         dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
701         ret = sst_ipc_tx_message_wait(ipc, request, NULL);
702         if (ret < 0) {
703                 dev_err(ipc->dev, "ipc: set pipeline state failed, err: %d\n", ret);
704                 return ret;
705         }
706         return ret;
707 }
708 EXPORT_SYMBOL_GPL(skl_ipc_set_pipeline_state);
709
710 int
711 skl_ipc_save_pipeline(struct sst_generic_ipc *ipc, u8 instance_id, int dma_id)
712 {
713         struct skl_ipc_header header = {0};
714         struct sst_ipc_message request = {0};
715         int ret;
716
717         header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
718         header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
719         header.primary |= IPC_GLB_TYPE(IPC_GLB_SAVE_PPL);
720         header.primary |= IPC_INSTANCE_ID(instance_id);
721
722         header.extension = IPC_DMA_ID(dma_id);
723         request.header = *(u64 *)(&header);
724
725         dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
726         ret = sst_ipc_tx_message_wait(ipc, request, NULL);
727         if (ret < 0) {
728                 dev_err(ipc->dev, "ipc: save pipeline failed, err: %d\n", ret);
729                 return ret;
730         }
731
732         return ret;
733 }
734 EXPORT_SYMBOL_GPL(skl_ipc_save_pipeline);
735
736 int skl_ipc_restore_pipeline(struct sst_generic_ipc *ipc, u8 instance_id)
737 {
738         struct skl_ipc_header header = {0};
739         struct sst_ipc_message request = {0};
740         int ret;
741
742         header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
743         header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
744         header.primary |= IPC_GLB_TYPE(IPC_GLB_RESTORE_PPL);
745         header.primary |= IPC_INSTANCE_ID(instance_id);
746         request.header = *(u64 *)(&header);
747
748         dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
749         ret = sst_ipc_tx_message_wait(ipc, request, NULL);
750         if (ret < 0) {
751                 dev_err(ipc->dev, "ipc: restore  pipeline failed, err: %d\n", ret);
752                 return ret;
753         }
754
755         return ret;
756 }
757 EXPORT_SYMBOL_GPL(skl_ipc_restore_pipeline);
758
759 int skl_ipc_set_dx(struct sst_generic_ipc *ipc, u8 instance_id,
760                 u16 module_id, struct skl_ipc_dxstate_info *dx)
761 {
762         struct skl_ipc_header header = {0};
763         struct sst_ipc_message request;
764         int ret;
765
766         header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
767         header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
768         header.primary |= IPC_GLB_TYPE(IPC_MOD_SET_DX);
769         header.primary |= IPC_MOD_INSTANCE_ID(instance_id);
770         header.primary |= IPC_MOD_ID(module_id);
771
772         request.header = *(u64 *)(&header);
773         request.data = dx;
774         request.size = sizeof(*dx);
775
776         dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
777                          header.primary, header.extension);
778         ret = sst_ipc_tx_message_wait(ipc, request, NULL);
779         if (ret < 0) {
780                 dev_err(ipc->dev, "ipc: set dx failed, err %d\n", ret);
781                 return ret;
782         }
783
784         return ret;
785 }
786 EXPORT_SYMBOL_GPL(skl_ipc_set_dx);
787
788 int skl_ipc_init_instance(struct sst_generic_ipc *ipc,
789                 struct skl_ipc_init_instance_msg *msg, void *param_data)
790 {
791         struct skl_ipc_header header = {0};
792         struct sst_ipc_message request;
793         int ret;
794         u32 *buffer = (u32 *)param_data;
795          /* param_block_size must be in dwords */
796         u16 param_block_size = msg->param_data_size / sizeof(u32);
797
798         print_hex_dump_debug("Param data:", DUMP_PREFIX_NONE,
799                 16, 4, buffer, param_block_size, false);
800
801         header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
802         header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
803         header.primary |= IPC_GLB_TYPE(IPC_MOD_INIT_INSTANCE);
804         header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
805         header.primary |= IPC_MOD_ID(msg->module_id);
806
807         header.extension = IPC_CORE_ID(msg->core_id);
808         header.extension |= IPC_PPL_INSTANCE_ID(msg->ppl_instance_id);
809         header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size);
810         header.extension |= IPC_DOMAIN(msg->domain);
811
812         request.header = *(u64 *)(&header);
813         request.data = param_data;
814         request.size = msg->param_data_size;
815
816         dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
817                          header.primary, header.extension);
818         ret = sst_ipc_tx_message_wait(ipc, request, NULL);
819
820         if (ret < 0) {
821                 dev_err(ipc->dev, "ipc: init instance failed\n");
822                 return ret;
823         }
824
825         return ret;
826 }
827 EXPORT_SYMBOL_GPL(skl_ipc_init_instance);
828
829 int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc,
830                 struct skl_ipc_bind_unbind_msg *msg)
831 {
832         struct skl_ipc_header header = {0};
833         struct sst_ipc_message request = {0};
834         u8 bind_unbind = msg->bind ? IPC_MOD_BIND : IPC_MOD_UNBIND;
835         int ret;
836
837         header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
838         header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
839         header.primary |= IPC_GLB_TYPE(bind_unbind);
840         header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
841         header.primary |= IPC_MOD_ID(msg->module_id);
842
843         header.extension = IPC_DST_MOD_ID(msg->dst_module_id);
844         header.extension |= IPC_DST_MOD_INSTANCE_ID(msg->dst_instance_id);
845         header.extension |= IPC_DST_QUEUE(msg->dst_queue);
846         header.extension |= IPC_SRC_QUEUE(msg->src_queue);
847         request.header = *(u64 *)(&header);
848
849         dev_dbg(ipc->dev, "In %s hdr=%x ext=%x\n", __func__, header.primary,
850                          header.extension);
851         ret = sst_ipc_tx_message_wait(ipc, request, NULL);
852         if (ret < 0) {
853                 dev_err(ipc->dev, "ipc: bind/unbind failed\n");
854                 return ret;
855         }
856
857         return ret;
858 }
859 EXPORT_SYMBOL_GPL(skl_ipc_bind_unbind);
860
861 /*
862  * In order to load a module we need to send IPC to initiate that. DMA will
863  * performed to load the module memory. The FW supports multiple module load
864  * at single shot, so we can send IPC with N modules represented by
865  * module_cnt
866  */
867 int skl_ipc_load_modules(struct sst_generic_ipc *ipc,
868                                 u8 module_cnt, void *data)
869 {
870         struct skl_ipc_header header = {0};
871         struct sst_ipc_message request;
872         int ret;
873
874         header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
875         header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
876         header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_MULTIPLE_MODS);
877         header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
878
879         request.header = *(u64 *)(&header);
880         request.data = data;
881         request.size = sizeof(u16) * module_cnt;
882
883         ret = sst_ipc_tx_message_nowait(ipc, request);
884         if (ret < 0)
885                 dev_err(ipc->dev, "ipc: load modules failed :%d\n", ret);
886
887         return ret;
888 }
889 EXPORT_SYMBOL_GPL(skl_ipc_load_modules);
890
891 int skl_ipc_unload_modules(struct sst_generic_ipc *ipc, u8 module_cnt,
892                                                         void *data)
893 {
894         struct skl_ipc_header header = {0};
895         struct sst_ipc_message request;
896         int ret;
897
898         header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
899         header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
900         header.primary |= IPC_GLB_TYPE(IPC_GLB_UNLOAD_MULTIPLE_MODS);
901         header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
902
903         request.header = *(u64 *)(&header);
904         request.data = data;
905         request.size = sizeof(u16) * module_cnt;
906
907         ret = sst_ipc_tx_message_wait(ipc, request, NULL);
908         if (ret < 0)
909                 dev_err(ipc->dev, "ipc: unload modules failed :%d\n", ret);
910
911         return ret;
912 }
913 EXPORT_SYMBOL_GPL(skl_ipc_unload_modules);
914
915 int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
916                 struct skl_ipc_large_config_msg *msg, u32 *param)
917 {
918         struct skl_ipc_header header = {0};
919         struct sst_ipc_message request;
920         int ret = 0;
921         size_t sz_remaining, tx_size, data_offset;
922
923         header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
924         header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
925         header.primary |= IPC_GLB_TYPE(IPC_MOD_LARGE_CONFIG_SET);
926         header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
927         header.primary |= IPC_MOD_ID(msg->module_id);
928
929         header.extension = IPC_DATA_OFFSET_SZ(msg->param_data_size);
930         header.extension |= IPC_LARGE_PARAM_ID(msg->large_param_id);
931         header.extension |= IPC_FINAL_BLOCK(0);
932         header.extension |= IPC_INITIAL_BLOCK(1);
933
934         sz_remaining = msg->param_data_size;
935         data_offset = 0;
936         while (sz_remaining != 0) {
937                 tx_size = sz_remaining > SKL_ADSP_W1_SZ
938                                 ? SKL_ADSP_W1_SZ : sz_remaining;
939                 if (tx_size == sz_remaining)
940                         header.extension |= IPC_FINAL_BLOCK(1);
941
942                 dev_dbg(ipc->dev, "In %s primary=%#x ext=%#x\n", __func__,
943                         header.primary, header.extension);
944                 dev_dbg(ipc->dev, "transmitting offset: %#x, size: %#x\n",
945                         (unsigned)data_offset, (unsigned)tx_size);
946
947                 request.header = *(u64 *)(&header);
948                 request.data = ((char *)param) + data_offset;
949                 request.size = tx_size;
950                 ret = sst_ipc_tx_message_wait(ipc, request, NULL);
951                 if (ret < 0) {
952                         dev_err(ipc->dev,
953                                 "ipc: set large config fail, err: %d\n", ret);
954                         return ret;
955                 }
956                 sz_remaining -= tx_size;
957                 data_offset = msg->param_data_size - sz_remaining;
958
959                 /* clear the fields */
960                 header.extension &= IPC_INITIAL_BLOCK_CLEAR;
961                 header.extension &= IPC_DATA_OFFSET_SZ_CLEAR;
962                 /* fill the fields */
963                 header.extension |= IPC_INITIAL_BLOCK(0);
964                 header.extension |= IPC_DATA_OFFSET_SZ(data_offset);
965         }
966
967         return ret;
968 }
969 EXPORT_SYMBOL_GPL(skl_ipc_set_large_config);
970
971 int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
972                 struct skl_ipc_large_config_msg *msg,
973                 u32 **payload, size_t *bytes)
974 {
975         struct skl_ipc_header header = {0};
976         struct sst_ipc_message request, reply = {0};
977         unsigned int *buf;
978         int ret;
979
980         reply.data = kzalloc(SKL_ADSP_W1_SZ, GFP_KERNEL);
981         if (!reply.data)
982                 return -ENOMEM;
983
984         header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
985         header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
986         header.primary |= IPC_GLB_TYPE(IPC_MOD_LARGE_CONFIG_GET);
987         header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
988         header.primary |= IPC_MOD_ID(msg->module_id);
989
990         header.extension = IPC_DATA_OFFSET_SZ(msg->param_data_size);
991         header.extension |= IPC_LARGE_PARAM_ID(msg->large_param_id);
992         header.extension |= IPC_FINAL_BLOCK(1);
993         header.extension |= IPC_INITIAL_BLOCK(1);
994
995         request.header = *(u64 *)&header;
996         request.data = *payload;
997         request.size = *bytes;
998         reply.size = SKL_ADSP_W1_SZ;
999
1000         ret = sst_ipc_tx_message_wait(ipc, request, &reply);
1001         if (ret < 0)
1002                 dev_err(ipc->dev, "ipc: get large config fail, err: %d\n", ret);
1003
1004         reply.size = (reply.header >> 32) & IPC_DATA_OFFSET_SZ_MASK;
1005         buf = krealloc(reply.data, reply.size, GFP_KERNEL);
1006         if (!buf) {
1007                 kfree(reply.data);
1008                 return -ENOMEM;
1009         }
1010         *payload = buf;
1011         *bytes = reply.size;
1012
1013         return ret;
1014 }
1015 EXPORT_SYMBOL_GPL(skl_ipc_get_large_config);
1016
1017 int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
1018                                 u8 dma_id, u8 table_id, bool wait)
1019 {
1020         struct skl_ipc_header header = {0};
1021         struct sst_ipc_message request = {0};
1022         int ret = 0;
1023
1024         header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
1025         header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
1026         header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_LIBRARY);
1027         header.primary |= IPC_MOD_INSTANCE_ID(table_id);
1028         header.primary |= IPC_MOD_ID(dma_id);
1029         request.header = *(u64 *)(&header);
1030
1031         if (wait)
1032                 ret = sst_ipc_tx_message_wait(ipc, request, NULL);
1033         else
1034                 ret = sst_ipc_tx_message_nowait(ipc, request);
1035
1036         if (ret < 0)
1037                 dev_err(ipc->dev, "ipc: load lib failed\n");
1038
1039         return ret;
1040 }
1041 EXPORT_SYMBOL_GPL(skl_sst_ipc_load_library);
1042
1043 int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg)
1044 {
1045         struct skl_ipc_header header = {0};
1046         struct sst_ipc_message request = {0};
1047         int ret;
1048
1049         header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
1050         header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
1051         header.primary |= IPC_GLB_TYPE(IPC_MOD_SET_D0IX);
1052         header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
1053         header.primary |= IPC_MOD_ID(msg->module_id);
1054
1055         header.extension = IPC_D0IX_WAKE(msg->wake);
1056         header.extension |= IPC_D0IX_STREAMING(msg->streaming);
1057         request.header = *(u64 *)(&header);
1058
1059         dev_dbg(ipc->dev, "In %s primary=%x ext=%x\n", __func__,
1060                         header.primary, header.extension);
1061
1062         /*
1063          * Use the nopm IPC here as we dont want it checking for D0iX
1064          */
1065         ret = sst_ipc_tx_message_nopm(ipc, request, NULL);
1066         if (ret < 0)
1067                 dev_err(ipc->dev, "ipc: set d0ix failed, err %d\n", ret);
1068
1069         return ret;
1070 }
1071 EXPORT_SYMBOL_GPL(skl_ipc_set_d0ix);