diff --git a/app/boards/acp_7_x_adsp.conf b/app/boards/acp_7_x_adsp.conf index 0ec10fff2bf7..04c63271c9ac 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 @@ -52,3 +54,4 @@ CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_44100=n CONFIG_CORE_COUNT=1 CONFIG_FORMAT_CONVERT_HIFI3=n CONFIG_PCM_CONVERTER_FORMAT_S24_4LE_MSB=y +CONFIG_XTENSA_INTERRUPT_NONPREEMPTABLE=y diff --git a/src/audio/dai-zephyr.c b/src/audio/dai-zephyr.c index e65457d34383..91e3f6021662 100644 --- a/src/audio/dai-zephyr.c +++ b/src/audio/dai-zephyr.c @@ -201,6 +201,7 @@ __cold int dai_set_config(struct dai *dai, struct ipc_config_dai *common_config, case SOF_DAI_AMD_SP: case SOF_DAI_AMD_SP_VIRTUAL: case SOF_DAI_AMD_BT: + case SOF_DAI_AMD_TDM: cfg.type = DAI_AMD_TDM; cfg_params = &sof_cfg->acptdm; break; diff --git a/src/include/ipc/dai-amd.h b/src/include/ipc/dai-amd.h index b167f03eed7e..4bfa10b150e8 100644 --- a/src/include/ipc/dai-amd.h +++ b/src/include/ipc/dai-amd.h @@ -24,6 +24,7 @@ struct sof_ipc_dai_acp_params { uint32_t fsync_rate; uint32_t tdm_slots; uint32_t tdm_mode; + uint32_t format; } __attribute__((packed, aligned(4))); /* ACP Configuration Request - SOF_IPC_DAI_AMD_SDW_CONFIG */ diff --git a/src/ipc/ipc3/dai.c b/src/ipc/ipc3/dai.c index d41fd355847d..af06e21955cd 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; @@ -195,6 +196,7 @@ int ipc_dai_data_config(struct dai_data *dd, struct comp_dev *dev) case SOF_DAI_AMD_SP_VIRTUAL: case SOF_DAI_AMD_HS: case SOF_DAI_AMD_HS_VIRTUAL: + case SOF_DAI_AMD_TDM: #if defined(CONFIG_AMD) && !defined(CONFIG_SOC_ACP_6_0) { struct acp_dma_dev_data *tdm_data = dd->dma->z_dev->data; @@ -213,6 +215,15 @@ int ipc_dai_data_config(struct dai_data *dd, struct comp_dev *dev) tdm_ctx = (struct tdm_context *)tdm_data->dai_index_ptr; } tdm_ctx->index = dd->dai->index; + tdm_ctx->frame_fmt = dev->ipc_config.frame_fmt; + /* AMD 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); + } + } } #endif break; diff --git a/src/lib/dai.c b/src/lib/dai.c index 585218104e61..68163282adc1 100644 --- a/src/lib/dai.c +++ b/src/lib/dai.c @@ -239,6 +239,7 @@ static int sof_dai_type_to_zephyr(uint32_t type) case SOF_DAI_AMD_SP: case SOF_DAI_AMD_SP_VIRTUAL: case SOF_DAI_AMD_BT: + case SOF_DAI_AMD_TDM: return DAI_AMD_TDM; default: return -EINVAL; @@ -316,6 +317,10 @@ static void dai_set_device_params(struct dai *d) d->dma_dev = SOF_DMA_DEV_HS | SOF_DMA_DEV_SP | SOF_DMA_DEV_BT; d->dma_caps = SOF_DMA_CAP_HS | SOF_DMA_CAP_SP | SOF_DMA_CAP_BT; break; + case SOF_DAI_AMD_TDM: + d->dma_dev = SOF_DMA_DEV_TDM; + d->dma_caps = SOF_DMA_CAP_TDM; + break; case SOF_DAI_MEDIATEK_AFE: d->dma_dev = SOF_DMA_DEV_AFE_MEMIF; break; 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..83eb206ee2e9 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 @@ -422,10 +422,13 @@ struct sdw_pin_data { }; struct tdm_context { + uint64_t prev_pos; + uint32_t buff_size; uint32_t tdm_instance; uint32_t pin_dir; uint32_t dma_channel; uint32_t index; + uint32_t frame_fmt; }; struct dmic_context { 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..22e72b0d5ea4 --- /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, tdm_config_data) +define(`ACPTDM_CONFIG', +` format "'$1`"' +` '$2 +` '$3 +` '$4 +` '$5 +`}' +$6 +) + +dnl ACPTDM_VIRTUAL_CONFIG(format, mclk, bclk, fsync, tdm, tdm_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" { diff --git a/zephyr/include/sof/lib/dma.h b/zephyr/include/sof/lib/dma.h index e11899d07a4c..4408d265804f 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(10) /**< 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 diff --git a/zephyr/lib/dma.c b/zephyr/lib/dma.c index 9a2fe540addf..1e28d7215026 100644 --- a/zephyr/lib/dma.c +++ b/zephyr/lib/dma.c @@ -243,8 +243,13 @@ APP_SYSUSER_DATA SHARED_DATA struct sof_dma dma[] = { .plat_data = { .dir = SOF_DMA_DIR_MEM_TO_DEV | SOF_DMA_DIR_DEV_TO_MEM, +#if defined(CONFIG_SOC_ACP_7_X) + .devs = SOF_DMA_DEV_TDM, + .caps = SOF_DMA_CAP_TDM, +#elif defined(CONFIG_SOC_ACP_7_0) .devs = SOF_DMA_DEV_HS | SOF_DMA_DEV_SP | SOF_DMA_DEV_BT, .caps = SOF_DMA_CAP_HS | SOF_DMA_CAP_SP | SOF_DMA_CAP_BT, +#endif .base = DMA0_BASE, .chan_size = DMA0_SIZE, .channels = 6,