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

Akhmed Zhitaev <[email protected]>
Newsgroups org.kernel.vger.linux-sound,org.freedesktop.lists.amd-gfx,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.