drm/nouveau/kms/nv50: ensure encoder normal power state is enabled at startup
authorBen Skeggs <bskeggs@redhat.com>
Fri, 4 Nov 2016 07:20:36 +0000 (17:20 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Mon, 7 Nov 2016 04:04:57 +0000 (14:04 +1000)
To handle low-power DPMS states, we currently change an OR's (Output
Resource) normal (active) power state to be off, leaving the rest of
the display configured as usual.

Under atomic modesetting, we will instead be doing a full modeset to
tear down the pipe fully when entering a low-power state.

As we'll no longer be touching the OR's PWR registers during runtime
operation, we need to ensure the normal power state is set correctly
during initialisation.

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

index 4c7b53fea37c1514955be263b5e520a89ada727c..742ac7cbff55f71b62a3ecf6a44cbc431105ffd1 100644 (file)
@@ -3790,6 +3790,7 @@ int
 nv50_display_init(struct drm_device *dev)
 {
        struct nv50_disp *disp = nv50_disp(dev);
+       struct drm_encoder *encoder;
        struct drm_plane *plane;
        struct drm_crtc *crtc;
        u32 *push;
@@ -3809,6 +3810,24 @@ nv50_display_init(struct drm_device *dev)
        evo_data(push, nv50_mast(dev)->base.sync.handle);
        evo_kick(push, nv50_mast(dev));
 
+       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+               if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) {
+                       const struct drm_encoder_helper_funcs *help;
+                       struct nouveau_encoder *nv_encoder;
+
+                       nv_encoder = nouveau_encoder(encoder);
+                       if (nv_encoder->dcb->type == DCB_OUTPUT_DP)
+                               nv_encoder->dcb->type = DCB_OUTPUT_EOL;
+
+                       help = encoder->helper_private;
+                       if (help && help->dpms)
+                               help->dpms(encoder, DRM_MODE_DPMS_ON);
+
+                       if (nv_encoder->dcb->type == DCB_OUTPUT_EOL)
+                               nv_encoder->dcb->type = DCB_OUTPUT_DP;
+               }
+       }
+
        drm_for_each_plane(plane, dev) {
                struct nv50_wndw *wndw = nv50_wndw(plane);
                if (plane->funcs != &nv50_wndw)