mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-15 15:04:27 +08:00
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 <cezary.rojewski@intel.com> Link: https://lore.kernel.org/r/20221202152841.672536-10-cezary.rojewski@intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
f7de161fc8
commit
dab8d000e2
@ -10,7 +10,7 @@ snd-soc-avs-objs += trace.o
|
||||
CFLAGS_trace.o := -I$(src)
|
||||
|
||||
ifneq ($(CONFIG_DEBUG_FS),)
|
||||
snd-soc-avs-objs += debugfs.o
|
||||
snd-soc-avs-objs += probes.o debugfs.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_SND_SOC_INTEL_AVS) += snd-soc-avs.o
|
||||
|
@ -722,4 +722,82 @@ int avs_ipc_set_system_time(struct avs_dev *adev)
|
||||
return avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID,
|
||||
AVS_BASEFW_SYSTEM_TIME, (u8 *)&sys_time, sizeof(sys_time));
|
||||
}
|
||||
|
||||
int avs_ipc_probe_get_dma(struct avs_dev *adev, struct avs_probe_dma **dmas, size_t *num_dmas)
|
||||
{
|
||||
size_t payload_size;
|
||||
u32 module_id;
|
||||
u8 *payload;
|
||||
int ret;
|
||||
|
||||
module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID);
|
||||
|
||||
ret = avs_ipc_get_large_config(adev, module_id, AVS_PROBE_INST_ID, AVS_PROBE_INJECTION_DMA,
|
||||
NULL, 0, &payload, &payload_size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*dmas = (struct avs_probe_dma *)payload;
|
||||
*num_dmas = payload_size / sizeof(**dmas);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int avs_ipc_probe_attach_dma(struct avs_dev *adev, struct avs_probe_dma *dmas, size_t num_dmas)
|
||||
{
|
||||
u32 module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID);
|
||||
|
||||
return avs_ipc_set_large_config(adev, module_id, AVS_PROBE_INST_ID, AVS_PROBE_INJECTION_DMA,
|
||||
(u8 *)dmas, array_size(sizeof(*dmas), num_dmas));
|
||||
}
|
||||
|
||||
int avs_ipc_probe_detach_dma(struct avs_dev *adev, union avs_connector_node_id *node_ids,
|
||||
size_t num_node_ids)
|
||||
{
|
||||
u32 module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID);
|
||||
|
||||
return avs_ipc_set_large_config(adev, module_id, AVS_PROBE_INST_ID,
|
||||
AVS_PROBE_INJECTION_DMA_DETACH, (u8 *)node_ids,
|
||||
array_size(sizeof(*node_ids), num_node_ids));
|
||||
}
|
||||
|
||||
int avs_ipc_probe_get_points(struct avs_dev *adev, struct avs_probe_point_desc **descs,
|
||||
size_t *num_descs)
|
||||
{
|
||||
size_t payload_size;
|
||||
u32 module_id;
|
||||
u8 *payload;
|
||||
int ret;
|
||||
|
||||
module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID);
|
||||
|
||||
ret = avs_ipc_get_large_config(adev, module_id, AVS_PROBE_INST_ID, AVS_PROBE_POINTS, NULL,
|
||||
0, &payload, &payload_size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*descs = (struct avs_probe_point_desc *)payload;
|
||||
*num_descs = payload_size / sizeof(**descs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int avs_ipc_probe_connect_points(struct avs_dev *adev, struct avs_probe_point_desc *descs,
|
||||
size_t num_descs)
|
||||
{
|
||||
u32 module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID);
|
||||
|
||||
return avs_ipc_set_large_config(adev, module_id, AVS_PROBE_INST_ID, AVS_PROBE_POINTS,
|
||||
(u8 *)descs, array_size(sizeof(*descs), num_descs));
|
||||
}
|
||||
|
||||
int avs_ipc_probe_disconnect_points(struct avs_dev *adev, union avs_probe_point_id *ids,
|
||||
size_t num_ids)
|
||||
{
|
||||
u32 module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID);
|
||||
|
||||
return avs_ipc_set_large_config(adev, module_id, AVS_PROBE_INST_ID,
|
||||
AVS_PROBE_POINTS_DISCONNECT, (u8 *)ids,
|
||||
array_size(sizeof(*ids), num_ids));
|
||||
}
|
||||
#endif
|
||||
|
@ -802,4 +802,57 @@ int avs_ipc_copier_set_sink_format(struct avs_dev *adev, u16 module_id,
|
||||
const struct avs_audio_format *src_fmt,
|
||||
const struct avs_audio_format *sink_fmt);
|
||||
|
||||
#define AVS_PROBE_INST_ID 0
|
||||
|
||||
enum avs_probe_runtime_param {
|
||||
AVS_PROBE_INJECTION_DMA = 1,
|
||||
AVS_PROBE_INJECTION_DMA_DETACH,
|
||||
AVS_PROBE_POINTS,
|
||||
AVS_PROBE_POINTS_DISCONNECT,
|
||||
};
|
||||
|
||||
struct avs_probe_dma {
|
||||
union avs_connector_node_id node_id;
|
||||
u32 dma_buffer_size;
|
||||
} __packed;
|
||||
|
||||
enum avs_probe_type {
|
||||
AVS_PROBE_TYPE_INPUT = 0,
|
||||
AVS_PROBE_TYPE_OUTPUT,
|
||||
AVS_PROBE_TYPE_INTERNAL
|
||||
};
|
||||
|
||||
union avs_probe_point_id {
|
||||
u32 value;
|
||||
struct {
|
||||
u32 module_id:16;
|
||||
u32 instance_id:8;
|
||||
u32 type:2;
|
||||
u32 index:6;
|
||||
} id;
|
||||
} __packed;
|
||||
|
||||
enum avs_connection_purpose {
|
||||
AVS_CONNECTION_PURPOSE_EXTRACT = 0,
|
||||
AVS_CONNECTION_PURPOSE_INJECT,
|
||||
AVS_CONNECTION_PURPOSE_INJECT_REEXTRACT,
|
||||
};
|
||||
|
||||
struct avs_probe_point_desc {
|
||||
union avs_probe_point_id id;
|
||||
u32 purpose;
|
||||
union avs_connector_node_id node_id;
|
||||
} __packed;
|
||||
|
||||
int avs_ipc_probe_get_dma(struct avs_dev *adev, struct avs_probe_dma **dmas, size_t *num_dmas);
|
||||
int avs_ipc_probe_attach_dma(struct avs_dev *adev, struct avs_probe_dma *dmas, size_t num_dmas);
|
||||
int avs_ipc_probe_detach_dma(struct avs_dev *adev, union avs_connector_node_id *node_ids,
|
||||
size_t num_node_ids);
|
||||
int avs_ipc_probe_get_points(struct avs_dev *adev, struct avs_probe_point_desc **descs,
|
||||
size_t *num_descs);
|
||||
int avs_ipc_probe_connect_points(struct avs_dev *adev, struct avs_probe_point_desc *descs,
|
||||
size_t num_descs);
|
||||
int avs_ipc_probe_disconnect_points(struct avs_dev *adev, union avs_probe_point_id *ids,
|
||||
size_t num_ids);
|
||||
|
||||
#endif /* __SOUND_SOC_INTEL_AVS_MSGS_H */
|
||||
|
46
sound/soc/intel/avs/probes.c
Normal file
46
sound/soc/intel/avs/probes.c
Normal file
@ -0,0 +1,46 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
|
||||
//
|
||||
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
|
||||
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
|
||||
//
|
||||
|
||||
#include "avs.h"
|
||||
#include "messages.h"
|
||||
|
||||
__maybe_unused
|
||||
static int avs_dsp_init_probe(struct avs_dev *adev, union avs_connector_node_id node_id,
|
||||
size_t buffer_size)
|
||||
|
||||
{
|
||||
struct avs_probe_cfg cfg = {{0}};
|
||||
struct avs_module_entry mentry;
|
||||
u16 dummy;
|
||||
|
||||
avs_get_module_entry(adev, &AVS_PROBE_MOD_UUID, &mentry);
|
||||
|
||||
/*
|
||||
* Probe module uses no cycles, audio data format and input and output
|
||||
* frame sizes are unused. It is also not owned by any pipeline.
|
||||
*/
|
||||
cfg.base.ibs = 1;
|
||||
/* BSS module descriptor is always segment of index=2. */
|
||||
cfg.base.is_pages = mentry.segments[2].flags.length;
|
||||
cfg.gtw_cfg.node_id = node_id;
|
||||
cfg.gtw_cfg.dma_buffer_size = buffer_size;
|
||||
|
||||
return avs_dsp_init_module(adev, mentry.module_id, INVALID_PIPELINE_ID, 0, 0, &cfg,
|
||||
sizeof(cfg), &dummy);
|
||||
}
|
||||
|
||||
__maybe_unused
|
||||
static void avs_dsp_delete_probe(struct avs_dev *adev)
|
||||
{
|
||||
struct avs_module_entry mentry;
|
||||
|
||||
avs_get_module_entry(adev, &AVS_PROBE_MOD_UUID, &mentry);
|
||||
|
||||
/* There is only ever one probe module instance. */
|
||||
avs_dsp_delete_module(adev, mentry.module_id, 0, INVALID_PIPELINE_ID, 0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user