Skip to content

Commit dab8d00

Browse files
crojewsk-intelbroonie
authored andcommitted
ASoC: Intel: avs: Add data probing requests
Data probing is a cAVS firmware functionality that allows for data extraction and injection directly from or to DMA stream. To support it, new functions and types are added. These facilitate communication with the firmware. Total of eight IPCs: - probe module initialization and cleanup - addition and removal of probe points - addition and removal of injection DMAs - dumping list of currently connected probe points or enlisted DMAs Signed-off-by: Cezary Rojewski <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent f7de161 commit dab8d00

File tree

4 files changed

+178
-1
lines changed

4 files changed

+178
-1
lines changed

sound/soc/intel/avs/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ snd-soc-avs-objs += trace.o
1010
CFLAGS_trace.o := -I$(src)
1111

1212
ifneq ($(CONFIG_DEBUG_FS),)
13-
snd-soc-avs-objs += debugfs.o
13+
snd-soc-avs-objs += probes.o debugfs.o
1414
endif
1515

1616
obj-$(CONFIG_SND_SOC_INTEL_AVS) += snd-soc-avs.o

sound/soc/intel/avs/messages.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,4 +722,82 @@ int avs_ipc_set_system_time(struct avs_dev *adev)
722722
return avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID,
723723
AVS_BASEFW_SYSTEM_TIME, (u8 *)&sys_time, sizeof(sys_time));
724724
}
725+
726+
int avs_ipc_probe_get_dma(struct avs_dev *adev, struct avs_probe_dma **dmas, size_t *num_dmas)
727+
{
728+
size_t payload_size;
729+
u32 module_id;
730+
u8 *payload;
731+
int ret;
732+
733+
module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID);
734+
735+
ret = avs_ipc_get_large_config(adev, module_id, AVS_PROBE_INST_ID, AVS_PROBE_INJECTION_DMA,
736+
NULL, 0, &payload, &payload_size);
737+
if (ret)
738+
return ret;
739+
740+
*dmas = (struct avs_probe_dma *)payload;
741+
*num_dmas = payload_size / sizeof(**dmas);
742+
743+
return 0;
744+
}
745+
746+
int avs_ipc_probe_attach_dma(struct avs_dev *adev, struct avs_probe_dma *dmas, size_t num_dmas)
747+
{
748+
u32 module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID);
749+
750+
return avs_ipc_set_large_config(adev, module_id, AVS_PROBE_INST_ID, AVS_PROBE_INJECTION_DMA,
751+
(u8 *)dmas, array_size(sizeof(*dmas), num_dmas));
752+
}
753+
754+
int avs_ipc_probe_detach_dma(struct avs_dev *adev, union avs_connector_node_id *node_ids,
755+
size_t num_node_ids)
756+
{
757+
u32 module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID);
758+
759+
return avs_ipc_set_large_config(adev, module_id, AVS_PROBE_INST_ID,
760+
AVS_PROBE_INJECTION_DMA_DETACH, (u8 *)node_ids,
761+
array_size(sizeof(*node_ids), num_node_ids));
762+
}
763+
764+
int avs_ipc_probe_get_points(struct avs_dev *adev, struct avs_probe_point_desc **descs,
765+
size_t *num_descs)
766+
{
767+
size_t payload_size;
768+
u32 module_id;
769+
u8 *payload;
770+
int ret;
771+
772+
module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID);
773+
774+
ret = avs_ipc_get_large_config(adev, module_id, AVS_PROBE_INST_ID, AVS_PROBE_POINTS, NULL,
775+
0, &payload, &payload_size);
776+
if (ret)
777+
return ret;
778+
779+
*descs = (struct avs_probe_point_desc *)payload;
780+
*num_descs = payload_size / sizeof(**descs);
781+
782+
return 0;
783+
}
784+
785+
int avs_ipc_probe_connect_points(struct avs_dev *adev, struct avs_probe_point_desc *descs,
786+
size_t num_descs)
787+
{
788+
u32 module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID);
789+
790+
return avs_ipc_set_large_config(adev, module_id, AVS_PROBE_INST_ID, AVS_PROBE_POINTS,
791+
(u8 *)descs, array_size(sizeof(*descs), num_descs));
792+
}
793+
794+
int avs_ipc_probe_disconnect_points(struct avs_dev *adev, union avs_probe_point_id *ids,
795+
size_t num_ids)
796+
{
797+
u32 module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID);
798+
799+
return avs_ipc_set_large_config(adev, module_id, AVS_PROBE_INST_ID,
800+
AVS_PROBE_POINTS_DISCONNECT, (u8 *)ids,
801+
array_size(sizeof(*ids), num_ids));
802+
}
725803
#endif

