diff --git a/tools/topology/CMakeLists.txt b/tools/topology/CMakeLists.txt index d1da6adf7ea4..5cc437921bf9 100644 --- a/tools/topology/CMakeLists.txt +++ b/tools/topology/CMakeLists.txt @@ -120,6 +120,8 @@ set(TPLGS "sof-jsl-da7219\;sof-jsl-da7219\;-DPLATFORM=jsl" "sof-jsl-da7219\;sof-jsl-da7219-mx98360a\;-DPLATFORM=jsl-dedede" "sof-imx8mp-wm8960\;sof-imx8mp-wm8960" + "sof-tgl-nocodec-mux-8ch\;sof-tgl-nocodec-mux-8ch" + "sof-tgl-nocodec-mux-4ch\;sof-tgl-nocodec-mux-4ch" ) add_custom_target(topologies ALL) diff --git a/tools/topology/sof-tgl-nocodec-mux-4ch.m4 b/tools/topology/sof-tgl-nocodec-mux-4ch.m4 new file mode 100644 index 000000000000..146ede5b0acc --- /dev/null +++ b/tools/topology/sof-tgl-nocodec-mux-4ch.m4 @@ -0,0 +1,131 @@ +# +# Topology for generic Tigerlake board with no codec and digital mic array. +# +# TGL Host GW DMAC support max 6 playback and max 6 capture channels so some +# pipelines/PCMs/DAIs are commented out to keep within HW bounds. If these +# are needed then they can be used provided other PCMs/pipelines/SSPs are +# commented out in their place. + +# Include topology builder +include(`utils.m4') +include(`dai.m4') +include(`ssp.m4') +include(`pipeline.m4') + +# Include TLV library +include(`common/tlv.m4') + +# Include Token library +include(`sof/tokens.m4') + +# Include Tigerlake DSP configuration +include(`platform/intel/tgl.m4') +# include(`platform/intel/dmic.m4') + +# +# Define the DEMUX bytes +# +include(`bytecontrol.m4') +CONTROLBYTES_PRIV(DEMUX_priv, +` bytes "0x53,0x4f,0x46,0x00,0x00,0x00,0x00,0x00,' +` 0x28,0x00,0x00,0x00,0x00,0x60,0x00,0x03,' +` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' +` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' +` 0x02,0x00,0x04,0x00,0x02,0x00,0x00,0x00,' +` 0x02,0x00,0x00,0x00,0x02,0x01,0x02,0x04,' +` 0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,' +` 0x03,0x00,0x00,0x00,0x04,0x01,0x02,0x04,' +` 0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00"' +) +DEBUG_START +# +# Define the pipelines +# +# PCM0 (4ch) ---> volume1-----> SSP0 +# PCM0 (2ch) <--- volume2 <-(2ch)-- MUXDEMUX <---- SSP0 +# | (4ch) +# V +# PCM3 (4ch) <--- volume3 <-----------+ + +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, +dnl time_domain, sched_comp) + +# Low Latency playback pipeline 0 on PCM 2 using max 2 channels of s32le. +# Schedule 48 frames per 1000us deadline on core 0 with priority 0 +PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, + 1, 0, 4, s32le, + 1000, 0, 0, + 48000, 48000, 48000) + +# Low Latency capture pipeline 1 on PCM 2 using max 2 channels of s32le. +# Schedule 48 frames per 1000us deadline on core 0 with priority 0 +PIPELINE_PCM_ADD(sof/pipe-demux-volume-capture.m4, + 2, 0, 4, s32le, + 1000, 0, 0, + 48000, 48000, 48000) + + +# +# DAIs configuration +# + +dnl DAI_ADD(pipeline, +dnl pipe id, dai type, dai_index, dai_be, +dnl buffer, periods, format, +dnl deadline, priority, core, time_domain) + +# playback DAI is SSP0 using 2 periods +# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 +DAI_ADD(sof/pipe-dai-playback.m4, + 1, SSP, 0, NoCodec-0, + PIPELINE_SOURCE_1, 2, s32le, + 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) + +# capture DAI is SSP0 using 2 periods +# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 +DAI_ADD(sof/pipe-dai-capture.m4, + 2, SSP, 0, NoCodec-0, + PIPELINE_SINK_2, 2, s32le, + 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) + +# +# Echo reference configuration +# + +# Low Latency capture pipeline 2 on PCM 3 using max 2 channels of s32le. +# Schedule 48 frames per 1000us deadline on core 0 with priority 0 +PIPELINE_PCM_ADD(sof/pipe-passthrough-capture-sched.m4, + 3, 1, 4, s32le, + 1000, 1, 0, + 48000, 48000, 48000, + SCHEDULE_TIME_DOMAIN_TIMER, + PIPELINE_SCHED_COMP_2) + +# Connect demux to capture +SectionGraph."PIPE_DEMUX" { + index "0" + + lines [ + # demux to capture + dapm(PIPELINE_SINK_3, PIPELINE_DEMUX_2) + ] +} + +dnl PCM_DUPLEX_ADD(name, pcm_id, playback, capture) +PCM_DUPLEX_ADD(Port0, 0, PIPELINE_PCM_1, PIPELINE_PCM_2) +PCM_CAPTURE_ADD(EchoRef, 1, PIPELINE_PCM_3) + +# +# BE configurations - overrides config in ACPI if present +# +DAI_CONFIG(SSP, 0, 0, NoCodec-0, + SSP_CONFIG(DSP_B, SSP_CLOCK(mclk, 38400000, codec_mclk_in), + SSP_CLOCK(bclk, 6144000, codec_slave), + SSP_CLOCK(fsync, 48000, codec_slave), + SSP_TDM(4, 32, 15, 15), + SSP_CONFIG_DATA(SSP, 0, 32, 0, SSP_QUIRK_LBM))) + +DEBUG_END \ No newline at end of file diff --git a/tools/topology/sof-tgl-nocodec-mux-8ch.m4 b/tools/topology/sof-tgl-nocodec-mux-8ch.m4 new file mode 100644 index 000000000000..267fcc9c282d --- /dev/null +++ b/tools/topology/sof-tgl-nocodec-mux-8ch.m4 @@ -0,0 +1,131 @@ +# +# Topology for generic Tigerlake board with no codec and digital mic array. +# +# TGL Host GW DMAC support max 6 playback and max 6 capture channels so some +# pipelines/PCMs/DAIs are commented out to keep within HW bounds. If these +# are needed then they can be used provided other PCMs/pipelines/SSPs are +# commented out in their place. + +# Include topology builder +include(`utils.m4') +include(`dai.m4') +include(`ssp.m4') +include(`pipeline.m4') + +# Include TLV library +include(`common/tlv.m4') + +# Include Token library +include(`sof/tokens.m4') + +# Include Tigerlake DSP configuration +include(`platform/intel/tgl.m4') +# include(`platform/intel/dmic.m4') + +# +# Define the DEMUX bytes +# +include(`bytecontrol.m4') +CONTROLBYTES_PRIV(DEMUX_priv, +` bytes "0x53,0x4f,0x46,0x00,0x00,0x00,0x00,0x00,' +` 0x28,0x00,0x00,0x00,0x00,0x60,0x00,0x03,' +` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' +` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' +` 0x02,0x00,0x08,0x00,0x02,0x00,0x00,0x00,' +` 0x02,0x00,0x00,0x00,0x04,0x01,0x02,0x04,' +` 0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,' +` 0x03,0x00,0x00,0x00,0x08,0x01,0x02,0x04,' +` 0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00"' +) +DEBUG_START +# +# Define the pipelines +# +# PCM0 (8ch) ---> volume1-----> SSP0 +# PCM0 (4ch) <--- volume2 <-(4ch)-- MUXDEMUX <---- SSP0 +# | (8ch) +# V +# PCM1 (8ch) <------------------------+ + +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, +dnl time_domain, sched_comp) + +# Low Latency playback pipeline 0 on PCM 2 using max 2 channels of s32le. +# Schedule 48 frames per 1000us deadline on core 0 with priority 0 +PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, + 1, 0, 8, s32le, + 1000, 0, 0, + 48000, 48000, 48000) + +# Low Latency capture pipeline 1 on PCM 2 using max 2 channels of s32le. +# Schedule 48 frames per 1000us deadline on core 0 with priority 0 +PIPELINE_PCM_ADD(sof/pipe-demux-volume-capture.m4, + 2, 0, 4, s32le, + 1000, 0, 0, + 48000, 48000, 48000) + + +# +# DAIs configuration +# + +dnl DAI_ADD(pipeline, +dnl pipe id, dai type, dai_index, dai_be, +dnl buffer, periods, format, +dnl deadline, priority, core, time_domain) + +# playback DAI is SSP2 using 2 periods +# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 +DAI_ADD(sof/pipe-dai-playback.m4, + 1, SSP, 0, NoCodec-0, + PIPELINE_SOURCE_1, 2, s32le, + 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) + +# capture DAI is SSP0 using 2 periods +# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 +DAI_ADD(sof/pipe-dai-capture.m4, + 2, SSP, 0, NoCodec-0, + PIPELINE_SINK_2, 2, s32le, + 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) + +# +# Echo reference configuration +# + +# Low Latency capture pipeline 2 on PCM 3 using max 2 channels of s32le. +# Schedule 48 frames per 1000us deadline on core 0 with priority 0 +PIPELINE_PCM_ADD(sof/pipe-passthrough-capture-sched.m4, + 3, 1, 8, s32le, + 1000, 1, 0, + 48000, 48000, 48000, + SCHEDULE_TIME_DOMAIN_TIMER, + PIPELINE_SCHED_COMP_2) + +# Connect demux to capture +SectionGraph."PIPE_DEMUX" { + index "0" + + lines [ + # demux to capture + dapm(PIPELINE_SINK_3, PIPELINE_DEMUX_2) + ] +} + +dnl PCM_DUPLEX_ADD(name, pcm_id, playback, capture) +PCM_DUPLEX_ADD(Port0, 0, PIPELINE_PCM_1, PIPELINE_PCM_2) +PCM_CAPTURE_ADD(EchoRef, 1, PIPELINE_PCM_3) + +# +# BE configurations - overrides config in ACPI if present +# +DAI_CONFIG(SSP, 0, 0, NoCodec-0, + SSP_CONFIG(DSP_B, SSP_CLOCK(mclk, 38400000, codec_mclk_in), + SSP_CLOCK(bclk, 12288000, codec_slave), + SSP_CLOCK(fsync, 48000, codec_slave), + SSP_TDM(8, 32, 255, 255), + SSP_CONFIG_DATA(SSP, 0, 32, 0, SSP_QUIRK_LBM))) + +DEBUG_END \ No newline at end of file diff --git a/tools/topology/sof/pipe-demux-volume-capture.m4 b/tools/topology/sof/pipe-demux-volume-capture.m4 new file mode 100644 index 000000000000..74f4be1bd1cf --- /dev/null +++ b/tools/topology/sof/pipe-demux-volume-capture.m4 @@ -0,0 +1,103 @@ +# Demux Volume Pipeline +# +# Low Latency Capture with demux and volume. +# +# Pipeline Endpoints for connection are :- +# +# Capture Demux +# B2 (DAI buffer) +# +# +# host PCM_P -- B0 <--- volume -- B1 <--- Demux-- B2 <-- sink DAI0 +# | +# + +# + +# Include topology builder +include(`utils.m4') +include(`buffer.m4') +include(`pcm.m4') +include(`pga.m4') +include(`muxdemux.m4') +include(`mixercontrol.m4') +include(`bytecontrol.m4') + +# demux Bytes control with max value of 255 +C_CONTROLBYTES(DEMUX, PIPELINE_ID, + CONTROLBYTES_OPS(bytes, 258 binds the mixer control to bytes get/put handlers, 258, 258), + CONTROLBYTES_EXTOPS(258 binds the mixer control to bytes get/put handlers, 258, 258), + , , , + CONTROLBYTES_MAX(, 304), + , + DEMUX_priv) + +# Volume Mixer control with max value of 32 +C_CONTROLMIXER(Master Capture Volume, PIPELINE_ID, + CONTROLMIXER_OPS(volsw, 256 binds the mixer control to volume get/put handlers, 256, 256), + CONTROLMIXER_MAX(, 32), + false, + CONTROLMIXER_TLV(TLV 32 steps from -64dB to 0dB for 2dB, vtlv_m64s2), + Channel register and shift for Front Left/Right, + LIST(` ', KCONTROL_CHANNEL(FL, 1, 0), KCONTROL_CHANNEL(FR, 1, 1))) + +# +# Volume configuration +# + +W_VENDORTUPLES(playback_pga_tokens, sof_volume_tokens, +LIST(` ', `SOF_TKN_VOLUME_RAMP_STEP_TYPE "0"' + ` ', `SOF_TKN_VOLUME_RAMP_STEP_MS "250"')) + +W_DATA(playback_pga_conf, playback_pga_tokens) + +# +# Components and Buffers +# + +# Host "Low latency Capture" PCM +# with 2 sink and 0 source periods +W_PCM_CAPTURE(PCM_ID, Low Latency Capture, 0, 2) + +# "Master Capture Volume" has 2 source and x sink periods for DAI ping-pong +W_PGA(0, PIPELINE_FORMAT, DAI_PERIODS, 2, playback_pga_conf, LIST(` ', "PIPELINE_ID Master Capture Volume")) + +# Mux 0 has 2 sink and source periods. +W_MUXDEMUX(0, 1, PIPELINE_FORMAT, 2, 2, LIST(` ', "DEMUX")) + +# Low Latency Buffers +W_BUFFER(0, COMP_BUFFER_SIZE(2, + COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)), + PLATFORM_HOST_MEM_CAP) +W_BUFFER(1, COMP_BUFFER_SIZE(2, + COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)), + PLATFORM_COMP_MEM_CAP) +W_BUFFER(2, COMP_BUFFER_SIZE(DAI_PERIODS, + COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)), + PLATFORM_COMP_MEM_CAP) + +# +# Pipeline Graph +# +# host PCM_P -- B0 <--- volume -- B1 <--- Demux-- B2 <-- sink DAI0 +P_GRAPH(pipe-demux-vol-capture-PIPELINE_ID, PIPELINE_ID, + LIST(` ', + `dapm(N_PCMC(PCM_ID), N_BUFFER(0))', + `dapm(N_BUFFER(0), N_PGA(0))', + `dapm(N_PGA(0), N_BUFFER(1))', + `dapm(N_BUFFER(1), N_MUXDEMUX(0))', + `dapm(N_MUXDEMUX(0), N_BUFFER(2))')) +# +# Pipeline Source and Sinks +# +indir(`define', concat(`PIPELINE_SINK_', PIPELINE_ID), N_BUFFER(2)) +indir(`define', concat(`PIPELINE_DEMUX_', PIPELINE_ID), N_MUXDEMUX(0)) +indir(`define', concat(`PIPELINE_PCM_', PIPELINE_ID), Low Latency Capture PCM_ID) + +# +# PCM Configuration +# + + +# PCM capabilities supported by FW +PCM_CAPABILITIES(Low Latency Capture PCM_ID, `S32_LE,S24_LE,S16_LE', 48000, 48000, 2, PIPELINE_CHANNELS, 2, 16, 192, 16384, 65536, 65536) + diff --git a/tools/topology/sof/pipe-volume-capture-sched.m4 b/tools/topology/sof/pipe-volume-capture-sched.m4 index 955f96d1ccc6..1a9208d157dd 100644 --- a/tools/topology/sof/pipe-volume-capture-sched.m4 +++ b/tools/topology/sof/pipe-volume-capture-sched.m4 @@ -25,6 +25,16 @@ C_CONTROLMIXER(Master Capture Volume, PIPELINE_ID, Channel register and shift for Front Left/Right, LIST(` ', KCONTROL_CHANNEL(FL, 1, 0), KCONTROL_CHANNEL(FR, 1, 1))) +# +# Volume Configuration +# + +W_VENDORTUPLES(capture_pga_tokens, sof_volume_tokens, +LIST(` ', `SOF_TKN_VOLUME_RAMP_STEP_TYPE "0"' + ` ', `SOF_TKN_VOLUME_RAMP_STEP_MS "250"')) + +W_DATA(capture_pga_conf, capture_pga_tokens) + # # Components and Buffers # @@ -34,7 +44,7 @@ C_CONTROLMIXER(Master Capture Volume, PIPELINE_ID, W_PCM_CAPTURE(PCM_ID, Passthrough Capture, 0, 2) # "Volume" has x source and 2 sink periods -W_PGA(0, PIPELINE_FORMAT, 2, DAI_PERIODS, LIST(` ', "PIPELINE_ID Master Capture Volume")) +W_PGA(0, PIPELINE_FORMAT, 2, DAI_PERIODS, capture_pga_conf, LIST(` ', "PIPELINE_ID Master Capture Volume")) # Capture Buffers W_BUFFER(0, COMP_BUFFER_SIZE(2, @@ -65,7 +75,7 @@ P_GRAPH(pipe-pass-vol-capture-PIPELINE_ID, PIPELINE_ID, indir(`define', concat(`PIPELINE_SINK_', PIPELINE_ID), N_BUFFER(1)) indir(`define', concat(`PIPELINE_PCM_', PIPELINE_ID), Passthrough Capture PCM_ID) -W_PIPELINE(SCHED_COMP, SCHEDULE_PERIOD, SCHEDULE_PRIORITY, SCHEDULE_CORE, SCHEDULE_TIME_DOMAIN, pipe_media_schedule_plat) +W_PIPELINE(N_PCMC(PCM_ID), SCHEDULE_PERIOD, SCHEDULE_PRIORITY, SCHEDULE_CORE, SCHEDULE_TIME_DOMAIN, pipe_media_schedule_plat) # # PCM Configuration #