From d92c8adf80fdcd4d08965fe8f8c55b19eb5e870f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 4 Nov 2016 17:20:36 +1000 Subject: [PATCH] drm/nouveau/kms/nv50: convert encoder mode_fixup into an atomic_check() Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_display.c | 70 +++++++++++++++++++------- 1 file 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 @@ nv50_crtc_create(struct drm_device *dev, int index) } /****************************************************************************** - * 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; -- GitLab