sound/soc/intel/avs/messages.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,4 +802,57 @@ int avs_ipc_copier_set_sink_format(struct avs_dev *adev, u16 module_id,
802802
const struct avs_audio_format *src_fmt,
803803
const struct avs_audio_format *sink_fmt);
804804

805+
#define AVS_PROBE_INST_ID 0
806+
807+
enum avs_probe_runtime_param {
808+
AVS_PROBE_INJECTION_DMA = 1,
809+
AVS_PROBE_INJECTION_DMA_DETACH,
810+
AVS_PROBE_POINTS,
811+
AVS_PROBE_POINTS_DISCONNECT,
812+
};
813+
814+
struct avs_probe_dma {
815+
union avs_connector_node_id node_id;
816+
u32 dma_buffer_size;
817+
} __packed;
818+
819+
enum avs_probe_type {
820+
AVS_PROBE_TYPE_INPUT = 0,
821+
AVS_PROBE_TYPE_OUTPUT,
822+
AVS_PROBE_TYPE_INTERNAL
823+
};
824+
825+
union avs_probe_point_id {
826+
u32 value;
827+
struct {
828+
u32 module_id:16;
829+
u32 instance_id:8;
830+
u32 type:2;
831+
u32 index:6;
832+
} id;
833+
} __packed;
834+
835+
enum avs_connection_purpose {
836+
AVS_CONNECTION_PURPOSE_EXTRACT = 0,
837+
AVS_CONNECTION_PURPOSE_INJECT,
838+
AVS_CONNECTION_PURPOSE_INJECT_REEXTRACT,
839+
};
840+
841+
struct avs_probe_point_desc {
842+
union avs_probe_point_id id;
843+
u32 purpose;
844+
union avs_connector_node_id node_id;
845+
} __packed;
846+
847+
int avs_ipc_probe_get_dma(struct avs_dev *adev, struct avs_probe_dma **dmas, size_t *num_dmas);
848+
int avs_ipc_probe_attach_dma(struct avs_dev *adev, struct avs_probe_dma *dmas, size_t num_dmas);
849+
int avs_ipc_probe_detach_dma(struct avs_dev *adev, union avs_connector_node_id *node_ids,
850+
size_t num_node_ids);
851+
int avs_ipc_probe_get_points(struct avs_dev *adev, struct avs_probe_point_desc **descs,
852+
size_t *num_descs);
853+
int avs_ipc_probe_connect_points(struct avs_dev *adev, struct avs_probe_point_desc *descs,
854+
size_t num_descs);
855+
int avs_ipc_probe_disconnect_points(struct avs_dev *adev, union avs_probe_point_id *ids,
856+
size_t num_ids);
857+
805858
#endif /* __SOUND_SOC_INTEL_AVS_MSGS_H */

sound/soc/intel/avs/probes.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
//
3+
// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
4+
//
5+
// Authors: Cezary Rojewski <[email protected]>
6+
// Amadeusz Slawinski <[email protected]>
7+
//
8+
9+
#include "avs.h"
10+
#include "messages.h"
11+
12+
__maybe_unused
13+
static int avs_dsp_init_probe(struct avs_dev *adev, union avs_connector_node_id node_id,
14+
size_t buffer_size)
15+
16+
{
17+
struct avs_probe_cfg cfg = {{0}};
18+
struct avs_module_entry mentry;
19+
u16 dummy;
20+
21+
avs_get_module_entry(adev, &AVS_PROBE_MOD_UUID, &mentry);
22+
23+
/*
24+
* Probe module uses no cycles, audio data format and input and output
25+
* frame sizes are unused. It is also not owned by any pipeline.
26+
*/
27+
cfg.base.ibs = 1;
28+
/* BSS module descriptor is always segment of index=2. */
29+
cfg.base.is_pages = mentry.segments[2].flags.length;
30+
cfg.gtw_cfg.node_id = node_id;
31+
cfg.gtw_cfg.dma_buffer_size = buffer_size;
32+
33+
return avs_dsp_init_module(adev, mentry.module_id, INVALID_PIPELINE_ID, 0, 0, &cfg,
34+
sizeof(cfg), &dummy);
35+
}
36+
37+
__maybe_unused
38+
static void avs_dsp_delete_probe(struct avs_dev *adev)
39+
{
40+
struct avs_module_entry mentry;
41+
42+
avs_get_module_entry(adev, &AVS_PROBE_MOD_UUID, &mentry);
43+
44+
/* There is only ever one probe module instance. */
45+
avs_dsp_delete_module(adev, mentry.module_id, 0, INVALID_PIPELINE_ID, 0);
46+
}

0 commit comments

Comments
 (0)