콘텐츠로 이동

DisplayPort 오디오: 동기 불일치, 지연 및 크랙

BC-250의 DisplayPort 출력을 통한 오디오가 영상은 완벽한데 약간 늦게 도착하거나, 음정이 약간 낮거나, 주기적인 크랙이 발생할 수 있습니다. 이 페이지는 실제 근본 원인(이 GPU에 특정한 디스플레이 드라이버의 spread-spectrum 버그), 어댑터 문제와 구별하는 방법, 해결 방법을 설명합니다.

이것은 액티브 DP-HDMI 어댑터가 오디오를 망가뜨리는 문제와 다른 문제입니다. 그 문제는 어댑터가 스트림을 재인코딩하는 것에 관한 것입니다. 이 페이지의 문제는 커널에 있으며 DisplayPort 출력 자체에 영향을 주므로, 네이티브 DP 모니터나 패시브 어댑터에서도 나타날 수 있습니다.


증상

  • 오디오와 영상이 동기화되지 않음, 보통 오디오가 약 100~200ms 늦음
  • 오디오 음정이 약간 낮음
  • 오디오 버퍼가 drift하면서 주기적인 크랙 또는 클릭
  • 영상은 영향 없음

액티브 어댑터에서 오디오가 전혀 나오지 않는 경우, 이 문제가 아니라 어댑터 문제입니다. 액티브 vs 패시브 어댑터 참조.


근본 원인

BC-250의 Cyan Skillfish GPU는 DCN201 디스플레이 블록을 사용하는 유일한 출시 AMD GPU이므로, 이 코드 경로는 사실상 BC-250 전용입니다.

DisplayPort 기준 클럭이 spread spectrum이 적용된 상태로 설정되어 있지만, 보드 펌웨어는 DisplayPort spread spectrum이 꺼져 있어야 한다고 말합니다. DisplayPort 오디오는 같은 기준에서 클럭되므로, 기준 클럭을 dither하면 복원된 오디오 샘플 클럭도 dither됩니다. 영상은 dither를 허용하지만, 오디오 타이밍은 허용하지 않습니다.

메인라인 커널 소스와 대조하여 확인된 체인:

  1. dcn201_clk_mgr.c, dcn201_clk_mgr_construct()가 dprefclk_ss_percentage = 0을 설정한 뒤, 함수 끝에서 조건 없이 dce_clock_read_ss_info()를 호출합니다.
  2. dce_clock_read_ss_info()(dce_clk_mgr.c에 있음)가 VBIOS를 조회합니다. GPU-PLL 조회는 이 VBIOS 리비전에서 unsupported를 반환하므로 DisplayPort 조회로 넘어갑니다.
  3. bios_parser2.c, get_ss_info_v4_2()가 DisplayPort 조회에 smu_info->gpuclk_ss_percentage(GPU 코어 클럭의 spread spectrum, 0x0177 같은 0이 아닌 값)를 반환합니다.
  4. 그 0이 아닌 percentage가 dce_adjust_dp_ref_freq_for_ss()에서 DisplayPort 기준 클럭에 적용되어 오디오 클럭을 이동시킵니다.

DisplayPort spread spectrum이 꺼져 있다고 실제로 말하는 VBIOS 필드(integrated_info->dp_ss_control = 0)는 dcn201_link_init()에서 읽히고 링크 트레이닝에 반영되지만, 클럭 매니저는 이를 보지 않습니다. 이 불일치가 버그입니다.

커널 7.1.x 메인라인에서는 미수정

이전 메모에는 6.19.10 이상에서 해결되었다고 했습니다. 이는 메인라인이 아니라 다운스트림 커뮤니티 커널(패치된 Bazzite / CachyOS 빌드)을 의미합니다. 메인라인 7.1.3은 여전히 dcn201_clk_mgr_construct()에서 dce_clock_read_ss_info()를 무조건 호출하므로 동기 불일치가 존재합니다. dp_ss_control 확인으로 호출을 제한하는 더 깔끔한 수정이 작성 시점에 커널 메일링 리스트에 준비 중이지만 아직 머지되지 않았습니다. 버전 번호를 신뢰하지 말고 커널별로 확인하세요 (아래 참조).


