Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions app/boards/acp_7_x_adsp.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
CONFIG_ACP_7_X=y
CONFIG_HAVE_AGENT=n
CONFIG_DCACHE_LINE_SIZE_DETECT=n
CONFIG_DCACHE_LINE_SIZE=128
CONFIG_DYNAMIC_INTERRUPTS=y
CONFIG_SHARED_INTERRUPTS=n
CONFIG_ZEPHYR_LOG=y
CONFIG_LOG_MODE_DEFERRED=n
CONFIG_LOG_MODE_MINIMAL=y
CONFIG_DMA=y
CONFIG_DMA_DOMAIN=n
CONFIG_ZEPHYR_NATIVE_DRIVERS=y
CONFIG_INTC_AMD_ACP=y
CONFIG_DMA_AMD_ACP_HOST=y
CONFIG_DMA_AMD_ACP_SDW=y
CONFIG_DAI_AMD_SDW=y
CONFIG_AMS=n
CONFIG_WRAP_ACTUAL_POSITION=y
CONFIG_TRACE=n
CONFIG_COMP_VOLUME=y
CONFIG_COMP_SRC=n
CONFIG_COMP_FIR=n
CONFIG_COMP_IIR=n
CONFIG_COMP_DCBLOCK=n
CONFIG_COMP_CROSSOVER=n
CONFIG_COMP_DRC=n
CONFIG_COMP_MULTIBAND_DRC=n
CONFIG_COMP_TONE=n
CONFIG_COMP_KPB=n
CONFIG_MAXIM_DSM=n
CONFIG_COMP_ASRC=n
CONFIG_COMP_IGO_NR=n
CONFIG_COMP_COPIER=n
CONFIG_COMP_RTNR=n
CONFIG_COMP_ARIA=n
CONFIG_COMP_BASEFW_IPC4=n
CONFIG_COMP_UP_DOWN_MIXER=n
CONFIG_COMP_TDFB=n
CONFIG_COMP_SEL=n
CONFIG_COMP_MIXER=n
CONFIG_ASRC_SUPPORT_CONVERSION_24000_TO_08000=n
CONFIG_ASRC_SUPPORT_CONVERSION_24000_TO_16000=n
CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_08000=n
CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_11025=n
CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_12000=n
CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_16000=n
CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_22050=n
CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_24000=n
CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_32000=n
CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_44100=n
CONFIG_CORE_COUNT=1
CONFIG_FORMAT_CONVERT_HIFI3=n
8 changes: 7 additions & 1 deletion scripts/xtensa-build-zephyr.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ class PlatformConfig:
"ACP_7_0_HiFi5_NNE_PROD",
RIMAGE_KEY = "key param ignored by acp_7_0"
),
"acp_7_x" : PlatformConfig(
"amd", "acp_7_x_adsp/acp_7_x",
f"RI-2022.9{xtensa_tools_version_postfix}",
"ACP73x_HiFi5_NNE_PROD",
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in latest push.
Updated XCHAL_CORE_ID in core-isa.h to "ACP73x_HiFi5_NNE_PROD" to match XTENSA_CORE. The core-isa.h value was incorrect, not the build script.

RIMAGE_KEY = "key param ignored by acp_7_x"
),
# MediaTek platforms
# (move to platform_configs_all on next Zephyr SDK release after 0.17.0)
"mt8195" : PlatformConfig(
Expand Down Expand Up @@ -1324,7 +1330,7 @@ def gzip_compress(fname, gzdst=None):
RI_INFO_UNSUPPORTED = []

RI_INFO_UNSUPPORTED += ['imx8', 'imx8x', 'imx8m', 'imx8m_cm7', 'imx8ulp', 'imx95']
RI_INFO_UNSUPPORTED += ['rn', 'acp_6_0', 'acp_7_0']
RI_INFO_UNSUPPORTED += ['rn', 'acp_6_0', 'acp_7_0', 'acp_7_x']
RI_INFO_UNSUPPORTED += ['mt8186', 'mt8188', 'mt8195', 'mt8196', 'mt8365']
RI_INFO_UNSUPPORTED += ['qemu_xtensa', 'qemu_xtensa_mmu']

Expand Down
32 changes: 32 additions & 0 deletions src/arch/xtensa/configs/acp_7_x_defconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
CONFIG_ACP_7_X=y
CONFIG_RIMAGE_SIGNING_SCHEMA="acp_7_3"
CONFIG_TRACE_CHANNEL=7
CONFIG_WRAP_ACTUAL_POSITION=y
CONFIG_CORE_COUNT=1
CONFIG_FORMAT_CONVERT_HIFI3=n
CONFIG_LP_SRAM=n
CONFIG_HAVE_AGENT=n
CONFIG_COMP_VOLUME=y
CONFIG_COMP_SRC=n
CONFIG_COMP_FIR=n
CONFIG_COMP_IIR=n
CONFIG_COMP_DCBLOCK=n
CONFIG_COMP_CROSSOVER=n
CONFIG_COMP_DRC=n
CONFIG_COMP_MULTIBAND_DRC=n
CONFIG_COMP_TONE=n
CONFIG_COMP_SWITCH=n
CONFIG_COMP_KPB=n
CONFIG_MAXIM_DSM=n
CONFIG_COMP_ASRC=n
CONFIG_COMP_IGO_NR=n
CONFIG_COMP_COPIER=n
CONFIG_COMP_RTNR=n
CONFIG_COMP_ARIA=n
CONFIG_COMP_BASEFW_IPC4=n
CONFIG_COMP_UP_DOWN_MIXER=n
CONFIG_COMP_TDFB=n
CONFIG_COMP_MUX=n
CONFIG_COMP_SEL=n
CONFIG_COMP_MIXER=n
CONFIG_PROBE=n
5 changes: 5 additions & 0 deletions src/audio/pcm_converter/pcm_converter_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -712,8 +712,13 @@ const struct pcm_func_map pcm_func_map[] = {
{ SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, pcm_convert_s32_to_s16 },
#endif /* CONFIG_PCM_CONVERTER_FORMAT_S32LE && CONFIG_PCM_CONVERTER_FORMAT_S16LE */
#if CONFIG_PCM_CONVERTER_FORMAT_S32LE && CONFIG_PCM_CONVERTER_FORMAT_S24LE
#if defined(CONFIG_SOC_ACP_7_X)
{ SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, just_copy },
{ SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, pcm_convert_s32_to_s24_be },
#else
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you @singalsu check this? This is first time we have HW dependencies the the PCM converter list.

It would prefer if we could keep same interpretations of the sample formats. This patch suggest your hardware natively 24bit encoding where the audio samples are stored in the 3 most significant bytes. The format we use for this is SOF_IPC_FRAME_S24_4LE_MSB.

So in theory, you'd set the correct format in either DSP topology, or some of the HW specific code. E.g. for Intel, we overrode the sample format in sof/src/ipc/ipc3/dai.c:ipc_dai_data_config().

Then we could keep the converter table vendor neutral.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review.
The ACP 7.X hardware DMA strips the LSB byte from the 32-bit container and transmits only the upper 3 bytes to the bus. So 24-bit samples need to be MSB-aligned (left-shifted by 8) in the 32-bit word before reaching the DMA — which is exactly what pcm_convert_s32_to_s24_be does.
The reason we handle this at the converter level rather than changing the format enum:
PipeWire/ALSA negotiates S24_LE or S32_LE and sends LSB-aligned data (S24_4LE). The host-side format negotiation expects this standard format.
The MSB alignment is a hardware-level requirement specific to how the ACP DMA feeds data to the bus, rather than a format property of the audio pipeline. The converter is the appropriate place to handle this.
Overriding the format in ipc_dai_data_config() would only change the format label without performing the actual bit-shift — the incoming data from the host is still LSB-aligned S24_4LE, so a real conversion step is still needed before the data reaches the DMA.
The #if defined(CONFIG_SOC_ACP_7_X) guard keeps this hardware-specific conversion isolated so it doesn't affect other platforms at all.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two negotiations here, the host side (what ALSA sends to/from SOF/DSP) and DAI side (what SOF/DSP sends to/from audio interfaces). So how this should work (playback example):

  • ALSA can send e.g. S24_LE to DSP (no change)
  • DSP pipe can use intermediate format based on what modules support (either process S24_LE natively or convert to their own intermediate format, this is configured in DSP topology)
  • at DSP output, another negotiation happens and if only a fixed format (e.g. S24_4LE), PCM converter will be setup to convert to the hw supported format

We already do this for some Intel hw audio interfaces and this has worked without having special cases in the PCM converter, so I'd expect same to work in your case for ACP.

Copy link
Copy Markdown
Author

@sneha-voona sneha-voona May 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @kv2019i for your response.
We had already investigated this approach earlier. The S24_4LE_MSB converter entries only exist in the IPC4 pcm_func_vc_map[] table (4-column lookup). The IPC3 pcm_func_map[] table (2-column, used by pcm_get_conversion_function()) has no S24_4LE_MSB entries. So we tried adding new generic S32_LE ↔ S24_4LE_MSB entries to the IPC3 converter table along with the format override in ipc_dai_data_config() — that approach also builds and works.

However, we kept it under CONFIG_SOC_ACP_7_X in the existing converter table to avoid adding new entries that could potentially impact other platforms. If you'd prefer the generic IPC3 table entries approach instead, we already have that ready and build-tested. Please let us know which you'd prefer.

{ SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, pcm_convert_s24_to_s32 },
{ SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, pcm_convert_s32_to_s24 },
#endif
Comment on lines +715 to +721
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review.
The ACP 7.X hardware DMA strips the LSB byte from the 32-bit container and transmits only the upper 3 bytes to the bus. So 24-bit samples need to be MSB-aligned (left-shifted by 8) in the 32-bit word before reaching the DMA — which is exactly what pcm_convert_s32_to_s24_be does.
The reason we handle this at the converter level rather than changing the format enum:
PipeWire/ALSA negotiates S24_LE or S32_LE and sends LSB-aligned data (S24_4LE). The host-side format negotiation expects this standard format.
The MSB alignment is a hardware-level requirement specific to how the ACP DMA feeds data to the bus, rather than a format property of the audio pipeline. The converter is the appropriate place to handle this.
Overriding the format in ipc_dai_data_config() would only change the format label without performing the actual bit-shift — the incoming data from the host is still LSB-aligned S24_4LE, so a real conversion step is still needed before the data reaches the DMA.
The #if defined(CONFIG_SOC_ACP_7_X) guard keeps this hardware-specific conversion isolated so it doesn't affect other platforms at all.

#endif /* CONFIG_PCM_CONVERTER_FORMAT_S32LE && CONFIG_PCM_CONVERTER_FORMAT_S24LE */
#if CONFIG_PCM_CONVERTER_FORMAT_FLOAT
{ SOF_IPC_FRAME_FLOAT, SOF_IPC_FRAME_FLOAT, just_copy },
Expand Down
7 changes: 7 additions & 0 deletions src/audio/volume/volume_ipc3.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,13 @@ int volume_set_config(struct processing_module *mod, uint32_t config_id,
volume_set_ramp_channel_counter(cd, cd->channels);

volume_ramp_check(mod);
#if defined(CONFIG_AMD)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks a bit odd? Why would this be HW/AMD specific functionality?

Copy link
Copy Markdown
Author

@sneha-voona sneha-voona May 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the review.
This fix addresses an issue we observed on AMD platforms where the scale_vol function pointer is not reset after volume reaches its maximum value. When volume hits max, is_passthrough is set to true and scale_vol points to the passthrough function. On subsequent volume decreases, is_passthrough remains set and the correct gain function is never re-selected, so the volume change has no audible effect.
We've guarded this under CONFIG_AMD since this is where we observed, debugged, and verified the fix. We haven't been able to confirm whether other platforms encounter the same behavior, so we kept the guard conservative to avoid any unintended side effects on other platforms.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sneha-voona This sounds like a generic bug, so I think we can drop the "#ifdef" and apply for all. @thesofproject/nxp and @thesofproject/mediatek can you check (as you have usage of this IPC3 volume component).

/* Update function pointer after all volume changes */
if (comp_dev_get_first_data_consumer(dev) != NULL) {
cd->is_passthrough = false;
set_volume_process(cd, dev, false);
}
#endif
break;

case SOF_CTRL_CMD_SWITCH:
Expand Down
6 changes: 5 additions & 1 deletion src/drivers/amd/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# SPDX-License-Identifier: BSD-3-Clause
add_subdirectory(common)
if(CONFIG_RENOIR OR CONFIG_VANGOGH OR CONFIG_REMBRANDT OR CONFIG_ACP_6_3 OR CONFIG_ACP_7_0)
add_subdirectory(common)
endif()
if(CONFIG_RENOIR)
add_subdirectory(renoir)
elseif(CONFIG_REMBRANDT OR CONFIG_ACP_6_3 OR CONFIG_ACP_7_0)
add_subdirectory(rembrandt)
elseif(CONFIG_VANGOGH)
add_subdirectory(vangogh)
elseif(CONFIG_ACP_7_X)
add_subdirectory(acp_7_x)
endif()
5 changes: 5 additions & 0 deletions src/drivers/amd/acp_7_x/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# SPDX-License-Identifier: BSD-3-Clause

add_local_sources(sof
ipc.c
)
Loading
Loading