summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_atomic.c
diff options
context:
space:
mode:
authorDaniel Stone2015-05-25 20:11:51 +0200
committerDaniel Vetter2015-05-26 15:50:38 +0200
commit99cf4a29fa24461bbfe22125967188a18383eb5c (patch)
tree3f07dc47f09b2454c697832f16436479d98a8619 /drivers/gpu/drm/drm_atomic.c
parentdrm: Add drm_atomic_set_mode_for_crtc (diff)
downloadkernel-qcow2-linux-99cf4a29fa24461bbfe22125967188a18383eb5c.tar.gz
kernel-qcow2-linux-99cf4a29fa24461bbfe22125967188a18383eb5c.tar.xz
kernel-qcow2-linux-99cf4a29fa24461bbfe22125967188a18383eb5c.zip
drm/atomic: Add current-mode blob to CRTC state
Add a blob property tracking the current mode to the CRTC state, and ensure it is properly updated and referenced. v2: Continue using crtc_state->mode inside getcrtc, instead of reading out the mode blob. Use IS_ERR and PTR_ERR from create_blob. Move set_mode_prop_for_crtc to later patch where it actually gets used. Enforce !!state->enable == !!state->mode_blob inside drm_atomic_crtc_check. Signed-off-by: Daniel Stone <daniels@collabora.com> Tested-by: Sean Paul <seanpaul@chromium.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/drm_atomic.c')
-rw-r--r--drivers/gpu/drm/drm_atomic.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index e749287390a3..327ccc71012f 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -304,11 +304,25 @@ EXPORT_SYMBOL(drm_atomic_get_crtc_state);
int drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state,
struct drm_display_mode *mode)
{
+ struct drm_mode_modeinfo umode;
+
/* Early return for no change. */
if (mode && memcmp(&state->mode, mode, sizeof(*mode)) == 0)
return 0;
+ if (state->mode_blob)
+ drm_property_unreference_blob(state->mode_blob);
+ state->mode_blob = NULL;
+
if (mode) {
+ drm_mode_convert_to_umode(&umode, mode);
+ state->mode_blob =
+ drm_property_create_blob(state->crtc->dev,
+ sizeof(umode),
+ &umode);
+ if (IS_ERR(state->mode_blob))
+ return PTR_ERR(state->mode_blob);
+
drm_mode_copy(&state->mode, mode);
state->enable = true;
DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n",
@@ -324,7 +338,6 @@ int drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state,
}
EXPORT_SYMBOL(drm_atomic_set_mode_for_crtc);
-
/**
* drm_atomic_crtc_set_property - set property on CRTC
* @crtc: the drm CRTC to set a property on
@@ -410,6 +423,23 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc,
return -EINVAL;
}
+ /* The state->enable vs. state->mode_blob checks can be WARN_ON,
+ * as this is a kernel-internal detail that userspace should never
+ * be able to trigger. */
+ if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) &&
+ WARN_ON(state->enable && !state->mode_blob)) {
+ DRM_DEBUG_ATOMIC("[CRTC:%d] enabled without mode blob\n",
+ crtc->base.id);
+ return -EINVAL;
+ }
+
+ if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) &&
+ WARN_ON(!state->enable && state->mode_blob)) {
+ DRM_DEBUG_ATOMIC("[CRTC:%d] disabled with mode blob\n",
+ crtc->base.id);
+ return -EINVAL;
+ }
+
return 0;
}