All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rob Clark <rob.clark@linaro.org>
To: dri-devel@lists.freedesktop.org
Cc: daniel.vetter@ffwll.ch, Rob Clark <rob@ti.com>, patches@linaro.org
Subject: [RFC 7/9] drm: add drm_crtc_state
Date: Sun,  9 Sep 2012 22:03:20 -0500	[thread overview]
Message-ID: <1347246202-24249-8-git-send-email-rob.clark@linaro.org> (raw)
In-Reply-To: <1347246202-24249-1-git-send-email-rob.clark@linaro.org>

From: Rob Clark <rob@ti.com>

Start breaking out the mutable state of the CRTC into it's own
structure.  Plus add _check_state() and _set_property() helpers.
This only moves the state that is related to scanout fb, which
is needed for nuclear-pageflip.  The rest of the mutable state
should be moved from drm_crtc to drm_crtc_state as part of the
atomic-modeset implementation.
---
 drivers/gpu/drm/drm_crtc.c        |   70 +++++++++++++++++++++++++++++++------
 drivers/gpu/drm/drm_crtc_helper.c |   51 ++++++++++++++-------------
 drivers/gpu/drm/drm_fb_helper.c   |   11 +++---
 include/drm/drm_crtc.h            |   44 +++++++++++++++++------
 4 files changed, 125 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 8be57e4..0ddd43e 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -397,7 +397,7 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb)
 
 	/* remove from any CRTC */
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		if (crtc->fb == fb) {
+		if (crtc->state->fb == fb) {
 			/* should turn off the crtc */
 			drm_mode_crtc_set_obj_prop(crtc, state, config->prop_crtc_id, 0);
 		}
@@ -447,7 +447,7 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
 
 	crtc->dev = dev;
 	crtc->funcs = funcs;
-	crtc->invert_dimensions = false;
+	crtc->state->invert_dimensions = false;
 
 	mutex_lock(&dev->mode_config.mutex);
 
@@ -496,6 +496,54 @@ void drm_crtc_cleanup(struct drm_crtc *crtc)
 }
 EXPORT_SYMBOL(drm_crtc_cleanup);
 
+int drm_crtc_check_state(struct drm_crtc *crtc,
+		struct drm_crtc_state *state)
+{
+	struct drm_framebuffer *fb = state->fb;
+	int hdisplay, vdisplay;
+
+	hdisplay = crtc->mode.hdisplay;
+	vdisplay = crtc->mode.vdisplay;
+
+	if (state->invert_dimensions)
+		swap(hdisplay, vdisplay);
+
+	if (hdisplay > fb->width ||
+	    vdisplay > fb->height ||
+	    state->x > fb->width - hdisplay ||
+	    state->y > fb->height - vdisplay) {
+		DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
+			      fb->width, fb->height, hdisplay, vdisplay,
+			      state->x, state->y,
+			      state->invert_dimensions ? " (inverted)" : "");
+		return -ENOSPC;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_crtc_check_state);
+
+int drm_crtc_set_property(struct drm_crtc *crtc,
+		struct drm_crtc_state *state,
+		struct drm_property *property, uint64_t value)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_mode_config *config = &dev->mode_config;
+
+	if (property == config->prop_fb_id) {
+		state->fb = U642VOID(value);
+	} else if (property == config->prop_crtc_x) {
+		state->x = *(int *)&value;
+	} else if (property == config->prop_crtc_y) {
+		state->y = *(int32_t *)&value;
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_crtc_set_property);
+
 /**
  * drm_mode_probed_add - add a mode to a connector's probed mode list
  * @connector: connector the new mode
@@ -1593,11 +1641,11 @@ int drm_mode_getcrtc(struct drm_device *dev,
 	}
 	crtc = obj_to_crtc(obj);
 
-	crtc_resp->x = crtc->x;
-	crtc_resp->y = crtc->y;
+	crtc_resp->x = crtc->state->x;
+	crtc_resp->y = crtc->state->y;
 	crtc_resp->gamma_size = crtc->gamma_size;
-	if (crtc->fb)
-		crtc_resp->fb_id = crtc->fb->base.id;
+	if (crtc->state->fb)
+		crtc_resp->fb_id = crtc->state->fb->base.id;
 	else
 		crtc_resp->fb_id = 0;
 
@@ -2042,12 +2090,12 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
 		/* If we have a mode we need a framebuffer. */
 		/* If we pass -1, set the mode with the currently bound fb */
 		if (crtc_req->fb_id == -1) {
-			if (!crtc->fb) {
+			if (!crtc->state->fb) {
 				DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
 				ret = -EINVAL;
 				goto out;
 			}
-			fb = crtc->fb;
+			fb = crtc->state->fb;
 		} else {
 			obj = drm_mode_object_find(dev, crtc_req->fb_id,
 						   DRM_MODE_OBJECT_FB);
@@ -2077,7 +2125,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
 		hdisplay = mode->hdisplay;
 		vdisplay = mode->vdisplay;
 
-		if (crtc->invert_dimensions)
+		if (crtc->state->invert_dimensions)
 			swap(hdisplay, vdisplay);
 
 		if (hdisplay > fb->width ||
@@ -2087,7 +2135,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
 			DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
 				      fb->width, fb->height,
 				      hdisplay, vdisplay, crtc_req->x, crtc_req->y,
-				      crtc->invert_dimensions ? " (inverted)" : "");
+				      crtc->state->invert_dimensions ? " (inverted)" : "");
 			ret = -ENOSPC;
 			goto out;
 		}
