Commit cf4484a0 authored by Mark Brown's avatar Mark Brown

ASoC: qdsp6: audioreach: add multi-port, SAL and MFC support

Merge series from Srinivas Kandagatla <srinivas.kandagatla@linaro.org>:

This patchset adds support to multi-port connections between AudioReach Modules
which is required for sophisticated graphs like ECNS or Speaker Protection.
Also as part of ECNS testing new module support for SAL and MFC are added.

Tested on SM8450 with ECNS.
parents ad850421 6648a6dc
...@@ -191,6 +191,33 @@ enum ar_event_types { ...@@ -191,6 +191,33 @@ enum ar_event_types {
#define AR_TKN_U32_MODULE_SRC_INSTANCE_ID 208 #define AR_TKN_U32_MODULE_SRC_INSTANCE_ID 208
#define AR_TKN_U32_MODULE_DST_INSTANCE_ID 209 #define AR_TKN_U32_MODULE_DST_INSTANCE_ID 209
#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID1 210
#define AR_TKN_U32_MODULE_DST_IN_PORT_ID1 211
#define AR_TKN_U32_MODULE_DST_INSTANCE_ID1 212
#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID2 213
#define AR_TKN_U32_MODULE_DST_IN_PORT_ID2 214
#define AR_TKN_U32_MODULE_DST_INSTANCE_ID2 215
#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID3 216
#define AR_TKN_U32_MODULE_DST_IN_PORT_ID3 217
#define AR_TKN_U32_MODULE_DST_INSTANCE_ID3 218
#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID4 219
#define AR_TKN_U32_MODULE_DST_IN_PORT_ID4 220
#define AR_TKN_U32_MODULE_DST_INSTANCE_ID4 221
#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID5 222
#define AR_TKN_U32_MODULE_DST_IN_PORT_ID5 223
#define AR_TKN_U32_MODULE_DST_INSTANCE_ID5 224
#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID6 225
#define AR_TKN_U32_MODULE_DST_IN_PORT_ID6 226
#define AR_TKN_U32_MODULE_DST_INSTANCE_ID6 227
#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID7 228
#define AR_TKN_U32_MODULE_DST_IN_PORT_ID7 229
#define AR_TKN_U32_MODULE_DST_INSTANCE_ID7 230
#define AR_TKN_U32_MODULE_HW_IF_IDX 250 #define AR_TKN_U32_MODULE_HW_IF_IDX 250
#define AR_TKN_U32_MODULE_HW_IF_TYPE 251 #define AR_TKN_U32_MODULE_HW_IF_TYPE 251
......
This diff is collapsed.
...@@ -15,6 +15,8 @@ struct q6apm_graph; ...@@ -15,6 +15,8 @@ struct q6apm_graph;
#define MODULE_ID_PCM_CNV 0x07001003 #define MODULE_ID_PCM_CNV 0x07001003
#define MODULE_ID_PCM_ENC 0x07001004 #define MODULE_ID_PCM_ENC 0x07001004
#define MODULE_ID_PCM_DEC 0x07001005 #define MODULE_ID_PCM_DEC 0x07001005
#define MODULE_ID_SAL 0x07001010
#define MODULE_ID_MFC 0x07001015
#define MODULE_ID_CODEC_DMA_SINK 0x07001023 #define MODULE_ID_CODEC_DMA_SINK 0x07001023
#define MODULE_ID_CODEC_DMA_SOURCE 0x07001024 #define MODULE_ID_CODEC_DMA_SOURCE 0x07001024
#define MODULE_ID_I2S_SINK 0x0700100A #define MODULE_ID_I2S_SINK 0x0700100A
...@@ -499,6 +501,16 @@ struct data_logging_config { ...@@ -499,6 +501,16 @@ struct data_logging_config {
uint32_t mode; uint32_t mode;
} __packed; } __packed;
#define PARAM_ID_SAL_OUTPUT_CFG 0x08001016
struct param_id_sal_output_config {
uint32_t bits_per_sample;
} __packed;
#define PARAM_ID_SAL_LIMITER_ENABLE 0x0800101E
struct param_id_sal_limiter_enable {
uint32_t enable_lim;
} __packed;
#define PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT 0x08001024 #define PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT 0x08001024
struct param_id_mfc_media_format { struct param_id_mfc_media_format {
...@@ -525,6 +537,11 @@ struct payload_media_fmt_pcm { ...@@ -525,6 +537,11 @@ struct payload_media_fmt_pcm {
uint8_t channel_mapping[]; uint8_t channel_mapping[];
} __packed; } __packed;
#define PARAM_ID_MODULE_ENABLE 0x08001026
struct param_id_module_enable {
uint32_t enable;
} __packed;
#define PARAM_ID_CODEC_DMA_INTF_CFG 0x08001063 #define PARAM_ID_CODEC_DMA_INTF_CFG 0x08001063
struct param_id_codec_dma_intf_cfg { struct param_id_codec_dma_intf_cfg {
...@@ -595,7 +612,11 @@ struct audioreach_graph_info { ...@@ -595,7 +612,11 @@ struct audioreach_graph_info {
int id; int id;
uint32_t num_sub_graphs; uint32_t num_sub_graphs;
struct list_head sg_list; struct list_head sg_list;
struct list_head connection_list; /* DPCM connection from FE Graph to BE graph */
uint32_t src_mod_inst_id;
uint32_t src_mod_op_port_id;
uint32_t dst_mod_inst_id;
uint32_t dst_mod_ip_port_id;
}; };
struct audioreach_sub_graph { struct audioreach_sub_graph {
...@@ -623,6 +644,8 @@ struct audioreach_container { ...@@ -623,6 +644,8 @@ struct audioreach_container {
struct audioreach_sub_graph *sub_graph; struct audioreach_sub_graph *sub_graph;
}; };
#define AR_MAX_MOD_LINKS 8
struct audioreach_module { struct audioreach_module {
uint32_t module_id; uint32_t module_id;
uint32_t instance_id; uint32_t instance_id;
...@@ -633,11 +656,12 @@ struct audioreach_module { ...@@ -633,11 +656,12 @@ struct audioreach_module {
uint32_t in_port; uint32_t in_port;
uint32_t out_port; uint32_t out_port;
uint32_t num_connections;
/* Connections */ /* Connections */
uint32_t src_mod_inst_id; uint32_t src_mod_inst_id;
uint32_t src_mod_op_port_id; uint32_t src_mod_op_port_id[AR_MAX_MOD_LINKS];
uint32_t dst_mod_inst_id; uint32_t dst_mod_inst_id[AR_MAX_MOD_LINKS];
uint32_t dst_mod_ip_port_id; uint32_t dst_mod_ip_port_id[AR_MAX_MOD_LINKS];
/* Format specifics */ /* Format specifics */
uint32_t ch_fmt; uint32_t ch_fmt;
...@@ -694,9 +718,8 @@ void *audioreach_alloc_apm_pkt(int pkt_size, uint32_t opcode, uint32_t token, ...@@ -694,9 +718,8 @@ void *audioreach_alloc_apm_pkt(int pkt_size, uint32_t opcode, uint32_t token,
void *audioreach_alloc_pkt(int payload_size, uint32_t opcode, void *audioreach_alloc_pkt(int payload_size, uint32_t opcode,
uint32_t token, uint32_t src_port, uint32_t token, uint32_t src_port,
uint32_t dest_port); uint32_t dest_port);
void *audioreach_alloc_graph_pkt(struct q6apm *apm, void *audioreach_alloc_graph_pkt(struct q6apm *apm, struct audioreach_graph_info
struct list_head *sg_list, *info);
int graph_id);
/* Topology specific */ /* Topology specific */
int audioreach_tplg_init(struct snd_soc_component *component); int audioreach_tplg_init(struct snd_soc_component *component);
...@@ -717,14 +740,4 @@ int audioreach_set_media_format(struct q6apm_graph *graph, ...@@ -717,14 +740,4 @@ int audioreach_set_media_format(struct q6apm_graph *graph,
int audioreach_shared_memory_send_eos(struct q6apm_graph *graph); int audioreach_shared_memory_send_eos(struct q6apm_graph *graph);
int audioreach_gain_set_vol_ctrl(struct q6apm *apm, int audioreach_gain_set_vol_ctrl(struct q6apm *apm,
struct audioreach_module *module, int vol); struct audioreach_module *module, int vol);
struct audioreach_module *audioreach_get_container_last_module(
struct audioreach_container *container);
struct audioreach_module *audioreach_get_container_first_module(
struct audioreach_container *container);
struct audioreach_module *audioreach_get_container_next_module(
struct audioreach_container *container,
struct audioreach_module *module);
#define list_for_each_container_module(mod, cont) \
for (mod = audioreach_get_container_first_module(cont); mod != NULL; \
mod = audioreach_get_container_next_module(cont, mod))
#endif /* __AUDIOREACH_H__ */ #endif /* __AUDIOREACH_H__ */
...@@ -63,7 +63,7 @@ static struct audioreach_graph *q6apm_get_audioreach_graph(struct q6apm *apm, ui ...@@ -63,7 +63,7 @@ static struct audioreach_graph *q6apm_get_audioreach_graph(struct q6apm *apm, ui
graph->info = info; graph->info = info;
graph->id = graph_id; graph->id = graph_id;
graph->graph = audioreach_alloc_graph_pkt(apm, &info->sg_list, graph_id); graph->graph = audioreach_alloc_graph_pkt(apm, info);
if (IS_ERR(graph->graph)) { if (IS_ERR(graph->graph)) {
void *err = graph->graph; void *err = graph->graph;
...@@ -178,87 +178,6 @@ static struct audioreach_module *__q6apm_find_module_by_mid(struct q6apm *apm, ...@@ -178,87 +178,6 @@ static struct audioreach_module *__q6apm_find_module_by_mid(struct q6apm *apm,
return NULL; return NULL;
} }
static struct audioreach_module *q6apm_graph_get_last_module(struct q6apm *apm, u32 sgid)
{
struct audioreach_container *container;
struct audioreach_module *module;
struct audioreach_sub_graph *sg;
mutex_lock(&apm->lock);
sg = idr_find(&apm->sub_graphs_idr, sgid);
mutex_unlock(&apm->lock);
if (!sg)
return NULL;
container = list_last_entry(&sg->container_list, struct audioreach_container, node);
module = audioreach_get_container_last_module(container);
return module;
}
static struct audioreach_module *q6apm_graph_get_first_module(struct q6apm *apm, u32 sgid)
{
struct audioreach_container *container;
struct audioreach_module *module;
struct audioreach_sub_graph *sg;
mutex_lock(&apm->lock);
sg = idr_find(&apm->sub_graphs_idr, sgid);
mutex_unlock(&apm->lock);
if (!sg)
return NULL;
container = list_first_entry(&sg->container_list, struct audioreach_container, node);
module = audioreach_get_container_first_module(container);
return module;
}
bool q6apm_is_sub_graphs_connected(struct q6apm *apm, u32 src_sgid, u32 dst_sgid)
{
struct audioreach_module *module;
u32 iid;
module = q6apm_graph_get_last_module(apm, src_sgid);
if (!module)
return false;
iid = module->instance_id;
module = q6apm_graph_get_first_module(apm, dst_sgid);
if (!module)
return false;
if (module->src_mod_inst_id == iid)
return true;
return false;
}
int q6apm_connect_sub_graphs(struct q6apm *apm, u32 src_sgid, u32 dst_sgid, bool connect)
{
struct audioreach_module *module;
u32 iid;
if (connect) {
module = q6apm_graph_get_last_module(apm, src_sgid);
if (!module)
return -ENODEV;
iid = module->instance_id;
} else {
iid = 0;
}
module = q6apm_graph_get_first_module(apm, dst_sgid);
if (!module)
return -ENODEV;
/* set src module in dst subgraph first module */
module->src_mod_inst_id = iid;
return 0;
}
int q6apm_graph_media_format_shmem(struct q6apm_graph *graph, int q6apm_graph_media_format_shmem(struct q6apm_graph *graph,
struct audioreach_module_config *cfg) struct audioreach_module_config *cfg)
{ {
...@@ -731,6 +650,7 @@ static int apm_probe(gpr_device_t *gdev) ...@@ -731,6 +650,7 @@ static int apm_probe(gpr_device_t *gdev)
apm->gdev = gdev; apm->gdev = gdev;
init_waitqueue_head(&apm->wait); init_waitqueue_head(&apm->wait);
INIT_LIST_HEAD(&apm->widget_list);
idr_init(&apm->graph_idr); idr_init(&apm->graph_idr);
idr_init(&apm->graph_info_idr); idr_init(&apm->graph_info_idr);
idr_init(&apm->sub_graphs_idr); idr_init(&apm->sub_graphs_idr);
......
...@@ -58,6 +58,7 @@ struct q6apm { ...@@ -58,6 +58,7 @@ struct q6apm {
struct mutex lock; struct mutex lock;
uint32_t state; uint32_t state;
struct list_head widget_list;
struct idr graph_idr; struct idr graph_idr;
struct idr graph_info_idr; struct idr graph_info_idr;
struct idr sub_graphs_idr; struct idr sub_graphs_idr;
...@@ -141,12 +142,7 @@ int q6apm_send_cmd_sync(struct q6apm *apm, struct gpr_pkt *pkt, ...@@ -141,12 +142,7 @@ int q6apm_send_cmd_sync(struct q6apm *apm, struct gpr_pkt *pkt,
/* Callback for graph specific */ /* Callback for graph specific */
struct audioreach_module *q6apm_find_module_by_mid(struct q6apm_graph *graph, struct audioreach_module *q6apm_find_module_by_mid(struct q6apm_graph *graph,
uint32_t mid); uint32_t mid);
void q6apm_set_fe_dai_ops(struct snd_soc_dai_driver *dai_drv); void q6apm_set_fe_dai_ops(struct snd_soc_dai_driver *dai_drv);
int q6apm_connect_sub_graphs(struct q6apm *apm, u32 src_sgid, u32 dst_sgid,
bool connect);
bool q6apm_is_sub_graphs_connected(struct q6apm *apm, u32 src_sgid,
u32 dst_sgid);
int q6apm_graph_get_rx_shmem_module_iid(struct q6apm_graph *graph); int q6apm_graph_get_rx_shmem_module_iid(struct q6apm_graph *graph);
#endif /* __APM_GRAPH_ */ #endif /* __APM_GRAPH_ */
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment