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

Reply via email to