@@ -3773,7 +3821,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
 		goto out;
 	crtc = obj_to_crtc(obj);
 
-	if (crtc->fb == NULL) {
+	if (crtc->state->fb == NULL) {
 		/* The framebuffer is currently unbound, presumably
 		 * due to a hotplug event, that userspace has not
 		 * yet discovered.
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 3252e70..65ed229 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -266,7 +266,7 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)
 				(*crtc_funcs->disable)(crtc);
 			else
 				(*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
-			crtc->fb = NULL;
+			crtc->state->fb = NULL;
 		}
 	}
 }
@@ -363,15 +363,15 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
 
 	saved_hwmode = crtc->hwmode;
 	saved_mode = crtc->mode;
-	saved_x = crtc->x;
-	saved_y = crtc->y;
+	saved_x = crtc->state->x;
+	saved_y = crtc->state->y;
 
 	/* Update crtc values up front so the driver can rely on them for mode
 	 * setting.
 	 */
 	crtc->mode = *mode;
-	crtc->x = x;
-	crtc->y = y;
+	crtc->state->x = x;
+	crtc->state->y = y;
 
 	/* Pass our mode to the connectors and the CRTC to give them a chance to
 	 * adjust it according to limitations or connector properties, and also
@@ -456,8 +456,8 @@ done:
 	if (!ret) {
 		crtc->hwmode = saved_hwmode;
 		crtc->mode = saved_mode;
-		crtc->x = saved_x;
-		crtc->y = saved_y;
+		crtc->state->x = saved_x;
+		crtc->state->y = saved_y;
 	}
 
 	return ret;
@@ -591,29 +591,29 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 
 	save_set.crtc = set->crtc;
 	save_set.mode = &set->crtc->mode;
-	save_set.x = set->crtc->x;
-	save_set.y = set->crtc->y;
-	save_set.fb = set->crtc->fb;
+	save_set.x = set->crtc->state->x;
+	save_set.y = set->crtc->state->y;
+	save_set.fb = set->crtc->state->fb;
 
 	/* We should be able to check here if the fb has the same properties
 	 * and then just flip_or_move it */
-	if (set->crtc->fb != set->fb) {
+	if (set->crtc->state->fb != set->fb) {
 		/* If we have no fb then treat it as a full mode set */
-		if (set->crtc->fb == NULL) {
+		if (set->crtc->state->fb == NULL) {
 			DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
 			mode_changed = true;
 		} else if (set->fb == NULL) {
 			mode_changed = true;
-		} else if (set->fb->depth != set->crtc->fb->depth) {
+		} else if (set->fb->depth != set->crtc->state->fb->depth) {
 			mode_changed = true;
 		} else if (set->fb->bits_per_pixel !=
-			   set->crtc->fb->bits_per_pixel) {
+			   set->crtc->state->fb->bits_per_pixel) {
 			mode_changed = true;
 		} else
 			fb_changed = true;
 	}
 
-	if (set->x != set->crtc->x || set->y != set->crtc->y)
+	if (set->x != set->crtc->state->x || set->y != set->crtc->state->y)
 		fb_changed = true;
 
 	if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) {
@@ -704,14 +704,14 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 			DRM_DEBUG_KMS("attempting to set mode from"
 					" userspace\n");
 			drm_mode_debug_printmodeline(set->mode);
-			old_fb = set->crtc->fb;
-			set->crtc->fb = set->fb;
+			old_fb = set->crtc->state->fb;
+			set->crtc->state->fb = set->fb;
 			if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
 						      set->x, set->y,
 						      old_fb)) {
 				DRM_ERROR("failed to set mode on [CRTC:%d]\n",
 					  set->crtc->base.id);
-				set->crtc->fb = old_fb;
+				set->crtc->state->fb = old_fb;
 				ret = -EINVAL;
 				goto fail;
 			}
@@ -724,16 +724,16 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 		}
 		drm_helper_disable_unused_functions(dev);
 	} else if (fb_changed) {
-		set->crtc->x = set->x;
-		set->crtc->y = set->y;
+		set->crtc->state->x = set->x;
+		set->crtc->state->y = set->y;
 
-		old_fb = set->crtc->fb;
-		if (set->crtc->fb != set->fb)
-			set->crtc->fb = set->fb;
+		old_fb = set->crtc->state->fb;
+		if (set->crtc->state->fb != set->fb)
+			set->crtc->state->fb = set->fb;
 		ret = crtc_funcs->mode_set_base(set->crtc,
 						set->x, set->y, old_fb);
 		if (ret != 0) {
-			set->crtc->fb = old_fb;
+			set->crtc->state->fb = old_fb;
 			goto fail;
 		}
 	}
