linux: fix HDMI audio on monitors with missing EDID audio modes (#18)

Some monitors do not advertise audio modes in their EDID CEA block,
causing audio_info.mode_count to be zero. When this happens, the
channel counting loop never executes and sceHdmiSetAudioConfig is
called with channels=0, which silently disables audio output on the
PS5 HDMI bridge.

Add a stereo (2ch) fallback when no audio modes are found so that
sceHdmiSetAudioConfig always receives a valid channel count.

Also fix a loop variable reuse bug where the inner audio channel
counting loop shared the iterator 'i' with the outer
for_each_oldnew_crtc_in_state loop. Rename the inner iterator to 'j'.
This commit is contained in:
Hasanuddin Abu Bakar
2026-06-22 23:54:33 +08:00
committed by GitHub
parent 2ee68463af
commit 06bb2bb268

View File

@@ -1566,7 +1566,7 @@ index f8c13bad4ac2..e2e6a2605f2a 100644
if ((mode->flags & DRM_MODE_FLAG_INTERLACE) || if ((mode->flags & DRM_MODE_FLAG_INTERLACE) ||
(mode->flags & DRM_MODE_FLAG_DBLSCAN)) (mode->flags & DRM_MODE_FLAG_DBLSCAN))
return result; return result;
@@ -10957,12 +10978,58 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) @@ -10957,12 +10978,62 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
drm_atomic_helper_update_legacy_modeset_state(dev, state); drm_atomic_helper_update_legacy_modeset_state(dev, state);
drm_dp_mst_atomic_wait_for_dependencies(state); drm_dp_mst_atomic_wait_for_dependencies(state);
@@ -1606,13 +1606,17 @@ index f8c13bad4ac2..e2e6a2605f2a 100644
+ drm_atomic_crtc_needs_modeset(new_crtc_state))) { + drm_atomic_crtc_needs_modeset(new_crtc_state))) {
+ if (dm_new_crtc_state->stream && dc_is_dp_signal(dm_new_crtc_state->stream->signal)) { + if (dm_new_crtc_state->stream && dc_is_dp_signal(dm_new_crtc_state->stream->signal)) {
+ struct dc_stream_state *stream = dm_new_crtc_state->stream; + struct dc_stream_state *stream = dm_new_crtc_state->stream;
+ int channels = 0; + int channels = 0, j;
+ +
+ for (i = 0; i < stream->audio_info.mode_count; i++) { + for (j = 0; j < stream->audio_info.mode_count; j++) {
+ if (stream->audio_info.modes[i].channel_count > channels) + if (stream->audio_info.modes[j].channel_count > channels)
+ channels = stream->audio_info.modes[i].channel_count; + channels = stream->audio_info.modes[j].channel_count;
+ } + }
+ +
+ /* Fallback to stereo if EDID has no audio modes */
+ if (channels == 0)
+ channels = 2;
+
+ sceHdmiSetVideoConfig(&new_crtc_state->mode); + sceHdmiSetVideoConfig(&new_crtc_state->mode);
+ sceHdmiDeviceSetVideoMute(0); + sceHdmiDeviceSetVideoMute(0);
+ sceHdmiSetAudioConfig(channels); + sceHdmiSetAudioConfig(channels);