arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / sound / soc / intel / avs / messages.c
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 "avs.h"
11 #include "messages.h"
12
13 #define AVS_CL_TIMEOUT_MS       5000
14
15 int avs_ipc_set_boot_config(struct avs_dev *adev, u32 dma_id, u32 purge)
16 {
17         union avs_global_msg msg = AVS_GLOBAL_REQUEST(ROM_CONTROL);
18         struct avs_ipc_msg request = {{0}};
19
20         msg.boot_cfg.rom_ctrl_msg_type = AVS_ROM_SET_BOOT_CONFIG;
21         msg.boot_cfg.dma_id = dma_id;
22         msg.boot_cfg.purge_request = purge;
23         request.header = msg.val;
24
25         return avs_dsp_send_rom_msg(adev, &request, "set boot config");
26 }
27
28 int avs_ipc_load_modules(struct avs_dev *adev, u16 *mod_ids, u32 num_mod_ids)
29 {
30         union avs_global_msg msg = AVS_GLOBAL_REQUEST(LOAD_MULTIPLE_MODULES);
31         struct avs_ipc_msg request;
32
33         msg.load_multi_mods.mod_cnt = num_mod_ids;
34         request.header = msg.val;
35         request.data = mod_ids;
36         request.size = sizeof(*mod_ids) * num_mod_ids;
37
38         return avs_dsp_send_msg_timeout(adev, &request, NULL, AVS_CL_TIMEOUT_MS,
39                                         "load multiple modules");
40 }
41
42 int avs_ipc_unload_modules(struct avs_dev *adev, u16 *mod_ids, u32 num_mod_ids)
43 {
44         union avs_global_msg msg = AVS_GLOBAL_REQUEST(UNLOAD_MULTIPLE_MODULES);
45         struct avs_ipc_msg request;
46
47         msg.load_multi_mods.mod_cnt = num_mod_ids;
48         request.header = msg.val;
49         request.data = mod_ids;
50         request.size = sizeof(*mod_ids) * num_mod_ids;
51
52         return avs_dsp_send_msg(adev, &request, NULL, "unload multiple modules");
53 }
54
55 int avs_ipc_load_library(struct avs_dev *adev, u32 dma_id, u32 lib_id)
56 {
57         union avs_global_msg msg = AVS_GLOBAL_REQUEST(LOAD_LIBRARY);
58         struct avs_ipc_msg request = {{0}};
59
60         msg.load_lib.dma_id = dma_id;
61         msg.load_lib.lib_id = lib_id;
62         request.header = msg.val;
63
64         return avs_dsp_send_msg_timeout(adev, &request, NULL, AVS_CL_TIMEOUT_MS, "load library");
65 }
66
67 int avs_ipc_create_pipeline(struct avs_dev *adev, u16 req_size, u8 priority,
68                             u8 instance_id, bool lp, u16 attributes)
69 {
70         union avs_global_msg msg = AVS_GLOBAL_REQUEST(CREATE_PIPELINE);
71         struct avs_ipc_msg request = {{0}};
72
73         msg.create_ppl.ppl_mem_size = req_size;
74         msg.create_ppl.ppl_priority = priority;
75         msg.create_ppl.instance_id = instance_id;
76         msg.ext.create_ppl.lp = lp;
77         msg.ext.create_ppl.attributes = attributes;
78         request.header = msg.val;
79
80         return avs_dsp_send_msg(adev, &request, NULL, "create pipeline");
81 }
82
83 int avs_ipc_delete_pipeline(struct avs_dev *adev, u8 instance_id)
84 {
85         union avs_global_msg msg = AVS_GLOBAL_REQUEST(DELETE_PIPELINE);
86         struct avs_ipc_msg request = {{0}};
87
88         msg.ppl.instance_id = instance_id;
89         request.header = msg.val;
90
91         return avs_dsp_send_msg(adev, &request, NULL, "delete pipeline");
92 }
93
94 int avs_ipc_set_pipeline_state(struct avs_dev *adev, u8 instance_id,
95                                enum avs_pipeline_state state)
96 {
97         union avs_global_msg msg = AVS_GLOBAL_REQUEST(SET_PIPELINE_STATE);
98         struct avs_ipc_msg request = {{0}};
99
100         msg.set_ppl_state.ppl_id = instance_id;
101         msg.set_ppl_state.state = state;
102         request.header = msg.val;
103
104         return avs_dsp_send_msg(adev, &request, NULL, "set pipeline state");
105 }
106
107 int avs_ipc_get_pipeline_state(struct avs_dev *adev, u8 instance_id,
108                                enum avs_pipeline_state *state)
109 {
110         union avs_global_msg msg = AVS_GLOBAL_REQUEST(GET_PIPELINE_STATE);
111         struct avs_ipc_msg request = {{0}};
112         struct avs_ipc_msg reply = {{0}};
113         int ret;
114
115         msg.get_ppl_state.ppl_id = instance_id;
116         request.header = msg.val;
117
118         ret = avs_dsp_send_msg(adev, &request, &reply, "get pipeline state");
119         if (!ret)
120                 *state = reply.rsp.ext.get_ppl_state.state;
121         return ret;
122 }
123
124 /*
125  * avs_ipc_init_instance - Initialize module instance
126  *
127  * @adev: Driver context
128  * @module_id: Module-type id
129  * @instance_id: Unique module instance id
130  * @ppl_id: Parent pipeline id
131  * @core_id: DSP core to allocate module on
132  * @domain: Processing domain (low latency or data processing)
133  * @param: Module-type specific configuration
134  * @param_size: Size of @param in bytes
135  *
136  * Argument verification, as well as pipeline state checks are done by the
137  * firmware.
138  *
139  * Note: @ppl_id and @core_id are independent of each other as single pipeline
140  * can be composed of module instances located on different DSP cores.
141  */
142 int avs_ipc_init_instance(struct avs_dev *adev, u16 module_id, u8 instance_id,
143                           u8 ppl_id, u8 core_id, u8 domain,
144                           void *param, u32 param_size)
145 {
146         union avs_module_msg msg = AVS_MODULE_REQUEST(INIT_INSTANCE);
147         struct avs_ipc_msg request;
148
149         msg.module_id = module_id;
150         msg.instance_id = instance_id;
151         /* firmware expects size provided in dwords */
152         msg.ext.init_instance.param_block_size = DIV_ROUND_UP(param_size, sizeof(u32));
153         msg.ext.init_instance.ppl_instance_id = ppl_id;
154         msg.ext.init_instance.core_id = core_id;
155         msg.ext.init_instance.proc_domain = domain;
156
157         request.header = msg.val;
158         request.data = param;
159         request.size = param_size;
160
161         return avs_dsp_send_msg(adev, &request, NULL, "init instance");
162 }
163
164 /*
165  * avs_ipc_delete_instance - Delete module instance
166  *
167  * @adev: Driver context
168  * @module_id: Module-type id
169  * @instance_id: Unique module instance id
170  *
171  * Argument verification, as well as pipeline state checks are done by the
172  * firmware.
173  *
174  * Note: only standalone modules i.e. without a parent pipeline shall be
175  * deleted using this IPC message. In all other cases, pipeline owning the
176  * modules performs cleanup automatically when it is deleted.
177  */
178 int avs_ipc_delete_instance(struct avs_dev *adev, u16 module_id, u8 instance_id)
179 {
180         union avs_module_msg msg = AVS_MODULE_REQUEST(DELETE_INSTANCE);
181         struct avs_ipc_msg request = {{0}};
182
183         msg.module_id = module_id;
184         msg.instance_id = instance_id;
185         request.header = msg.val;
186
187         return avs_dsp_send_msg(adev, &request, NULL, "delete instance");
188 }
189
190 /*
191  * avs_ipc_bind - Bind two module instances
192  *
193  * @adev: Driver context
194  * @module_id: Source module-type id
195  * @instance_id: Source module instance id
196  * @dst_module_id: Sink module-type id
197  * @dst_instance_id: Sink module instance id
198  * @dst_queue: Sink module pin to bind @src_queue with
199  * @src_queue: Source module pin to bind @dst_queue with
200  */
201 int avs_ipc_bind(struct avs_dev *adev, u16 module_id, u8 instance_id,
202                  u16 dst_module_id, u8 dst_instance_id,
203                  u8 dst_queue, u8 src_queue)
204 {
205         union avs_module_msg msg = AVS_MODULE_REQUEST(BIND);
206         struct avs_ipc_msg request = {{0}};
207
208         msg.module_id = module_id;
209         msg.instance_id = instance_id;
210         msg.ext.bind_unbind.dst_module_id = dst_module_id;
211         msg.ext.bind_unbind.dst_instance_id = dst_instance_id;
212         msg.ext.bind_unbind.dst_queue = dst_queue;
213         msg.ext.bind_unbind.src_queue = src_queue;
214         request.header = msg.val;
215
216         return avs_dsp_send_msg(adev, &request, NULL, "bind modules");
217 }
218
219 /*
220  * avs_ipc_unbind - Unbind two module instances
221  *
222  * @adev: Driver context
223  * @module_id: Source module-type id
224  * @instance_id: Source module instance id
225  * @dst_module_id: Sink module-type id
226  * @dst_instance_id: Sink module instance id
227  * @dst_queue: Sink module pin to unbind @src_queue from
228  * @src_queue: Source module pin to unbind @dst_queue from
229  */
230 int avs_ipc_unbind(struct avs_dev *adev, u16 module_id, u8 instance_id,
231                    u16 dst_module_id, u8 dst_instance_id,
232                    u8 dst_queue, u8 src_queue)
233 {
234         union avs_module_msg msg = AVS_MODULE_REQUEST(UNBIND);
235         struct avs_ipc_msg request = {{0}};
236
237         msg.module_id = module_id;
238         msg.instance_id = instance_id;
239         msg.ext.bind_unbind.dst_module_id = dst_module_id;
240         msg.ext.bind_unbind.dst_instance_id = dst_instance_id;
241         msg.ext.bind_unbind.dst_queue = dst_queue;
242         msg.ext.bind_unbind.src_queue = src_queue;
243         request.header = msg.val;
244
245         return avs_dsp_send_msg(adev, &request, NULL, "unbind modules");
246 }
247
248 static int __avs_ipc_set_large_config(struct avs_dev *adev, u16 module_id, u8 instance_id,
249                                       u8 param_id, bool init_block, bool final_block,
250                                       u8 *request_data, size_t request_size, size_t off_size)
251 {
252         union avs_module_msg msg = AVS_MODULE_REQUEST(LARGE_CONFIG_SET);
253         struct avs_ipc_msg request;
254
255         msg.module_id = module_id;
256         msg.instance_id = instance_id;
257         msg.ext.large_config.data_off_size = off_size;
258         msg.ext.large_config.large_param_id = param_id;
259         msg.ext.large_config.final_block = final_block;
260         msg.ext.large_config.init_block = init_block;
261
262         request.header = msg.val;
263         request.data = request_data;
264         request.size = request_size;
265
266         return avs_dsp_send_msg(adev, &request, NULL, "large config set");
267 }
268
269 int avs_ipc_set_large_config(struct avs_dev *adev, u16 module_id,
270                              u8 instance_id, u8 param_id,
271                              u8 *request, size_t request_size)
272 {
273         size_t remaining, tx_size;
274         bool final;
275         int ret;
276
277         remaining = request_size;
278         tx_size = min_t(size_t, AVS_MAILBOX_SIZE, remaining);
279         final = (tx_size == remaining);
280
281         /* Initial request states total payload size. */
282         ret = __avs_ipc_set_large_config(adev, module_id, instance_id,
283                                          param_id, 1, final, request, tx_size,
284                                          request_size);
285         if (ret)
286                 return ret;
287
288         remaining -= tx_size;
289
290         /* Loop the rest only when payload exceeds mailbox's size. */
291         while (remaining) {
292                 size_t offset;
293
294                 offset = request_size - remaining;
295                 tx_size = min_t(size_t, AVS_MAILBOX_SIZE, remaining);
296                 final = (tx_size == remaining);
297
298                 ret = __avs_ipc_set_large_config(adev, module_id, instance_id,
299                                                  param_id, 0, final,
300                                                  request + offset, tx_size,
301                                                  offset);
302                 if (ret)
303                         return ret;
304
305                 remaining -= tx_size;
306         }
307
308         return 0;
309 }
310
311 int avs_ipc_get_large_config(struct avs_dev *adev, u16 module_id, u8 instance_id,
312                              u8 param_id, u8 *request_data, size_t request_size,
313                              u8 **reply_data, size_t *reply_size)
314 {
315         union avs_module_msg msg = AVS_MODULE_REQUEST(LARGE_CONFIG_GET);
316         struct avs_ipc_msg request;
317         struct avs_ipc_msg reply = {{0}};
318         void *buf;
319         int ret;
320
321         reply.data = kzalloc(AVS_MAILBOX_SIZE, GFP_KERNEL);
322         if (!reply.data)
323                 return -ENOMEM;
324
325         msg.module_id = module_id;
326         msg.instance_id = instance_id;
327         msg.ext.large_config.data_off_size = request_size;
328         msg.ext.large_config.large_param_id = param_id;
329         /* final_block is always 0 on request. Updated by fw on reply. */
330         msg.ext.large_config.final_block = 0;
331         msg.ext.large_config.init_block = 1;
332
333         request.header = msg.val;
334         request.data = request_data;
335         request.size = request_size;
336         reply.size = AVS_MAILBOX_SIZE;
337
338         ret = avs_dsp_send_msg(adev, &request, &reply, "large config get");
339         if (ret) {
340                 kfree(reply.data);
341                 return ret;
342         }
343
344         buf = krealloc(reply.data, reply.size, GFP_KERNEL);
345         if (!buf) {
346                 kfree(reply.data);
347                 return -ENOMEM;
348         }
349
350         *reply_data = buf;
351         *reply_size = reply.size;
352
353         return 0;
354 }
355
356 int avs_ipc_set_dx(struct avs_dev *adev, u32 core_mask, bool powerup)
357 {
358         union avs_module_msg msg = AVS_MODULE_REQUEST(SET_DX);
359         struct avs_ipc_msg request;
360         struct avs_dxstate_info dx;
361
362         dx.core_mask = core_mask;
363         dx.dx_mask = powerup ? core_mask : 0;
364         request.header = msg.val;
365         request.data = &dx;
366         request.size = sizeof(dx);
367
368         return avs_dsp_send_pm_msg(adev, &request, NULL, true, "set dx");
369 }
370
371 /*
372  * avs_ipc_set_d0ix - Set power gating policy (entering D0IX substates)
373  *
374  * @enable_pg: Whether to enable or disable power gating
375  * @streaming: Whether a stream is running when transitioning
376  */
377 int avs_ipc_set_d0ix(struct avs_dev *adev, bool enable_pg, bool streaming)
378 {
379         union avs_module_msg msg = AVS_MODULE_REQUEST(SET_D0IX);
380         struct avs_ipc_msg request = {{0}};
381
382         msg.ext.set_d0ix.wake = enable_pg;
383         msg.ext.set_d0ix.streaming = streaming;
384
385         request.header = msg.val;
386
387         return avs_dsp_send_pm_msg(adev, &request, NULL, false, "set d0ix");
388 }
389
390 int avs_ipc_get_fw_config(struct avs_dev *adev, struct avs_fw_cfg *cfg)
391 {
392         struct avs_tlv *tlv;
393         size_t payload_size;
394         size_t offset = 0;
395         u8 *payload;
396         int ret;
397
398         ret = avs_ipc_get_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID,
399                                        AVS_BASEFW_FIRMWARE_CONFIG, NULL, 0,
400                                        &payload, &payload_size);
401         if (ret)
402                 return ret;
403         /* Non-zero payload expected for FIRMWARE_CONFIG. */
404         if (!payload_size)
405                 return -EREMOTEIO;
406
407         while (offset < payload_size) {
408                 tlv = (struct avs_tlv *)(payload + offset);
409
410                 switch (tlv->type) {
411                 case AVS_FW_CFG_FW_VERSION:
412                         memcpy(&cfg->fw_version, tlv->value, sizeof(cfg->fw_version));
413                         break;
414
415                 case AVS_FW_CFG_MEMORY_RECLAIMED:
416                         cfg->memory_reclaimed = *tlv->value;
417                         break;
418
419                 case AVS_FW_CFG_SLOW_CLOCK_FREQ_HZ:
420                         cfg->slow_clock_freq_hz = *tlv->value;
421                         break;
422
423                 case AVS_FW_CFG_FAST_CLOCK_FREQ_HZ:
424                         cfg->fast_clock_freq_hz = *tlv->value;
425                         break;
426
427                 case AVS_FW_CFG_ALH_SUPPORT_LEVEL:
428                         cfg->alh_support = *tlv->value;
429                         break;
430
431                 case AVS_FW_CFG_IPC_DL_MAILBOX_BYTES:
432                         cfg->ipc_dl_mailbox_bytes = *tlv->value;
433                         break;
434
435                 case AVS_FW_CFG_IPC_UL_MAILBOX_BYTES:
436                         cfg->ipc_ul_mailbox_bytes = *tlv->value;
437                         break;
438
439                 case AVS_FW_CFG_TRACE_LOG_BYTES:
440                         cfg->trace_log_bytes = *tlv->value;
441                         break;
442
443                 case AVS_FW_CFG_MAX_PPL_COUNT:
444                         cfg->max_ppl_count = *tlv->value;
445                         break;
446
447                 case AVS_FW_CFG_MAX_ASTATE_COUNT:
448                         cfg->max_astate_count = *tlv->value;
449                         break;
450
451                 case AVS_FW_CFG_MAX_MODULE_PIN_COUNT:
452                         cfg->max_module_pin_count = *tlv->value;
453                         break;
454
455                 case AVS_FW_CFG_MODULES_COUNT:
456                         cfg->modules_count = *tlv->value;
457                         break;
458
459                 case AVS_FW_CFG_MAX_MOD_INST_COUNT:
460                         cfg->max_mod_inst_count = *tlv->value;
461                         break;
462
463                 case AVS_FW_CFG_MAX_LL_TASKS_PER_PRI_COUNT:
464                         cfg->max_ll_tasks_per_pri_count = *tlv->value;
465                         break;
466
467                 case AVS_FW_CFG_LL_PRI_COUNT:
468                         cfg->ll_pri_count = *tlv->value;
469                         break;
470
471                 case AVS_FW_CFG_MAX_DP_TASKS_COUNT:
472                         cfg->max_dp_tasks_count = *tlv->value;
473                         break;
474
475                 case AVS_FW_CFG_MAX_LIBS_COUNT:
476                         cfg->max_libs_count = *tlv->value;
477                         break;
478
479                 case AVS_FW_CFG_XTAL_FREQ_HZ:
480                         cfg->xtal_freq_hz = *tlv->value;
481                         break;
482
483                 case AVS_FW_CFG_POWER_GATING_POLICY:
484                         cfg->power_gating_policy = *tlv->value;
485                         break;
486
487                 /* Known but not useful to us. */
488                 case AVS_FW_CFG_DMA_BUFFER_CONFIG:
489                 case AVS_FW_CFG_SCHEDULER_CONFIG:
490                 case AVS_FW_CFG_CLOCKS_CONFIG:
491                 case AVS_FW_CFG_RESERVED:
492                         break;
493
494                 default:
495                         dev_info(adev->dev, "Unrecognized fw param: %d\n", tlv->type);
496                         break;
497                 }
498
499                 offset += sizeof(*tlv) + tlv->length;
500         }
501
502         /* No longer needed, free it as it's owned by the get_large_config() caller. */
503         kfree(payload);
504         return ret;
505 }
506
507 int avs_ipc_get_hw_config(struct avs_dev *adev, struct avs_hw_cfg *cfg)
508 {
509         struct avs_tlv *tlv;
510         size_t payload_size;
511         size_t size, offset = 0;
512         u8 *payload;
513         int ret;
514
515         ret = avs_ipc_get_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID,
516                                        AVS_BASEFW_HARDWARE_CONFIG, NULL, 0,
517                                        &payload, &payload_size);
518         if (ret)
519                 return ret;
520         /* Non-zero payload expected for HARDWARE_CONFIG. */
521         if (!payload_size)
522                 return -EREMOTEIO;
523
524         while (offset < payload_size) {
525                 tlv = (struct avs_tlv *)(payload + offset);
526
527                 switch (tlv->type) {
528                 case AVS_HW_CFG_AVS_VER:
529                         cfg->avs_version = *tlv->value;
530                         break;
531
532                 case AVS_HW_CFG_DSP_CORES:
533                         cfg->dsp_cores = *tlv->value;
534                         break;
535
536                 case AVS_HW_CFG_MEM_PAGE_BYTES:
537                         cfg->mem_page_bytes = *tlv->value;
538                         break;
539
540                 case AVS_HW_CFG_TOTAL_PHYS_MEM_PAGES:
541                         cfg->total_phys_mem_pages = *tlv->value;
542                         break;
543
544                 case AVS_HW_CFG_I2S_CAPS:
545                         cfg->i2s_caps.i2s_version = tlv->value[0];
546                         size = tlv->value[1];
547                         cfg->i2s_caps.ctrl_count = size;
548                         if (!size)
549                                 break;
550
551                         /* Multiply to get entire array size. */
552                         size *= sizeof(*cfg->i2s_caps.ctrl_base_addr);
553                         cfg->i2s_caps.ctrl_base_addr = devm_kmemdup(adev->dev,
554                                                                     &tlv->value[2],
555                                                                     size, GFP_KERNEL);
556                         if (!cfg->i2s_caps.ctrl_base_addr) {
557                                 ret = -ENOMEM;
558                                 goto exit;
559                         }
560                         break;
561
562                 case AVS_HW_CFG_GATEWAY_COUNT:
563                         cfg->gateway_count = *tlv->value;
564                         break;
565
566                 case AVS_HW_CFG_HP_EBB_COUNT:
567                         cfg->hp_ebb_count = *tlv->value;
568                         break;
569
570                 case AVS_HW_CFG_LP_EBB_COUNT:
571                         cfg->lp_ebb_count = *tlv->value;
572                         break;
573
574                 case AVS_HW_CFG_EBB_SIZE_BYTES:
575                         cfg->ebb_size_bytes = *tlv->value;
576                         break;
577
578                 case AVS_HW_CFG_GPDMA_CAPS:
579                         break;
580
581                 default:
582                         dev_info(adev->dev, "Unrecognized hw config: %d\n", tlv->type);
583                         break;
584                 }
585
586                 offset += sizeof(*tlv) + tlv->length;
587         }
588
589 exit:
590         /* No longer needed, free it as it's owned by the get_large_config() caller. */
591         kfree(payload);
592         return ret;
593 }
594
595 int avs_ipc_get_modules_info(struct avs_dev *adev, struct avs_mods_info **info)
596 {
597         size_t payload_size;
598         u8 *payload;
599         int ret;
600
601         ret = avs_ipc_get_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID,
602                                        AVS_BASEFW_MODULES_INFO, NULL, 0,
603                                        &payload, &payload_size);
604         if (ret)
605                 return ret;
606         /* Non-zero payload expected for MODULES_INFO. */
607         if (!payload_size)
608                 return -EREMOTEIO;
609
610         *info = (struct avs_mods_info *)payload;
611         return 0;
612 }
613
614 int avs_ipc_copier_set_sink_format(struct avs_dev *adev, u16 module_id,
615                                    u8 instance_id, u32 sink_id,
616                                    const struct avs_audio_format *src_fmt,
617                                    const struct avs_audio_format *sink_fmt)
618 {
619         struct avs_copier_sink_format cpr_fmt;
620
621         cpr_fmt.sink_id = sink_id;
622         /* Firmware expects driver to resend copier's input format. */
623         cpr_fmt.src_fmt = *src_fmt;
624         cpr_fmt.sink_fmt = *sink_fmt;
625
626         return avs_ipc_set_large_config(adev, module_id, instance_id,
627                                         AVS_COPIER_SET_SINK_FORMAT,
628                                         (u8 *)&cpr_fmt, sizeof(cpr_fmt));
629 }
630
631 int avs_ipc_peakvol_set_volume(struct avs_dev *adev, u16 module_id, u8 instance_id,
632                                struct avs_volume_cfg *vol)
633 {
634         return avs_ipc_set_large_config(adev, module_id, instance_id, AVS_PEAKVOL_VOLUME, (u8 *)vol,
635                                         sizeof(*vol));
636 }
637
638 int avs_ipc_peakvol_get_volume(struct avs_dev *adev, u16 module_id, u8 instance_id,
639                                struct avs_volume_cfg **vols, size_t *num_vols)
640 {
641         size_t payload_size;
642         u8 *payload;
643         int ret;
644
645         ret = avs_ipc_get_large_config(adev, module_id, instance_id, AVS_PEAKVOL_VOLUME, NULL, 0,
646                                        &payload, &payload_size);
647         if (ret)
648                 return ret;
649
650         /* Non-zero payload expected for PEAKVOL_VOLUME. */
651         if (!payload_size)
652                 return -EREMOTEIO;
653
654         *vols = (struct avs_volume_cfg *)payload;
655         *num_vols = payload_size / sizeof(**vols);
656
657         return 0;
658 }
659
660 #ifdef CONFIG_DEBUG_FS
661 int avs_ipc_set_enable_logs(struct avs_dev *adev, u8 *log_info, size_t size)
662 {
663         return avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID,
664                                         AVS_BASEFW_ENABLE_LOGS, log_info, size);
665 }
666
667 int avs_ipc_set_system_time(struct avs_dev *adev)
668 {
669         struct avs_sys_time sys_time;
670         u64 us;
671
672         /* firmware expects UTC time in micro seconds */
673         us = ktime_to_us(ktime_get());
674         sys_time.val_l = us & UINT_MAX;
675         sys_time.val_u = us >> 32;
676
677         return avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID,
678                                         AVS_BASEFW_SYSTEM_TIME, (u8 *)&sys_time, sizeof(sys_time));
679 }
680
681 int avs_ipc_probe_get_dma(struct avs_dev *adev, struct avs_probe_dma **dmas, size_t *num_dmas)
682 {
683         size_t payload_size;
684         u32 module_id;
685         u8 *payload;
686         int ret;
687
688         module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID);
689
690         ret = avs_ipc_get_large_config(adev, module_id, AVS_PROBE_INST_ID, AVS_PROBE_INJECTION_DMA,
691                                        NULL, 0, &payload, &payload_size);
692         if (ret)
693                 return ret;
694
695         *dmas = (struct avs_probe_dma *)payload;
696         *num_dmas = payload_size / sizeof(**dmas);
697
698         return 0;
699 }
700
701 int avs_ipc_probe_attach_dma(struct avs_dev *adev, struct avs_probe_dma *dmas, size_t num_dmas)
702 {
703         u32 module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID);
704
705         return avs_ipc_set_large_config(adev, module_id, AVS_PROBE_INST_ID, AVS_PROBE_INJECTION_DMA,
706                                         (u8 *)dmas, array_size(sizeof(*dmas), num_dmas));
707 }
708
709 int avs_ipc_probe_detach_dma(struct avs_dev *adev, union avs_connector_node_id *node_ids,
710                              size_t num_node_ids)
711 {
712         u32 module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID);
713
714         return avs_ipc_set_large_config(adev, module_id, AVS_PROBE_INST_ID,
715                                         AVS_PROBE_INJECTION_DMA_DETACH, (u8 *)node_ids,
716                                         array_size(sizeof(*node_ids), num_node_ids));
717 }
718
719 int avs_ipc_probe_get_points(struct avs_dev *adev, struct avs_probe_point_desc **descs,
720                              size_t *num_descs)
721 {
722         size_t payload_size;
723         u32 module_id;
724         u8 *payload;
725         int ret;
726
727         module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID);
728
729         ret = avs_ipc_get_large_config(adev, module_id, AVS_PROBE_INST_ID, AVS_PROBE_POINTS, NULL,
730                                        0, &payload, &payload_size);
731         if (ret)
732                 return ret;
733
734         *descs = (struct avs_probe_point_desc *)payload;
735         *num_descs = payload_size / sizeof(**descs);
736
737         return 0;
738 }
739
740 int avs_ipc_probe_connect_points(struct avs_dev *adev, struct avs_probe_point_desc *descs,
741                                  size_t num_descs)
742 {
743         u32 module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID);
744
745         return avs_ipc_set_large_config(adev, module_id, AVS_PROBE_INST_ID, AVS_PROBE_POINTS,
746                                         (u8 *)descs, array_size(sizeof(*descs), num_descs));
747 }
748
749 int avs_ipc_probe_disconnect_points(struct avs_dev *adev, union avs_probe_point_id *ids,
750                                     size_t num_ids)
751 {
752         u32 module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID);
753
754         return avs_ipc_set_large_config(adev, module_id, AVS_PROBE_INST_ID,
755                                         AVS_PROBE_POINTS_DISCONNECT, (u8 *)ids,
756                                         array_size(sizeof(*ids), num_ids));
757 }
758 #endif