diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2016-11-04 10:20:36 +0300 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2016-11-07 07:04:58 +0300 |
commit | d92c8adf80fdcd4d08965fe8f8c55b19eb5e870f (patch) | |
tree | c8a0f183cb58c719ad47a3a4148b122aea596301 | |
parent | f20c665ca04a958c007bb047eca42eb1ae2cb7d0 (diff) | |
download | linux-d92c8adf80fdcd4d08965fe8f8c55b19eb5e870f.tar.xz |
drm/nouveau/kms/nv50: convert encoder mode_fixup into an atomic_check()
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_display.c | 70 |
1 files changed, 53 insertions, 17 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 617c57daad21..03a3e3fc84ab 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -2773,8 +2773,50 @@ out: } /****************************************************************************** - * Encoder helpers + * Output path helpers *****************************************************************************/ +static int +nv50_outp_atomic_check_view(struct drm_encoder *encoder, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + struct drm_display_mode *native_mode) +{ + struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; + struct drm_display_mode *mode = &crtc_state->mode; + struct drm_connector *connector = conn_state->connector; + struct nouveau_conn_atom *asyc = nouveau_conn_atom(conn_state); + struct nouveau_drm *drm = nouveau_drm(encoder->dev); + + NV_ATOMIC(drm, "%s atomic_check\n", encoder->name); + asyc->scaler.full = false; + if (!native_mode) + return 0; + + if (asyc->scaler.mode == DRM_MODE_SCALE_NONE) { + switch (connector->connector_type) { + case DRM_MODE_CONNECTOR_LVDS: + case DRM_MODE_CONNECTOR_eDP: + /* Force use of scaler for non-EDID modes. */ + if (adjusted_mode->type & DRM_MODE_TYPE_DRIVER) + break; + mode = native_mode; + asyc->scaler.full = true; + break; + default: + break; + } + } else { + mode = native_mode; + } + + if (!drm_mode_equal(adjusted_mode, mode)) { + drm_mode_copy(adjusted_mode, mode); + crtc_state->mode_changed = true; + } + + return 0; +} + static bool nv50_encoder_mode_fixup(struct drm_encoder *encoder, const struct drm_display_mode *mode, @@ -2785,23 +2827,17 @@ nv50_encoder_mode_fixup(struct drm_encoder *encoder, nv_connector = nouveau_encoder_connector_get(nv_encoder); if (nv_connector && nv_connector->native_mode) { - nv_connector->scaling_full = false; - if (nv_connector->scaling_mode == DRM_MODE_SCALE_NONE) { - switch (nv_connector->type) { - case DCB_CONNECTOR_LVDS: - case DCB_CONNECTOR_LVDS_SPWG: - case DCB_CONNECTOR_eDP: - /* force use of scaler for non-edid modes */ - if (adjusted_mode->type & DRM_MODE_TYPE_DRIVER) - return true; - nv_connector->scaling_full = true; - break; - default: - return true; - } - } + struct nouveau_conn_atom *asyc + = nouveau_conn_atom(nv_connector->base.state); + struct drm_crtc_state crtc_state = { + .mode = *mode, + .adjusted_mode = *adjusted_mode, + }; - drm_mode_copy(adjusted_mode, nv_connector->native_mode); + nv50_outp_atomic_check_view(encoder, &crtc_state, &asyc->state, + nv_connector->native_mode); + nv_connector->scaling_full = asyc->scaler.full; + drm_mode_copy(adjusted_mode, &crtc_state.adjusted_mode); } return true; |