]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/gpu/drm/nouveau/nv50_display.c
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma
[linux.git] / drivers / gpu / drm / nouveau / nv50_display.c
index e3132a2ce34d60acb9eb75cdf83ec1506e8f874b..2bc0dc9852144cfe0825b5da075333d9e85c5b9c 100644 (file)
@@ -3674,15 +3674,24 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe)
        drm_mode_connector_attach_encoder(connector, encoder);
 
        if (dcbe->type == DCB_OUTPUT_DP) {
+               struct nv50_disp *disp = nv50_disp(encoder->dev);
                struct nvkm_i2c_aux *aux =
                        nvkm_i2c_aux_find(i2c, dcbe->i2c_index);
                if (aux) {
-                       nv_encoder->i2c = &nv_connector->aux.ddc;
+                       if (disp->disp->oclass < GF110_DISP) {
+                               /* HW has no support for address-only
+                                * transactions, so we're required to
+                                * use custom I2C-over-AUX code.
+                                */
+                               nv_encoder->i2c = &aux->i2c;
+                       } else {
+                               nv_encoder->i2c = &nv_connector->aux.ddc;
+                       }
                        nv_encoder->aux = aux;
                }
 
                /*TODO: Use DP Info Table to check for support. */
-               if (nv50_disp(encoder->dev)->disp->oclass >= GF110_DISP) {
+               if (disp->disp->oclass >= GF110_DISP) {
                        ret = nv50_mstm_new(nv_encoder, &nv_connector->aux, 16,
                                            nv_connector->base.base.id,
                                            &nv_encoder->dp.mstm);
@@ -3931,6 +3940,8 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
 
                NV_ATOMIC(drm, "%s: clr %04x (set %04x)\n", crtc->name,
                          asyh->clr.mask, asyh->set.mask);
+               if (crtc_state->active && !asyh->state.active)
+                       drm_crtc_vblank_off(crtc);
 
                if (asyh->clr.mask) {
                        nv50_head_flush_clr(head, asyh, atom->flush_disable);
@@ -4016,11 +4027,13 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
                        nv50_head_flush_set(head, asyh);
                        interlock_core = 1;
                }
-       }
 
-       for_each_crtc_in_state(state, crtc, crtc_state, i) {
-               if (crtc->state->event)
-                       drm_crtc_vblank_get(crtc);
+               if (asyh->state.active) {
+                       if (!crtc_state->active)
+                               drm_crtc_vblank_on(crtc);
+                       if (asyh->state.event)
+                               drm_crtc_vblank_get(crtc);
+               }
        }
 
        /* Update plane(s). */
@@ -4067,12 +4080,14 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
                if (crtc->state->event) {
                        unsigned long flags;
                        /* Get correct count/ts if racing with vblank irq */
-                       drm_accurate_vblank_count(crtc);
+                       if (crtc->state->active)
+                               drm_accurate_vblank_count(crtc);
                        spin_lock_irqsave(&crtc->dev->event_lock, flags);
                        drm_crtc_send_vblank_event(crtc, crtc->state->event);
                        spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
                        crtc->state->event = NULL;
-                       drm_crtc_vblank_put(crtc);
+                       if (crtc->state->active)
+                               drm_crtc_vblank_put(crtc);
                }
        }