@@ -888,7 +888,8 @@ int drm_helper_resume_force_mode(struct drm_device *dev)
 			continue;
 
 		ret = drm_crtc_helper_set_mode(crtc, &crtc->mode,
-					       crtc->x, crtc->y, crtc->fb);
+					       crtc->state->x, crtc->state->y,
+					       crtc->state->fb);
 
 		if (ret == false)
 			DRM_ERROR("failed to set mode on crtc %p\n", crtc);
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index f546d1e..d70b787 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -185,7 +185,7 @@ static struct drm_framebuffer *drm_mode_config_fb(struct drm_crtc *crtc)
 
 	list_for_each_entry(c, &dev->mode_config.crtc_list, head) {
 		if (crtc->base.id == c->base.id)
-			return c->fb;
+			return c->state->fb;
 	}
 
 	return NULL;
@@ -214,8 +214,9 @@ int drm_fb_helper_debug_leave(struct fb_info *info)
 		}
 
 		drm_fb_helper_restore_lut_atomic(mode_set->crtc);
-		funcs->mode_set_base_atomic(mode_set->crtc, fb, crtc->x,
-					    crtc->y, LEAVE_ATOMIC_MODE_SET);
+		funcs->mode_set_base_atomic(mode_set->crtc, fb,
+				crtc->state->x, crtc->state->y,
+				LEAVE_ATOMIC_MODE_SET);
 	}
 
 	return 0;
@@ -1361,9 +1362,9 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
 
 	mutex_lock(&dev->mode_config.mutex);
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		if (crtc->fb)
+		if (crtc->state->fb)
 			crtcs_bound++;
-		if (crtc->fb == fb_helper->fb)
+		if (crtc->state->fb == fb_helper->fb)
 			bound++;
 	}
 
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index a0bec04..9417aaa 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -352,18 +352,41 @@ struct drm_crtc_funcs {
 };
 
 /**
+ * drm_crtc_state - mutable crtc state
+ * @fb: the framebuffer that the CRTC is currently bound to
+ * @invert_dimensions: for purposes of error checking crtc vs fb sizes,
+ *    invert the width/height of the crtc.  This is used if the driver
+ *    is performing 90 or 270 degree rotated scanout
+ * @x: x position on screen
+ * @y: y position on screen
+ */
+struct drm_crtc_state {
+	/*
+	 * NOTE: more should move from 'struct drm_crtc' into here as
+	 * part of the atomic-modeset support:
+	 *   + enabled
+	 *   + mode
+	 *   + hwmode
+	 *   + framedur_ns
+	 *   + linedur_ns
+	 *   + pixeldur_ns
+	 *
+	 * For now, I'm just moving what is needed for nuclear-pageflip
+	 */
+	struct drm_framebuffer *fb;
+	bool invert_dimensions;
+	int x, y;
+};
+
+/**
  * drm_crtc - central CRTC control structure
  * @dev: parent DRM device
  * @head: list management
  * @base: base KMS object for ID tracking etc.
+ * @state: the mutable state
  * @enabled: is this CRTC enabled?
  * @mode: current mode timings
  * @hwmode: mode timings as programmed to hw regs
- * @invert_dimensions: for purposes of error checking crtc vs fb sizes,
- *    invert the width/height of the crtc.  This is used if the driver
- *    is performing 90 or 270 degree rotated scanout
- * @x: x position on screen
- * @y: y position on screen
  * @funcs: CRTC control functions
  * @gamma_size: size of gamma ramp
  * @gamma_store: gamma ramp values
@@ -382,8 +405,7 @@ struct drm_crtc {
 
 	struct drm_mode_object base;
 
-	/* framebuffer the connector is currently bound to */
-	struct drm_framebuffer *fb;
+	struct drm_crtc_state *state;
 
 	bool enabled;
 