진단

먼저 오디오 싱크가 존재하고 유효한지 확인하세요. 작동하는 DisplayPort 링크에서는 present하고 valid한 ELD를 얻습니다:

aplay -l
# card 0: Generic [HD-Audio Generic], device 3: HDMI 0 [<your monitor name>]

cat /proc/asound/card*/eld*
# monitor_present   1
# eld_valid         1
# connection_type   DisplayPort

eld_valid가 1이고 오디오 포맷이 정상으로 보이지만 여전히 지연, 음정 또는 크랙이 들리면, 어댑터나 EDID가 아니라 기준 클럭 spread spectrum을 가리킵니다.

EDID는 파일 관리자 복사가 아니라 cat으로 캡처하세요 (sysfs 파일 복사 시 0바이트 결과):

cat /sys/class/drm/card*-DP-1/edid > ~/edid
edid-decode ~/edid   # look for the Audio Data Block and sample rates

오디오 재생 중에는 협상된 스트림 파라미터가 실제 사용 중인 포맷을 확인합니다:

cat /proc/asound/card*/pcm*p/sub*/hw_params   # rate, format, channels during playback

내 커널에 수정이 포함되어 있나요?

수정은 지금까지 다운스트림 커널에만 있었으므로 버전 번호는 신뢰할 수 없습니다. 소스를 직접 확인하세요. kernel-devel은 헤더만 제공하므로 매칭 커널 소스 트리가 필요합니다 (예: dnf download --source kernel 또는 배포판의 kernel-source 패키지):

grep -n dp_ss_control <kernel-source>/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c

dcn201_clk_mgr_construct()가 dp_ss_control 확인으로 dce_clock_read_ss_info()를 보호하면 수정이 포함되어 있습니다. 호출이 무조건이면 포함되지 않았습니다.


해결 방법

하드웨어 우회 (재빌드 불필요)

버그를 우회하지 수정하지는 않습니다:

  • 패시브 DP-to-HDMI 어댑터 또는 네이티브 DisplayPort 모니터가 가장 단순합니다.
  • USB DAC는 오디오를 DisplayPort에서 완전히 분리하며, 커널을 재빌드할 수 없을 때 신뢰할 수 있는 방법입니다.

커널 패치 (실제 수정)

런타임 노브는 없습니다. ignore_dpref_ss는 dc_config 필드이며 모듈 파라미터가 아니고 amdgpu.dcdebugmask로도 접근할 수 없으므로, 수정에는 재빌드된 amdgpu 모듈 또는 커널이 필요합니다.

패치는 펌웨어가 꺼져 있다고 말할 때 DisplayPort spread spectrum을 클리어합니다. dcn201_clk_mgr_construct()에 적용:

-    dce_clock_read_ss_info(clk_mgr);
+    /* BC-250: get_ss_info_v4_2() reports the shared GPU-clock spread spectrum
+     * on the DisplayPort query, which desyncs DP audio. Only read DP-ref SS
+     * when the VBIOS says DP spread spectrum is enabled. */
+    if (bp->integrated_info && bp->integrated_info->dp_ss_control)
+        dce_clock_read_ss_info(clk_mgr);

패치된 amdgpu 모듈 빌드는 40 CU 잠금 해제 빌드와 같은 흐름을 따릅니다 (커널 소스, 패치, 컴파일, initramfs 재빌드). 40 CU 잠금 해제용으로 이미 모듈을 재빌드하는 경우, 같은 패스에 이 패치를 추가하세요. 이 패치는 아직 참조 보드에서 테스트되지 않았으므로, 정확한 빌드 단계는 여기서 검증된 것이 아니라 보고된 내용으로 취급하세요.

커널 업데이트 시 되돌아짐

40 CU 잠금 해제와 같이, 패치된 out-of-tree 모듈은 매 커널 업데이트마다 되돌아갑니다. 업데이트 후 재빌드하거나 커널을 고정하세요.


크레딧

근본 원인 분석 및 DCN201 패치는 BC-250 Discord 커뮤니티 작업입니다 (Trov, essdee 및 mzk10의 교차 확인). 위 코드 경로는 메인라인 커널 소스와 대조하여 재확인되었습니다.