summaryrefslogtreecommitdiff
path: root/drm/nouveau
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2016-11-04 17:20:36 +1000
committerBen Skeggs <bskeggs@redhat.com>2016-11-07 10:06:23 +1000
commit0380f45d2a12ca18f32e6735df5b4654f4b4606e (patch)
treeb8e8af42f273fc7bbb9092f9128ecc260406b8ab /drm/nouveau
parent5d6f4c0eda2b2f1d12f104a14d898a5ac821fc0d (diff)
downloadnouveau-0380f45d2a12ca18f32e6735df5b4654f4b4606e.tar.gz
kms/nv50: convert encoder mode_fixup into an atomic_check()
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drm/nouveau')
-rw-r--r--drm/nouveau/nv50_display.c70
1 files changed, 53 insertions, 17 deletions
diff --git a/drm/nouveau/nv50_display.c b/drm/nouveau/nv50_display.c
index 617c57daa..03a3e3fc8 100644
--- a/drm/nouveau/nv50_display.c
+++ b/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;