amd/acp7x: smart_amp: enable Maxim DSM for 2x max98388 on TDM2 - #11250
Open
LongWang100 wants to merge 1 commit into
Open
LongWang100 wants to merge 1 commit into
LongWang100 wants to merge 1 commit into
Conversation
LongWang100
requested review from
dbaluta,
kv2019i,
lbetlej,
lgirdwood,
mmaka1,
plbossart and
ranj063
as code owners
September 30, 2026 03:21
Collaborator
|
Can one of the admins verify this patch?
|
Bring up the Maxim DSM smart amplifier path on ACP7x (Steam Deck /
Gainsborough) with two max98388 amplifiers on a 2-slot TDM2 link.
smart_amp.c:
- Fix source buffer detection on IPC3: bound_module is only assigned by
module_bind() in module_adapter_ipc4.c and stays NULL on IPC3 platforms,
so dereferencing it faulted the DSP. Compare producer pipeline ids
instead -- works under both IPC versions.
- Add 16-byte alignment for DSP buffers via mod_alloc_align(): without it,
Xtensa HiFi AE_L32X2/AE_S64 instructions take LoadStoreAlignmentCause.
- Null-guard source_buf after re-prepare to prevent stale pointer reuse.
maxim_dsm_stub.c:
- Fix stub to fill all output fields read by the caller. The upstream
stub returned DSM_API_OK without writing omemsizerequestedbytes, so
get_handle_size() returned 0, the PRIVATE memblk was never allocated,
dsmhandle stayed NULL and every subsequent DSM call failed with -EINVAL.
The fixed stub also passes through audio (input -> output) so the glue
layer and topology can be validated without libdsm.a.
smart_amp_maxim_dsm.c:
- Fix DSM_FF_BUF_DB_SZ: upstream used FF_BUF_SZ * FF_MAX_CH_NUM = 192,
which is too small for a 2 ms period (192 samples) + pre-fill frame
(96). Change to FF_BUF_SZ * 4 = 384 to cover periods up to 3 ms.
- Add ivFormat=3 (DSM_IV_FORMAT_INTERLEAVED_16_BIT_MSB) support for the
2-slot layout where each max98388 interleaves V and I within one slot
using the sample MSB as a flag. The upstream 4*idx de-interleave stride
reads only one MSB polarity and causes INSUFFICIENT_INPUT_DATA.
- Replace memcpy_s with dsm_buf_shift_down() (memmove-based): SOF's
memcpy_s detects overlapping src/dst and returns -EINVAL without
copying, which occurs whenever period > 2 ms and caused silent buffer
desynchronisation.
- Change if to while in ff_proc and fb_proc: a 2 ms period delivers 2 DSM
frames; if drained only one per call, causing w_ptr to grow until
overflow.
- Remove duplicate dsm_api_ff_process() call in the 32-bit else branch:
libdsm decrements *ipNrSamples in place, making it a no-op today, but
any code re-arming ifsamples per branch would double-advance the
adaptive state (excursion/thermal model, RDC, LMS).
- Set ibsamples = fb_fr_sz_samples * nchannels = 96: libdsm divides by
nChannels internally; passing 48 gives 24 % ffFrameSize != 0 and
returns INVALID_PARAM on every call.
sof-acp_7_x_i2s.m4:
- Switch TDM2 from pipe-passthrough to pipe-smart-amplifier + pipe-amp-ref-capture.
- Define all required SMART_* macros for 2-channel configuration.
- Add cross-pipeline SectionGraph wiring demux -> smart_amp feedback buffer.
- Define REF_CHMAP = {0x01, 0x02} so the echo reference second channel
comes from slot 1 (second amp), not the non-existent slot 2.
- Declare SMART_UUID explicitly to make the active build mode visible.
pipe-amp-ref-capture.m4:
- Allow platforms to pre-define REF_CHMAP to override the default 4-slot
mapping, which routes ch1 to in ch2 (non-existent on 2-slot hardware)
and permanently silences ch1 via mux.c:215.
app/maxim_dsm_overlay.conf:
- Add Kconfig overlay for the three-step DSM bring-up sequence:
step 1 PASSTHRU_AMP, step 2 MAXIM_DSM_STUB, step 3 real libdsm.a.
Signed-off-by: Long Wang <long.wang@analog.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Bring up the Maxim DSM smart amplifier path on ACP7x (Steam Deck /
Gainsborough) with two max98388 amplifiers on a 2-slot TDM2 link.
This patch fixes a series of bugs discovered during hardware bring-up
and wires up the full topology pipeline (playback → smart_amp →
ref-capture → DSM feedback).
Changes
smart_amp.cbound_moduleis only populated bymodule_bind()inmodule_adapter_ipc4.cand is NULL on IPC3platforms; dereferencing it caused a DSP fault. Switch to comparing
producer pipeline IDs, which works under both IPC versions.
mod_alloc_align()to satisfy Xtensa HiFi
AE_L32X2/AE_S64alignment requirements;without this the DSP raises
LoadStoreAlignmentCause.source_bufafter re-prepare to prevent stale pointerreuse.
maxim_dsm_stub.cDSM_API_OKwithout writing
omemsizerequestedbytes, soget_handle_size()returned0, the PRIVATE memblk was never allocated,
dsmhandlestayed NULL, andevery subsequent DSM call failed with
-EINVAL.layer and topology can be validated without
libdsm.a.smart_amp_maxim_dsm.cDSM_FF_BUF_DB_SZ: upstream usedFF_BUF_SZ * FF_MAX_CH_NUM= 192, too small for a 2 ms period (192 samples) + pre-fill frame (96).
Change to
FF_BUF_SZ * 4= 384 to cover periods up to 3 ms.ivFormat=3(DSM_IV_FORMAT_INTERLEAVED_16_BIT_MSB) support:each max98388 interleaves V and I within one TDM slot using the sample
MSB as a flag; the upstream 4*idx stride read only one MSB polarity and
returned
INSUFFICIENT_INPUT_DATA.memcpy_swithdsm_buf_shift_down()(memmove-based):SOF's
memcpy_srejects overlapping src/dst with-EINVAL, whichoccurs whenever period > 2 ms and caused silent buffer desynchronisation.
iftowhileinff_proc/fb_proc: a 2 ms perioddelivers 2 DSM frames; the previous
ifdrained only one per call,causing
w_ptrto grow until overflow.dsm_api_ff_process()call in the 32-bit elsebranch: libdsm decrements
*ipNrSamplesin-place; a second call woulddouble-advance the adaptive state (excursion/thermal model, RDC, LMS).
ibsamples = fb_fr_sz_samples * nchannels= 96: libdsm dividesby
nChannelsinternally; passing 48 gave24 % ffFrameSize != 0andreturned
INVALID_PARAMon every call.sof-acp_7_x_i2s.m4amp-ref-capture.
SMART_*macros for 2-channel configuration.REF_CHMAP = {0x01, 0x02}so the echo reference second channelcomes from slot 1 (second amp), not the non-existent slot 2.
SMART_UUIDexplicitly to make the active build mode visible.pipe-amp-ref-capture.m4REF_CHMAPto override the default4-slot mapping, which routes ch1 to in ch2 (non-existent on 2-slot
hardware) and permanently silences ch1 via
mux.c:215.app/maxim_dsm_overlay.confPASSTHRU_AMP— verify audio path without DSMMAXIM_DSM_STUB— validate glue layer and topologylibdsm.a— full DSM protectionTest plan
DSM_API_OKreturned,dsmhandlenon-NULL, audio passes throughcorrect on both channels, no
INSUFFICIENT_INPUT_DATA/INVALID_PARAM🤖 Generated with Claude Code