AMD Phoenix 1002:1640 Radeon HDA WALLCLK becomes 5.76 MHz after s2idle resume

From: Akhmed Zhitaev

Date: Sun Aug 16 2026 - 11:20:52 EST


Hello,

I am investigating an AMD Phoenix/Hawk Point laptop with an integrated Radeon GPU and a reproducible audio-timing failure after s2idle resume.

Hardware:

GPU: 0000:6e:00.0, PCI ID 1002:1900
Radeon HDA: 0000:6e:00.1, PCI ID 1002:1640
Analog HDA: 0000:6e:00.6
Parent: 0000:00:08.1, Phoenix internal GPP bridge
DCN: 3.1.4
NBIO: 7.7.0, nbio_v7_7_funcs
MP1/SMU: 13.0.10, smu_v13_0_0

The internal eDP panel is active. No external HDMI/DP sink is connected; Radeon HDA ELD entries report no monitor present and invalid ELD.

After cold boot, Radeon HDMI/DP playback is normal. After a reproducing s2idle cycle, playback stutters in Firefox, Telegram/AyuGram, and mpv. The failure reproduces with direct ALSA, without PipeWire; with hardware decoding enabled or disabled; and with Vulkan or OpenGL rendering. The Ryzen analog HDA remains smooth.

With mpv, normal A/V synchronization, display-resample, and display-vdrop stutter. --video-sync=desync makes video smooth while A/V drifts by seconds.

Direct HDA controller measurements were taken through the existing kernel MMIO mapping. The active stream used S32_LE, 8 channels, 48000 Hz, buffer_size 32768 frames. Expected transport rate is 1,536,000 bytes/s.

GOOD cold boot:
WALLCLK approximately 23,999,690 Hz
LPIB approximately 1,535,987 bytes/s
approximately 47,999 frames/s

BAD after s2idle:
WALLCLK approximately 5,759,926 Hz
LPIB approximately 368,638 bytes/s
approximately 11,519 frames/s

The BAD/GOOD ratio is approximately 0.24, close to 6/25. System monotonic timestamps advance normally, so this is not merely an ALSA timestamp or hw_ptr accounting error.

HDA PM-boundary probes show:

GOOD cold boot: hda_intel_init_chip() -> approximately 24 MHz
BAD resume: hda_intel_init_chip() -> approximately 5.76 MHz

A complete runtime suspend/resume of 0000:6e:00.1 produced:

runtime-suspend-entry: approximately 5.76 MHz
after controller shutdown: 0
runtime-resume-entry: 0
after azx_init_pci(): 0
after hda_intel_init_chip(): approximately 5.76 MHz

The bad source clock therefore survives the local HDA controller power cycle.

The following did not restore 24 MHz:

snd_hda_intel unbind/bind of 0000:6e:00.1
PCI PM reset of 0000:6e:00.1
full runtime suspend/resume of 0000:6e:00.1
amdgpu MODE2 GPU recovery followed by SMU resume

MODE1 was attempted once, but GFX/MES resume failed. No post-MODE1 HDA WALLCLK measurement was obtained, so no conclusion about MODE1 HDA recovery is drawn.

The HDAU ACPI power resource performs OFF -> ON successfully. Radeon HDA normal resume is ordered after completion of the amdgpu parent resume.

The active AMDGPU resume path in the v7.1.8 tree is:

amdgpu_pmops_resume()
-> amdgpu_device_resume()
-> amdgpu_device_ip_resume()
phase1: soc21_common_resume, gmc_v11_0_resume, ih_v6_0_resume
phase2: smu_resume, gfx_v11_0_resume, sdma_v6_0_resume,
vcn_v4_0_resume, jpeg_v4_0_resume, mes_v11_0_resume
phase3: dm_resume

On normal non-SR-IOV resume, PSP is excluded from the IP resume phases. For S0ix, PSP is also intentionally skipped during suspend because the source describes it as always-on hardware whose firmware/TMR state is reused.

The active smu_v13_0_0_ppt_funcs has no gfx_state_change_set member, so the generic D0-entry call has no ASIC-specific implementation on this path.

The active NBIO discovery dispatch is:

IP_VERSION(7, 7, 0) / (7, 7, 1)
-> adev->nbio.funcs = &nbio_v7_7_funcs

soc21_common_resume() invokes soc21_common_hw_init(), which calls nbio_v7_7_init_registers() during resume as well as cold initialization.

Read-only NBIO snapshots of the registers referenced by the active implementation were bit-identical at pre-s0ix, post-resume-pre-atomic, and post-atomic-restore:

BIF0_PCIE_MST_CTRL_3
BIF0_CPM_CONTROL
BIF0_PCIE_CNTL2
BIF0_PCIE_TX_POWER_CTRL_1
RCC_DEV0_EPF5_STRAP4

The logged DCN audio DTO and clock-manager state did not show a corresponding 6/25 change. These display-side DTO registers are distinct from the PCI HDA WALLCLK register.

The v7.1.8 tree contains BacoAudioD3PME and EnableAudioStutterWA definitions, but BacoAudioD3PME is not mapped in the active smu_v13_0_0 message map and the active PPT implementation has no set_azalia_d3_pme callback. EnableAudioStutterWA has no active Phoenix mapping or callback. Neither is being presented as a known fix, and neither was sent.

The evidence establishes that the Radeon HDA WALLCLK itself changes from approximately 24 MHz to approximately 5.76 MHz after s2idle; the stream DMA follows the same ratio; the state survives local HDA recovery and MODE2 recovery; and it is not explained by the logged DCN DTO or NBIO state. The remaining hypothesis is a platform- or firmware-owned reference-clock mux/divider or power-domain state affecting GP17/HDAU that is not restored correctly across S0ix. This is a hypothesis, not a demonstrated register-level root cause.

I would appreciate guidance on whether Phoenix/Hawk Point PMFW has a documented HDA/Azalia clock restore sequence, whether an audio-specific SMU message is expected for this ASIC, and whether PSP or platform firmware is expected to restore the GP17/HDAU reference clock during S0ix resume.

No kernel workaround has been added, and no undocumented SMU message has been issued.

======================================================================
Appendix A: Representative GOOD/BAD HDA measurements
======================================================================

HDA controller timing samples (PCI 0000:6e:00.1, PCM8, S32_LE, 8ch, 48000 Hz)

GOOD cold boot:
WALLCLK_Hz=23999690
LPIB_Bps=1535987
frames_per_sec=47999
configured_rate=48000

BAD after s2idle + AC wake:
WALLCLK_Hz=5759926
LPIB_Bps=368638
frames_per_sec=11519
configured_rate=48000

BAD/GOOD ratio: approximately 0.24 (approximately 6/25).

======================================================================
Appendix B: HDA PM-boundary measurements
======================================================================

Radeon HDA PM-boundary WALLCLK measurements (0000:6e:00.1, 1002:1640)

GOOD cold-boot initialization:
hda_intel_init_chip(): approximately 24 MHz

Failing system resume after s2idle:
hda_intel_init_chip(): approximately 5.76 MHz

BAD runtime suspend/resume:
runtime-suspend-entry: approximately 5.76 MHz
after controller shutdown: 0
runtime-resume-entry: 0
after azx_init_pci(): 0
after hda_intel_init_chip(): approximately 5.76 MHz

======================================================================
Appendix C: NBIO/DCN state snapshots
======================================================================

NBIO 7.7.0, implementation nbio_v7_7_funcs.

Read-only NBIO snapshots were bit-identical at:

pre-s0ix
post-resume-pre-atomic
post-atomic-restore

Registers:
BIF0_PCIE_MST_CTRL_3
BIF0_CPM_CONTROL
BIF0_PCIE_CNTL2
BIF0_PCIE_TX_POWER_CTRL_1
RCC_DEV0_EPF5_STRAP4

Relevant DCN phase state:
xtalin=24000, dccg_ref=24000
audio_dtb_dto=00000001/00000000
audio_dto_src=00000030
dtb_p=00000492

The visible DCN audio DTO state did not change by the 6/25 ratio across the failing resume. These display-side DTO registers are distinct from the PCI HDA controller WALLCLK register.

Thanks,
Akhmed Zhitaev