From 3b12ef768def960d4f1901955d616a2568d08da7 Mon Sep 17 00:00:00 2001 From: Tomasz Lissowski Date: Thu, 18 Jul 2024 17:23:19 +0200 Subject: [PATCH 1/4] dai-zephyr: pass full copier gateway config to dai_set_config() Currently, the dai_set_config() function is called with copier gateway config data passed but without the config length, possibly making the config not parsable for some DAI drivers. This patch adds passing of the full ipc4_copier_gateway_cfg structure, giving DAI drivers the ability to access config length if needed. Signed-off-by: Tomasz Lissowski --- src/audio/dai-zephyr.c | 9 +++++---- src/ipc/ipc4/dai.c | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/audio/dai-zephyr.c b/src/audio/dai-zephyr.c index 6c845ff19ea5..e5873d1c3000 100644 --- a/src/audio/dai-zephyr.c +++ b/src/audio/dai-zephyr.c @@ -140,6 +140,7 @@ int dai_set_config(struct dai *dai, struct ipc_config_dai *common_config, { const struct device *dev = dai->dev; const struct sof_ipc_dai_config *sof_cfg = spec_config; + const struct ipc4_copier_gateway_cfg *gtw_cfg = spec_config; struct dai_config cfg; const void *cfg_params; bool is_blob; @@ -153,7 +154,7 @@ int dai_set_config(struct dai *dai, struct ipc_config_dai *common_config, switch (common_config->type) { case SOF_DAI_INTEL_SSP: cfg.type = is_blob ? DAI_INTEL_SSP_NHLT : DAI_INTEL_SSP; - cfg_params = is_blob ? spec_config : &sof_cfg->ssp; + cfg_params = is_blob ? (void *)>w_cfg->config_data : (void *)&sof_cfg->ssp; dai_set_link_hda_config(&cfg.link_config, common_config, cfg_params); /* Store tdm slot group index*/ @@ -161,17 +162,17 @@ int dai_set_config(struct dai *dai, struct ipc_config_dai *common_config, break; case SOF_DAI_INTEL_ALH: cfg.type = is_blob ? DAI_INTEL_ALH_NHLT : DAI_INTEL_ALH; - cfg_params = is_blob ? spec_config : &sof_cfg->alh; + cfg_params = is_blob ? (void *)>w_cfg->config_data : (void *)&sof_cfg->alh; break; case SOF_DAI_INTEL_DMIC: cfg.type = is_blob ? DAI_INTEL_DMIC_NHLT : DAI_INTEL_DMIC; - cfg_params = is_blob ? spec_config : &sof_cfg->dmic; + cfg_params = is_blob ? (void *)>w_cfg->config_data : (void *)&sof_cfg->dmic; dai_set_link_hda_config(&cfg.link_config, common_config, cfg_params); break; case SOF_DAI_INTEL_HDA: cfg.type = is_blob ? DAI_INTEL_HDA_NHLT : DAI_INTEL_HDA; - cfg_params = is_blob ? spec_config : &sof_cfg->hda; + cfg_params = is_blob ? (void *)>w_cfg->config_data : (void *)&sof_cfg->hda; break; case SOF_DAI_IMX_SAI: cfg.type = DAI_IMX_SAI; diff --git a/src/ipc/ipc4/dai.c b/src/ipc/ipc4/dai.c index 5c5a12ee8927..11f9b5aedc06 100644 --- a/src/ipc/ipc4/dai.c +++ b/src/ipc/ipc4/dai.c @@ -393,7 +393,7 @@ int dai_config(struct dai_data *dd, struct comp_dev *dev, struct ipc_config_dai if (ret < 0) return ret; - return dai_set_config(dd->dai, common_config, copier_cfg->gtw_cfg.config_data); + return dai_set_config(dd->dai, common_config, &copier_cfg->gtw_cfg); } #if CONFIG_ZEPHYR_NATIVE_DRIVERS From 0ba3ac2f707b441ee38073ad49e01ee58d14c6d1 Mon Sep 17 00:00:00 2001 From: Tomasz Lissowski Date: Thu, 21 Mar 2024 09:27:56 +0100 Subject: [PATCH 2/4] dai: use dai_type items in calls to dai_get_device() Add strict use of dai_type enum items as a call parameter for dai_get_device() function. Currently, both the dai_type and sof_ipc_dai_type items are used inconsistently. Signed-off-by: Tomasz Lissowski --- src/lib/dai.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/lib/dai.c b/src/lib/dai.c index 1a3a49ab3596..e4d2f7cac43c 100644 --- a/src/lib/dai.c +++ b/src/lib/dai.c @@ -157,7 +157,7 @@ const struct device *dai_get_device(uint32_t type, uint32_t index) int dir; int i; - dir = (type == SOF_DAI_INTEL_DMIC) ? DAI_DIR_RX : DAI_DIR_BOTH; + dir = (type == DAI_INTEL_DMIC) ? DAI_DIR_RX : DAI_DIR_BOTH; for (i = 0; i < ARRAY_SIZE(zephyr_dev); i++) { if (dai_config_get(zephyr_dev[i], &cfg, dir)) @@ -210,8 +210,44 @@ struct dai *dai_get(uint32_t type, uint32_t index, uint32_t flags) { const struct device *dev; struct dai *d; + uint32_t z_type; - dev = dai_get_device(type, index); + switch (type) { + case SOF_DAI_INTEL_SSP: + z_type = DAI_INTEL_SSP; + break; + case SOF_DAI_INTEL_DMIC: + z_type = DAI_INTEL_DMIC; + break; + case SOF_DAI_INTEL_HDA: + z_type = DAI_INTEL_HDA; + break; + case SOF_DAI_INTEL_ALH: + z_type = DAI_INTEL_ALH; + break; + case SOF_DAI_IMX_SAI: + z_type = DAI_IMX_SAI; + break; + case SOF_DAI_IMX_ESAI: + z_type = DAI_IMX_ESAI; + break; + case SOF_DAI_AMD_BT: + z_type = DAI_AMD_BT; + break; + case SOF_DAI_AMD_SP: + z_type = DAI_AMD_SP; + break; + case SOF_DAI_AMD_DMIC: + z_type = DAI_AMD_DMIC; + break; + case SOF_DAI_MEDIATEK_AFE: + z_type = DAI_MEDIATEK_AFE; + break; + default: + return NULL; + } + + dev = dai_get_device(z_type, index); if (!dev) { tr_err(&dai_tr, "dai_get: failed to get dai with index %d type %d", index, type); From 2613355133eb4dfbd4646db83281c5a594801fca Mon Sep 17 00:00:00 2001 From: Tomasz Lissowski Date: Thu, 13 Jun 2024 19:33:41 +0200 Subject: [PATCH 3/4] dai: add support for Intel UAOL DAI This adds support for Intel USB Audio Offload Link (UAOL) DAI. Signed-off-by: Tomasz Lissowski --- src/audio/base_fw_intel.c | 64 ++++++++++++++++++++++++++++++++++- src/audio/copier/copier.c | 2 ++ src/audio/copier/copier_dai.c | 13 +++++++ src/audio/dai-zephyr.c | 7 ++++ src/include/ipc/dai.h | 3 +- src/ipc/ipc4/dai.c | 23 +++++++++++++ src/ipc/ipc4/helper.c | 12 +++++++ src/lib/dai.c | 7 ++++ 8 files changed, 129 insertions(+), 2 deletions(-) diff --git a/src/audio/base_fw_intel.c b/src/audio/base_fw_intel.c index 5c38d07960cc..f1c64a082098 100644 --- a/src/audio/base_fw_intel.c +++ b/src/audio/base_fw_intel.c @@ -23,6 +23,10 @@ #include +#if CONFIG_UAOL_INTEL_ADSP +#include +#endif + #include #include #include @@ -33,6 +37,20 @@ struct ipc4_modules_info { struct sof_man_module modules[0]; } __packed __aligned(4); +struct ipc4_uaol_link_capabilities { + uint32_t input_streams_supported : 4; + uint32_t output_streams_supported : 4; + uint32_t bidirectional_streams_supported : 5; + uint32_t rsvd : 19; + uint32_t max_tx_fifo_size; + uint32_t max_rx_fifo_size; +} __packed __aligned(4); + +struct ipc4_uaol_capabilities { + uint32_t link_count; + struct ipc4_uaol_link_capabilities link_caps[]; +} __packed __aligned(4); + /* * TODO: default to value of ACE1.x platforms. This is defined * in multiple places in Zephyr, mm_drv_intel_adsp.h and @@ -61,7 +79,7 @@ int basefw_vendor_fw_config(uint32_t *data_offset, char *data) tlv_value_uint32_set(tuple, IPC4_SLOW_CLOCK_FREQ_HZ_FW_CFG, IPC4_ALH_CAVS_1_8); tuple = tlv_next(tuple); - tlv_value_uint32_set(tuple, IPC4_UAOL_SUPPORT, 0); + tlv_value_uint32_set(tuple, IPC4_UAOL_SUPPORT, 1); tuple = tlv_next(tuple); tlv_value_uint32_set(tuple, IPC4_ALH_SUPPORT_LEVEL_FW_CFG, IPC4_ALH_CAVS_1_8); @@ -72,6 +90,41 @@ int basefw_vendor_fw_config(uint32_t *data_offset, char *data) return 0; } +#if CONFIG_UAOL_INTEL_ADSP + +#define UAOL_DEV(node) DEVICE_DT_GET(node), +static const struct device *uaol_devs[] = { + DT_FOREACH_STATUS_OKAY(intel_adsp_uaol, UAOL_DEV) +}; + +static void tlv_value_set_uaol_caps(struct sof_tlv *tuple, uint32_t type) +{ + const unsigned int dev_count = ARRAY_SIZE(uaol_devs); + struct uaol_capabilities dev_cap; + struct ipc4_uaol_capabilities *caps = (struct ipc4_uaol_capabilities *)tuple->value; + size_t caps_size = offsetof(struct ipc4_uaol_capabilities, link_caps[dev_count]); + unsigned int i; + int ret; + + memset(caps, 0, caps_size); + + caps->link_count = dev_count; + for (i = 0; i < dev_count; i++) { + ret = uaol_get_capabilities(uaol_devs[i], &dev_cap); + if (ret) + continue; + + caps->link_caps[i].input_streams_supported = dev_cap.input_streams; + caps->link_caps[i].output_streams_supported = dev_cap.output_streams; + caps->link_caps[i].bidirectional_streams_supported = dev_cap.bidirectional_streams; + caps->link_caps[i].max_tx_fifo_size = dev_cap.max_tx_fifo_size; + caps->link_caps[i].max_rx_fifo_size = dev_cap.max_rx_fifo_size; + } + + tlv_value_set(tuple, type, caps_size, caps); +} +#endif + int basefw_vendor_hw_config(uint32_t *data_offset, char *data) { struct sof_tlv *tuple = (struct sof_tlv *)data; @@ -100,6 +153,11 @@ int basefw_vendor_hw_config(uint32_t *data_offset, char *data) tlv_value_uint32_set(tuple, IPC4_I2S_CAPS_HW_CFG, I2S_VER_30_PTL); #endif +#if CONFIG_UAOL_INTEL_ADSP + tuple = tlv_next(tuple); + tlv_value_set_uaol_caps(tuple, IPC4_UAOL_CAPS_HW_CFG); +#endif + tuple = tlv_next(tuple); *data_offset = (int)((char *)tuple - data); @@ -376,6 +434,10 @@ int basefw_vendor_dma_control(uint32_t node_id, const char *config_data, size_t case ipc4_i2s_link_input_class: type = DAI_INTEL_SSP; break; + case ipc4_alh_uaol_stream_link_output_class: + case ipc4_alh_uaol_stream_link_input_class: + type = DAI_INTEL_UAOL; + break; default: return IPC4_INVALID_RESOURCE_ID; } diff --git a/src/audio/copier/copier.c b/src/audio/copier/copier.c index 0fe324cb78f3..979e1485e444 100644 --- a/src/audio/copier/copier.c +++ b/src/audio/copier/copier.c @@ -139,6 +139,8 @@ static int copier_init(struct processing_module *mod) case ipc4_i2s_link_input_class: case ipc4_alh_link_output_class: case ipc4_alh_link_input_class: + case ipc4_alh_uaol_stream_link_output_class: + case ipc4_alh_uaol_stream_link_input_class: ret = copier_dai_create(dev, cd, copier, ipc_pipe->pipeline); if (ret < 0) { comp_err(dev, "unable to create dai"); diff --git a/src/audio/copier/copier_dai.c b/src/audio/copier/copier_dai.c index 587a133ebd75..06cac2c5d747 100644 --- a/src/audio/copier/copier_dai.c +++ b/src/audio/copier/copier_dai.c @@ -311,6 +311,19 @@ int copier_dai_create(struct comp_dev *dev, struct copier_data *cd, if (ret) return ret; break; + case ipc4_alh_uaol_stream_link_output_class: + case ipc4_alh_uaol_stream_link_input_class: + dai.type = SOF_DAI_INTEL_UAOL; + dai.is_config_blob = true; + cd->gtw_type = ipc4_gtw_alh; + ret = ipc4_find_dma_config(&dai, (uint8_t *)cd->gtw_cfg, + copier->gtw_cfg.config_length * 4); + if (ret != IPC4_SUCCESS) { + comp_err(dev, "No uaol dma_config found in blob!"); + return -EINVAL; + } + dai.out_fmt = &copier->out_fmt; + break; case ipc4_dmic_link_input_class: dai.type = SOF_DAI_INTEL_DMIC; dai.is_config_blob = true; diff --git a/src/audio/dai-zephyr.c b/src/audio/dai-zephyr.c index e5873d1c3000..d2690fdeabfd 100644 --- a/src/audio/dai-zephyr.c +++ b/src/audio/dai-zephyr.c @@ -150,6 +150,8 @@ int dai_set_config(struct dai *dai, struct ipc_config_dai *common_config, cfg.format = sof_cfg->format; cfg.options = sof_cfg->flags; cfg.rate = common_config->sampling_frequency; + cfg.channels = common_config->out_fmt->channels_count; + cfg.word_size = common_config->out_fmt->valid_bit_depth; switch (common_config->type) { case SOF_DAI_INTEL_SSP: @@ -182,6 +184,11 @@ int dai_set_config(struct dai *dai, struct ipc_config_dai *common_config, cfg.type = DAI_IMX_ESAI; cfg_params = &sof_cfg->esai; break; + case SOF_DAI_INTEL_UAOL: + cfg.type = DAI_INTEL_UAOL; + cfg_params = gtw_cfg; + dai_set_link_hda_config(&cfg.link_config, common_config, >w_cfg->config_data); + break; default: return -EINVAL; } diff --git a/src/include/ipc/dai.h b/src/include/ipc/dai.h index b5b29316f9e6..14c49b75681b 100644 --- a/src/include/ipc/dai.h +++ b/src/include/ipc/dai.h @@ -94,7 +94,8 @@ enum sof_ipc_dai_type { SOF_DAI_AMD_SP_VIRTUAL, /**host_dma_config[0]->stream_id; break; + case SOF_DAI_INTEL_UAOL: + link_cfg.full = 0; + link_cfg.part.hchan = out_fmt->channels_count - 1; + link_cfg.part.dir = common_config->direction; + link_cfg.part.stream = common_config->host_dma_config[0]->stream_id; + break; default: /* other types of DAIs not need link_config */ return; @@ -115,6 +121,13 @@ int dai_config_dma_channel(struct dai_data *dd, struct comp_dev *dev, const void */ channel = 0; break; +#if ACE_VERSION > ACE_VERSION_1_5 + case SOF_DAI_INTEL_UAOL: + channel = 0; + if (dai->host_dma_config[0]->pre_allocated_by_host) + channel = dai->host_dma_config[0]->dma_channel_id; + break; +#endif default: /* other types of DAIs not handled for now */ comp_err(dev, "dai_config_dma_channel(): Unknown dai type %d", dai->type); @@ -177,6 +190,16 @@ int ipc_dai_data_config(struct dai_data *dd, struct comp_dev *dev) dev->ipc_config.frame_fmt, dd->stream_id); break; + case SOF_DAI_INTEL_UAOL: +#ifdef CONFIG_ZEPHYR_NATIVE_DRIVERS + dd->stream_id = dai_get_stream_id(dai_p, dai->direction); + dev->ipc_config.frame_fmt = SOF_IPC_FRAME_S32_LE; + dd->config.burst_elems = dai_get_fifo_depth(dd->dai, dai->direction); + break; +#else + /* only native Zephyr driver supported */ + return -EINVAL; +#endif default: /* other types of DAIs not handled for now */ comp_warn(dev, "dai_data_config(): Unknown dai type %d", dai->type); diff --git a/src/ipc/ipc4/helper.c b/src/ipc/ipc4/helper.c index eb08414b323f..6db8050f01e4 100644 --- a/src/ipc/ipc4/helper.c +++ b/src/ipc/ipc4/helper.c @@ -1055,6 +1055,18 @@ int ipc4_add_comp_dev(struct comp_dev *dev) int ipc4_find_dma_config(struct ipc_config_dai *dai, uint8_t *data_buffer, uint32_t size) { #if ACE_VERSION > ACE_VERSION_1_5 + if (dai->type == SOF_DAI_INTEL_UAOL) { + void *value_ptr = NULL; + uint32_t value_size; + + tlv_value_get(data_buffer, size, GTW_DMA_CONFIG_ID, &value_ptr, &value_size); + if (!value_ptr) + return IPC4_INVALID_REQUEST; + + dai->host_dma_config[0] = (struct ipc_dma_config *)value_ptr; + return IPC4_SUCCESS; + } + uint32_t *dma_config_id = GET_IPC_DMA_CONFIG_ID(data_buffer, size); if (*dma_config_id != GTW_DMA_CONFIG_ID) diff --git a/src/lib/dai.c b/src/lib/dai.c index e4d2f7cac43c..cbba21c3db47 100644 --- a/src/lib/dai.c +++ b/src/lib/dai.c @@ -149,6 +149,9 @@ const struct device *zephyr_dev[] = { #if CONFIG_DAI_NXP_ESAI DT_FOREACH_STATUS_OKAY(nxp_dai_esai, GET_DEVICE_LIST) #endif +#if CONFIG_DAI_INTEL_UAOL + DT_FOREACH_STATUS_OKAY(intel_uaol_dai, GET_DEVICE_LIST) +#endif }; const struct device *dai_get_device(uint32_t type, uint32_t index) @@ -197,6 +200,7 @@ static void dai_set_device_params(struct dai *d) #endif break; case SOF_DAI_INTEL_HDA: + case SOF_DAI_INTEL_UAOL: d->dma_dev = SOF_DMA_DEV_HDA; d->dma_caps = SOF_DMA_CAP_HDA; break; @@ -243,6 +247,9 @@ struct dai *dai_get(uint32_t type, uint32_t index, uint32_t flags) case SOF_DAI_MEDIATEK_AFE: z_type = DAI_MEDIATEK_AFE; break; + case SOF_DAI_INTEL_UAOL: + z_type = DAI_INTEL_UAOL; + break; default: return NULL; } From d3c99ca933ffadc2dd3490835e2a3dee117ff225 Mon Sep 17 00:00:00 2001 From: Tomasz Lissowski Date: Tue, 17 Dec 2024 12:23:07 +0100 Subject: [PATCH 4/4] west.yml: update zephyr Signed-off-by: Tomasz Lissowski --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 93c803c8d725..2494943dec16 100644 --- a/west.yml +++ b/west.yml @@ -43,7 +43,7 @@ manifest: - name: zephyr repo-path: zephyr - revision: 36517253160663f5cdb0f496cb166236fe4ad4c4 + revision: pull/69906/head remote: zephyrproject # Import some projects listed in zephyr/west.yml@revision