From 9342936150a9a806f22ba99c88a98b884aad438d Mon Sep 17 00:00:00 2001 From: DineshKumar Kalva Date: Fri, 12 Jun 2026 18:40:20 +0530 Subject: [PATCH 1/5] ipc: dai: add SOF_DAI_AMD_TDM type and DMA capability bitmasks Add SOF_DAI_AMD_TDM to the sof_ipc_dai_type enum, placed before SOF_DAI_INTEL_UAOL to maintain ABI ordering. Add format field to sof_ipc_dai_acp_params to carry the sample format (16/24/32-bit) from topology to the DAI driver. Add SOF_DMA_CAP_TDM (BIT(16)) and SOF_DMA_DEV_TDM (BIT(16)) capability/device bitmasks for the ACP TDM DMA controller. Signed-off-by: DineshKumar Kalva Signed-off-by: Sneha Voona --- src/include/ipc/dai-amd.h | 1 + src/include/ipc/dai.h | 2 ++ zephyr/include/sof/lib/dma.h | 2 ++ 3 files changed, 5 insertions(+) diff --git a/src/include/ipc/dai-amd.h b/src/include/ipc/dai-amd.h index ceeb870c163e..d0da461858fb 100644 --- a/src/include/ipc/dai-amd.h +++ b/src/include/ipc/dai-amd.h @@ -23,6 +23,7 @@ struct sof_ipc_dai_acp_params { uint32_t reserved0; uint32_t fsync_rate; uint32_t tdm_slots; + uint32_t format; } __attribute__((packed, aligned(4))); /* ACP Configuration Request - SOF_IPC_DAI_AMD_SDW_CONFIG */ diff --git a/src/include/ipc/dai.h b/src/include/ipc/dai.h index dfc2a3e9ffb0..473dba3715ad 100644 --- a/src/include/ipc/dai.h +++ b/src/include/ipc/dai.h @@ -97,6 +97,7 @@ enum sof_ipc_dai_type { SOF_DAI_IMX_MICFIL, /**< i.MX MICFIL */ SOF_DAI_AMD_SDW, /**< Amd SDW */ SOF_DAI_INTEL_UAOL, /**< Intel UAOL */ + SOF_DAI_AMD_TDM /**< Amd TDM */ }; #define SOF_DAI_CONFIG_HW_SPEC_OFFSET offsetof(struct sof_ipc_dai_config, ssp) @@ -130,6 +131,7 @@ struct sof_ipc_dai_config { struct sof_ipc_dai_afe_params afe; struct sof_ipc_dai_micfil_params micfil; struct sof_ipc_dai_acp_sdw_params acpsdw; + struct sof_ipc_dai_acp_params acptdm; }; } __attribute__((packed, aligned(4))); diff --git a/zephyr/include/sof/lib/dma.h b/zephyr/include/sof/lib/dma.h index 509495634097..9a9b09df1b06 100644 --- a/zephyr/include/sof/lib/dma.h +++ b/zephyr/include/sof/lib/dma.h @@ -81,6 +81,7 @@ struct k_heap; #define SOF_DMA_CAP_HS_VIRTUAL BIT(7) /**< HS VIRTUAL DMA */ #define SOF_DMA_CAP_HS BIT(8) /**< HS DMA */ #define SOF_DMA_CAP_SW BIT(9) /**< SW DMA */ +#define SOF_DMA_CAP_TDM BIT(16) /**< connectable to ACP TDM I2S */ /* DMA dev type bitmasks used to define the type of DMA */ @@ -100,6 +101,7 @@ struct k_heap; #define SOF_DMA_DEV_HS BIT(13) /**< connectable to ACP HS I2S */ #define SOF_DMA_DEV_MICFIL BIT(14) /**< connectable to MICFIL fifo */ #define SOF_DMA_DEV_SW BIT(15) /**< connectable to ACP SW */ +#define SOF_DMA_DEV_TDM BIT(16) /**< connectable to ACP TDM I2S */ /* DMA access privilege flag */ #define SOF_DMA_ACCESS_EXCLUSIVE 1 From 5f2225207954048fd1e2bd042a969956f32a8c9a Mon Sep 17 00:00:00 2001 From: DineshKumar Kalva Date: Fri, 12 Jun 2026 18:40:31 +0530 Subject: [PATCH 2/5] dai: acp: add SOF_DAI_AMD_TDM to DAI and DMA dispatch tables Route SOF_DAI_AMD_TDM through the DAI and DMA layer: - dai-zephyr.c: add SOF_DAI_AMD_TDM -> DAI_AMD_TDM / acptdm params - lib/dai.c: map SOF_DAI_AMD_TDM -> DAI_AMD_TDM in type conversion and set SOF_DMA_DEV_TDM/SOF_DMA_CAP_TDM in dai_set_device_params() - ipc3/dai.c: add SOF_DAI_AMD_TDM to dai_config_dma_channel(); handle TDM context allocation with struct tdm_context for CONFIG_SOC_ACP_7_X, propagating frame_fmt, pin_dir and dma_channel - zephyr/lib/dma.c: add amd_acp_tdm_dma DMA array entry guarded by DT_HAS_COMPAT_STATUS_OKAY(amd_acp_tdm_dma) Signed-off-by: DineshKumar Kalva Signed-off-by: Sneha Voona --- src/audio/dai-zephyr.c | 4 ++++ src/ipc/ipc3/dai.c | 35 +++++++++++++++++++++++++++++++++++ src/lib/dai.c | 9 +++++++++ zephyr/lib/dma.c | 15 +++++++++++++++ 4 files changed, 63 insertions(+) diff --git a/src/audio/dai-zephyr.c b/src/audio/dai-zephyr.c index fc2a065741cd..8b4c6be7dab8 100644 --- a/src/audio/dai-zephyr.c +++ b/src/audio/dai-zephyr.c @@ -196,6 +196,10 @@ __cold int dai_set_config(struct dai *dai, struct ipc_config_dai *common_config, cfg.type = DAI_AMD_SDW; cfg_params = &sof_cfg->acpsdw; break; + case SOF_DAI_AMD_TDM: + cfg.type = DAI_AMD_TDM; + cfg_params = &sof_cfg->acptdm; + break; case SOF_DAI_INTEL_UAOL: cfg.type = DAI_INTEL_UAOL; cfg.channels = common_config->gtw_fmt->channels_count; diff --git a/src/ipc/ipc3/dai.c b/src/ipc/ipc3/dai.c index ce7be827b887..90f166647bf9 100644 --- a/src/ipc/ipc3/dai.c +++ b/src/ipc/ipc3/dai.c @@ -95,6 +95,7 @@ int dai_config_dma_channel(struct dai_data *dd, struct comp_dev *dev, const void break; case SOF_DAI_AMD_HS: case SOF_DAI_AMD_HS_VIRTUAL: + case SOF_DAI_AMD_TDM: case SOF_DAI_AMD_SDW: { struct dai_config *params = (struct dai_config *)dd->dai->dev->config; @@ -197,6 +198,40 @@ int ipc_dai_data_config(struct dai_data *dd, struct comp_dev *dev) audio_stream_set_frm_fmt(&dd->dma_buffer->stream, dev->ipc_config.frame_fmt); break; + case SOF_DAI_AMD_TDM: +#if defined(CONFIG_AMD) && defined(CONFIG_SOC_ACP_7_X) + { + struct acp_dma_dev_data *tdm_dev_data = dd->dma->z_dev->data; + struct tdm_context *tdm_ctx; + + /* AMD TDM HW needs 24-bit data MSB-aligned in 32-bit word */ + if (dev->ipc_config.frame_fmt == SOF_IPC_FRAME_S24_4LE) + dev->ipc_config.frame_fmt = SOF_IPC_FRAME_S24_4LE_MSB; + if (dd->dma_buffer) + audio_stream_set_frm_fmt(&dd->dma_buffer->stream, + dev->ipc_config.frame_fmt); + + /* Free the old ptr if set from a previous DAI type */ + if (!tdm_dev_data->dai_index_ptr) { + tdm_ctx = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, + sizeof(*tdm_ctx)); + tdm_dev_data->dai_index_ptr = tdm_ctx; + } else { + tdm_ctx = tdm_dev_data->dai_index_ptr; + } + tdm_ctx->index = dd->dai->index; + tdm_ctx->pin_dir = dai->direction; +#ifdef CONFIG_ZEPHYR_NATIVE_DRIVERS + tdm_ctx->dma_channel = dd->chan_index >= 0 ? + (uint32_t)dd->chan_index : ACP_TDM_INVALID_32; +#else + tdm_ctx->dma_channel = dd->chan ? + dd->chan->index : ACP_TDM_INVALID_32; +#endif + tdm_ctx->frame_fmt = dev->ipc_config.frame_fmt; + } +#endif /* CONFIG_AMD && CONFIG_SOC_ACP_7_X */ + break; case SOF_DAI_AMD_HS: case SOF_DAI_AMD_HS_VIRTUAL: case SOF_DAI_AMD_SDW: diff --git a/src/lib/dai.c b/src/lib/dai.c index d51266aa345e..2bc0d7931743 100644 --- a/src/lib/dai.c +++ b/src/lib/dai.c @@ -189,6 +189,9 @@ const struct device *zephyr_dev[] = { #if CONFIG_DAI_AMD_SDW DT_FOREACH_STATUS_OKAY(amd_acp_sdw_dai, GET_DEVICE_LIST) #endif +#if CONFIG_DAI_AMD_TDM + DT_FOREACH_STATUS_OKAY(amd_tdm_dai, GET_DEVICE_LIST) +#endif #if CONFIG_DAI_INTEL_UAOL DT_FOREACH_STATUS_OKAY(intel_uaol_dai, GET_DEVICE_LIST) #endif @@ -238,6 +241,8 @@ static int sof_dai_type_to_zephyr(uint32_t type) case SOF_DAI_AMD_HS_VIRTUAL: case SOF_DAI_AMD_SDW: return DAI_AMD_SDW; + case SOF_DAI_AMD_TDM: + return DAI_AMD_TDM; default: return -EINVAL; } @@ -308,6 +313,10 @@ static void dai_set_device_params(struct dai *d) case SOF_DAI_MEDIATEK_AFE: d->dma_dev = SOF_DMA_DEV_AFE_MEMIF; break; + case SOF_DAI_AMD_TDM: + d->dma_dev = SOF_DMA_DEV_TDM; + d->dma_caps = SOF_DMA_CAP_TDM; + break; default: break; } diff --git a/zephyr/lib/dma.c b/zephyr/lib/dma.c index 851c05ae77cc..417481cb7e24 100644 --- a/zephyr/lib/dma.c +++ b/zephyr/lib/dma.c @@ -239,6 +239,21 @@ APP_SYSUSER_DATA SHARED_DATA struct sof_dma dma[] = { }, .z_dev = DEVICE_DT_GET(DT_NODELABEL(acp_sdw_dma)), }, +#if DT_HAS_COMPAT_STATUS_OKAY(amd_acp_tdm_dma) +{ + .plat_data = { + .dir = SOF_DMA_DIR_MEM_TO_DEV | + SOF_DMA_DIR_DEV_TO_MEM, + .devs = SOF_DMA_DEV_TDM, + .caps = SOF_DMA_CAP_TDM, + .base = DMA0_BASE, + .chan_size = DMA0_SIZE, + .channels = DT_PROP(DT_NODELABEL(acp_tdm_dma), dma_channels), + .period_count = 2, + }, + .z_dev = DEVICE_DT_GET(DT_NODELABEL(acp_tdm_dma)), +}, +#endif #endif #if DT_HAS_COMPAT_STATUS_OKAY(mediatek_afe_memif_dma) { From 46c1c73dc43d2eedaa540e752ff7fa8e39b83d8f Mon Sep 17 00:00:00 2001 From: DineshKumar Kalva Date: Fri, 12 Jun 2026 18:40:40 +0530 Subject: [PATCH 3/5] platform: amd: acp_7_x: add TDM invalid-index sentinel macros Add ACP_TDM_INVALID_32 and ACP_TDM_INVALID_16 sentinel values to both acp_7_0 and acp_7_x platform_misc.h. These are used by the TDM DAI and DMA drivers to mark unallocated channels/indices, consistent with the existing SDW driver conventions. Signed-off-by: DineshKumar Kalva Signed-off-by: Sneha Voona --- src/platform/amd/acp_7_0/include/platform/platform_misc.h | 3 +++ src/platform/amd/acp_7_x/include/platform/platform_misc.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/platform/amd/acp_7_0/include/platform/platform_misc.h b/src/platform/amd/acp_7_0/include/platform/platform_misc.h index 2338a91317e0..eab5d5cfc87c 100644 --- a/src/platform/amd/acp_7_0/include/platform/platform_misc.h +++ b/src/platform/amd/acp_7_0/include/platform/platform_misc.h @@ -421,6 +421,9 @@ struct sdw_pin_data { uint32_t instance; }; +#define ACP_TDM_INVALID_32 0xFFFFFFFFU +#define ACP_TDM_INVALID_16 0xFFFFU + struct tdm_context { uint32_t tdm_instance; uint32_t pin_dir; diff --git a/src/platform/amd/acp_7_x/include/platform/platform_misc.h b/src/platform/amd/acp_7_x/include/platform/platform_misc.h index 949f3622374f..7fdd665ce4e7 100644 --- a/src/platform/amd/acp_7_x/include/platform/platform_misc.h +++ b/src/platform/amd/acp_7_x/include/platform/platform_misc.h @@ -548,6 +548,9 @@ struct sdw_pin_data { uint32_t instance1; }; +#define ACP_TDM_INVALID_32 0xFFFFFFFFU +#define ACP_TDM_INVALID_16 0xFFFFU + struct tdm_context { uint64_t prev_pos; uint32_t buff_size; From fca7c8402d63f3f263e7cd56bd1653774ed04c5a Mon Sep 17 00:00:00 2001 From: DineshKumar Kalva Date: Fri, 12 Jun 2026 18:41:15 +0530 Subject: [PATCH 4/5] acp_7_x: board: enable TDM DAI and DMA drivers Enable CONFIG_DMA_AMD_ACP_TDM and CONFIG_DAI_AMD_TDM for the ACP 7.X ADSP board to activate TDM audio support. Signed-off-by: DineshKumar Kalva Signed-off-by: Sneha Voona --- app/boards/acp_7_x_adsp.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/boards/acp_7_x_adsp.conf b/app/boards/acp_7_x_adsp.conf index 0ec10fff2bf7..7e6ea479b173 100644 --- a/app/boards/acp_7_x_adsp.conf +++ b/app/boards/acp_7_x_adsp.conf @@ -14,7 +14,9 @@ CONFIG_INTC_AMD_ACP=y CONFIG_DMA_AMD_ACP_HOST=y CONFIG_DMA_AMD_ACP_SDW=y CONFIG_DMA_AMD_ACP_SDW_CHANNEL_COUNT=64 +CONFIG_DMA_AMD_ACP_TDM=y CONFIG_DAI_AMD_SDW=y +CONFIG_DAI_AMD_TDM=y CONFIG_AMS=n CONFIG_WRAP_ACTUAL_POSITION=y CONFIG_TRACE=n From ea6b086d8497f354f7ecfa48e87553c39b05feb4 Mon Sep 17 00:00:00 2001 From: DineshKumar Kalva Date: Fri, 12 Jun 2026 18:41:34 +0530 Subject: [PATCH 5/5] tools: topology: add ACP 7.X TDM I2S topology support Add TDM I2S topology templates for ACP 7.X: - platform/common/acp-tdm.m4: TDM DAI and pipeline macros - sof-acp_7_x_i2s.m4: default 16-bit TDM topology - sof-acp_7_x_i2s_24bit.m4: 24-bit TDM topology - dai.m4: add SOF_DAI_AMD_TDM token - tokens.m4: add acptdm format token - CMakeLists.txt: register new topology targets Signed-off-by: DineshKumar Kalva Signed-off-by: Sneha Voona --- tools/topology/topology1/CMakeLists.txt | 2 + tools/topology/topology1/m4/dai.m4 | 2 +- .../topology1/platform/common/acp-tdm.m4 | 74 +++++++ tools/topology/topology1/sof-acp_7_x_i2s.m4 | 187 ++++++++++++++++++ .../topology1/sof-acp_7_x_i2s_24bit.m4 | 165 ++++++++++++++++ tools/topology/topology1/sof/tokens.m4 | 1 + 6 files changed, 430 insertions(+), 1 deletion(-) create mode 100644 tools/topology/topology1/platform/common/acp-tdm.m4 create mode 100644 tools/topology/topology1/sof-acp_7_x_i2s.m4 create mode 100644 tools/topology/topology1/sof-acp_7_x_i2s_24bit.m4 diff --git a/tools/topology/topology1/CMakeLists.txt b/tools/topology/topology1/CMakeLists.txt index f00903368c6a..95d81a01629f 100644 --- a/tools/topology/topology1/CMakeLists.txt +++ b/tools/topology/topology1/CMakeLists.txt @@ -123,6 +123,8 @@ set(TPLGS "sof-acp_7_0\;sof-acp_7_0" "sof-acp_7_0_sdw\;sof-acp_7_0-rt722-l0" "sof-acp_7_x_sdw\;sof-acp7x-rt721-l0" + "sof-acp_7_x_i2s\;sof-acp7x" + "sof-acp_7_x_i2s_24bit\;sof-acp7x-24bit" ) # This empty 'production/' source subdirectory exists only to create the diff --git a/tools/topology/topology1/m4/dai.m4 b/tools/topology/topology1/m4/dai.m4 index cd968c6c61fd..4dc5d5ec5135 100644 --- a/tools/topology/topology1/m4/dai.m4 +++ b/tools/topology/topology1/m4/dai.m4 @@ -155,7 +155,7 @@ define(`DO_DAI_CONFIG', `' ` id "'$3`"' `' -` ifelse($1, `SSP', $5, $1, `HDA', $5, $1, `ALH', $5, $1, `ESAI', $5, $1, `SAI', $5, $1, `MICFIL', $5, $1, `AFE', $5, $1, `ACP', $5, $1, `ACPSP', $5, $1,`ACPSP_VIRTUAL', $5, $1, `ACPHS', $5, $1, `ACPHS_VIRTUAL', $5, $1, `ACP_SDW', $5, $1, `ACPDMIC', $5, `}')' +` ifelse($1, `SSP', $5, $1, `HDA', $5, $1, `ALH', $5, $1, `ESAI', $5, $1, `SAI', $5, $1, `MICFIL', $5, $1, `AFE', $5, $1, `ACP', $5, $1, `ACPSP', $5, $1,`ACPSP_VIRTUAL', $5, $1, `ACPHS', $5, $1, `ACPHS_VIRTUAL', $5, $1, `ACP_SDW', $5, $1, `ACPDMIC', $5, $1, `ACPTDM', $5, `}')' `ifelse($1, `DMIC', $5, `')' `SectionVendorTuples."'N_DAI_CONFIG($1$2)`_tuples_common" {' ` tokens "sof_dai_tokens"' diff --git a/tools/topology/topology1/platform/common/acp-tdm.m4 b/tools/topology/topology1/platform/common/acp-tdm.m4 new file mode 100644 index 000000000000..fdedb2968d3e --- /dev/null +++ b/tools/topology/topology1/platform/common/acp-tdm.m4 @@ -0,0 +1,74 @@ +divert(-1) + +dnl ACPTDM related macros + +dnl ACP_CLOCK(clock, freq, codec_provider, polarity) +dnl polarity is optional +define(`ACP_CLOCK', + $1 STR($3) + $1_freq STR($2)) + `ifelse($4, `inverted', `$1_invert "true"',`')') + +dnl ACP_TDM(slots, width, tx_mask, rx_mask) +define(`ACP_TDM', +` tdm_slots 'STR($1) +` tdm_slot_width 'STR($2) +` tx_slots 'STR($3) +` rx_slots 'STR($4) +) + +dnl ACP_CONFIG(format, mclk, bclk, fsync, tdm, esai_config_data) +define(`ACPTDM_CONFIG', +` format "'$1`"' +` '$2 +` '$3 +` '$4 +` '$5 +`}' +$6 +) + +dnl ACPTDM_VIRTUAL_CONFIG(format, mclk, bclk, fsync, tdm, esai_config_data) +define(`ACPTDM_VIRTUAL_CONFIG', +` format "'$1`"' +` '$2 +` '$3 +` '$4 +` '$5 +`}' +$6 +) + +dnl ACPTDM_CONFIG_DATA(type, idx, rate, channel,i2s_tdm_mode) +#i2s_tdm_mode 1-> tdm mode, 0->i2s mode +define(`ACPTDM_CONFIG_DATA', +`SectionVendorTuples."'N_DAI_CONFIG($1$2)`_tuples" {' +` tokens "sof_acp_tokens"' +` tuples."word" {' +` SOF_TKN_AMD_ACP_RATE' STR($3) +` SOF_TKN_AMD_ACP_CH' STR($4) +` SOF_TKN_AMD_ACP_I2S_TDM_MODE' STR($5) +` SOF_TKN_AMD_ACP_I2S_BITDEPTH' STR($6) +` }' +`}' +`SectionData."'N_DAI_CONFIG($1$2)`_data" {' +` tuples "'N_DAI_CONFIG($1$2)`_tuples"' +`}' +) + +dnl ACPTDM_VIRTUAL_CONFIG_DATA(type, idx, rate, channel,i2s_tdm_mode) +#i2s_tdm_mode 1-> tdm mode, 0->i2s mode +define(`ACPTDM_VIRTUAL_CONFIG_DATA', +`SectionVendorTuples."'N_DAI_CONFIG($1$2)`_tuples" {' +` tokens "sof_acp_tokens"' +` tuples."word" {' +` SOF_TKN_AMD_ACP_RATE' STR($3) +` SOF_TKN_AMD_ACP_CH' STR($4) +` SOF_TKN_AMD_ACP_I2S_TDM_MODE' STR($5) +` }' +`}' +`SectionData."'N_DAI_CONFIG($1$2)`_data" {' +` tuples "'N_DAI_CONFIG($1$2)`_tuples"' +`}' +) +divert(0)dnl diff --git a/tools/topology/topology1/sof-acp_7_x_i2s.m4 b/tools/topology/topology1/sof-acp_7_x_i2s.m4 new file mode 100644 index 000000000000..6f633f700a56 --- /dev/null +++ b/tools/topology/topology1/sof-acp_7_x_i2s.m4 @@ -0,0 +1,187 @@ +# +# Topology for ACP_7_X with TDM. +# +# Include topology builder +include(`utils.m4') +include(`dai.m4') +include(`pipeline.m4') +include(`acp-tdm.m4') + +# Include TLV library +include(`common/tlv.m4') + +# Include Token library +include(`sof/tokens.m4') + +# Include ACP DSP configuration +include(`platform/amd/acp.m4') + +# +# Pipeline Graph (16-bit / s16le): +# +# PLAYBACK: +# [Host PCM ] -> [Passthrough Pipeline ] -> [ACPTDM DAI ] +# s16le 2ch s16le 48kHz s16le 2ch +# | +# [acp-i2s0-codec] +# I2S bclk=3.072MHz +# fsync=48kHz, 2ch +# | +# CAPTURE: +# [ACPTDM DAI ] -> [Passthrough Pipeline ] -> [Host PCM ] +# s16le 2ch s16le 48kHz s16le 2ch +# + +DEBUG_START +#====================================================================== +# Playback pipeline 1 on PCM 0 using max 2 channels of s16le. + +dnl PIPELINE_PCM_ADD(pipeline, +dnl pipe id, pcm, max channels, format, +dnl period, priority, core, +dnl pcm_min_rate, pcm_max_rate, pipeline_rate) +# Playback pipeline 0 on PCM 0, dai index 0, link id 0 using max 2 channels of s16le. + +# Schedule 96 frames per 2000us deadline on core 0 with priority 0 +PIPELINE_PCM_ADD(sof/pipe-passthrough-playback.m4, + 0, 0, 2, s16le, + 2000, 0, 0, + 48000, 48000, 48000) + +# Capture pipeline 3 on PCM 0, dai index 0 using max 2 channels of s16le. +PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, + 3, 0, 2, s16le, + 2000, 0, 0, + 48000, 48000, 48000) +#=========================================================================== +dnl DAI_ADD(pipeline, +dnl pipe id, dai type, dai_index, dai_be, +dnl buffer, periods, format, +dnl deadline, priority, core, time_domain) + +# Schedule 96 frames per 2000us deadline on core 0 with priority 0 + +# playback DAI is ACPTDM using 2 periods +DAI_ADD(sof/pipe-dai-playback.m4, + 0, ACPTDM, 0, acp-i2s0-codec, + PIPELINE_SOURCE_0, 2, s16le, + 2000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) + +# Capture DAI is ACPTDM using 2 periods +DAI_ADD(sof/pipe-dai-capture.m4, + 3, ACPTDM, 0, acp-i2s0-codec, + PIPELINE_SINK_3, 2, s16le, + 2000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) +#=========================================================================== +# playback DAI is ACPTDM using 2 periods + +dnl DAI_CONFIG(type, dai_index, link_id, name, ACPTDM_config/acpdmic_config) +dnl ACPTDM_CONFIG(format, mclk, bclk, fsync, tdm, ACPTDM_config_data) +dnl ACP_CLOCK(clock, freq, codec_provider, polarity) +dnl ACPTDM_CONFIG_DATA(type, idx, valid bits, mclk_id) +dnl mclk_id is optional + +DAI_CONFIG(ACPTDM, 0, 0, acp-i2s0-codec, + ACPTDM_CONFIG(I2S, ACP_CLOCK(mclk, 49152000, codec_mclk_in), + ACP_CLOCK(bclk, 3072000, codec_consumer), + ACP_CLOCK(fsync, 48000, codec_consumer), + ACP_TDM(2, 32, 3, 3),ACPTDM_CONFIG_DATA(ACPTDM, 0, 48000, 2, 0, 0)) +) +dnl PCM_DUPLEX_ADD(name, pcm_id, playback_pipeline, capture_pipeline) +PCM_DUPLEX_ADD(I2STDM0, 0, PIPELINE_PCM_0, PIPELINE_PCM_3) + +#==================================================================================================================== +# TDM instance 1 + +dnl PIPELINE_PCM_ADD(pipeline, +dnl pipe id, pcm, max channels, format, +dnl period, priority, core, +dnl pcm_min_rate, pcm_max_rate, pipeline_rate) + +PIPELINE_PCM_ADD(sof/pipe-passthrough-playback.m4, + 1, 1, 2, s16le, + 2000, 0, 0, + 48000, 48000, 48000) +PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, + 4, 1, 2, s16le, + 2000, 0, 0, + 48000, 48000, 48000) + +dnl DAI_ADD(pipeline, +dnl pipe id, dai type, dai_index, dai_be, +dnl buffer, periods, format, +dnl deadline, priority, core, time_domain) + +DAI_ADD(sof/pipe-dai-playback.m4, + 1, ACPTDM, 1, acp-i2s1-codec, + PIPELINE_SOURCE_1, 2, s16le, + 2000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) + +DAI_ADD(sof/pipe-dai-capture.m4, + 4, ACPTDM, 1, acp-i2s1-codec, + PIPELINE_SINK_4, 2, s16le, + 2000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) +dnl DAI_CONFIG(type, dai_index, link_id, name, ACPTDM_config/acpdmic_config) +dnl ACPTDM_CONFIG(format, mclk, bclk, fsync, tdm, ACPTDM_config_data) +dnl ACP_CLOCK(clock, freq, codec_provider, polarity) +dnl ACPTDM_CONFIG_DATA(type, idx, valid bits, mclk_id) +dnl mclk_id is optional + +DAI_CONFIG(ACPTDM, 1, 1, acp-i2s1-codec, + ACPTDM_CONFIG(I2S, ACP_CLOCK(mclk, 49152000, codec_mclk_in), + ACP_CLOCK(bclk, 3072000, codec_consumer), + ACP_CLOCK(fsync, 48000, codec_consumer), + ACP_TDM(2, 32, 3, 3), ACPTDM_CONFIG_DATA(ACPTDM, 1, 48000, 2, 0))) + +dnl PCM_DUPLEX_ADD(name, pcm_id, playback_pipeline, capture_pipeline) +PCM_DUPLEX_ADD(I2STDM1, 1, PIPELINE_PCM_1, PIPELINE_PCM_4) + +#==================================================================================================================== +# TDM instance 2 + +dnl PIPELINE_PCM_ADD(pipeline, +dnl pipe id, pcm, max channels, format, +dnl period, priority, core, +dnl pcm_min_rate, pcm_max_rate, pipeline_rate) + +PIPELINE_PCM_ADD(sof/pipe-passthrough-playback.m4, + 2, 2, 2, s16le, + 2000, 0, 0, + 48000, 48000, 48000) +PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, + 5, 2, 2, s16le, + 2000, 0, 0, + 48000, 48000, 48000) + +dnl DAI_ADD(pipeline, +dnl pipe id, dai type, dai_index, dai_be, +dnl buffer, periods, format, +dnl deadline, priority, core, time_domain) + +DAI_ADD(sof/pipe-dai-playback.m4, + 2, ACPTDM, 2, acp-i2s2-codec, + PIPELINE_SOURCE_2, 2, s16le, + 2000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) + +DAI_ADD(sof/pipe-dai-capture.m4, + 5, ACPTDM, 2, acp-i2s2-codec, + PIPELINE_SINK_5, 2, s16le, + 2000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) + +dnl DAI_CONFIG(type, dai_index, link_id, name, ACPTDM_config/acpdmic_config) +dnl ACPTDM_CONFIG(format, mclk, bclk, fsync, tdm, ACPTDM_config_data) +dnl ACP_CLOCK(clock, freq, codec_provider, polarity) +dnl ACPTDM_CONFIG_DATA(type, idx, valid bits, mclk_id) +dnl mclk_id is optional + +DAI_CONFIG(ACPTDM, 2, 2, acp-i2s2-codec, + ACPTDM_CONFIG(I2S, ACP_CLOCK(mclk, 49152000, codec_mclk_in), + ACP_CLOCK(bclk, 3072000, codec_consumer), + ACP_CLOCK(fsync, 48000, codec_consumer), + ACP_TDM(2, 32, 3, 3), ACPTDM_CONFIG_DATA(ACPTDM, 2, 48000, 2, 0))) + +dnl PCM_DUPLEX_ADD(name, pcm_id, playback_pipeline, capture_pipeline) +PCM_DUPLEX_ADD(I2STDM2, 2, PIPELINE_PCM_2, PIPELINE_PCM_5) +#==================================================================================================================== + +DEBUG_END diff --git a/tools/topology/topology1/sof-acp_7_x_i2s_24bit.m4 b/tools/topology/topology1/sof-acp_7_x_i2s_24bit.m4 new file mode 100644 index 000000000000..dabf7927d90c --- /dev/null +++ b/tools/topology/topology1/sof-acp_7_x_i2s_24bit.m4 @@ -0,0 +1,165 @@ +# +# Topology for ACP_7_x with TDM (24-bit). +# +# Include topology builder +include(`utils.m4') +include(`dai.m4') +include(`pipeline.m4') +include(`acp-tdm.m4') + +# Include TLV library +include(`common/tlv.m4') + +# Include Token library +include(`sof/tokens.m4') + +# Include ACP DSP configuration +include(`platform/amd/acp.m4') + +# +# Pipeline Graph (24-bit / s24le): +# +# PLAYBACK/CAPTURE: +# TDM0, TDM1, TDM2 each expose a duplex PCM. +# Host side uses s32le; DAI side uses s24le (frame_fmt=1). +# + +DEBUG_START +#====================================================================== +# Playback/Capture pipelines for three TDM instances (24-bit). + +# TDM instance 0 + +dnl PIPELINE_PCM_ADD(pipeline, +dnl pipe id, pcm, max channels, format, +dnl period, priority, core, +dnl pcm_min_rate, pcm_max_rate, pipeline_rate) +PIPELINE_PCM_ADD(sof/pipe-passthrough-playback.m4, + 0, 0, 2, s32le, + 2000, 0, 0, + 48000, 48000, 48000) + +PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, + 3, 0, 2, s32le, + 2000, 0, 0, + 48000, 48000, 48000) + +dnl DAI_ADD(pipeline, +dnl pipe id, dai type, dai_index, dai_be, +dnl buffer, periods, format, +dnl deadline, priority, core, time_domain) +DAI_ADD(sof/pipe-dai-playback.m4, + 0, ACPTDM, 0, acp-i2s0-codec, + PIPELINE_SOURCE_0, 2, s24le, + 2000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) + +DAI_ADD(sof/pipe-dai-capture.m4, + 3, ACPTDM, 0, acp-i2s0-codec, + PIPELINE_SINK_3, 2, s24le, + 2000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) + +dnl DAI_CONFIG(type, dai_index, link_id, name, ACPTDM_config/acpdmic_config) +dnl ACPTDM_CONFIG(format, mclk, bclk, fsync, tdm, ACPTDM_config_data) +dnl ACP_CLOCK(clock, freq, codec_provider, polarity) +dnl ACPTDM_CONFIG_DATA(type, idx, rate, tdm_mode, frame_fmt(0 for s16le, 1 for s24le, 2 for s32le)) +dnl mclk_id is optional +DAI_CONFIG(ACPTDM, 0, 0, acp-i2s0-codec, + ACPTDM_CONFIG(I2S, ACP_CLOCK(mclk, 49152000, codec_mclk_in), + ACP_CLOCK(bclk, 3072000, codec_consumer), + ACP_CLOCK(fsync, 48000, codec_consumer), + ACP_TDM(2, 32, 3, 3), ACPTDM_CONFIG_DATA(ACPTDM, 0, 48000, 2, 0, 1))) + +dnl PCM_DUPLEX_ADD(name, pcm_id, playback_pipeline, capture_pipeline) +PCM_DUPLEX_ADD(I2STDM0, 0, PIPELINE_PCM_0, PIPELINE_PCM_3) + +#============================ +# TDM instance 1 + +dnl PIPELINE_PCM_ADD(pipeline, +dnl pipe id, pcm, max channels, format, +dnl period, priority, core, +dnl pcm_min_rate, pcm_max_rate, pipeline_rate) +PIPELINE_PCM_ADD(sof/pipe-passthrough-playback.m4, + 1, 1, 2, s32le, + 2000, 0, 0, + 48000, 48000, 48000) + +PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, + 4, 1, 2, s32le, + 2000, 0, 0, + 48000, 48000, 48000) + +dnl DAI_ADD(pipeline, +dnl pipe id, dai type, dai_index, dai_be, +dnl buffer, periods, format, +dnl deadline, priority, core, time_domain) +DAI_ADD(sof/pipe-dai-playback.m4, + 1, ACPTDM, 1, acp-i2s1-codec, + PIPELINE_SOURCE_1, 2, s24le, + 2000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) + +DAI_ADD(sof/pipe-dai-capture.m4, + 4, ACPTDM, 1, acp-i2s1-codec, + PIPELINE_SINK_4, 2, s24le, + 2000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) + +dnl DAI_CONFIG(type, dai_index, link_id, name, ACPTDM_config/acpdmic_config) +dnl ACPTDM_CONFIG(format, mclk, bclk, fsync, tdm, ACPTDM_config_data) +dnl ACP_CLOCK(clock, freq, codec_provider, polarity) +dnl ACPTDM_CONFIG_DATA(type, idx, rate, tdm_mode, frame_fmt(0 for s16le, 1 for s24le, 2 for s32le)) +dnl mclk_id is optional +DAI_CONFIG(ACPTDM, 1, 1, acp-i2s1-codec, + ACPTDM_CONFIG(I2S, ACP_CLOCK(mclk, 49152000, codec_mclk_in), + ACP_CLOCK(bclk, 3072000, codec_consumer), + ACP_CLOCK(fsync, 48000, codec_consumer), + ACP_TDM(2, 32, 3, 3), ACPTDM_CONFIG_DATA(ACPTDM, 1, 48000, 2, 0, 1))) + +dnl PCM_DUPLEX_ADD(name, pcm_id, playback_pipeline, capture_pipeline) +PCM_DUPLEX_ADD(I2STDM1, 1, PIPELINE_PCM_1, PIPELINE_PCM_4) + +#============================ +# TDM instance 2 + +dnl PIPELINE_PCM_ADD(pipeline, +dnl pipe id, pcm, max channels, format, +dnl period, priority, core, +dnl pcm_min_rate, pcm_max_rate, pipeline_rate) +PIPELINE_PCM_ADD(sof/pipe-passthrough-playback.m4, + 2, 2, 2, s32le, + 2000, 0, 0, + 48000, 48000, 48000) + +PIPELINE_PCM_ADD(sof/pipe-passthrough-capture.m4, + 5, 2, 2, s32le, + 2000, 0, 0, + 48000, 48000, 48000) + +dnl DAI_ADD(pipeline, +dnl pipe id, dai type, dai_index, dai_be, +dnl buffer, periods, format, +dnl deadline, priority, core, time_domain) +DAI_ADD(sof/pipe-dai-playback.m4, + 2, ACPTDM, 2, acp-i2s2-codec, + PIPELINE_SOURCE_2, 2, s24le, + 2000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) + +DAI_ADD(sof/pipe-dai-capture.m4, + 5, ACPTDM, 2, acp-i2s2-codec, + PIPELINE_SINK_5, 2, s24le, + 2000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) + +dnl DAI_CONFIG(type, dai_index, link_id, name, ACPTDM_config/acpdmic_config) +dnl ACPTDM_CONFIG(format, mclk, bclk, fsync, tdm, ACPTDM_config_data) +dnl ACP_CLOCK(clock, freq, codec_provider, polarity) +dnl ACPTDM_CONFIG_DATA(type, idx, rate, tdm_mode, frame_fmt(0 for s16le, 1 for s24le, 2 for s32le)) +dnl mclk_id is optional +DAI_CONFIG(ACPTDM, 2, 2, acp-i2s2-codec, + ACPTDM_CONFIG(I2S, ACP_CLOCK(mclk, 49152000, codec_mclk_in), + ACP_CLOCK(bclk, 3072000, codec_consumer), + ACP_CLOCK(fsync, 48000, codec_consumer), + ACP_TDM(2, 32, 3, 3), ACPTDM_CONFIG_DATA(ACPTDM, 2, 48000, 2, 0, 1))) + +dnl PCM_DUPLEX_ADD(name, pcm_id, playback_pipeline, capture_pipeline) +PCM_DUPLEX_ADD(I2STDM2, 2, PIPELINE_PCM_2, PIPELINE_PCM_5) + +DEBUG_END diff --git a/tools/topology/topology1/sof/tokens.m4 b/tools/topology/topology1/sof/tokens.m4 index b9748bb52fbc..a9a12f5264b6 100644 --- a/tools/topology/topology1/sof/tokens.m4 +++ b/tools/topology/topology1/sof/tokens.m4 @@ -141,6 +141,7 @@ SectionVendorTokens."sof_acp_tokens" { SOF_TKN_AMD_ACP_RATE "1700" SOF_TKN_AMD_ACP_CH "1701" SOF_TKN_AMD_ACP_I2S_TDM_MODE "1702" + SOF_TKN_AMD_ACP_I2S_BITDEPTH "1703" } SectionVendorTokens."sof_acpdmic_tokens" {