drm/nouveau/kms/gt215-: fix race with audio driver runpm
authorBen Skeggs <bskeggs@redhat.com>
Fri, 29 May 2020 07:57:29 +0000 (17:57 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Mon, 1 Jun 2020 07:28:42 +0000 (17:28 +1000)
The audio driver can call into nouveau right while we're in the middle
of re-fetching the EDID, and decide it no longer needs to be awake.

Stop depending on EDID in the audio component get_eld() callback, and
instead cache whether audio support is present from the prior modeset.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/dispnv50/disp.c
drivers/gpu/drm/nouveau/nouveau_encoder.h

index 7622490d86024cbe92e61c8ec0bf39a80aad1b48..e8ac510f8298ae565e2b4e450af14885129451f0 100644 (file)
@@ -510,7 +510,7 @@ nv50_audio_component_get_eld(struct device *kdev, int port, int dev_id,
                if (!nv_connector || !nv_crtc || nv_encoder->or != port ||
                    nv_crtc->index != dev_id)
                        continue;
-               *enabled = drm_detect_monitor_audio(nv_connector->edid);
+               *enabled = nv_encoder->audio;
                if (*enabled) {
                        ret = drm_eld_size(nv_connector->base.eld);
                        memcpy(buf, nv_connector->base.eld,
@@ -600,6 +600,7 @@ nv50_audio_disable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc)
                                (0x0100 << nv_crtc->index),
        };
 
+       nv_encoder->audio = false;
        nvif_mthd(&disp->disp->object, 0, &args, sizeof(args));
 
        nv50_audio_component_eld_notify(drm->audio.component, nv_encoder->or,
@@ -636,6 +637,7 @@ nv50_audio_enable(struct drm_encoder *encoder, struct drm_display_mode *mode)
 
        nvif_mthd(&disp->disp->object, 0, &args,
                  sizeof(args.base) + drm_eld_size(args.data));
+       nv_encoder->audio = true;
 
        nv50_audio_component_eld_notify(drm->audio.component, nv_encoder->or,
                                        nv_crtc->index);
index de51733b04761586f7e737fb0426e8192d01bdfa..a72c412ac8b14887959fd64f7f49074e50c3d79c 100644 (file)
@@ -52,6 +52,7 @@ struct nouveau_encoder {
         * actually programmed on the hw, not the proposed crtc */
        struct drm_crtc *crtc;
        u32 ctrl;
+       bool audio;
 
        struct drm_display_mode mode;
        int last_dpms;