@@ -395,9 +417,6 @@ struct drm_crtc {
 	 */
 	struct drm_display_mode hwmode;
 
-	bool invert_dimensions;
-
-	int x, y;
 	const struct drm_crtc_funcs *funcs;
 
 	/* CRTC gamma size for reporting to userspace */
@@ -858,6 +877,11 @@ extern int drm_crtc_init(struct drm_device *dev,
 			 struct drm_crtc *crtc,
 			 const struct drm_crtc_funcs *funcs);
 extern void drm_crtc_cleanup(struct drm_crtc *crtc);
+extern int drm_crtc_check_state(struct drm_crtc *crtc,
+		struct drm_crtc_state *state);
+extern int drm_crtc_set_property(struct drm_crtc *crtc,
+		struct drm_crtc_state *state,
+		struct drm_property *property, uint64_t value);
 
 extern int drm_connector_init(struct drm_device *dev,
 			      struct drm_connector *connector,
-- 
1.7.9.5

  parent reply	other threads:[~2012-09-10  3:05 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-09-10  3:03 [RFC 0/9] nuclear pageflip Rob Clark
2012-09-10  3:03 ` [RFC 1/9] drm: add atomic fxns Rob Clark
2012-09-12 16:57   ` Jesse Barnes
2012-09-12 17:35     ` Rob Clark
2012-09-12 18:03       ` Ville Syrjälä
2012-09-12 18:34         ` Rob Clark
2012-09-12 19:05       ` Jesse Barnes
2012-09-12 19:57         ` Rob Clark
2012-09-10  3:03 ` [RFC 2/9] drm: add object property type Rob Clark
2012-09-10  3:03 ` [RFC 3/9] drm: add DRM_MODE_PROP_DYNAMIC property flag Rob Clark
2012-09-10  3:03 ` [RFC 4/9] drm: convert plane to properties Rob Clark
2012-09-10  3:03 ` [RFC 5/9] drm: add drm_plane_state Rob Clark
2012-09-10  3:03 ` [RFC 6/9] drm: convert page_flip to properties Rob Clark
2012-09-10  3:03 ` Rob Clark [this message]
2012-09-10  3:03 ` [RFC 8/9] drm: nuclear pageflip Rob Clark
2012-09-10  3:03 ` [RFC 9/9] drm/omap: update for atomic age Rob Clark
2012-09-10  3:19 ` [RFC 0/9] nuclear pageflip Rob Clark
2012-09-11 21:15   ` Ben Widawsky
2012-09-11 22:07     ` Rob Clark
2012-09-12  8:59       ` Ville Syrjälä
2012-09-12 12:30         ` Rob Clark
2012-09-12 14:23           ` Ville Syrjälä
2012-09-12 14:28             ` Rob Clark
2012-09-12 14:34               ` Ville Syrjälä
2012-09-12 14:42                 ` Rob Clark
2012-09-12 15:12                   ` Ville Syrjälä
2012-09-12 15:23                     ` Rob Clark
2012-09-12 15:32                       ` Ville Syrjälä
2012-09-12 15:48                         ` Rob Clark
2012-09-12 17:27                           ` Ville Syrjälä
2012-09-12 18:00                             ` Clark, Rob
2012-09-12 18:58                               ` Ville Syrjälä
2012-09-12 19:40                                 ` Rob Clark
2012-09-13  8:40                                   ` Ville Syrjälä
2012-09-13 13:39                                     ` Rob Clark
2012-09-13 14:29                                       ` Ville Syrjälä
2012-09-13 16:35                                         ` Rob Clark
2012-09-14 12:50                                           ` Ville Syrjälä
2012-09-14 13:25                                             ` Rob Clark
2012-09-14 13:58                                               ` Ville Syrjälä
2012-09-14 14:45                                                 ` Rob Clark
2012-09-14 15:48                                                   ` Ville Syrjälä
2012-09-14 16:29                                                     ` Rob Clark
2012-09-14 17:02                                                       ` Ville Syrjälä
2012-09-14 17:34                                                         ` Rob Clark
2012-09-14 18:23                                                           ` Ville Syrjälä
2012-09-14 21:51                                                             ` Rob Clark
2012-09-15  2:12                                           ` Rob Clark
2012-09-15 14:56                                             ` Ville Syrjälä
2012-09-15 16:07                                               ` Rob Clark
2012-09-15 17:04                                                 ` Ville Syrjälä
2012-09-15 17:15                                                   ` Rob Clark
2012-09-15 19:08                                                     ` Ville Syrjälä
2012-09-15 20:16                                                       ` Rob Clark
2012-09-14 21:14                                 ` Jesse Barnes
2012-09-14 21:42                                   ` Rob Clark
2012-09-14 21:46                                   ` Kristian Høgsberg
2012-09-15 14:53                                     ` Ville Syrjälä
2012-09-15 16:05                                       ` Rob Clark
2012-09-15 18:00                                         ` Ville Syrjälä
2012-09-15 20:10                                           ` Rob Clark

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1347246202-24249-8-git-send-email-rob.clark@linaro.org \
    --to=rob.clark@linaro.org \
    --cc=daniel.vetter@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=patches@linaro.org \
    --cc=rob@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.