All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] Updated plane support v3
@ 2011-06-20 20:11 Jesse Barnes
  2011-06-20 20:11   ` Jesse Barnes
                   ` (6 more replies)
  0 siblings, 7 replies; 27+ messages in thread
From: Jesse Barnes @ 2011-06-20 20:11 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx, Marcus Lorentzon, Alan Cox

This version adds both source and dest rect params to the set_plane
ioctl, and makes the source fixed point to support hardware that needs
it.

I haven't changed the name of the SNB implementation yet (per Chris's
suggestions) but will before it gets upstream.

I'd be interested to see whether these interfaces will work for other
hardware, so please take a close look at them and ideally implement them
on your hardware to make sure (see my userspace example code from
earlier posts if you want something to crib from).

Thanks,
Jesse

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 1/4] drm: add plane support
  2011-06-20 20:11 [RFC] Updated plane support v3 Jesse Barnes
@ 2011-06-20 20:11   ` Jesse Barnes
  2011-06-20 20:11   ` Jesse Barnes
                     ` (5 subsequent siblings)
  6 siblings, 0 replies; 27+ messages in thread
From: Jesse Barnes @ 2011-06-20 20:11 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx, Marcus Lorentzon, Alan Cox, Jesse Barnes

Planes are a bit like half-CRTCs.  They have a location and fb, but
don't drive outputs directly.  Add support for handling them to the core
KMS code.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/drm_crtc.c |  235 +++++++++++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/drm_drv.c  |    3 +
 include/drm/drm.h          |    3 +
 include/drm/drm_crtc.h     |   73 ++++++++++++++-
 include/drm/drm_mode.h     |   35 +++++++
 5 files changed, 346 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 872747c..9be36a5 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -533,6 +533,47 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
 }
 EXPORT_SYMBOL(drm_encoder_cleanup);
 
+void drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
+		    unsigned long possible_crtcs,
+		    const struct drm_plane_funcs *funcs,
+		    uint32_t *formats, uint32_t format_count)
+{
+	mutex_lock(&dev->mode_config.mutex);
+
+	plane->dev = dev;
+	drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
+	plane->funcs = funcs;
+	plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
+				      GFP_KERNEL);
+	if (!plane->format_types) {
+		DRM_DEBUG_KMS("out of memory when allocating plane\n");
+		drm_mode_object_put(dev, &plane->base);
+		return;
+	}
+
+	memcpy(plane->format_types, formats, format_count);
+	plane->format_count = format_count;
+	plane->possible_crtcs = possible_crtcs;
+
+	list_add_tail(&plane->head, &dev->mode_config.plane_list);
+	dev->mode_config.num_plane++;
+
+	mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_plane_init);
+
+void drm_plane_cleanup(struct drm_plane *plane)
+{
+	struct drm_device *dev = plane->dev;
+
+	mutex_lock(&dev->mode_config.mutex);
+	drm_mode_object_put(dev, &plane->base);
+	list_del(&plane->head);
+	dev->mode_config.num_plane--;
+	mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_plane_cleanup);
+
 /**
  * drm_mode_create - create a new display mode
  * @dev: DRM device
@@ -864,6 +905,7 @@ void drm_mode_config_init(struct drm_device *dev)
 	INIT_LIST_HEAD(&dev->mode_config.encoder_list);
 	INIT_LIST_HEAD(&dev->mode_config.property_list);
 	INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
+	INIT_LIST_HEAD(&dev->mode_config.plane_list);
 	idr_init(&dev->mode_config.crtc_idr);
 
 	mutex_lock(&dev->mode_config.mutex);
@@ -1467,6 +1509,193 @@ out:
 }
 
 /**
+ * drm_mode_getplane_res - get plane info
+ * @dev: DRM device
+ * @data: ioctl data
+ * @file_priv: DRM file info
+ *
+ * Return an plane count and set of IDs.
+ */
+int drm_mode_getplane_res(struct drm_device *dev, void *data,
+			    struct drm_file *file_priv)
+{
+	struct drm_mode_get_plane_res *plane_resp = data;
+	struct drm_mode_config *config;
+	struct drm_plane *plane;
+	uint32_t __user *plane_ptr;
+	int copied = 0, ret = 0;
+
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		return -EINVAL;
+
+	mutex_lock(&dev->mode_config.mutex);
+	config = &dev->mode_config;
+
+	/*
+	 * This ioctl is called twice, once to determine how much space is
+	 * needed, and the 2nd time to fill it.
+	 */
+	if (config->num_plane &&
+	    (plane_resp->count_planes >= config->num_plane)) {
+		plane_ptr = (uint32_t *)(unsigned long)plane_resp->plane_id_ptr;
+
+		list_for_each_entry(plane, &config->plane_list, head) {
+			if (put_user(plane->base.id, plane_ptr + copied)) {
+				ret = -EFAULT;
+				goto out;
+			}
+			copied++;
+		}
+	}
+	plane_resp->count_planes = config->num_plane;
+
+out:
+	mutex_unlock(&dev->mode_config.mutex);
+	return ret;
+}
+
+/**
+ * drm_mode_getplane - get plane info
+ * @dev: DRM device
+ * @data: ioctl data
+ * @file_priv: DRM file info
+ *
+ * Return plane info, including formats supported, gamma size, any
+ * current fb, etc.
+ */
+int drm_mode_getplane(struct drm_device *dev, void *data,
+			struct drm_file *file_priv)
+{
+	struct drm_mode_get_plane *plane_resp = data;
+	struct drm_mode_object *obj;
+	struct drm_plane *plane;
+	uint32_t __user *format_ptr;
+	int ret = 0;
+
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		return -EINVAL;
+
+	mutex_lock(&dev->mode_config.mutex);
+	obj = drm_mode_object_find(dev, plane_resp->plane_id,
+				   DRM_MODE_OBJECT_PLANE);
+	if (!obj) {
+		ret = -EINVAL;
+		goto out;
+	}
+	plane = obj_to_plane(obj);
+
+	if (plane->crtc)
+		plane_resp->crtc_id = plane->crtc->base.id;
+	else
+		plane_resp->crtc_id = 0;
+
+	if (plane->fb)
+		plane_resp->fb_id = plane->fb->base.id;
+	else
+		plane_resp->fb_id = 0;
+
+	plane_resp->plane_id = plane->base.id;
+	plane_resp->possible_crtcs = plane->possible_crtcs;
+	plane_resp->gamma_size = plane->gamma_size;
+
+	/*
+	 * This ioctl is called twice, once to determine how much space is
+	 * needed, and the 2nd time to fill it.
+	 */
+	if (plane->format_count &&
+	    (plane_resp->count_format_types >= plane->format_count)) {
+		format_ptr = (uint32_t *)(unsigned long)plane_resp->format_type_ptr;
+		if (copy_to_user(format_ptr,
+				 plane->format_types,
+				 sizeof(uint32_t) * plane->format_count)) {
+			ret = -EFAULT;
+			goto out;
+		}
+	}
+	plane_resp->count_format_types = plane->format_count;
+
+out:
+	mutex_unlock(&dev->mode_config.mutex);
+	return ret;
+}
+
+/**
+ * drm_mode_setplane - set up or tear down an plane
+ * @dev: DRM device
+ * @data: ioctl data*
+ * @file_prive: DRM file info
+ *
+ * Set plane info, including placement, fb, scaling, and other factors.
+ * Or pass a NULL fb to disable.
+ */
+int drm_mode_setplane(struct drm_device *dev, void *data,
+			struct drm_file *file_priv)
+{
+	struct drm_mode_set_plane *plane_req = data;
+	struct drm_mode_object *obj;
+	struct drm_plane *plane;
+	struct drm_crtc *crtc;
+	struct drm_framebuffer *fb;
+	int ret = 0;
+
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		return -EINVAL;
+
+	mutex_lock(&dev->mode_config.mutex);
+
+	/*
+	 * First, find the plane, crtc, and fb objects.  If not available,
+	 * we don't bother to call the driver.
+	 */
+	obj = drm_mode_object_find(dev, plane_req->plane_id,
+				   DRM_MODE_OBJECT_PLANE);
+	if (!obj) {
+		DRM_DEBUG_KMS("Unknown plane ID %d\n",
+			      plane_req->plane_id);
+		ret = -EINVAL;
+		goto out;
+	}
+	plane = obj_to_plane(obj);
+
+	/* No fb means shut it down */
+	if (!plane_req->fb_id) {
+		plane->funcs->disable_plane(plane);
+		goto out;
+	}
+
+	obj = drm_mode_object_find(dev, plane_req->crtc_id,
+				   DRM_MODE_OBJECT_CRTC);
+	if (!obj) {
+		DRM_DEBUG_KMS("Unknown crtc ID %d\n",
+			      plane_req->crtc_id);
+		ret = -EINVAL;
+		goto out;
+	}
+	crtc = obj_to_crtc(obj);
+
+	obj = drm_mode_object_find(dev, plane_req->fb_id,
+				   DRM_MODE_OBJECT_FB);
+	if (!obj) {
+		DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
+			      plane_req->fb_id);
+		ret = -EINVAL;
+		goto out;
+	}
+	fb = obj_to_fb(obj);
+
+	ret = plane->funcs->update_plane(plane, crtc, fb,
+					 plane_req->crtc_x, plane_req->crtc_y,
+					 plane_req->crtc_w, plane_req->crtc_h,
+					 plane_req->src_x, plane_req->src_y,
+					 plane_req->src_h, plane_req->src_w);
+
+out:
+	mutex_unlock(&dev->mode_config.mutex);
+
+	return ret;
+}
+
+/**
  * drm_mode_setcrtc - set CRTC configuration
  * @inode: inode from the ioctl
  * @filp: file * from the ioctl
@@ -1689,11 +1918,13 @@ int drm_mode_addfb(struct drm_device *dev,
 		return -EINVAL;
 
 	if ((config->min_width > r->width) || (r->width > config->max_width)) {
-		DRM_ERROR("mode new framebuffer width not within limits\n");
+		DRM_ERROR("bad framebuffer width %d, should be >= %d && <= %d\n",
+			  r->width, config->min_width, config->max_width);
 		return -EINVAL;
 	}
 	if ((config->min_height > r->height) || (r->height > config->max_height)) {
-		DRM_ERROR("mode new framebuffer height not within limits\n");
+		DRM_ERROR("bad framebuffer height %d, should be >= %d && <= %d\n",
+			  r->height, config->min_height, config->max_height);
 		return -EINVAL;
 	}
 
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 93a112d..15da618 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -135,8 +135,11 @@ static struct drm_ioctl_desc drm_ioctls[] = {
 	DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),
 
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 4be33b4..2897967 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -714,6 +714,9 @@ struct drm_get_cap {
 #define DRM_IOCTL_MODE_CREATE_DUMB DRM_IOWR(0xB2, struct drm_mode_create_dumb)
 #define DRM_IOCTL_MODE_MAP_DUMB    DRM_IOWR(0xB3, struct drm_mode_map_dumb)
 #define DRM_IOCTL_MODE_DESTROY_DUMB    DRM_IOWR(0xB4, struct drm_mode_destroy_dumb)
+#define DRM_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xB5, struct drm_mode_get_plane_res)
+#define DRM_IOCTL_MODE_GETPLANE	DRM_IOWR(0xB6, struct drm_mode_get_plane)
+#define DRM_IOCTL_MODE_SETPLANE	DRM_IOWR(0xB7, struct drm_mode_set_plane)
 
 /**
  * Device specific ioctls should only be in their respective headers
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 9573e0c..caa72ae 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -44,6 +44,7 @@ struct drm_framebuffer;
 #define DRM_MODE_OBJECT_PROPERTY 0xb0b0b0b0
 #define DRM_MODE_OBJECT_FB 0xfbfbfbfb
 #define DRM_MODE_OBJECT_BLOB 0xbbbbbbbb
+#define DRM_MODE_OBJECT_PLANE 0xeeeeeeee
 
 struct drm_mode_object {
 	uint32_t id;
@@ -276,6 +277,7 @@ struct drm_crtc;
 struct drm_connector;
 struct drm_encoder;
 struct drm_pending_vblank_event;
+struct drm_plane;
 
 /**
  * drm_crtc_funcs - control CRTCs for a given device
@@ -523,6 +525,60 @@ struct drm_connector {
 };
 
 /**
+ * drm_plane_funcs - driver plane control functions
+ * @update_plane: update the plane configuration
+ */
+struct drm_plane_funcs {
+	int (*update_plane)(struct drm_plane *plane,
+			    struct drm_crtc *crtc, struct drm_framebuffer *fb,
+			    int crtc_x, int crtc_y,
+			    unsigned int crtc_w, unsigned int crtc_h,
+			    uint32_t src_x, uint32_t src_y,
+			    uint32_t src_w, uint32_t src_h);
+	void (*disable_plane)(struct drm_plane *plane);
+};
+
+/**
+ * drm_plane - central DRM plane control structure
+ * @dev: DRM device this plane belongs to
+ * @kdev: kernel device
+ * @attr: kdev attributes
+ * @head: for list management
+ * @base: base mode object
+ * @crtc_x: x position of plane (relative to pipe base)
+ * @crtc_y: y position of plane
+ * @x: x offset into fb
+ * @y: y offset into fb
+ * @crtc: CRTC this plane is feeding
+ */
+struct drm_plane {
+	struct drm_device *dev;
+	struct device kdev;
+	struct device_attribute *attr;
+	struct list_head head;
+
+	struct drm_mode_object base;
+
+	int crtc_x, crtc_y;
+	int x, y;
+	uint32_t possible_crtcs;
+	uint32_t *format_types;
+	uint32_t format_count;
+
+	struct drm_crtc *crtc;
+	struct drm_framebuffer *fb;
+
+	/* CRTC gamma size for reporting to userspace */
+	uint32_t gamma_size;
+	uint16_t *gamma_store;
+
+	bool enabled;
+
+	const struct drm_plane_funcs *funcs;
+	void *helper_private;
+};
+
+/**
  * struct drm_mode_set
  *
  * Represents a single crtc the connectors that it drives with what mode
@@ -576,6 +632,8 @@ struct drm_mode_config {
 	struct list_head connector_list;
 	int num_encoder;
 	struct list_head encoder_list;
+	int num_plane;
+	struct list_head plane_list;
 
 	int num_crtc;
 	struct list_head crtc_list;
@@ -628,6 +686,7 @@ struct drm_mode_config {
 #define obj_to_fb(x) container_of(x, struct drm_framebuffer, base)
 #define obj_to_property(x) container_of(x, struct drm_property, base)
 #define obj_to_blob(x) container_of(x, struct drm_property_blob, base)
+#define obj_to_plane(x) container_of(x, struct drm_plane, base)
 
 
 extern void drm_crtc_init(struct drm_device *dev,
@@ -647,6 +706,13 @@ extern void drm_encoder_init(struct drm_device *dev,
 			     const struct drm_encoder_funcs *funcs,
 			     int encoder_type);
 
+extern void drm_plane_init(struct drm_device *dev,
+			   struct drm_plane *plane,
+			   unsigned long possible_crtcs,
+			   const struct drm_plane_funcs *funcs,
+			   uint32_t *formats, uint32_t format_count);
+extern void drm_plane_cleanup(struct drm_plane *plane);
+
 extern void drm_encoder_cleanup(struct drm_encoder *encoder);
 
 extern char *drm_get_connector_name(struct drm_connector *connector);
@@ -740,13 +806,18 @@ extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
 /* IOCTLs */
 extern int drm_mode_getresources(struct drm_device *dev,
 				 void *data, struct drm_file *file_priv);
-
+extern int drm_mode_getplane_res(struct drm_device *dev, void *data,
+				   struct drm_file *file_priv);
 extern int drm_mode_getcrtc(struct drm_device *dev,
 			    void *data, struct drm_file *file_priv);
 extern int drm_mode_getconnector(struct drm_device *dev,
 			      void *data, struct drm_file *file_priv);
 extern int drm_mode_setcrtc(struct drm_device *dev,
 			    void *data, struct drm_file *file_priv);
+extern int drm_mode_getplane(struct drm_device *dev,
+			       void *data, struct drm_file *file_priv);
+extern int drm_mode_setplane(struct drm_device *dev,
+			       void *data, struct drm_file *file_priv);
 extern int drm_mode_cursor_ioctl(struct drm_device *dev,
 				void *data, struct drm_file *file_priv);
 extern int drm_mode_addfb(struct drm_device *dev,
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index c4961ea..fa6d348 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -120,6 +120,41 @@ struct drm_mode_crtc {
 	struct drm_mode_modeinfo mode;
 };
 
+/* Planes blend with or override other bits on the CRTC */
+struct drm_mode_set_plane {
+	__u32 plane_id;
+	__u32 crtc_id;
+	__u32 fb_id; /* fb object contains surface format type */
+
+	/* Signed dest location allows it to be partially off screen */
+	__s32 crtc_x, crtc_y;
+	__u32 crtc_w, crtc_h;
+
+	/* Source values are 16.16 fixed point */
+	__u32 src_x, src_y;
+	__u32 src_h, src_w;
+
+	__u32 zpos;
+};
+
+struct drm_mode_get_plane {
+	__u64 format_type_ptr;
+	__u32 plane_id;
+
+	__u32 crtc_id;
+	__u32 fb_id;
+
+	__u32 possible_crtcs;
+	__u32 gamma_size;
+
+	__u32 count_format_types;
+};
+
+struct drm_mode_get_plane_res {
+	__u64 plane_id_ptr;
+	__u32 count_planes;
+};
+
 #define DRM_MODE_ENCODER_NONE	0
 #define DRM_MODE_ENCODER_DAC	1
 #define DRM_MODE_ENCODER_TMDS	2
-- 
1.7.4.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 1/4] drm: add plane support
@ 2011-06-20 20:11   ` Jesse Barnes
  0 siblings, 0 replies; 27+ messages in thread
From: Jesse Barnes @ 2011-06-20 20:11 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

Planes are a bit like half-CRTCs.  They have a location and fb, but
don't drive outputs directly.  Add support for handling them to the core
KMS code.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/drm_crtc.c |  235 +++++++++++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/drm_drv.c  |    3 +
 include/drm/drm.h          |    3 +
 include/drm/drm_crtc.h     |   73 ++++++++++++++-
 include/drm/drm_mode.h     |   35 +++++++
 5 files changed, 346 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 872747c..9be36a5 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -533,6 +533,47 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
 }
 EXPORT_SYMBOL(drm_encoder_cleanup);
 
+void drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
+		    unsigned long possible_crtcs,
+		    const struct drm_plane_funcs *funcs,
+		    uint32_t *formats, uint32_t format_count)
+{
+	mutex_lock(&dev->mode_config.mutex);
+
+	plane->dev = dev;
+	drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
+	plane->funcs = funcs;
+	plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
+				      GFP_KERNEL);
+	if (!plane->format_types) {
+		DRM_DEBUG_KMS("out of memory when allocating plane\n");
+		drm_mode_object_put(dev, &plane->base);
+		return;
+	}
+
+	memcpy(plane->format_types, formats, format_count);
+	plane->format_count = format_count;
+	plane->possible_crtcs = possible_crtcs;
+
+	list_add_tail(&plane->head, &dev->mode_config.plane_list);
+	dev->mode_config.num_plane++;
+
+	mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_plane_init);
+
+void drm_plane_cleanup(struct drm_plane *plane)
+{
+	struct drm_device *dev = plane->dev;
+
+	mutex_lock(&dev->mode_config.mutex);
+	drm_mode_object_put(dev, &plane->base);
+	list_del(&plane->head);
+	dev->mode_config.num_plane--;
+	mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_plane_cleanup);
+
 /**
  * drm_mode_create - create a new display mode
  * @dev: DRM device
@@ -864,6 +905,7 @@ void drm_mode_config_init(struct drm_device *dev)
 	INIT_LIST_HEAD(&dev->mode_config.encoder_list);
 	INIT_LIST_HEAD(&dev->mode_config.property_list);
 	INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
+	INIT_LIST_HEAD(&dev->mode_config.plane_list);
 	idr_init(&dev->mode_config.crtc_idr);
 
 	mutex_lock(&dev->mode_config.mutex);
@@ -1467,6 +1509,193 @@ out:
 }
 
 /**
+ * drm_mode_getplane_res - get plane info
+ * @dev: DRM device
+ * @data: ioctl data
+ * @file_priv: DRM file info
+ *
+ * Return an plane count and set of IDs.
+ */
+int drm_mode_getplane_res(struct drm_device *dev, void *data,
+			    struct drm_file *file_priv)
+{
+	struct drm_mode_get_plane_res *plane_resp = data;
+	struct drm_mode_config *config;
+	struct drm_plane *plane;
+	uint32_t __user *plane_ptr;
+	int copied = 0, ret = 0;
+
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		return -EINVAL;
+
+	mutex_lock(&dev->mode_config.mutex);
+	config = &dev->mode_config;
+
+	/*
+	 * This ioctl is called twice, once to determine how much space is
+	 * needed, and the 2nd time to fill it.
+	 */
+	if (config->num_plane &&
+	    (plane_resp->count_planes >= config->num_plane)) {
+		plane_ptr = (uint32_t *)(unsigned long)plane_resp->plane_id_ptr;
+
+		list_for_each_entry(plane, &config->plane_list, head) {
+			if (put_user(plane->base.id, plane_ptr + copied)) {
+				ret = -EFAULT;
+				goto out;
+			}
+			copied++;
+		}
+	}
+	plane_resp->count_planes = config->num_plane;
+
+out:
+	mutex_unlock(&dev->mode_config.mutex);
+	return ret;
+}
+
+/**
+ * drm_mode_getplane - get plane info
+ * @dev: DRM device
+ * @data: ioctl data
+ * @file_priv: DRM file info
+ *
+ * Return plane info, including formats supported, gamma size, any
+ * current fb, etc.
+ */
+int drm_mode_getplane(struct drm_device *dev, void *data,
+			struct drm_file *file_priv)
+{
+	struct drm_mode_get_plane *plane_resp = data;
+	struct drm_mode_object *obj;
+	struct drm_plane *plane;
+	uint32_t __user *format_ptr;
+	int ret = 0;
+
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		return -EINVAL;
+
+	mutex_lock(&dev->mode_config.mutex);
+	obj = drm_mode_object_find(dev, plane_resp->plane_id,
+				   DRM_MODE_OBJECT_PLANE);
+	if (!obj) {
+		ret = -EINVAL;
+		goto out;
+	}
+	plane = obj_to_plane(obj);
+
+	if (plane->crtc)
+		plane_resp->crtc_id = plane->crtc->base.id;
+	else
+		plane_resp->crtc_id = 0;
+
+	if (plane->fb)
+		plane_resp->fb_id = plane->fb->base.id;
+	else
+		plane_resp->fb_id = 0;
+
+	plane_resp->plane_id = plane->base.id;
+	plane_resp->possible_crtcs = plane->possible_crtcs;
+	plane_resp->gamma_size = plane->gamma_size;
+
+	/*
+	 * This ioctl is called twice, once to determine how much space is
+	 * needed, and the 2nd time to fill it.
+	 */
+	if (plane->format_count &&
+	    (plane_resp->count_format_types >= plane->format_count)) {
+		format_ptr = (uint32_t *)(unsigned long)plane_resp->format_type_ptr;
+		if (copy_to_user(format_ptr,
+				 plane->format_types,
+				 sizeof(uint32_t) * plane->format_count)) {
+			ret = -EFAULT;
+			goto out;
+		}
+	}
+	plane_resp->count_format_types = plane->format_count;
+
+out:
+	mutex_unlock(&dev->mode_config.mutex);
+	return ret;
+}
+
+/**
+ * drm_mode_setplane - set up or tear down an plane
+ * @dev: DRM device
+ * @data: ioctl data*
+ * @file_prive: DRM file info
+ *
+ * Set plane info, including placement, fb, scaling, and other factors.
+ * Or pass a NULL fb to disable.
+ */
+int drm_mode_setplane(struct drm_device *dev, void *data,
+			struct drm_file *file_priv)
+{
+	struct drm_mode_set_plane *plane_req = data;
+	struct drm_mode_object *obj;
+	struct drm_plane *plane;
+	struct drm_crtc *crtc;
+	struct drm_framebuffer *fb;
+	int ret = 0;
+
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		return -EINVAL;
+
+	mutex_lock(&dev->mode_config.mutex);
+
+	/*
+	 * First, find the plane, crtc, and fb objects.  If not available,
+	 * we don't bother to call the driver.
+	 */
+	obj = drm_mode_object_find(dev, plane_req->plane_id,
+				   DRM_MODE_OBJECT_PLANE);
+	if (!obj) {
+		DRM_DEBUG_KMS("Unknown plane ID %d\n",
+			      plane_req->plane_id);
+		ret = -EINVAL;
+		goto out;
+	}
+	plane = obj_to_plane(obj);
+
+	/* No fb means shut it down */
+	if (!plane_req->fb_id) {
+		plane->funcs->disable_plane(plane);
+		goto out;
+	}
+
+	obj = drm_mode_object_find(dev, plane_req->crtc_id,
+				   DRM_MODE_OBJECT_CRTC);
+	if (!obj) {
+		DRM_DEBUG_KMS("Unknown crtc ID %d\n",
+			      plane_req->crtc_id);
+		ret = -EINVAL;
+		goto out;
+	}
+	crtc = obj_to_crtc(obj);
+
+	obj = drm_mode_object_find(dev, plane_req->fb_id,
+				   DRM_MODE_OBJECT_FB);
+	if (!obj) {
+		DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
+			      plane_req->fb_id);
+		ret = -EINVAL;
+		goto out;
+	}
+	fb = obj_to_fb(obj);
+
+	ret = plane->funcs->update_plane(plane, crtc, fb,
+					 plane_req->crtc_x, plane_req->crtc_y,
+					 plane_req->crtc_w, plane_req->crtc_h,
+					 plane_req->src_x, plane_req->src_y,
+					 plane_req->src_h, plane_req->src_w);
+
+out:
+	mutex_unlock(&dev->mode_config.mutex);
+
+	return ret;
+}
+
+/**
  * drm_mode_setcrtc - set CRTC configuration
  * @inode: inode from the ioctl
  * @filp: file * from the ioctl
@@ -1689,11 +1918,13 @@ int drm_mode_addfb(struct drm_device *dev,
 		return -EINVAL;
 
 	if ((config->min_width > r->width) || (r->width > config->max_width)) {
-		DRM_ERROR("mode new framebuffer width not within limits\n");
+		DRM_ERROR("bad framebuffer width %d, should be >= %d && <= %d\n",
+			  r->width, config->min_width, config->max_width);
 		return -EINVAL;
 	}
 	if ((config->min_height > r->height) || (r->height > config->max_height)) {
-		DRM_ERROR("mode new framebuffer height not within limits\n");
+		DRM_ERROR("bad framebuffer height %d, should be >= %d && <= %d\n",
+			  r->height, config->min_height, config->max_height);
 		return -EINVAL;
 	}
 
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 93a112d..15da618 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -135,8 +135,11 @@ static struct drm_ioctl_desc drm_ioctls[] = {
 	DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),
 
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 4be33b4..2897967 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -714,6 +714,9 @@ struct drm_get_cap {
 #define DRM_IOCTL_MODE_CREATE_DUMB DRM_IOWR(0xB2, struct drm_mode_create_dumb)
 #define DRM_IOCTL_MODE_MAP_DUMB    DRM_IOWR(0xB3, struct drm_mode_map_dumb)
 #define DRM_IOCTL_MODE_DESTROY_DUMB    DRM_IOWR(0xB4, struct drm_mode_destroy_dumb)
+#define DRM_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xB5, struct drm_mode_get_plane_res)
+#define DRM_IOCTL_MODE_GETPLANE	DRM_IOWR(0xB6, struct drm_mode_get_plane)
+#define DRM_IOCTL_MODE_SETPLANE	DRM_IOWR(0xB7, struct drm_mode_set_plane)
 
 /**
  * Device specific ioctls should only be in their respective headers
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 9573e0c..caa72ae 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -44,6 +44,7 @@ struct drm_framebuffer;
 #define DRM_MODE_OBJECT_PROPERTY 0xb0b0b0b0
 #define DRM_MODE_OBJECT_FB 0xfbfbfbfb
 #define DRM_MODE_OBJECT_BLOB 0xbbbbbbbb
+#define DRM_MODE_OBJECT_PLANE 0xeeeeeeee
 
 struct drm_mode_object {
 	uint32_t id;
@@ -276,6 +277,7 @@ struct drm_crtc;
 struct drm_connector;
 struct drm_encoder;
 struct drm_pending_vblank_event;
+struct drm_plane;
 
 /**
  * drm_crtc_funcs - control CRTCs for a given device
@@ -523,6 +525,60 @@ struct drm_connector {
 };
 
 /**
+ * drm_plane_funcs - driver plane control functions
+ * @update_plane: update the plane configuration
+ */
+struct drm_plane_funcs {
+	int (*update_plane)(struct drm_plane *plane,
+			    struct drm_crtc *crtc, struct drm_framebuffer *fb,
+			    int crtc_x, int crtc_y,
+			    unsigned int crtc_w, unsigned int crtc_h,
+			    uint32_t src_x, uint32_t src_y,
+			    uint32_t src_w, uint32_t src_h);
+	void (*disable_plane)(struct drm_plane *plane);
+};
+
+/**
+ * drm_plane - central DRM plane control structure
+ * @dev: DRM device this plane belongs to
+ * @kdev: kernel device
+ * @attr: kdev attributes
+ * @head: for list management
+ * @base: base mode object
+ * @crtc_x: x position of plane (relative to pipe base)
+ * @crtc_y: y position of plane
+ * @x: x offset into fb
+ * @y: y offset into fb
+ * @crtc: CRTC this plane is feeding
+ */
+struct drm_plane {
+	struct drm_device *dev;
+	struct device kdev;
+	struct device_attribute *attr;
+	struct list_head head;
+
+	struct drm_mode_object base;
+
+	int crtc_x, crtc_y;
+	int x, y;
+	uint32_t possible_crtcs;
+	uint32_t *format_types;
+	uint32_t format_count;
+
+	struct drm_crtc *crtc;
+	struct drm_framebuffer *fb;
+
+	/* CRTC gamma size for reporting to userspace */
+	uint32_t gamma_size;
+	uint16_t *gamma_store;
+
+	bool enabled;
+
+	const struct drm_plane_funcs *funcs;
+	void *helper_private;
+};
+
+/**
  * struct drm_mode_set
  *
  * Represents a single crtc the connectors that it drives with what mode
@@ -576,6 +632,8 @@ struct drm_mode_config {
 	struct list_head connector_list;
 	int num_encoder;
 	struct list_head encoder_list;
+	int num_plane;
+	struct list_head plane_list;
 
 	int num_crtc;
 	struct list_head crtc_list;
@@ -628,6 +686,7 @@ struct drm_mode_config {
 #define obj_to_fb(x) container_of(x, struct drm_framebuffer, base)
 #define obj_to_property(x) container_of(x, struct drm_property, base)
 #define obj_to_blob(x) container_of(x, struct drm_property_blob, base)
+#define obj_to_plane(x) container_of(x, struct drm_plane, base)
 
 
 extern void drm_crtc_init(struct drm_device *dev,
@@ -647,6 +706,13 @@ extern void drm_encoder_init(struct drm_device *dev,
 			     const struct drm_encoder_funcs *funcs,
 			     int encoder_type);
 
+extern void drm_plane_init(struct drm_device *dev,
+			   struct drm_plane *plane,
+			   unsigned long possible_crtcs,
+			   const struct drm_plane_funcs *funcs,
+			   uint32_t *formats, uint32_t format_count);
+extern void drm_plane_cleanup(struct drm_plane *plane);
+
 extern void drm_encoder_cleanup(struct drm_encoder *encoder);
 
 extern char *drm_get_connector_name(struct drm_connector *connector);
@@ -740,13 +806,18 @@ extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
 /* IOCTLs */
 extern int drm_mode_getresources(struct drm_device *dev,
 				 void *data, struct drm_file *file_priv);
-
+extern int drm_mode_getplane_res(struct drm_device *dev, void *data,
+				   struct drm_file *file_priv);
 extern int drm_mode_getcrtc(struct drm_device *dev,
 			    void *data, struct drm_file *file_priv);
 extern int drm_mode_getconnector(struct drm_device *dev,
 			      void *data, struct drm_file *file_priv);
 extern int drm_mode_setcrtc(struct drm_device *dev,
 			    void *data, struct drm_file *file_priv);
+extern int drm_mode_getplane(struct drm_device *dev,
+			       void *data, struct drm_file *file_priv);
+extern int drm_mode_setplane(struct drm_device *dev,
+			       void *data, struct drm_file *file_priv);
 extern int drm_mode_cursor_ioctl(struct drm_device *dev,
 				void *data, struct drm_file *file_priv);
 extern int drm_mode_addfb(struct drm_device *dev,
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index c4961ea..fa6d348 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -120,6 +120,41 @@ struct drm_mode_crtc {
 	struct drm_mode_modeinfo mode;
 };
 
+/* Planes blend with or override other bits on the CRTC */
+struct drm_mode_set_plane {
+	__u32 plane_id;
+	__u32 crtc_id;
+	__u32 fb_id; /* fb object contains surface format type */
+
+	/* Signed dest location allows it to be partially off screen */
+	__s32 crtc_x, crtc_y;
+	__u32 crtc_w, crtc_h;
+
+	/* Source values are 16.16 fixed point */
+	__u32 src_x, src_y;
+	__u32 src_h, src_w;
+
+	__u32 zpos;
+};
+
+struct drm_mode_get_plane {
+	__u64 format_type_ptr;
+	__u32 plane_id;
+
+	__u32 crtc_id;
+	__u32 fb_id;
+
+	__u32 possible_crtcs;
+	__u32 gamma_size;
+
+	__u32 count_format_types;
+};
+
+struct drm_mode_get_plane_res {
+	__u64 plane_id_ptr;
+	__u32 count_planes;
+};
+
 #define DRM_MODE_ENCODER_NONE	0
 #define DRM_MODE_ENCODER_DAC	1
 #define DRM_MODE_ENCODER_TMDS	2
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
  2011-06-20 20:11 [RFC] Updated plane support v3 Jesse Barnes
@ 2011-06-20 20:11   ` Jesse Barnes
  2011-06-20 20:11   ` Jesse Barnes
                     ` (5 subsequent siblings)
  6 siblings, 0 replies; 27+ messages in thread
From: Jesse Barnes @ 2011-06-20 20:11 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx, Marcus Lorentzon, Alan Cox, Jesse Barnes

To properly support the various plane formats supported by different
hardware, the kernel must know the pixel format of a framebuffer object.
So add a new ioctl taking a format argument corresponding to a fourcc
name from videodev2.h.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/drm_crtc.c                |   71 ++++++++++++++++++++++++++++-
 drivers/gpu/drm/drm_crtc_helper.c         |    3 +-
 drivers/gpu/drm/drm_drv.c                 |    1 +
 drivers/gpu/drm/i915/intel_display.c      |    9 ++--
 drivers/gpu/drm/i915/intel_drv.h          |    2 +-
 drivers/gpu/drm/i915/intel_fb.c           |    3 +-
 drivers/gpu/drm/nouveau/nouveau_display.c |    4 +-
 drivers/gpu/drm/radeon/radeon_display.c   |    4 +-
 drivers/gpu/drm/radeon/radeon_fb.c        |    5 +-
 drivers/gpu/drm/radeon/radeon_mode.h      |    2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c       |    2 +-
 drivers/staging/gma500/psb_fb.c           |    2 +-
 include/drm/drm.h                         |    1 +
 include/drm/drm_crtc.h                    |    6 ++-
 include/drm/drm_crtc_helper.h             |    2 +-
 include/drm/drm_mode.h                    |   14 ++++++
 16 files changed, 112 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 9be36a5..f963cf5 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1909,7 +1909,76 @@ out:
 int drm_mode_addfb(struct drm_device *dev,
 		   void *data, struct drm_file *file_priv)
 {
-	struct drm_mode_fb_cmd *r = data;
+	struct drm_mode_fb_cmd *or = data;
+	struct drm_mode_fb_cmd2 r;
+	struct drm_mode_config *config = &dev->mode_config;
+	struct drm_framebuffer *fb;
+	int ret = 0;
+
+	/* Use new struct with format internally */
+	r.fb_id = or->fb_id;
+	r.width = or->width;
+	r.height = or->height;
+	r.pitch = or->pitch;
+	r.bpp = or->bpp;
+	r.depth = or->depth;
+	r.pixel_format = 0;
+	r.handle = or->handle;
+
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		return -EINVAL;
+
+	if ((config->min_width > r.width) || (r.width > config->max_width)) {
+		DRM_ERROR("mode new framebuffer width not within limits\n");
+		return -EINVAL;
+	}
+	if ((config->min_height > r.height) || (r.height > config->max_height)) {
+		DRM_ERROR("mode new framebuffer height not within limits\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&dev->mode_config.mutex);
+
+	/* TODO check buffer is sufficiently large */
+	/* TODO setup destructor callback */
+
+	fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r);
+	if (IS_ERR(fb)) {
+		DRM_ERROR("could not create framebuffer\n");
+		ret = PTR_ERR(fb);
+		goto out;
+	}
+
+	or->fb_id = fb->base.id;
+	list_add(&fb->filp_head, &file_priv->fbs);
+	DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
+
+out:
+	mutex_unlock(&dev->mode_config.mutex);
+	return ret;
+}
+
+/**
+ * drm_mode_addfb2 - add an FB to the graphics configuration
+ * @inode: inode from the ioctl
+ * @filp: file * from the ioctl
+ * @cmd: cmd from ioctl
+ * @arg: arg from ioctl
+ *
+ * LOCKING:
+ * Takes mode config lock.
+ *
+ * Add a new FB to the specified CRTC, given a user request with format.
+ *
+ * Called by the user via ioctl.
+ *
+ * RETURNS:
+ * Zero on success, errno on failure.
+ */
+int drm_mode_addfb2(struct drm_device *dev,
+		    void *data, struct drm_file *file_priv)
+{
+	struct drm_mode_fb_cmd2 *r = data;
 	struct drm_mode_config *config = &dev->mode_config;
 	struct drm_framebuffer *fb;
 	int ret = 0;
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 9236965..5adab04 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -801,13 +801,14 @@ void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
 EXPORT_SYMBOL(drm_helper_connector_dpms);
 
 int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
-				   struct drm_mode_fb_cmd *mode_cmd)
+				   struct drm_mode_fb_cmd2 *mode_cmd)
 {
 	fb->width = mode_cmd->width;
 	fb->height = mode_cmd->height;
 	fb->pitch = mode_cmd->pitch;
 	fb->bits_per_pixel = mode_cmd->bpp;
 	fb->depth = mode_cmd->depth;
+	fb->pixel_format = mode_cmd->pixel_format;
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 15da618..f24b9b6 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -152,6 +152,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 0b6fd36..8a6e3ab 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5803,7 +5803,7 @@ static struct drm_display_mode load_detect_mode = {
 
 static struct drm_framebuffer *
 intel_framebuffer_create(struct drm_device *dev,
-			 struct drm_mode_fb_cmd *mode_cmd,
+			 struct drm_mode_fb_cmd2 *mode_cmd,
 			 struct drm_i915_gem_object *obj)
 {
 	struct intel_framebuffer *intel_fb;
@@ -5845,7 +5845,7 @@ intel_framebuffer_create_for_mode(struct drm_device *dev,
 				  int depth, int bpp)
 {
 	struct drm_i915_gem_object *obj;
-	struct drm_mode_fb_cmd mode_cmd;
+	struct drm_mode_fb_cmd2 mode_cmd;
 
 	obj = i915_gem_alloc_object(dev,
 				    intel_framebuffer_size_for_mode(mode, bpp));
@@ -5857,6 +5857,7 @@ intel_framebuffer_create_for_mode(struct drm_device *dev,
 	mode_cmd.depth = depth;
 	mode_cmd.bpp = bpp;
 	mode_cmd.pitch = intel_framebuffer_pitch_for_width(mode_cmd.width, bpp);
+	mode_cmd.pixel_format = 0;
 
 	return intel_framebuffer_create(dev, &mode_cmd, obj);
 }
@@ -6978,7 +6979,7 @@ static const struct drm_framebuffer_funcs intel_fb_funcs = {
 
 int intel_framebuffer_init(struct drm_device *dev,
 			   struct intel_framebuffer *intel_fb,
-			   struct drm_mode_fb_cmd *mode_cmd,
+			   struct drm_mode_fb_cmd2 *mode_cmd,
 			   struct drm_i915_gem_object *obj)
 {
 	int ret;
@@ -7013,7 +7014,7 @@ int intel_framebuffer_init(struct drm_device *dev,
 static struct drm_framebuffer *
 intel_user_framebuffer_create(struct drm_device *dev,
 			      struct drm_file *filp,
-			      struct drm_mode_fb_cmd *mode_cmd)
+			      struct drm_mode_fb_cmd2 *mode_cmd)
 {
 	struct drm_i915_gem_object *obj;
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 0dc9018..3cfc391 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -326,7 +326,7 @@ extern int intel_pin_and_fence_fb_obj(struct drm_device *dev,
 
 extern int intel_framebuffer_init(struct drm_device *dev,
 				  struct intel_framebuffer *ifb,
-				  struct drm_mode_fb_cmd *mode_cmd,
+				  struct drm_mode_fb_cmd2 *mode_cmd,
 				  struct drm_i915_gem_object *obj);
 extern int intel_fbdev_init(struct drm_device *dev);
 extern void intel_fbdev_fini(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index ec49bae..11baa99 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -65,7 +65,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct fb_info *info;
 	struct drm_framebuffer *fb;
-	struct drm_mode_fb_cmd mode_cmd;
+	struct drm_mode_fb_cmd2 mode_cmd;
 	struct drm_i915_gem_object *obj;
 	struct device *device = &dev->pdev->dev;
 	int size, ret;
@@ -80,6 +80,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
 	mode_cmd.bpp = sizes->surface_bpp;
 	mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 7) / 8), 64);
 	mode_cmd.depth = sizes->surface_depth;
+	mode_cmd.pixel_format = 0;
 
 	size = mode_cmd.pitch * mode_cmd.height;
 	size = ALIGN(size, PAGE_SIZE);
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index eb514ea..b03df00 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -64,7 +64,7 @@ static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = {
 int
 nouveau_framebuffer_init(struct drm_device *dev,
 			 struct nouveau_framebuffer *nv_fb,
-			 struct drm_mode_fb_cmd *mode_cmd,
+			 struct drm_mode_fb_cmd2 *mode_cmd,
 			 struct nouveau_bo *nvbo)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -121,7 +121,7 @@ nouveau_framebuffer_init(struct drm_device *dev,
 static struct drm_framebuffer *
 nouveau_user_framebuffer_create(struct drm_device *dev,
 				struct drm_file *file_priv,
-				struct drm_mode_fb_cmd *mode_cmd)
+				struct drm_mode_fb_cmd2 *mode_cmd)
 {
 	struct nouveau_framebuffer *nouveau_fb;
 	struct drm_gem_object *gem;
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index ae247ee..74ffab6 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -1122,7 +1122,7 @@ static const struct drm_framebuffer_funcs radeon_fb_funcs = {
 void
 radeon_framebuffer_init(struct drm_device *dev,
 			struct radeon_framebuffer *rfb,
-			struct drm_mode_fb_cmd *mode_cmd,
+			struct drm_mode_fb_cmd2 *mode_cmd,
 			struct drm_gem_object *obj)
 {
 	rfb->obj = obj;
@@ -1133,7 +1133,7 @@ radeon_framebuffer_init(struct drm_device *dev,
 static struct drm_framebuffer *
 radeon_user_framebuffer_create(struct drm_device *dev,
 			       struct drm_file *file_priv,
-			       struct drm_mode_fb_cmd *mode_cmd)
+			       struct drm_mode_fb_cmd2 *mode_cmd)
 {
 	struct drm_gem_object *obj;
 	struct radeon_framebuffer *radeon_fb;
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 0b7b486..06215ac 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -103,7 +103,7 @@ static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj)
 }
 
 static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
-					 struct drm_mode_fb_cmd *mode_cmd,
+					 struct drm_mode_fb_cmd2 *mode_cmd,
 					 struct drm_gem_object **gobj_p)
 {
 	struct radeon_device *rdev = rfbdev->rdev;
@@ -187,7 +187,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
 	struct radeon_device *rdev = rfbdev->rdev;
 	struct fb_info *info;
 	struct drm_framebuffer *fb = NULL;
-	struct drm_mode_fb_cmd mode_cmd;
+	struct drm_mode_fb_cmd2 mode_cmd;
 	struct drm_gem_object *gobj = NULL;
 	struct radeon_bo *rbo = NULL;
 	struct device *device = &rdev->pdev->dev;
@@ -203,6 +203,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
 
 	mode_cmd.bpp = sizes->surface_bpp;
 	mode_cmd.depth = sizes->surface_depth;
+	mode_cmd.pixel_format = 0;
 
 	ret = radeonfb_create_pinned_object(rfbdev, &mode_cmd, &gobj);
 	rbo = gem_to_radeon_bo(gobj);
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 977a341..121eb56 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -637,7 +637,7 @@ extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green
 				     u16 *blue, int regno);
 void radeon_framebuffer_init(struct drm_device *dev,
 			     struct radeon_framebuffer *rfb,
-			     struct drm_mode_fb_cmd *mode_cmd,
+			     struct drm_mode_fb_cmd2 *mode_cmd,
 			     struct drm_gem_object *obj);
 
 int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index dfe32e6..f6566a8 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -836,7 +836,7 @@ out_err1:
 
 static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
 						 struct drm_file *file_priv,
-						 struct drm_mode_fb_cmd *mode_cmd)
+						 struct drm_mode_fb_cmd2 *mode_cmd)
 {
 	struct vmw_private *dev_priv = vmw_priv(dev);
 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index 99c03a2..3cfa632 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -481,7 +481,7 @@ out_err1:
  */
 static struct drm_framebuffer *psb_user_framebuffer_create
 			(struct drm_device *dev, struct drm_file *filp,
-			 struct drm_mode_fb_cmd *cmd)
+			 struct drm_mode_fb_cmd2 *cmd)
 {
         struct gtt_range *r;
         struct drm_gem_object *obj;
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 2897967..49d94ed 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -717,6 +717,7 @@ struct drm_get_cap {
 #define DRM_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xB5, struct drm_mode_get_plane_res)
 #define DRM_IOCTL_MODE_GETPLANE	DRM_IOWR(0xB6, struct drm_mode_get_plane)
 #define DRM_IOCTL_MODE_SETPLANE	DRM_IOWR(0xB7, struct drm_mode_set_plane)
+#define DRM_IOCTL_MODE_ADDFB2		DRM_IOWR(0xB8, struct drm_mode_fb_cmd2)
 
 /**
  * Device specific ioctls should only be in their respective headers
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index caa72ae..6ac4d74 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -29,6 +29,7 @@
 #include <linux/spinlock.h>
 #include <linux/types.h>
 #include <linux/idr.h>
+#include <linux/videodev2.h> /* for plane formats */
 
 #include <linux/fb.h>
 
@@ -244,6 +245,7 @@ struct drm_framebuffer {
 	unsigned int depth;
 	int bits_per_pixel;
 	int flags;
+	uint32_t pixel_format; /* fourcc format */
 	struct list_head filp_head;
 	/* if you are using the helper */
 	void *helper_private;
@@ -604,7 +606,7 @@ struct drm_mode_set {
  * struct drm_mode_config_funcs - configure CRTCs for a given screen layout
  */
 struct drm_mode_config_funcs {
-	struct drm_framebuffer *(*fb_create)(struct drm_device *dev, struct drm_file *file_priv, struct drm_mode_fb_cmd *mode_cmd);
+	struct drm_framebuffer *(*fb_create)(struct drm_device *dev, struct drm_file *file_priv, struct drm_mode_fb_cmd2 *mode_cmd);
 	void (*output_poll_changed)(struct drm_device *dev);
 };
 
@@ -822,6 +824,8 @@ extern int drm_mode_cursor_ioctl(struct drm_device *dev,
 				void *data, struct drm_file *file_priv);
 extern int drm_mode_addfb(struct drm_device *dev,
 			  void *data, struct drm_file *file_priv);
+extern int drm_mode_addfb2(struct drm_device *dev,
+			   void *data, struct drm_file *file_priv);
 extern int drm_mode_rmfb(struct drm_device *dev,
 			 void *data, struct drm_file *file_priv);
 extern int drm_mode_getfb(struct drm_device *dev,
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index 73b0712..e88b7d7 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -117,7 +117,7 @@ extern bool drm_helper_encoder_in_use(struct drm_encoder *encoder);
 extern void drm_helper_connector_dpms(struct drm_connector *connector, int mode);
 
 extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
-					  struct drm_mode_fb_cmd *mode_cmd);
+					  struct drm_mode_fb_cmd2 *mode_cmd);
 
 static inline void drm_crtc_helper_add(struct drm_crtc *crtc,
 				       const struct drm_crtc_helper_funcs *funcs)
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index fa6d348..82cd587 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -27,6 +27,8 @@
 #ifndef _DRM_MODE_H
 #define _DRM_MODE_H
 
+#include <linux/videodev2.h>
+
 #define DRM_DISPLAY_INFO_LEN	32
 #define DRM_CONNECTOR_NAME_LEN	32
 #define DRM_DISPLAY_MODE_LEN	32
@@ -264,6 +266,18 @@ struct drm_mode_fb_cmd {
 	__u32 handle;
 };
 
+/* For addfb2 ioctl, contains format info */
+struct drm_mode_fb_cmd2 {
+	__u32 fb_id;
+	__u32 width, height;
+	__u32 pitch;
+	__u32 bpp;
+	__u32 depth;
+	__u32 pixel_format; /* fourcc code from videodev2.h */
+	/* driver specific handle */
+	__u32 handle;
+};
+
 #define DRM_MODE_FB_DIRTY_ANNOTATE_COPY 0x01
 #define DRM_MODE_FB_DIRTY_ANNOTATE_FILL 0x02
 #define DRM_MODE_FB_DIRTY_FLAGS         0x03
-- 
1.7.4.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
@ 2011-06-20 20:11   ` Jesse Barnes
  0 siblings, 0 replies; 27+ messages in thread
From: Jesse Barnes @ 2011-06-20 20:11 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx, Marcus Lorentzon, Alan Cox

To properly support the various plane formats supported by different
hardware, the kernel must know the pixel format of a framebuffer object.
So add a new ioctl taking a format argument corresponding to a fourcc
name from videodev2.h.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/drm_crtc.c                |   71 ++++++++++++++++++++++++++++-
 drivers/gpu/drm/drm_crtc_helper.c         |    3 +-
 drivers/gpu/drm/drm_drv.c                 |    1 +
 drivers/gpu/drm/i915/intel_display.c      |    9 ++--
 drivers/gpu/drm/i915/intel_drv.h          |    2 +-
 drivers/gpu/drm/i915/intel_fb.c           |    3 +-
 drivers/gpu/drm/nouveau/nouveau_display.c |    4 +-
 drivers/gpu/drm/radeon/radeon_display.c   |    4 +-
 drivers/gpu/drm/radeon/radeon_fb.c        |    5 +-
 drivers/gpu/drm/radeon/radeon_mode.h      |    2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c       |    2 +-
 drivers/staging/gma500/psb_fb.c           |    2 +-
 include/drm/drm.h                         |    1 +
 include/drm/drm_crtc.h                    |    6 ++-
 include/drm/drm_crtc_helper.h             |    2 +-
 include/drm/drm_mode.h                    |   14 ++++++
 16 files changed, 112 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 9be36a5..f963cf5 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1909,7 +1909,76 @@ out:
 int drm_mode_addfb(struct drm_device *dev,
 		   void *data, struct drm_file *file_priv)
 {
-	struct drm_mode_fb_cmd *r = data;
+	struct drm_mode_fb_cmd *or = data;
+	struct drm_mode_fb_cmd2 r;
+	struct drm_mode_config *config = &dev->mode_config;
+	struct drm_framebuffer *fb;
+	int ret = 0;
+
+	/* Use new struct with format internally */
+	r.fb_id = or->fb_id;
+	r.width = or->width;
+	r.height = or->height;
+	r.pitch = or->pitch;
+	r.bpp = or->bpp;
+	r.depth = or->depth;
+	r.pixel_format = 0;
+	r.handle = or->handle;
+
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		return -EINVAL;
+
+	if ((config->min_width > r.width) || (r.width > config->max_width)) {
+		DRM_ERROR("mode new framebuffer width not within limits\n");
+		return -EINVAL;
+	}
+	if ((config->min_height > r.height) || (r.height > config->max_height)) {
+		DRM_ERROR("mode new framebuffer height not within limits\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&dev->mode_config.mutex);
+
+	/* TODO check buffer is sufficiently large */
+	/* TODO setup destructor callback */
+
+	fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r);
+	if (IS_ERR(fb)) {
+		DRM_ERROR("could not create framebuffer\n");
+		ret = PTR_ERR(fb);
+		goto out;
+	}
+
+	or->fb_id = fb->base.id;
+	list_add(&fb->filp_head, &file_priv->fbs);
+	DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
+
+out:
+	mutex_unlock(&dev->mode_config.mutex);
+	return ret;
+}
+
+/**
+ * drm_mode_addfb2 - add an FB to the graphics configuration
+ * @inode: inode from the ioctl
+ * @filp: file * from the ioctl
+ * @cmd: cmd from ioctl
+ * @arg: arg from ioctl
+ *
+ * LOCKING:
+ * Takes mode config lock.
+ *
+ * Add a new FB to the specified CRTC, given a user request with format.
+ *
+ * Called by the user via ioctl.
+ *
+ * RETURNS:
+ * Zero on success, errno on failure.
+ */
+int drm_mode_addfb2(struct drm_device *dev,
+		    void *data, struct drm_file *file_priv)
+{
+	struct drm_mode_fb_cmd2 *r = data;
 	struct drm_mode_config *config = &dev->mode_config;
 	struct drm_framebuffer *fb;
 	int ret = 0;
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 9236965..5adab04 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -801,13 +801,14 @@ void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
 EXPORT_SYMBOL(drm_helper_connector_dpms);
 
 int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
-				   struct drm_mode_fb_cmd *mode_cmd)
+				   struct drm_mode_fb_cmd2 *mode_cmd)
 {
 	fb->width = mode_cmd->width;
 	fb->height = mode_cmd->height;
 	fb->pitch = mode_cmd->pitch;
 	fb->bits_per_pixel = mode_cmd->bpp;
 	fb->depth = mode_cmd->depth;
+	fb->pixel_format = mode_cmd->pixel_format;
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 15da618..f24b9b6 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -152,6 +152,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 0b6fd36..8a6e3ab 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5803,7 +5803,7 @@ static struct drm_display_mode load_detect_mode = {
 
 static struct drm_framebuffer *
 intel_framebuffer_create(struct drm_device *dev,
-			 struct drm_mode_fb_cmd *mode_cmd,
+			 struct drm_mode_fb_cmd2 *mode_cmd,
 			 struct drm_i915_gem_object *obj)
 {
 	struct intel_framebuffer *intel_fb;
@@ -5845,7 +5845,7 @@ intel_framebuffer_create_for_mode(struct drm_device *dev,
 				  int depth, int bpp)
 {
 	struct drm_i915_gem_object *obj;
-	struct drm_mode_fb_cmd mode_cmd;
+	struct drm_mode_fb_cmd2 mode_cmd;
 
 	obj = i915_gem_alloc_object(dev,
 				    intel_framebuffer_size_for_mode(mode, bpp));
@@ -5857,6 +5857,7 @@ intel_framebuffer_create_for_mode(struct drm_device *dev,
 	mode_cmd.depth = depth;
 	mode_cmd.bpp = bpp;
 	mode_cmd.pitch = intel_framebuffer_pitch_for_width(mode_cmd.width, bpp);
+	mode_cmd.pixel_format = 0;
 
 	return intel_framebuffer_create(dev, &mode_cmd, obj);
 }
@@ -6978,7 +6979,7 @@ static const struct drm_framebuffer_funcs intel_fb_funcs = {
 
 int intel_framebuffer_init(struct drm_device *dev,
 			   struct intel_framebuffer *intel_fb,
-			   struct drm_mode_fb_cmd *mode_cmd,
+			   struct drm_mode_fb_cmd2 *mode_cmd,
 			   struct drm_i915_gem_object *obj)
 {
 	int ret;
@@ -7013,7 +7014,7 @@ int intel_framebuffer_init(struct drm_device *dev,
 static struct drm_framebuffer *
 intel_user_framebuffer_create(struct drm_device *dev,
 			      struct drm_file *filp,
-			      struct drm_mode_fb_cmd *mode_cmd)
+			      struct drm_mode_fb_cmd2 *mode_cmd)
 {
 	struct drm_i915_gem_object *obj;
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 0dc9018..3cfc391 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -326,7 +326,7 @@ extern int intel_pin_and_fence_fb_obj(struct drm_device *dev,
 
 extern int intel_framebuffer_init(struct drm_device *dev,
 				  struct intel_framebuffer *ifb,
-				  struct drm_mode_fb_cmd *mode_cmd,
+				  struct drm_mode_fb_cmd2 *mode_cmd,
 				  struct drm_i915_gem_object *obj);
 extern int intel_fbdev_init(struct drm_device *dev);
 extern void intel_fbdev_fini(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index ec49bae..11baa99 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -65,7 +65,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct fb_info *info;
 	struct drm_framebuffer *fb;
-	struct drm_mode_fb_cmd mode_cmd;
+	struct drm_mode_fb_cmd2 mode_cmd;
 	struct drm_i915_gem_object *obj;
 	struct device *device = &dev->pdev->dev;
 	int size, ret;
@@ -80,6 +80,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
 	mode_cmd.bpp = sizes->surface_bpp;
 	mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 7) / 8), 64);
 	mode_cmd.depth = sizes->surface_depth;
+	mode_cmd.pixel_format = 0;
 
 	size = mode_cmd.pitch * mode_cmd.height;
 	size = ALIGN(size, PAGE_SIZE);
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index eb514ea..b03df00 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -64,7 +64,7 @@ static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = {
 int
 nouveau_framebuffer_init(struct drm_device *dev,
 			 struct nouveau_framebuffer *nv_fb,
-			 struct drm_mode_fb_cmd *mode_cmd,
+			 struct drm_mode_fb_cmd2 *mode_cmd,
 			 struct nouveau_bo *nvbo)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -121,7 +121,7 @@ nouveau_framebuffer_init(struct drm_device *dev,
 static struct drm_framebuffer *
 nouveau_user_framebuffer_create(struct drm_device *dev,
 				struct drm_file *file_priv,
-				struct drm_mode_fb_cmd *mode_cmd)
+				struct drm_mode_fb_cmd2 *mode_cmd)
 {
 	struct nouveau_framebuffer *nouveau_fb;
 	struct drm_gem_object *gem;
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index ae247ee..74ffab6 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -1122,7 +1122,7 @@ static const struct drm_framebuffer_funcs radeon_fb_funcs = {
 void
 radeon_framebuffer_init(struct drm_device *dev,
 			struct radeon_framebuffer *rfb,
-			struct drm_mode_fb_cmd *mode_cmd,
+			struct drm_mode_fb_cmd2 *mode_cmd,
 			struct drm_gem_object *obj)
 {
 	rfb->obj = obj;
@@ -1133,7 +1133,7 @@ radeon_framebuffer_init(struct drm_device *dev,
 static struct drm_framebuffer *
 radeon_user_framebuffer_create(struct drm_device *dev,
 			       struct drm_file *file_priv,
-			       struct drm_mode_fb_cmd *mode_cmd)
+			       struct drm_mode_fb_cmd2 *mode_cmd)
 {
 	struct drm_gem_object *obj;
 	struct radeon_framebuffer *radeon_fb;
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 0b7b486..06215ac 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -103,7 +103,7 @@ static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj)
 }
 
 static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
-					 struct drm_mode_fb_cmd *mode_cmd,
+					 struct drm_mode_fb_cmd2 *mode_cmd,
 					 struct drm_gem_object **gobj_p)
 {
 	struct radeon_device *rdev = rfbdev->rdev;
@@ -187,7 +187,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
 	struct radeon_device *rdev = rfbdev->rdev;
 	struct fb_info *info;
 	struct drm_framebuffer *fb = NULL;
-	struct drm_mode_fb_cmd mode_cmd;
+	struct drm_mode_fb_cmd2 mode_cmd;
 	struct drm_gem_object *gobj = NULL;
 	struct radeon_bo *rbo = NULL;
 	struct device *device = &rdev->pdev->dev;
@@ -203,6 +203,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
 
 	mode_cmd.bpp = sizes->surface_bpp;
 	mode_cmd.depth = sizes->surface_depth;
+	mode_cmd.pixel_format = 0;
 
 	ret = radeonfb_create_pinned_object(rfbdev, &mode_cmd, &gobj);
 	rbo = gem_to_radeon_bo(gobj);
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 977a341..121eb56 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -637,7 +637,7 @@ extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green
 				     u16 *blue, int regno);
 void radeon_framebuffer_init(struct drm_device *dev,
 			     struct radeon_framebuffer *rfb,
-			     struct drm_mode_fb_cmd *mode_cmd,
+			     struct drm_mode_fb_cmd2 *mode_cmd,
 			     struct drm_gem_object *obj);
 
 int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index dfe32e6..f6566a8 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -836,7 +836,7 @@ out_err1:
 
 static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
 						 struct drm_file *file_priv,
-						 struct drm_mode_fb_cmd *mode_cmd)
+						 struct drm_mode_fb_cmd2 *mode_cmd)
 {
 	struct vmw_private *dev_priv = vmw_priv(dev);
 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index 99c03a2..3cfa632 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -481,7 +481,7 @@ out_err1:
  */
 static struct drm_framebuffer *psb_user_framebuffer_create
 			(struct drm_device *dev, struct drm_file *filp,
-			 struct drm_mode_fb_cmd *cmd)
+			 struct drm_mode_fb_cmd2 *cmd)
 {
         struct gtt_range *r;
         struct drm_gem_object *obj;
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 2897967..49d94ed 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -717,6 +717,7 @@ struct drm_get_cap {
 #define DRM_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xB5, struct drm_mode_get_plane_res)
 #define DRM_IOCTL_MODE_GETPLANE	DRM_IOWR(0xB6, struct drm_mode_get_plane)
 #define DRM_IOCTL_MODE_SETPLANE	DRM_IOWR(0xB7, struct drm_mode_set_plane)
+#define DRM_IOCTL_MODE_ADDFB2		DRM_IOWR(0xB8, struct drm_mode_fb_cmd2)
 
 /**
  * Device specific ioctls should only be in their respective headers
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index caa72ae..6ac4d74 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -29,6 +29,7 @@
 #include <linux/spinlock.h>
 #include <linux/types.h>
 #include <linux/idr.h>
+#include <linux/videodev2.h> /* for plane formats */
 
 #include <linux/fb.h>
 
@@ -244,6 +245,7 @@ struct drm_framebuffer {
 	unsigned int depth;
 	int bits_per_pixel;
 	int flags;
+	uint32_t pixel_format; /* fourcc format */
 	struct list_head filp_head;
 	/* if you are using the helper */
 	void *helper_private;
@@ -604,7 +606,7 @@ struct drm_mode_set {
  * struct drm_mode_config_funcs - configure CRTCs for a given screen layout
  */
 struct drm_mode_config_funcs {
-	struct drm_framebuffer *(*fb_create)(struct drm_device *dev, struct drm_file *file_priv, struct drm_mode_fb_cmd *mode_cmd);
+	struct drm_framebuffer *(*fb_create)(struct drm_device *dev, struct drm_file *file_priv, struct drm_mode_fb_cmd2 *mode_cmd);
 	void (*output_poll_changed)(struct drm_device *dev);
 };
 
@@ -822,6 +824,8 @@ extern int drm_mode_cursor_ioctl(struct drm_device *dev,
 				void *data, struct drm_file *file_priv);
 extern int drm_mode_addfb(struct drm_device *dev,
 			  void *data, struct drm_file *file_priv);
+extern int drm_mode_addfb2(struct drm_device *dev,
+			   void *data, struct drm_file *file_priv);
 extern int drm_mode_rmfb(struct drm_device *dev,
 			 void *data, struct drm_file *file_priv);
 extern int drm_mode_getfb(struct drm_device *dev,
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index 73b0712..e88b7d7 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -117,7 +117,7 @@ extern bool drm_helper_encoder_in_use(struct drm_encoder *encoder);
 extern void drm_helper_connector_dpms(struct drm_connector *connector, int mode);
 
 extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
-					  struct drm_mode_fb_cmd *mode_cmd);
+					  struct drm_mode_fb_cmd2 *mode_cmd);
 
 static inline void drm_crtc_helper_add(struct drm_crtc *crtc,
 				       const struct drm_crtc_helper_funcs *funcs)
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index fa6d348..82cd587 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -27,6 +27,8 @@
 #ifndef _DRM_MODE_H
 #define _DRM_MODE_H
 
+#include <linux/videodev2.h>
+
 #define DRM_DISPLAY_INFO_LEN	32
 #define DRM_CONNECTOR_NAME_LEN	32
 #define DRM_DISPLAY_MODE_LEN	32
@@ -264,6 +266,18 @@ struct drm_mode_fb_cmd {
 	__u32 handle;
 };
 
+/* For addfb2 ioctl, contains format info */
+struct drm_mode_fb_cmd2 {
+	__u32 fb_id;
+	__u32 width, height;
+	__u32 pitch;
+	__u32 bpp;
+	__u32 depth;
+	__u32 pixel_format; /* fourcc code from videodev2.h */
+	/* driver specific handle */
+	__u32 handle;
+};
+
 #define DRM_MODE_FB_DIRTY_ANNOTATE_COPY 0x01
 #define DRM_MODE_FB_DIRTY_ANNOTATE_FILL 0x02
 #define DRM_MODE_FB_DIRTY_FLAGS         0x03
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 3/4] drm/i915: rename existing overlay support to "legacy"
  2011-06-20 20:11 [RFC] Updated plane support v3 Jesse Barnes
@ 2011-06-20 20:11   ` Jesse Barnes
  2011-06-20 20:11   ` Jesse Barnes
                     ` (5 subsequent siblings)
  6 siblings, 0 replies; 27+ messages in thread
From: Jesse Barnes @ 2011-06-20 20:11 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx, Marcus Lorentzon, Alan Cox, Jesse Barnes

The old overlay block has all sorts of quirks and is very different than
ILK+ video sprites.  So rename it to legacy to make that clear and clash
less with core overlay support.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/i915_debugfs.c  |    2 +-
 drivers/gpu/drm/i915/i915_drv.h      |   12 ++--
 drivers/gpu/drm/i915/i915_irq.c      |    2 +-
 drivers/gpu/drm/i915/intel_display.c |    2 +-
 drivers/gpu/drm/i915/intel_drv.h     |    4 +-
 drivers/gpu/drm/i915/intel_overlay.c |  126 +++++++++++++++++-----------------
 6 files changed, 74 insertions(+), 74 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 51c2257..c83ed15 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -825,7 +825,7 @@ static int i915_error_state(struct seq_file *m, void *unused)
 	}
 
 	if (error->overlay)
-		intel_overlay_print_error_state(m, error->overlay);
+		intel_legacy_overlay_print_error_state(m, error->overlay);
 
 	if (error->display)
 		intel_display_print_error_state(m, dev, error->display);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 31e199f..062e80e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -117,8 +117,8 @@ struct intel_opregion {
 };
 #define OPREGION_SIZE            (8*1024)
 
-struct intel_overlay;
-struct intel_overlay_error_state;
+struct intel_legacy_overlay;
+struct intel_legacy_overlay_error_state;
 
 struct drm_i915_master_private {
 	drm_local_map_t *sarea;
@@ -191,7 +191,7 @@ struct drm_i915_error_state {
 		u32 cache_level:2;
 	} *active_bo, *pinned_bo;
 	u32 active_bo_count, pinned_bo_count;
-	struct intel_overlay_error_state *overlay;
+	struct intel_legacy_overlay_error_state *overlay;
 	struct intel_display_error_state *display;
 };
 
@@ -336,7 +336,7 @@ typedef struct drm_i915_private {
 	struct intel_opregion opregion;
 
 	/* overlay */
-	struct intel_overlay *overlay;
+	struct intel_legacy_overlay *overlay;
 
 	/* LVDS info */
 	int backlight_level;  /* restore backlight to this value */
@@ -1329,8 +1329,8 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
 
 /* overlay */
 #ifdef CONFIG_DEBUG_FS
-extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev);
-extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error);
+extern struct intel_legacy_overlay_error_state *intel_legacy_overlay_capture_error_state(struct drm_device *dev);
+extern void intel_legacy_overlay_print_error_state(struct seq_file *m, struct intel_legacy_overlay_error_state *error);
 
 extern struct intel_display_error_state *intel_display_capture_error_state(struct drm_device *dev);
 extern void intel_display_print_error_state(struct seq_file *m,
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b79619a..7a34167 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -991,7 +991,7 @@ static void i915_capture_error_state(struct drm_device *dev)
 
 	do_gettimeofday(&error->time);
 
-	error->overlay = intel_overlay_capture_error_state(dev);
+	error->overlay = intel_legacy_overlay_capture_error_state(dev);
 	error->display = intel_display_capture_error_state(dev);
 
 	spin_lock_irqsave(&dev_priv->error_lock, flags);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8a6e3ab..7901f16 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2936,7 +2936,7 @@ static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
 
 		mutex_lock(&dev->struct_mutex);
 		dev_priv->mm.interruptible = false;
-		(void) intel_overlay_switch_off(intel_crtc->overlay);
+		(void) intel_legacy_overlay_switch_off(intel_crtc->overlay);
 		dev_priv->mm.interruptible = true;
 		mutex_unlock(&dev->struct_mutex);
 	}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 3cfc391..d73e622 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -161,7 +161,7 @@ struct intel_crtc {
 	bool busy; /* is scanout buffer being updated frequently? */
 	struct timer_list idle_timer;
 	bool lowfreq_avail;
-	struct intel_overlay *overlay;
+	struct intel_legacy_overlay *overlay;
 	struct intel_unpin_work *unpin_work;
 	int fdi_lanes;
 
@@ -337,7 +337,7 @@ extern void intel_finish_page_flip_plane(struct drm_device *dev, int plane);
 
 extern void intel_setup_overlay(struct drm_device *dev);
 extern void intel_cleanup_overlay(struct drm_device *dev);
-extern int intel_overlay_switch_off(struct intel_overlay *overlay);
+extern int intel_legacy_overlay_switch_off(struct intel_legacy_overlay *overlay);
 extern int intel_overlay_put_image(struct drm_device *dev, void *data,
 				   struct drm_file *file_priv);
 extern int intel_overlay_attrs(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index a670c00..42e6561 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -170,7 +170,7 @@ struct overlay_registers {
     u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
 };
 
-struct intel_overlay {
+struct intel_legacy_overlay {
 	struct drm_device *dev;
 	struct intel_crtc *crtc;
 	struct drm_i915_gem_object *vid_bo;
@@ -186,11 +186,11 @@ struct intel_overlay {
 	struct drm_i915_gem_object *reg_bo;
 	/* flip handling */
 	uint32_t last_flip_req;
-	void (*flip_tail)(struct intel_overlay *);
+	void (*flip_tail)(struct intel_legacy_overlay *);
 };
 
 static struct overlay_registers *
-intel_overlay_map_regs(struct intel_overlay *overlay)
+intel_legacy_overlay_map_regs(struct intel_legacy_overlay *overlay)
 {
         drm_i915_private_t *dev_priv = overlay->dev->dev_private;
 	struct overlay_registers *regs;
@@ -204,16 +204,16 @@ intel_overlay_map_regs(struct intel_overlay *overlay)
 	return regs;
 }
 
-static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
+static void intel_legacy_overlay_unmap_regs(struct intel_legacy_overlay *overlay,
 				     struct overlay_registers *regs)
 {
 	if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
 		io_mapping_unmap(regs);
 }
 
-static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
+static int intel_legacy_overlay_do_wait_request(struct intel_legacy_overlay *overlay,
 					 struct drm_i915_gem_request *request,
-					 void (*tail)(struct intel_overlay *))
+					 void (*tail)(struct intel_legacy_overlay *))
 {
 	struct drm_device *dev = overlay->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -284,7 +284,7 @@ i830_deactivate_pipe_a(struct drm_device *dev)
 }
 
 /* overlay needs to be disable in OCMD reg */
-static int intel_overlay_on(struct intel_overlay *overlay)
+static int intel_legacy_overlay_on(struct intel_legacy_overlay *overlay)
 {
 	struct drm_device *dev = overlay->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -319,7 +319,7 @@ static int intel_overlay_on(struct intel_overlay *overlay)
 	OUT_RING(MI_NOOP);
 	ADVANCE_LP_RING();
 
-	ret = intel_overlay_do_wait_request(overlay, request, NULL);
+	ret = intel_legacy_overlay_do_wait_request(overlay, request, NULL);
 out:
 	if (pipe_a_quirk)
 		i830_deactivate_pipe_a(dev);
@@ -328,7 +328,7 @@ out:
 }
 
 /* overlay needs to be enabled in OCMD reg */
-static int intel_overlay_continue(struct intel_overlay *overlay,
+static int intel_legacy_overlay_continue(struct intel_legacy_overlay *overlay,
 				  bool load_polyphase_filter)
 {
 	struct drm_device *dev = overlay->dev;
@@ -371,7 +371,7 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
 	return 0;
 }
 
-static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
+static void intel_legacy_overlay_release_old_vid_tail(struct intel_legacy_overlay *overlay)
 {
 	struct drm_i915_gem_object *obj = overlay->old_vid_bo;
 
@@ -381,7 +381,7 @@ static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
 	overlay->old_vid_bo = NULL;
 }
 
-static void intel_overlay_off_tail(struct intel_overlay *overlay)
+static void intel_legacy_overlay_off_tail(struct intel_legacy_overlay *overlay)
 {
 	struct drm_i915_gem_object *obj = overlay->vid_bo;
 
@@ -398,7 +398,7 @@ static void intel_overlay_off_tail(struct intel_overlay *overlay)
 }
 
 /* overlay needs to be disabled in OCMD reg */
-static int intel_overlay_off(struct intel_overlay *overlay)
+static int intel_legacy_overlay_off(struct intel_legacy_overlay *overlay)
 {
 	struct drm_device *dev = overlay->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -433,13 +433,13 @@ static int intel_overlay_off(struct intel_overlay *overlay)
 	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
 	ADVANCE_LP_RING();
 
-	return intel_overlay_do_wait_request(overlay, request,
-					     intel_overlay_off_tail);
+	return intel_legacy_overlay_do_wait_request(overlay, request,
+					     intel_legacy_overlay_off_tail);
 }
 
 /* recover from an interruption due to a signal
  * We have to be careful not to repeat work forever an make forward progess. */
-static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
+static int intel_legacy_overlay_recover_from_interrupt(struct intel_legacy_overlay *overlay)
 {
 	struct drm_device *dev = overlay->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -461,9 +461,9 @@ static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
 
 /* Wait for pending overlay flip and release old frame.
  * Needs to be called before the overlay register are changed
- * via intel_overlay_(un)map_regs
+ * via intel_legacy_overlay_(un)map_regs
  */
-static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
+static int intel_legacy_overlay_release_old_vid(struct intel_legacy_overlay *overlay)
 {
 	struct drm_device *dev = overlay->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -493,13 +493,13 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
 		OUT_RING(MI_NOOP);
 		ADVANCE_LP_RING();
 
-		ret = intel_overlay_do_wait_request(overlay, request,
-						    intel_overlay_release_old_vid_tail);
+		ret = intel_legacy_overlay_do_wait_request(overlay, request,
+						    intel_legacy_overlay_release_old_vid_tail);
 		if (ret)
 			return ret;
 	}
 
-	intel_overlay_release_old_vid_tail(overlay);
+	intel_legacy_overlay_release_old_vid_tail(overlay);
 	return 0;
 }
 
@@ -625,7 +625,7 @@ static void update_polyphase_filter(struct overlay_registers *regs)
 	memcpy(regs->UV_HCOEFS, uv_static_hcoeffs, sizeof(uv_static_hcoeffs));
 }
 
-static bool update_scaling_factors(struct intel_overlay *overlay,
+static bool update_scaling_factors(struct intel_legacy_overlay *overlay,
 				   struct overlay_registers *regs,
 				   struct put_image_params *params)
 {
@@ -682,7 +682,7 @@ static bool update_scaling_factors(struct intel_overlay *overlay,
 	return scale_changed;
 }
 
-static void update_colorkey(struct intel_overlay *overlay,
+static void update_colorkey(struct intel_legacy_overlay *overlay,
 			    struct overlay_registers *regs)
 {
 	u32 key = overlay->color_key;
@@ -756,7 +756,7 @@ static u32 overlay_cmd_reg(struct put_image_params *params)
 	return cmd;
 }
 
-static int intel_overlay_do_put_image(struct intel_overlay *overlay,
+static int intel_legacy_overlay_do_put_image(struct intel_legacy_overlay *overlay,
 				      struct drm_i915_gem_object *new_bo,
 				      struct put_image_params *params)
 {
@@ -769,7 +769,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
 	BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
 	BUG_ON(!overlay);
 
-	ret = intel_overlay_release_old_vid(overlay);
+	ret = intel_legacy_overlay_release_old_vid(overlay);
 	if (ret != 0)
 		return ret;
 
@@ -786,7 +786,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
 		goto out_unpin;
 
 	if (!overlay->active) {
-		regs = intel_overlay_map_regs(overlay);
+		regs = intel_legacy_overlay_map_regs(overlay);
 		if (!regs) {
 			ret = -ENOMEM;
 			goto out_unpin;
@@ -796,14 +796,14 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
 			regs->OCONFIG |= OCONF_CSC_MODE_BT709;
 		regs->OCONFIG |= overlay->crtc->pipe == 0 ?
 			OCONF_PIPE_A : OCONF_PIPE_B;
-		intel_overlay_unmap_regs(overlay, regs);
+		intel_legacy_overlay_unmap_regs(overlay, regs);
 
-		ret = intel_overlay_on(overlay);
+		ret = intel_legacy_overlay_on(overlay);
 		if (ret != 0)
 			goto out_unpin;
 	}
 
-	regs = intel_overlay_map_regs(overlay);
+	regs = intel_legacy_overlay_map_regs(overlay);
 	if (!regs) {
 		ret = -ENOMEM;
 		goto out_unpin;
@@ -846,9 +846,9 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
 
 	regs->OCMD = overlay_cmd_reg(params);
 
-	intel_overlay_unmap_regs(overlay, regs);
+	intel_legacy_overlay_unmap_regs(overlay, regs);
 
-	ret = intel_overlay_continue(overlay, scale_changed);
+	ret = intel_legacy_overlay_continue(overlay, scale_changed);
 	if (ret)
 		goto out_unpin;
 
@@ -862,7 +862,7 @@ out_unpin:
 	return ret;
 }
 
-int intel_overlay_switch_off(struct intel_overlay *overlay)
+int intel_legacy_overlay_switch_off(struct intel_legacy_overlay *overlay)
 {
 	struct overlay_registers *regs;
 	struct drm_device *dev = overlay->dev;
@@ -871,30 +871,30 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
 	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
 	BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
 
-	ret = intel_overlay_recover_from_interrupt(overlay);
+	ret = intel_legacy_overlay_recover_from_interrupt(overlay);
 	if (ret != 0)
 		return ret;
 
 	if (!overlay->active)
 		return 0;
 
-	ret = intel_overlay_release_old_vid(overlay);
+	ret = intel_legacy_overlay_release_old_vid(overlay);
 	if (ret != 0)
 		return ret;
 
-	regs = intel_overlay_map_regs(overlay);
+	regs = intel_legacy_overlay_map_regs(overlay);
 	regs->OCMD = 0;
-	intel_overlay_unmap_regs(overlay, regs);
+	intel_legacy_overlay_unmap_regs(overlay, regs);
 
-	ret = intel_overlay_off(overlay);
+	ret = intel_legacy_overlay_off(overlay);
 	if (ret != 0)
 		return ret;
 
-	intel_overlay_off_tail(overlay);
+	intel_legacy_overlay_off_tail(overlay);
 	return 0;
 }
 
-static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
+static int check_overlay_possible_on_crtc(struct intel_legacy_overlay *overlay,
 					  struct intel_crtc *crtc)
 {
 	drm_i915_private_t *dev_priv = overlay->dev->dev_private;
@@ -910,7 +910,7 @@ static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
 	return 0;
 }
 
-static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
+static void update_pfit_vscale_ratio(struct intel_legacy_overlay *overlay)
 {
 	struct drm_device *dev = overlay->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -934,7 +934,7 @@ static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
 	overlay->pfit_vscale_ratio = ratio;
 }
 
-static int check_overlay_dst(struct intel_overlay *overlay,
+static int check_overlay_dst(struct intel_legacy_overlay *overlay,
 			     struct drm_intel_overlay_put_image *rec)
 {
 	struct drm_display_mode *mode = &overlay->crtc->base.mode;
@@ -1106,7 +1106,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
 {
 	struct drm_intel_overlay_put_image *put_image_rec = data;
 	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct intel_overlay *overlay;
+	struct intel_legacy_overlay *overlay;
 	struct drm_mode_object *drmmode_obj;
 	struct intel_crtc *crtc;
 	struct drm_i915_gem_object *new_bo;
@@ -1128,7 +1128,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
 		mutex_lock(&dev->mode_config.mutex);
 		mutex_lock(&dev->struct_mutex);
 
-		ret = intel_overlay_switch_off(overlay);
+		ret = intel_legacy_overlay_switch_off(overlay);
 
 		mutex_unlock(&dev->struct_mutex);
 		mutex_unlock(&dev->mode_config.mutex);
@@ -1164,13 +1164,13 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
 		goto out_unlock;
 	}
 
-	ret = intel_overlay_recover_from_interrupt(overlay);
+	ret = intel_legacy_overlay_recover_from_interrupt(overlay);
 	if (ret != 0)
 		goto out_unlock;
 
 	if (overlay->crtc != crtc) {
 		struct drm_display_mode *mode = &crtc->base.mode;
-		ret = intel_overlay_switch_off(overlay);
+		ret = intel_legacy_overlay_switch_off(overlay);
 		if (ret != 0)
 			goto out_unlock;
 
@@ -1232,7 +1232,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
 	if (ret != 0)
 		goto out_unlock;
 
-	ret = intel_overlay_do_put_image(overlay, new_bo, params);
+	ret = intel_legacy_overlay_do_put_image(overlay, new_bo, params);
 	if (ret != 0)
 		goto out_unlock;
 
@@ -1253,7 +1253,7 @@ out_free:
 	return ret;
 }
 
-static void update_reg_attrs(struct intel_overlay *overlay,
+static void update_reg_attrs(struct intel_legacy_overlay *overlay,
 			     struct overlay_registers *regs)
 {
 	regs->OCLRC0 = (overlay->contrast << 18) | (overlay->brightness & 0xff);
@@ -1309,7 +1309,7 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
 {
 	struct drm_intel_overlay_attrs *attrs = data;
         drm_i915_private_t *dev_priv = dev->dev_private;
-	struct intel_overlay *overlay;
+	struct intel_legacy_overlay *overlay;
 	struct overlay_registers *regs;
 	int ret;
 
@@ -1355,7 +1355,7 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
 		overlay->contrast   = attrs->contrast;
 		overlay->saturation = attrs->saturation;
 
-		regs = intel_overlay_map_regs(overlay);
+		regs = intel_legacy_overlay_map_regs(overlay);
 		if (!regs) {
 			ret = -ENOMEM;
 			goto out_unlock;
@@ -1363,7 +1363,7 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
 
 		update_reg_attrs(overlay, regs);
 
-		intel_overlay_unmap_regs(overlay, regs);
+		intel_legacy_overlay_unmap_regs(overlay, regs);
 
 		if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
 			if (IS_GEN2(dev))
@@ -1398,7 +1398,7 @@ out_unlock:
 void intel_setup_overlay(struct drm_device *dev)
 {
         drm_i915_private_t *dev_priv = dev->dev_private;
-	struct intel_overlay *overlay;
+	struct intel_legacy_overlay *overlay;
 	struct drm_i915_gem_object *reg_bo;
 	struct overlay_registers *regs;
 	int ret;
@@ -1406,7 +1406,7 @@ void intel_setup_overlay(struct drm_device *dev)
 	if (!HAS_OVERLAY(dev))
 		return;
 
-	overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL);
+	overlay = kzalloc(sizeof(struct intel_legacy_overlay), GFP_KERNEL);
 	if (!overlay)
 		return;
 	overlay->dev = dev;
@@ -1446,7 +1446,7 @@ void intel_setup_overlay(struct drm_device *dev)
 	overlay->contrast = 75;
 	overlay->saturation = 146;
 
-	regs = intel_overlay_map_regs(overlay);
+	regs = intel_legacy_overlay_map_regs(overlay);
 	if (!regs)
 		goto out_free_bo;
 
@@ -1454,7 +1454,7 @@ void intel_setup_overlay(struct drm_device *dev)
 	update_polyphase_filter(regs);
 	update_reg_attrs(overlay, regs);
 
-	intel_overlay_unmap_regs(overlay, regs);
+	intel_legacy_overlay_unmap_regs(overlay, regs);
 
 	dev_priv->overlay = overlay;
 	DRM_INFO("initialized overlay support\n");
@@ -1488,7 +1488,7 @@ void intel_cleanup_overlay(struct drm_device *dev)
 #ifdef CONFIG_DEBUG_FS
 #include <linux/seq_file.h>
 
-struct intel_overlay_error_state {
+struct intel_legacy_overlay_error_state {
 	struct overlay_registers regs;
 	unsigned long base;
 	u32 dovsta;
@@ -1496,7 +1496,7 @@ struct intel_overlay_error_state {
 };
 
 static struct overlay_registers *
-intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
+intel_legacy_overlay_map_regs_atomic(struct intel_legacy_overlay *overlay)
 {
 	drm_i915_private_t *dev_priv = overlay->dev->dev_private;
 	struct overlay_registers *regs;
@@ -1510,7 +1510,7 @@ intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
 	return regs;
 }
 
-static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
+static void intel_legacy_overlay_unmap_regs_atomic(struct intel_legacy_overlay *overlay,
 					    struct overlay_registers *regs)
 {
 	if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
@@ -1518,12 +1518,12 @@ static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
 }
 
 
-struct intel_overlay_error_state *
-intel_overlay_capture_error_state(struct drm_device *dev)
+struct intel_legacy_overlay_error_state *
+intel_legacy_overlay_capture_error_state(struct drm_device *dev)
 {
         drm_i915_private_t *dev_priv = dev->dev_private;
-	struct intel_overlay *overlay = dev_priv->overlay;
-	struct intel_overlay_error_state *error;
+	struct intel_legacy_overlay *overlay = dev_priv->overlay;
+	struct intel_legacy_overlay_error_state *error;
 	struct overlay_registers __iomem *regs;
 
 	if (!overlay || !overlay->active)
@@ -1540,12 +1540,12 @@ intel_overlay_capture_error_state(struct drm_device *dev)
 	else
 		error->base = (long) overlay->reg_bo->gtt_offset;
 
-	regs = intel_overlay_map_regs_atomic(overlay);
+	regs = intel_legacy_overlay_map_regs_atomic(overlay);
 	if (!regs)
 		goto err;
 
 	memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
-	intel_overlay_unmap_regs_atomic(overlay, regs);
+	intel_legacy_overlay_unmap_regs_atomic(overlay, regs);
 
 	return error;
 
@@ -1555,7 +1555,7 @@ err:
 }
 
 void
-intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error)
+intel_legacy_overlay_print_error_state(struct seq_file *m, struct intel_legacy_overlay_error_state *error)
 {
 	seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
 		   error->dovsta, error->isr);
-- 
1.7.4.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 3/4] drm/i915: rename existing overlay support to "legacy"
@ 2011-06-20 20:11   ` Jesse Barnes
  0 siblings, 0 replies; 27+ messages in thread
From: Jesse Barnes @ 2011-06-20 20:11 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

The old overlay block has all sorts of quirks and is very different than
ILK+ video sprites.  So rename it to legacy to make that clear and clash
less with core overlay support.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/i915_debugfs.c  |    2 +-
 drivers/gpu/drm/i915/i915_drv.h      |   12 ++--
 drivers/gpu/drm/i915/i915_irq.c      |    2 +-
 drivers/gpu/drm/i915/intel_display.c |    2 +-
 drivers/gpu/drm/i915/intel_drv.h     |    4 +-
 drivers/gpu/drm/i915/intel_overlay.c |  126 +++++++++++++++++-----------------
 6 files changed, 74 insertions(+), 74 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 51c2257..c83ed15 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -825,7 +825,7 @@ static int i915_error_state(struct seq_file *m, void *unused)
 	}
 
 	if (error->overlay)
-		intel_overlay_print_error_state(m, error->overlay);
+		intel_legacy_overlay_print_error_state(m, error->overlay);
 
 	if (error->display)
 		intel_display_print_error_state(m, dev, error->display);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 31e199f..062e80e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -117,8 +117,8 @@ struct intel_opregion {
 };
 #define OPREGION_SIZE            (8*1024)
 
-struct intel_overlay;
-struct intel_overlay_error_state;
+struct intel_legacy_overlay;
+struct intel_legacy_overlay_error_state;
 
 struct drm_i915_master_private {
 	drm_local_map_t *sarea;
@@ -191,7 +191,7 @@ struct drm_i915_error_state {
 		u32 cache_level:2;
 	} *active_bo, *pinned_bo;
 	u32 active_bo_count, pinned_bo_count;
-	struct intel_overlay_error_state *overlay;
+	struct intel_legacy_overlay_error_state *overlay;
 	struct intel_display_error_state *display;
 };
 
@@ -336,7 +336,7 @@ typedef struct drm_i915_private {
 	struct intel_opregion opregion;
 
 	/* overlay */
-	struct intel_overlay *overlay;
+	struct intel_legacy_overlay *overlay;
 
 	/* LVDS info */
 	int backlight_level;  /* restore backlight to this value */
@@ -1329,8 +1329,8 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
 
 /* overlay */
 #ifdef CONFIG_DEBUG_FS
-extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev);
-extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error);
+extern struct intel_legacy_overlay_error_state *intel_legacy_overlay_capture_error_state(struct drm_device *dev);
+extern void intel_legacy_overlay_print_error_state(struct seq_file *m, struct intel_legacy_overlay_error_state *error);
 
 extern struct intel_display_error_state *intel_display_capture_error_state(struct drm_device *dev);
 extern void intel_display_print_error_state(struct seq_file *m,
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b79619a..7a34167 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -991,7 +991,7 @@ static void i915_capture_error_state(struct drm_device *dev)
 
 	do_gettimeofday(&error->time);
 
-	error->overlay = intel_overlay_capture_error_state(dev);
+	error->overlay = intel_legacy_overlay_capture_error_state(dev);
 	error->display = intel_display_capture_error_state(dev);
 
 	spin_lock_irqsave(&dev_priv->error_lock, flags);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8a6e3ab..7901f16 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2936,7 +2936,7 @@ static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
 
 		mutex_lock(&dev->struct_mutex);
 		dev_priv->mm.interruptible = false;
-		(void) intel_overlay_switch_off(intel_crtc->overlay);
+		(void) intel_legacy_overlay_switch_off(intel_crtc->overlay);
 		dev_priv->mm.interruptible = true;
 		mutex_unlock(&dev->struct_mutex);
 	}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 3cfc391..d73e622 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -161,7 +161,7 @@ struct intel_crtc {
 	bool busy; /* is scanout buffer being updated frequently? */
 	struct timer_list idle_timer;
 	bool lowfreq_avail;
-	struct intel_overlay *overlay;
+	struct intel_legacy_overlay *overlay;
 	struct intel_unpin_work *unpin_work;
 	int fdi_lanes;
 
@@ -337,7 +337,7 @@ extern void intel_finish_page_flip_plane(struct drm_device *dev, int plane);
 
 extern void intel_setup_overlay(struct drm_device *dev);
 extern void intel_cleanup_overlay(struct drm_device *dev);
-extern int intel_overlay_switch_off(struct intel_overlay *overlay);
+extern int intel_legacy_overlay_switch_off(struct intel_legacy_overlay *overlay);
 extern int intel_overlay_put_image(struct drm_device *dev, void *data,
 				   struct drm_file *file_priv);
 extern int intel_overlay_attrs(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index a670c00..42e6561 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -170,7 +170,7 @@ struct overlay_registers {
     u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
 };
 
-struct intel_overlay {
+struct intel_legacy_overlay {
 	struct drm_device *dev;
 	struct intel_crtc *crtc;
 	struct drm_i915_gem_object *vid_bo;
@@ -186,11 +186,11 @@ struct intel_overlay {
 	struct drm_i915_gem_object *reg_bo;
 	/* flip handling */
 	uint32_t last_flip_req;
-	void (*flip_tail)(struct intel_overlay *);
+	void (*flip_tail)(struct intel_legacy_overlay *);
 };
 
 static struct overlay_registers *
-intel_overlay_map_regs(struct intel_overlay *overlay)
+intel_legacy_overlay_map_regs(struct intel_legacy_overlay *overlay)
 {
         drm_i915_private_t *dev_priv = overlay->dev->dev_private;
 	struct overlay_registers *regs;
@@ -204,16 +204,16 @@ intel_overlay_map_regs(struct intel_overlay *overlay)
 	return regs;
 }
 
-static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
+static void intel_legacy_overlay_unmap_regs(struct intel_legacy_overlay *overlay,
 				     struct overlay_registers *regs)
 {
 	if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
 		io_mapping_unmap(regs);
 }
 
-static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
+static int intel_legacy_overlay_do_wait_request(struct intel_legacy_overlay *overlay,
 					 struct drm_i915_gem_request *request,
-					 void (*tail)(struct intel_overlay *))
+					 void (*tail)(struct intel_legacy_overlay *))
 {
 	struct drm_device *dev = overlay->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -284,7 +284,7 @@ i830_deactivate_pipe_a(struct drm_device *dev)
 }
 
 /* overlay needs to be disable in OCMD reg */
-static int intel_overlay_on(struct intel_overlay *overlay)
+static int intel_legacy_overlay_on(struct intel_legacy_overlay *overlay)
 {
 	struct drm_device *dev = overlay->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -319,7 +319,7 @@ static int intel_overlay_on(struct intel_overlay *overlay)
 	OUT_RING(MI_NOOP);
 	ADVANCE_LP_RING();
 
-	ret = intel_overlay_do_wait_request(overlay, request, NULL);
+	ret = intel_legacy_overlay_do_wait_request(overlay, request, NULL);
 out:
 	if (pipe_a_quirk)
 		i830_deactivate_pipe_a(dev);
@@ -328,7 +328,7 @@ out:
 }
 
 /* overlay needs to be enabled in OCMD reg */
-static int intel_overlay_continue(struct intel_overlay *overlay,
+static int intel_legacy_overlay_continue(struct intel_legacy_overlay *overlay,
 				  bool load_polyphase_filter)
 {
 	struct drm_device *dev = overlay->dev;
@@ -371,7 +371,7 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
 	return 0;
 }
 
-static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
+static void intel_legacy_overlay_release_old_vid_tail(struct intel_legacy_overlay *overlay)
 {
 	struct drm_i915_gem_object *obj = overlay->old_vid_bo;
 
@@ -381,7 +381,7 @@ static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
 	overlay->old_vid_bo = NULL;
 }
 
-static void intel_overlay_off_tail(struct intel_overlay *overlay)
+static void intel_legacy_overlay_off_tail(struct intel_legacy_overlay *overlay)
 {
 	struct drm_i915_gem_object *obj = overlay->vid_bo;
 
@@ -398,7 +398,7 @@ static void intel_overlay_off_tail(struct intel_overlay *overlay)
 }
 
 /* overlay needs to be disabled in OCMD reg */
-static int intel_overlay_off(struct intel_overlay *overlay)
+static int intel_legacy_overlay_off(struct intel_legacy_overlay *overlay)
 {
 	struct drm_device *dev = overlay->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -433,13 +433,13 @@ static int intel_overlay_off(struct intel_overlay *overlay)
 	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
 	ADVANCE_LP_RING();
 
-	return intel_overlay_do_wait_request(overlay, request,
-					     intel_overlay_off_tail);
+	return intel_legacy_overlay_do_wait_request(overlay, request,
+					     intel_legacy_overlay_off_tail);
 }
 
 /* recover from an interruption due to a signal
  * We have to be careful not to repeat work forever an make forward progess. */
-static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
+static int intel_legacy_overlay_recover_from_interrupt(struct intel_legacy_overlay *overlay)
 {
 	struct drm_device *dev = overlay->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -461,9 +461,9 @@ static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
 
 /* Wait for pending overlay flip and release old frame.
  * Needs to be called before the overlay register are changed
- * via intel_overlay_(un)map_regs
+ * via intel_legacy_overlay_(un)map_regs
  */
-static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
+static int intel_legacy_overlay_release_old_vid(struct intel_legacy_overlay *overlay)
 {
 	struct drm_device *dev = overlay->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -493,13 +493,13 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
 		OUT_RING(MI_NOOP);
 		ADVANCE_LP_RING();
 
-		ret = intel_overlay_do_wait_request(overlay, request,
-						    intel_overlay_release_old_vid_tail);
+		ret = intel_legacy_overlay_do_wait_request(overlay, request,
+						    intel_legacy_overlay_release_old_vid_tail);
 		if (ret)
 			return ret;
 	}
 
-	intel_overlay_release_old_vid_tail(overlay);
+	intel_legacy_overlay_release_old_vid_tail(overlay);
 	return 0;
 }
 
@@ -625,7 +625,7 @@ static void update_polyphase_filter(struct overlay_registers *regs)
 	memcpy(regs->UV_HCOEFS, uv_static_hcoeffs, sizeof(uv_static_hcoeffs));
 }
 
-static bool update_scaling_factors(struct intel_overlay *overlay,
+static bool update_scaling_factors(struct intel_legacy_overlay *overlay,
 				   struct overlay_registers *regs,
 				   struct put_image_params *params)
 {
@@ -682,7 +682,7 @@ static bool update_scaling_factors(struct intel_overlay *overlay,
 	return scale_changed;
 }
 
-static void update_colorkey(struct intel_overlay *overlay,
+static void update_colorkey(struct intel_legacy_overlay *overlay,
 			    struct overlay_registers *regs)
 {
 	u32 key = overlay->color_key;
@@ -756,7 +756,7 @@ static u32 overlay_cmd_reg(struct put_image_params *params)
 	return cmd;
 }
 
-static int intel_overlay_do_put_image(struct intel_overlay *overlay,
+static int intel_legacy_overlay_do_put_image(struct intel_legacy_overlay *overlay,
 				      struct drm_i915_gem_object *new_bo,
 				      struct put_image_params *params)
 {
@@ -769,7 +769,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
 	BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
 	BUG_ON(!overlay);
 
-	ret = intel_overlay_release_old_vid(overlay);
+	ret = intel_legacy_overlay_release_old_vid(overlay);
 	if (ret != 0)
 		return ret;
 
@@ -786,7 +786,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
 		goto out_unpin;
 
 	if (!overlay->active) {
-		regs = intel_overlay_map_regs(overlay);
+		regs = intel_legacy_overlay_map_regs(overlay);
 		if (!regs) {
 			ret = -ENOMEM;
 			goto out_unpin;
@@ -796,14 +796,14 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
 			regs->OCONFIG |= OCONF_CSC_MODE_BT709;
 		regs->OCONFIG |= overlay->crtc->pipe == 0 ?
 			OCONF_PIPE_A : OCONF_PIPE_B;
-		intel_overlay_unmap_regs(overlay, regs);
+		intel_legacy_overlay_unmap_regs(overlay, regs);
 
-		ret = intel_overlay_on(overlay);
+		ret = intel_legacy_overlay_on(overlay);
 		if (ret != 0)
 			goto out_unpin;
 	}
 
-	regs = intel_overlay_map_regs(overlay);
+	regs = intel_legacy_overlay_map_regs(overlay);
 	if (!regs) {
 		ret = -ENOMEM;
 		goto out_unpin;
@@ -846,9 +846,9 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
 
 	regs->OCMD = overlay_cmd_reg(params);
 
-	intel_overlay_unmap_regs(overlay, regs);
+	intel_legacy_overlay_unmap_regs(overlay, regs);
 
-	ret = intel_overlay_continue(overlay, scale_changed);
+	ret = intel_legacy_overlay_continue(overlay, scale_changed);
 	if (ret)
 		goto out_unpin;
 
@@ -862,7 +862,7 @@ out_unpin:
 	return ret;
 }
 
-int intel_overlay_switch_off(struct intel_overlay *overlay)
+int intel_legacy_overlay_switch_off(struct intel_legacy_overlay *overlay)
 {
 	struct overlay_registers *regs;
 	struct drm_device *dev = overlay->dev;
@@ -871,30 +871,30 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
 	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
 	BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
 
-	ret = intel_overlay_recover_from_interrupt(overlay);
+	ret = intel_legacy_overlay_recover_from_interrupt(overlay);
 	if (ret != 0)
 		return ret;
 
 	if (!overlay->active)
 		return 0;
 
-	ret = intel_overlay_release_old_vid(overlay);
+	ret = intel_legacy_overlay_release_old_vid(overlay);
 	if (ret != 0)
 		return ret;
 
-	regs = intel_overlay_map_regs(overlay);
+	regs = intel_legacy_overlay_map_regs(overlay);
 	regs->OCMD = 0;
-	intel_overlay_unmap_regs(overlay, regs);
+	intel_legacy_overlay_unmap_regs(overlay, regs);
 
-	ret = intel_overlay_off(overlay);
+	ret = intel_legacy_overlay_off(overlay);
 	if (ret != 0)
 		return ret;
 
-	intel_overlay_off_tail(overlay);
+	intel_legacy_overlay_off_tail(overlay);
 	return 0;
 }
 
-static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
+static int check_overlay_possible_on_crtc(struct intel_legacy_overlay *overlay,
 					  struct intel_crtc *crtc)
 {
 	drm_i915_private_t *dev_priv = overlay->dev->dev_private;
@@ -910,7 +910,7 @@ static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
 	return 0;
 }
 
-static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
+static void update_pfit_vscale_ratio(struct intel_legacy_overlay *overlay)
 {
 	struct drm_device *dev = overlay->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -934,7 +934,7 @@ static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
 	overlay->pfit_vscale_ratio = ratio;
 }
 
-static int check_overlay_dst(struct intel_overlay *overlay,
+static int check_overlay_dst(struct intel_legacy_overlay *overlay,
 			     struct drm_intel_overlay_put_image *rec)
 {
 	struct drm_display_mode *mode = &overlay->crtc->base.mode;
@@ -1106,7 +1106,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
 {
 	struct drm_intel_overlay_put_image *put_image_rec = data;
 	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct intel_overlay *overlay;
+	struct intel_legacy_overlay *overlay;
 	struct drm_mode_object *drmmode_obj;
 	struct intel_crtc *crtc;
 	struct drm_i915_gem_object *new_bo;
@@ -1128,7 +1128,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
 		mutex_lock(&dev->mode_config.mutex);
 		mutex_lock(&dev->struct_mutex);
 
-		ret = intel_overlay_switch_off(overlay);
+		ret = intel_legacy_overlay_switch_off(overlay);
 
 		mutex_unlock(&dev->struct_mutex);
 		mutex_unlock(&dev->mode_config.mutex);
@@ -1164,13 +1164,13 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
 		goto out_unlock;
 	}
 
-	ret = intel_overlay_recover_from_interrupt(overlay);
+	ret = intel_legacy_overlay_recover_from_interrupt(overlay);
 	if (ret != 0)
 		goto out_unlock;
 
 	if (overlay->crtc != crtc) {
 		struct drm_display_mode *mode = &crtc->base.mode;
-		ret = intel_overlay_switch_off(overlay);
+		ret = intel_legacy_overlay_switch_off(overlay);
 		if (ret != 0)
 			goto out_unlock;
 
@@ -1232,7 +1232,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
 	if (ret != 0)
 		goto out_unlock;
 
-	ret = intel_overlay_do_put_image(overlay, new_bo, params);
+	ret = intel_legacy_overlay_do_put_image(overlay, new_bo, params);
 	if (ret != 0)
 		goto out_unlock;
 
@@ -1253,7 +1253,7 @@ out_free:
 	return ret;
 }
 
-static void update_reg_attrs(struct intel_overlay *overlay,
+static void update_reg_attrs(struct intel_legacy_overlay *overlay,
 			     struct overlay_registers *regs)
 {
 	regs->OCLRC0 = (overlay->contrast << 18) | (overlay->brightness & 0xff);
@@ -1309,7 +1309,7 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
 {
 	struct drm_intel_overlay_attrs *attrs = data;
         drm_i915_private_t *dev_priv = dev->dev_private;
-	struct intel_overlay *overlay;
+	struct intel_legacy_overlay *overlay;
 	struct overlay_registers *regs;
 	int ret;
 
@@ -1355,7 +1355,7 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
 		overlay->contrast   = attrs->contrast;
 		overlay->saturation = attrs->saturation;
 
-		regs = intel_overlay_map_regs(overlay);
+		regs = intel_legacy_overlay_map_regs(overlay);
 		if (!regs) {
 			ret = -ENOMEM;
 			goto out_unlock;
@@ -1363,7 +1363,7 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
 
 		update_reg_attrs(overlay, regs);
 
-		intel_overlay_unmap_regs(overlay, regs);
+		intel_legacy_overlay_unmap_regs(overlay, regs);
 
 		if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
 			if (IS_GEN2(dev))
@@ -1398,7 +1398,7 @@ out_unlock:
 void intel_setup_overlay(struct drm_device *dev)
 {
         drm_i915_private_t *dev_priv = dev->dev_private;
-	struct intel_overlay *overlay;
+	struct intel_legacy_overlay *overlay;
 	struct drm_i915_gem_object *reg_bo;
 	struct overlay_registers *regs;
 	int ret;
@@ -1406,7 +1406,7 @@ void intel_setup_overlay(struct drm_device *dev)
 	if (!HAS_OVERLAY(dev))
 		return;
 
-	overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL);
+	overlay = kzalloc(sizeof(struct intel_legacy_overlay), GFP_KERNEL);
 	if (!overlay)
 		return;
 	overlay->dev = dev;
@@ -1446,7 +1446,7 @@ void intel_setup_overlay(struct drm_device *dev)
 	overlay->contrast = 75;
 	overlay->saturation = 146;
 
-	regs = intel_overlay_map_regs(overlay);
+	regs = intel_legacy_overlay_map_regs(overlay);
 	if (!regs)
 		goto out_free_bo;
 
@@ -1454,7 +1454,7 @@ void intel_setup_overlay(struct drm_device *dev)
 	update_polyphase_filter(regs);
 	update_reg_attrs(overlay, regs);
 
-	intel_overlay_unmap_regs(overlay, regs);
+	intel_legacy_overlay_unmap_regs(overlay, regs);
 
 	dev_priv->overlay = overlay;
 	DRM_INFO("initialized overlay support\n");
@@ -1488,7 +1488,7 @@ void intel_cleanup_overlay(struct drm_device *dev)
 #ifdef CONFIG_DEBUG_FS
 #include <linux/seq_file.h>
 
-struct intel_overlay_error_state {
+struct intel_legacy_overlay_error_state {
 	struct overlay_registers regs;
 	unsigned long base;
 	u32 dovsta;
@@ -1496,7 +1496,7 @@ struct intel_overlay_error_state {
 };
 
 static struct overlay_registers *
-intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
+intel_legacy_overlay_map_regs_atomic(struct intel_legacy_overlay *overlay)
 {
 	drm_i915_private_t *dev_priv = overlay->dev->dev_private;
 	struct overlay_registers *regs;
@@ -1510,7 +1510,7 @@ intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
 	return regs;
 }
 
-static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
+static void intel_legacy_overlay_unmap_regs_atomic(struct intel_legacy_overlay *overlay,
 					    struct overlay_registers *regs)
 {
 	if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
@@ -1518,12 +1518,12 @@ static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
 }
 
 
-struct intel_overlay_error_state *
-intel_overlay_capture_error_state(struct drm_device *dev)
+struct intel_legacy_overlay_error_state *
+intel_legacy_overlay_capture_error_state(struct drm_device *dev)
 {
         drm_i915_private_t *dev_priv = dev->dev_private;
-	struct intel_overlay *overlay = dev_priv->overlay;
-	struct intel_overlay_error_state *error;
+	struct intel_legacy_overlay *overlay = dev_priv->overlay;
+	struct intel_legacy_overlay_error_state *error;
 	struct overlay_registers __iomem *regs;
 
 	if (!overlay || !overlay->active)
@@ -1540,12 +1540,12 @@ intel_overlay_capture_error_state(struct drm_device *dev)
 	else
 		error->base = (long) overlay->reg_bo->gtt_offset;
 
-	regs = intel_overlay_map_regs_atomic(overlay);
+	regs = intel_legacy_overlay_map_regs_atomic(overlay);
 	if (!regs)
 		goto err;
 
 	memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
-	intel_overlay_unmap_regs_atomic(overlay, regs);
+	intel_legacy_overlay_unmap_regs_atomic(overlay, regs);
 
 	return error;
 
@@ -1555,7 +1555,7 @@ err:
 }
 
 void
-intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error)
+intel_legacy_overlay_print_error_state(struct seq_file *m, struct intel_legacy_overlay_error_state *error)
 {
 	seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
 		   error->dovsta, error->isr);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 4/4] drm/i915: add SNB video sprite support
  2011-06-20 20:11 [RFC] Updated plane support v3 Jesse Barnes
@ 2011-06-20 20:11   ` Jesse Barnes
  2011-06-20 20:11   ` Jesse Barnes
                     ` (5 subsequent siblings)
  6 siblings, 0 replies; 27+ messages in thread
From: Jesse Barnes @ 2011-06-20 20:11 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx, Marcus Lorentzon, Alan Cox, Jesse Barnes

The video sprites support video surface formats natively and can handle
scaling well.  So add support for them using the new DRM core overlay
support functions.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/Makefile         |    1 +
 drivers/gpu/drm/i915/i915_reg.h       |   52 +++++++++
 drivers/gpu/drm/i915/intel_display.c  |   19 +++-
 drivers/gpu/drm/i915/intel_drv.h      |   14 +++
 drivers/gpu/drm/i915/intel_fb.c       |    6 +
 drivers/gpu/drm/i915/intel_overlay2.c |  188 +++++++++++++++++++++++++++++++++
 6 files changed, 274 insertions(+), 6 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_overlay2.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 0ae6a7c..6193471 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -28,6 +28,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
 	  intel_dvo.o \
 	  intel_ringbuffer.o \
 	  intel_overlay.o \
+	  intel_overlay2.o \
 	  intel_opregion.o \
 	  dvo_ch7xxx.o \
 	  dvo_ch7017.o \
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 2f967af..c81c4e7 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2627,6 +2627,58 @@
 #define _DSPBSURF		0x7119C
 #define _DSPBTILEOFF		0x711A4
 
+/* Sprite A control */
+#define _DVSACNTR		0x72180
+#define   DVS_ENABLE		(1<<31)
+#define   DVS_GAMMA_ENABLE	(1<<30)
+#define   DVS_PIXFORMAT_MASK	(3<<25)
+#define   DVS_FORMAT_YUV422	(0<<25)
+#define   DVS_FORMAT_RGBX101010	(1<<25)
+#define   DVS_FORMAT_RGBX888	(2<<25)
+#define   DVS_FORMAT_RGBX161616	(3<<25)
+#define   DVS_SOURCE_KEY	(1<<22)
+#define   DVS_RGB_ORDER_RGBX	(1<<20)
+#define   DVS_YUV_BYTE_ORDER_MASK (3<<16)
+#define   DVS_YUV_ORDER_YUYV	(0<<16)
+#define   DVS_YUV_ORDER_UYVY	(1<<16)
+#define   DVS_YUV_ORDER_YVYU	(2<<16)
+#define   DVS_YUV_ORDER_VYUY	(3<<16)
+#define   DVS_DEST_KEY		(1<<2)
+#define   DVS_TRICKLE_FEED_DISABLE (1<<14)
+#define   DVS_TILED		(1<<10)
+#define _DVSASTRIDE		0x72188
+#define _DVSAPOS		0x7218c
+#define _DVSASIZE		0x72190
+#define _DVSAKEYVAL		0x72194
+#define _DVSAKEYMSK		0x72198
+#define _DVSASURF		0x7219c
+#define _DVSAKEYMAXVAL		0x721a0
+#define _DVSATILEOFF		0x721a4
+#define _DVSASURFLIVE		0x721ac
+#define _DVSASCALE		0x72204
+#define _DVSAGAMC		0x72300
+
+#define _DVSBCNTR		0x73180
+#define _DVSBSTRIDE		0x73188
+#define _DVSBPOS		0x7318c
+#define _DVSBSIZE		0x73190
+#define _DVSBKEYVAL		0x73194
+#define _DVSBKEYMSK		0x73198
+#define _DVSBSURF		0x7319c
+#define _DVSBKEYMAXVAL		0x731a0
+#define _DVSBTILEOFF		0x731a4
+#define _DVSBSURFLIVE		0x731ac
+#define _DVSBSCALE		0x73204
+#define _DVSBGAMC		0x73300
+
+#define DVSCNTR(pipe) _PIPE(pipe, _DVSACNTR, _DVSBCNTR)
+#define DVSSTRIDE(pipe) _PIPE(pipe, _DVSASTRIDE, _DVSBSTRIDE)
+#define DVSPOS(pipe) _PIPE(pipe, _DVSAPOS, _DVSBPOS)
+#define DVSSURF(pipe) _PIPE(pipe, _DVSASURF, _DVSBSURF)
+#define DVSSIZE(pipe) _PIPE(pipe, _DVSASIZE, _DVSBSIZE)
+#define DVSSCALE(pipe) _PIPE(pipe, _DVSASCALE, _DVSBSCALE)
+#define DVSTILEOFF(pipe) _PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF)
+
 /* VBIOS regs */
 #define VGACNTRL		0x71400
 # define VGA_DISP_DISABLE			(1 << 31)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 7901f16..72a570a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -900,8 +900,8 @@ static void assert_panel_unlocked(struct drm_i915_private *dev_priv,
 	     pipe_name(pipe));
 }
 
-static void assert_pipe(struct drm_i915_private *dev_priv,
-			enum pipe pipe, bool state)
+void assert_pipe(struct drm_i915_private *dev_priv,
+		 enum pipe pipe, bool state)
 {
 	int reg;
 	u32 val;
@@ -914,8 +914,6 @@ static void assert_pipe(struct drm_i915_private *dev_priv,
 	     "pipe %c assertion failure (expected %s, current %s)\n",
 	     pipe_name(pipe), state_string(state), state_string(cur_state));
 }
-#define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
-#define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
 
 static void assert_plane_enabled(struct drm_i915_private *dev_priv,
 				 enum plane plane)
@@ -4319,7 +4317,8 @@ static void sandybridge_update_wm(struct drm_device *dev)
 				 &sandybridge_cursor_wm_info, latency,
 				 &plane_wm, &cursor_wm)) {
 		I915_WRITE(WM0_PIPEA_ILK,
-			   (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
+			   (plane_wm << WM0_PIPE_PLANE_SHIFT) |
+			   (plane_wm << WM0_PIPE_SPRITE_SHIFT) | cursor_wm);
 		DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
 			      " plane %d, " "cursor: %d\n",
 			      plane_wm, cursor_wm);
@@ -4331,7 +4330,8 @@ static void sandybridge_update_wm(struct drm_device *dev)
 				 &sandybridge_cursor_wm_info, latency,
 				 &plane_wm, &cursor_wm)) {
 		I915_WRITE(WM0_PIPEB_ILK,
-			   (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
+			   (plane_wm << WM0_PIPE_PLANE_SHIFT) |
+			   (plane_wm << WM0_PIPE_SPRITE_SHIFT) | cursor_wm);
 		DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
 			      " plane %d, cursor: %d\n",
 			      plane_wm, cursor_wm);
@@ -4371,6 +4371,11 @@ static void sandybridge_update_wm(struct drm_device *dev)
 		   (plane_wm << WM1_LP_SR_SHIFT) |
 		   cursor_wm);
 
+#if 0
+	I915_WRITE(WM1S_LP_ILK,
+		   WM1S_LP_EN |
+#endif
+
 	/* WM2 */
 	if (!ironlake_compute_srwm(dev, 2, enabled,
 				   SNB_READ_WM2_LATENCY() * 500,
@@ -8013,6 +8018,8 @@ void intel_modeset_init(struct drm_device *dev)
 
 	for (i = 0; i < dev_priv->num_pipe; i++) {
 		intel_crtc_init(dev, i);
+		if (HAS_PCH_SPLIT(dev))
+			intel_plane_init(dev, i);
 	}
 
 	/* Just disable it once at startup */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d73e622..232d797 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -173,10 +173,18 @@ struct intel_crtc {
 	unsigned int bpp;
 };
 
+struct intel_plane {
+	struct drm_plane base;
+	enum pipe pipe;
+	struct drm_i915_gem_object *obj;
+	u32 lut_r[1024], lut_g[1024], lut_b[1024];
+};
+
 #define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
 #define to_intel_connector(x) container_of(x, struct intel_connector, base)
 #define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
 #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
+#define to_intel_plane(x) container_of(x, struct intel_plane, base)
 
 #define DIP_TYPE_AVI    0x82
 #define DIP_VERSION_AVI 0x2
@@ -255,6 +263,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
 extern bool intel_dpd_is_edp(struct drm_device *dev);
 extern void intel_edp_link_config (struct intel_encoder *, int *, int *);
 extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder);
+extern void intel_plane_init(struct drm_device *dev, enum pipe pipe);
 
 /* intel_panel.c */
 extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
@@ -346,5 +355,10 @@ extern int intel_overlay_attrs(struct drm_device *dev, void *data,
 extern void intel_fb_output_poll_changed(struct drm_device *dev);
 extern void intel_fb_restore_mode(struct drm_device *dev);
 
+extern void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
+			bool state);
+#define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
+#define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
+
 extern void intel_init_clock_gating(struct drm_device *dev);
 #endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index 11baa99..513a40c 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -270,8 +270,14 @@ void intel_fb_restore_mode(struct drm_device *dev)
 {
 	int ret;
 	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_mode_config *config = &dev->mode_config;
+	struct drm_plane *plane;
 
 	ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper);
 	if (ret)
 		DRM_DEBUG("failed to restore crtc mode\n");
+
+	/* Be sure to shut off any planes that may be active */
+	list_for_each_entry(plane, &config->plane_list, head)
+		plane->funcs->disable_plane(plane);
 }
diff --git a/drivers/gpu/drm/i915/intel_overlay2.c b/drivers/gpu/drm/i915/intel_overlay2.c
new file mode 100644
index 0000000..19fd76f
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_overlay2.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *   Jesse Barnes <jbarnes@virtuousgeek.org>
+ *
+ * New plane/sprite handling.
+ *
+ * The older chips had a separate interface for programming plane related
+ * registers; newer ones are much simpler and we can use the new DRM plane
+ * support.
+ */
+#include "drmP.h"
+#include "drm_crtc.h"
+#include "intel_drv.h"
+#include "i915_drm.h"
+#include "i915_drv.h"
+
+static int
+intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
+		   struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+		   unsigned int crtc_w, unsigned int crtc_h,
+		   uint32_t src_x, uint32_t src_y,
+		   uint32_t src_w, uint32_t src_h)
+{
+	struct drm_device *dev = plane->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+	struct intel_framebuffer *intel_fb;
+	struct drm_i915_gem_object *obj, *old_obj;
+	int pipe = intel_plane->pipe;
+	unsigned long start, offset;
+	u32 dvscntr;
+	u32 reg = DVSCNTR(pipe);
+	int ret = 0;
+	int x = src_x >> 16, y = src_y >> 16;
+
+	assert_pipe_enabled(dev_priv, pipe);
+
+	intel_fb = to_intel_framebuffer(fb);
+	obj = intel_fb->obj;
+
+	old_obj = intel_plane->obj;
+
+	mutex_lock(&dev->struct_mutex);
+	ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
+	if (ret)
+		goto out_unlock;
+
+	intel_plane->obj = obj;
+
+	dvscntr = I915_READ(reg);
+
+	/* Mask out pixel format bits in case we change it */
+	dvscntr &= ~DVS_PIXFORMAT_MASK;
+	dvscntr &= ~DVS_RGB_ORDER_RGBX;
+	dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK;
+
+	switch (fb->pixel_format) {
+	case V4L2_PIX_FMT_BGR32:
+		dvscntr |= DVS_FORMAT_RGBX888;
+		break;
+	case V4L2_PIX_FMT_RGB32:
+		dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_RGBX;
+		break;
+	case V4L2_PIX_FMT_YUYV:
+		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
+		break;
+	case V4L2_PIX_FMT_YVYU:
+		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
+		break;
+	case V4L2_PIX_FMT_UYVY:
+		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
+		break;
+	case V4L2_PIX_FMT_VYUY:
+		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
+		break;
+	default:
+		ret = -EINVAL;
+		DRM_DEBUG_KMS("bad pixel format\n");
+		goto out_unlock;
+	}
+
+	if (obj->tiling_mode != I915_TILING_X) {
+		DRM_DEBUG_KMS("plane surfaces must be X tiled\n");
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	dvscntr |= DVS_TILED;
+
+	/* must disable */
+	dvscntr |= DVS_TRICKLE_FEED_DISABLE;
+	dvscntr |= DVS_DEST_KEY;
+	dvscntr |= DVS_ENABLE;
+
+	start = obj->gtt_offset;
+	offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
+
+	I915_WRITE(DVSSTRIDE(pipe), fb->pitch);
+	I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
+	I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x);
+	I915_WRITE(DVSSIZE(pipe), (fb->height << 16) | fb->width);
+	I915_WRITE(DVSSCALE(pipe), 0);
+	I915_WRITE(reg, dvscntr);
+	I915_WRITE(DVSSURF(pipe), start);
+	POSTING_READ(DVSSURF(pipe));
+
+	/* Unpin old obj after new one is active to avoid ugliness */
+	if (old_obj) {
+		intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe);
+		i915_gem_object_unpin(old_obj);
+	}
+
+out_unlock:
+	mutex_unlock(&dev->struct_mutex);
+
+	return ret;
+}
+
+static void
+intel_disable_plane(struct drm_plane *plane)
+{
+	struct drm_device *dev = plane->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+	int pipe = intel_plane->pipe;
+
+	I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE);
+	I915_WRITE(DVSSURF(pipe), 0);
+	POSTING_READ(DVSSURF(pipe));
+}
+
+static const struct drm_plane_funcs intel_plane_funcs = {
+	.update_plane = intel_update_plane,
+	.disable_plane = intel_disable_plane,
+};
+
+static uint32_t snb_plane_formats[] = {
+	V4L2_PIX_FMT_BGR32,
+	V4L2_PIX_FMT_RGB32,
+	V4L2_PIX_FMT_YUYV,
+	V4L2_PIX_FMT_YVYU,
+	V4L2_PIX_FMT_UYVY,
+	V4L2_PIX_FMT_VYUY,
+};
+
+void
+intel_plane_init(struct drm_device *dev, enum pipe pipe)
+{
+	struct intel_plane *intel_plane;
+	unsigned long possible_crtcs;
+
+	if (!IS_GEN6(dev)) {
+		DRM_ERROR("new plane code only for SNB\n");
+		return;
+	}
+
+	intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL);
+	if (!intel_plane)
+		return;
+
+	intel_plane->pipe = pipe;
+	possible_crtcs = (1 << pipe);
+	drm_plane_init(dev, &intel_plane->base, possible_crtcs,
+		       &intel_plane_funcs, snb_plane_formats,
+		       ARRAY_SIZE(snb_plane_formats));
+}
+
-- 
1.7.4.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 4/4] drm/i915: add SNB video sprite support
@ 2011-06-20 20:11   ` Jesse Barnes
  0 siblings, 0 replies; 27+ messages in thread
From: Jesse Barnes @ 2011-06-20 20:11 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

The video sprites support video surface formats natively and can handle
scaling well.  So add support for them using the new DRM core overlay
support functions.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/Makefile         |    1 +
 drivers/gpu/drm/i915/i915_reg.h       |   52 +++++++++
 drivers/gpu/drm/i915/intel_display.c  |   19 +++-
 drivers/gpu/drm/i915/intel_drv.h      |   14 +++
 drivers/gpu/drm/i915/intel_fb.c       |    6 +
 drivers/gpu/drm/i915/intel_overlay2.c |  188 +++++++++++++++++++++++++++++++++
 6 files changed, 274 insertions(+), 6 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_overlay2.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 0ae6a7c..6193471 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -28,6 +28,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
 	  intel_dvo.o \
 	  intel_ringbuffer.o \
 	  intel_overlay.o \
+	  intel_overlay2.o \
 	  intel_opregion.o \
 	  dvo_ch7xxx.o \
 	  dvo_ch7017.o \
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 2f967af..c81c4e7 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2627,6 +2627,58 @@
 #define _DSPBSURF		0x7119C
 #define _DSPBTILEOFF		0x711A4
 
+/* Sprite A control */
+#define _DVSACNTR		0x72180
+#define   DVS_ENABLE		(1<<31)
+#define   DVS_GAMMA_ENABLE	(1<<30)
+#define   DVS_PIXFORMAT_MASK	(3<<25)
+#define   DVS_FORMAT_YUV422	(0<<25)
+#define   DVS_FORMAT_RGBX101010	(1<<25)
+#define   DVS_FORMAT_RGBX888	(2<<25)
+#define   DVS_FORMAT_RGBX161616	(3<<25)
+#define   DVS_SOURCE_KEY	(1<<22)
+#define   DVS_RGB_ORDER_RGBX	(1<<20)
+#define   DVS_YUV_BYTE_ORDER_MASK (3<<16)
+#define   DVS_YUV_ORDER_YUYV	(0<<16)
+#define   DVS_YUV_ORDER_UYVY	(1<<16)
+#define   DVS_YUV_ORDER_YVYU	(2<<16)
+#define   DVS_YUV_ORDER_VYUY	(3<<16)
+#define   DVS_DEST_KEY		(1<<2)
+#define   DVS_TRICKLE_FEED_DISABLE (1<<14)
+#define   DVS_TILED		(1<<10)
+#define _DVSASTRIDE		0x72188
+#define _DVSAPOS		0x7218c
+#define _DVSASIZE		0x72190
+#define _DVSAKEYVAL		0x72194
+#define _DVSAKEYMSK		0x72198
+#define _DVSASURF		0x7219c
+#define _DVSAKEYMAXVAL		0x721a0
+#define _DVSATILEOFF		0x721a4
+#define _DVSASURFLIVE		0x721ac
+#define _DVSASCALE		0x72204
+#define _DVSAGAMC		0x72300
+
+#define _DVSBCNTR		0x73180
+#define _DVSBSTRIDE		0x73188
+#define _DVSBPOS		0x7318c
+#define _DVSBSIZE		0x73190
+#define _DVSBKEYVAL		0x73194
+#define _DVSBKEYMSK		0x73198
+#define _DVSBSURF		0x7319c
+#define _DVSBKEYMAXVAL		0x731a0
+#define _DVSBTILEOFF		0x731a4
+#define _DVSBSURFLIVE		0x731ac
+#define _DVSBSCALE		0x73204
+#define _DVSBGAMC		0x73300
+
+#define DVSCNTR(pipe) _PIPE(pipe, _DVSACNTR, _DVSBCNTR)
+#define DVSSTRIDE(pipe) _PIPE(pipe, _DVSASTRIDE, _DVSBSTRIDE)
+#define DVSPOS(pipe) _PIPE(pipe, _DVSAPOS, _DVSBPOS)
+#define DVSSURF(pipe) _PIPE(pipe, _DVSASURF, _DVSBSURF)
+#define DVSSIZE(pipe) _PIPE(pipe, _DVSASIZE, _DVSBSIZE)
+#define DVSSCALE(pipe) _PIPE(pipe, _DVSASCALE, _DVSBSCALE)
+#define DVSTILEOFF(pipe) _PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF)
+
 /* VBIOS regs */
 #define VGACNTRL		0x71400
 # define VGA_DISP_DISABLE			(1 << 31)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 7901f16..72a570a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -900,8 +900,8 @@ static void assert_panel_unlocked(struct drm_i915_private *dev_priv,
 	     pipe_name(pipe));
 }
 
-static void assert_pipe(struct drm_i915_private *dev_priv,
-			enum pipe pipe, bool state)
+void assert_pipe(struct drm_i915_private *dev_priv,
+		 enum pipe pipe, bool state)
 {
 	int reg;
 	u32 val;
@@ -914,8 +914,6 @@ static void assert_pipe(struct drm_i915_private *dev_priv,
 	     "pipe %c assertion failure (expected %s, current %s)\n",
 	     pipe_name(pipe), state_string(state), state_string(cur_state));
 }
-#define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
-#define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
 
 static void assert_plane_enabled(struct drm_i915_private *dev_priv,
 				 enum plane plane)
@@ -4319,7 +4317,8 @@ static void sandybridge_update_wm(struct drm_device *dev)
 				 &sandybridge_cursor_wm_info, latency,
 				 &plane_wm, &cursor_wm)) {
 		I915_WRITE(WM0_PIPEA_ILK,
-			   (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
+			   (plane_wm << WM0_PIPE_PLANE_SHIFT) |
+			   (plane_wm << WM0_PIPE_SPRITE_SHIFT) | cursor_wm);
 		DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
 			      " plane %d, " "cursor: %d\n",
 			      plane_wm, cursor_wm);
@@ -4331,7 +4330,8 @@ static void sandybridge_update_wm(struct drm_device *dev)
 				 &sandybridge_cursor_wm_info, latency,
 				 &plane_wm, &cursor_wm)) {
 		I915_WRITE(WM0_PIPEB_ILK,
-			   (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
+			   (plane_wm << WM0_PIPE_PLANE_SHIFT) |
+			   (plane_wm << WM0_PIPE_SPRITE_SHIFT) | cursor_wm);
 		DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
 			      " plane %d, cursor: %d\n",
 			      plane_wm, cursor_wm);
@@ -4371,6 +4371,11 @@ static void sandybridge_update_wm(struct drm_device *dev)
 		   (plane_wm << WM1_LP_SR_SHIFT) |
 		   cursor_wm);
 
+#if 0
+	I915_WRITE(WM1S_LP_ILK,
+		   WM1S_LP_EN |
+#endif
+
 	/* WM2 */
 	if (!ironlake_compute_srwm(dev, 2, enabled,
 				   SNB_READ_WM2_LATENCY() * 500,
@@ -8013,6 +8018,8 @@ void intel_modeset_init(struct drm_device *dev)
 
 	for (i = 0; i < dev_priv->num_pipe; i++) {
 		intel_crtc_init(dev, i);
+		if (HAS_PCH_SPLIT(dev))
+			intel_plane_init(dev, i);
 	}
 
 	/* Just disable it once at startup */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d73e622..232d797 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -173,10 +173,18 @@ struct intel_crtc {
 	unsigned int bpp;
 };
 
+struct intel_plane {
+	struct drm_plane base;
+	enum pipe pipe;
+	struct drm_i915_gem_object *obj;
+	u32 lut_r[1024], lut_g[1024], lut_b[1024];
+};
+
 #define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
 #define to_intel_connector(x) container_of(x, struct intel_connector, base)
 #define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
 #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
+#define to_intel_plane(x) container_of(x, struct intel_plane, base)
 
 #define DIP_TYPE_AVI    0x82
 #define DIP_VERSION_AVI 0x2
@@ -255,6 +263,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
 extern bool intel_dpd_is_edp(struct drm_device *dev);
 extern void intel_edp_link_config (struct intel_encoder *, int *, int *);
 extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder);
+extern void intel_plane_init(struct drm_device *dev, enum pipe pipe);
 
 /* intel_panel.c */
 extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
@@ -346,5 +355,10 @@ extern int intel_overlay_attrs(struct drm_device *dev, void *data,
 extern void intel_fb_output_poll_changed(struct drm_device *dev);
 extern void intel_fb_restore_mode(struct drm_device *dev);
 
+extern void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
+			bool state);
+#define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
+#define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
+
 extern void intel_init_clock_gating(struct drm_device *dev);
 #endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index 11baa99..513a40c 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -270,8 +270,14 @@ void intel_fb_restore_mode(struct drm_device *dev)
 {
 	int ret;
 	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_mode_config *config = &dev->mode_config;
+	struct drm_plane *plane;
 
 	ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper);
 	if (ret)
 		DRM_DEBUG("failed to restore crtc mode\n");
+
+	/* Be sure to shut off any planes that may be active */
+	list_for_each_entry(plane, &config->plane_list, head)
+		plane->funcs->disable_plane(plane);
 }
diff --git a/drivers/gpu/drm/i915/intel_overlay2.c b/drivers/gpu/drm/i915/intel_overlay2.c
new file mode 100644
index 0000000..19fd76f
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_overlay2.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *   Jesse Barnes <jbarnes@virtuousgeek.org>
+ *
+ * New plane/sprite handling.
+ *
+ * The older chips had a separate interface for programming plane related
+ * registers; newer ones are much simpler and we can use the new DRM plane
+ * support.
+ */
+#include "drmP.h"
+#include "drm_crtc.h"
+#include "intel_drv.h"
+#include "i915_drm.h"
+#include "i915_drv.h"
+
+static int
+intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
+		   struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+		   unsigned int crtc_w, unsigned int crtc_h,
+		   uint32_t src_x, uint32_t src_y,
+		   uint32_t src_w, uint32_t src_h)
+{
+	struct drm_device *dev = plane->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+	struct intel_framebuffer *intel_fb;
+	struct drm_i915_gem_object *obj, *old_obj;
+	int pipe = intel_plane->pipe;
+	unsigned long start, offset;
+	u32 dvscntr;
+	u32 reg = DVSCNTR(pipe);
+	int ret = 0;
+	int x = src_x >> 16, y = src_y >> 16;
+
+	assert_pipe_enabled(dev_priv, pipe);
+
+	intel_fb = to_intel_framebuffer(fb);
+	obj = intel_fb->obj;
+
+	old_obj = intel_plane->obj;
+
+	mutex_lock(&dev->struct_mutex);
+	ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
+	if (ret)
+		goto out_unlock;
+
+	intel_plane->obj = obj;
+
+	dvscntr = I915_READ(reg);
+
+	/* Mask out pixel format bits in case we change it */
+	dvscntr &= ~DVS_PIXFORMAT_MASK;
+	dvscntr &= ~DVS_RGB_ORDER_RGBX;
+	dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK;
+
+	switch (fb->pixel_format) {
+	case V4L2_PIX_FMT_BGR32:
+		dvscntr |= DVS_FORMAT_RGBX888;
+		break;
+	case V4L2_PIX_FMT_RGB32:
+		dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_RGBX;
+		break;
+	case V4L2_PIX_FMT_YUYV:
+		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
+		break;
+	case V4L2_PIX_FMT_YVYU:
+		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
+		break;
+	case V4L2_PIX_FMT_UYVY:
+		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
+		break;
+	case V4L2_PIX_FMT_VYUY:
+		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
+		break;
+	default:
+		ret = -EINVAL;
+		DRM_DEBUG_KMS("bad pixel format\n");
+		goto out_unlock;
+	}
+
+	if (obj->tiling_mode != I915_TILING_X) {
+		DRM_DEBUG_KMS("plane surfaces must be X tiled\n");
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	dvscntr |= DVS_TILED;
+
+	/* must disable */
+	dvscntr |= DVS_TRICKLE_FEED_DISABLE;
+	dvscntr |= DVS_DEST_KEY;
+	dvscntr |= DVS_ENABLE;
+
+	start = obj->gtt_offset;
+	offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
+
+	I915_WRITE(DVSSTRIDE(pipe), fb->pitch);
+	I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
+	I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x);
+	I915_WRITE(DVSSIZE(pipe), (fb->height << 16) | fb->width);
+	I915_WRITE(DVSSCALE(pipe), 0);
+	I915_WRITE(reg, dvscntr);
+	I915_WRITE(DVSSURF(pipe), start);
+	POSTING_READ(DVSSURF(pipe));
+
+	/* Unpin old obj after new one is active to avoid ugliness */
+	if (old_obj) {
+		intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe);
+		i915_gem_object_unpin(old_obj);
+	}
+
+out_unlock:
+	mutex_unlock(&dev->struct_mutex);
+
+	return ret;
+}
+
+static void
+intel_disable_plane(struct drm_plane *plane)
+{
+	struct drm_device *dev = plane->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+	int pipe = intel_plane->pipe;
+
+	I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE);
+	I915_WRITE(DVSSURF(pipe), 0);
+	POSTING_READ(DVSSURF(pipe));
+}
+
+static const struct drm_plane_funcs intel_plane_funcs = {
+	.update_plane = intel_update_plane,
+	.disable_plane = intel_disable_plane,
+};
+
+static uint32_t snb_plane_formats[] = {
+	V4L2_PIX_FMT_BGR32,
+	V4L2_PIX_FMT_RGB32,
+	V4L2_PIX_FMT_YUYV,
+	V4L2_PIX_FMT_YVYU,
+	V4L2_PIX_FMT_UYVY,
+	V4L2_PIX_FMT_VYUY,
+};
+
+void
+intel_plane_init(struct drm_device *dev, enum pipe pipe)
+{
+	struct intel_plane *intel_plane;
+	unsigned long possible_crtcs;
+
+	if (!IS_GEN6(dev)) {
+		DRM_ERROR("new plane code only for SNB\n");
+		return;
+	}
+
+	intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL);
+	if (!intel_plane)
+		return;
+
+	intel_plane->pipe = pipe;
+	possible_crtcs = (1 << pipe);
+	drm_plane_init(dev, &intel_plane->base, possible_crtcs,
+		       &intel_plane_funcs, snb_plane_formats,
+		       ARRAY_SIZE(snb_plane_formats));
+}
+
-- 
1.7.4.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [RFC] Updated plane support v3
  2011-06-20 20:11 [RFC] Updated plane support v3 Jesse Barnes
                   ` (3 preceding siblings ...)
  2011-06-20 20:11   ` Jesse Barnes
@ 2011-06-21  8:55 ` Marcus Lorentzon
  2011-06-21  9:12   ` Daniel Vetter
  2011-06-21 16:13   ` Jesse Barnes
  2011-06-21 11:21 ` Rob Clark
  2011-09-19  8:03 ` Joonyoung Shim
  6 siblings, 2 replies; 27+ messages in thread
From: Marcus Lorentzon @ 2011-06-21  8:55 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: intel-gfx, dri-devel

On 06/20/2011 10:11 PM, Jesse Barnes wrote:
> This version adds both source and dest rect params to the set_plane
> ioctl, and makes the source fixed point to support hardware that needs
> it.
>
> I haven't changed the name of the SNB implementation yet (per Chris's
> suggestions) but will before it gets upstream.
>
> I'd be interested to see whether these interfaces will work for other
> hardware, so please take a close look at them and ideally implement them
> on your hardware to make sure (see my userspace example code from
> earlier posts if you want something to crib from).
>
> Thanks,
> Jesse
>
>    
Is it possible to position a plane above and below the "normal" crtc 
framebuffer? Plane z-order is unsigned, and I would assume 0 is default 
z-order.
Applications will need to position planes above and below crtc normal 
framebuffer. Below when using a translucent or color keyed framebuffer, 
and above if framebuffer is opaque.

So maybe add a one liner comment about z-order meaning and make it 
signed unless ordering should be solved in another way.

And should it be possible to only define planes with no crtc framebuffer 
at all? Use case, for example letter boxed video on black background 
with small UI controls/subtitles. In this case it's not power efficient 
to have a fullscreen fb with mostly if not all transparent pixels.

/BR
/Marcus

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFC] Updated plane support v3
  2011-06-21  8:55 ` [RFC] Updated plane support v3 Marcus Lorentzon
@ 2011-06-21  9:12   ` Daniel Vetter
  2011-06-21 16:13   ` Jesse Barnes
  1 sibling, 0 replies; 27+ messages in thread
From: Daniel Vetter @ 2011-06-21  9:12 UTC (permalink / raw)
  To: Marcus Lorentzon; +Cc: intel-gfx, dri-devel

On Tue, Jun 21, 2011 at 10:55, Marcus Lorentzon
<marcus.xm.lorentzon@stericsson.com> wrote:
> And should it be possible to only define planes with no crtc framebuffer at
> all? Use case, for example letter boxed video on black background with small
> UI controls/subtitles. In this case it's not power efficient to have a
> fullscreen fb with mostly if not all transparent pixels.

I think we could shoe-horn this use-case into the current framework by
using a special crtc-property "ignore attached fb, use this default
color instead". But I think this would be better done in a second step
when we tackle atomic vsync flips across multiple planes and the
underlying crtc - that might also require us to change certain
properties in the same flip command.

-Daniel
-- 
Daniel Vetter
daniel.vetter@ffwll.ch - +41 (0) 79 364 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFC] Updated plane support v3
  2011-06-20 20:11 [RFC] Updated plane support v3 Jesse Barnes
                   ` (4 preceding siblings ...)
  2011-06-21  8:55 ` [RFC] Updated plane support v3 Marcus Lorentzon
@ 2011-06-21 11:21 ` Rob Clark
  2011-06-21 13:16   ` Rob Clark
  2011-06-21 16:19   ` Jesse Barnes
  2011-09-19  8:03 ` Joonyoung Shim
  6 siblings, 2 replies; 27+ messages in thread
From: Rob Clark @ 2011-06-21 11:21 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: intel-gfx, dri-devel

On Mon, Jun 20, 2011 at 3:11 PM, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> This version adds both source and dest rect params to the set_plane
> ioctl, and makes the source fixed point to support hardware that needs
> it.
>
> I haven't changed the name of the SNB implementation yet (per Chris's
> suggestions) but will before it gets upstream.
>
> I'd be interested to see whether these interfaces will work for other
> hardware, so please take a close look at them and ideally implement them
> on your hardware to make sure (see my userspace example code from
> earlier posts if you want something to crib from).

Cool, thanks for this

I'm just thinking through how I'd implement the driver part in omap
drm driver.. so please bear with me if I'm misunderstanding..

In particular I'm thinking about being able to use a given video pipe
(basically like a dma channel) as either framebuffer layer or overlay
at various points in time, depending on how many displays are
attached.  Is the idea to use drm_plane *only* for overlay layer, and
still use crtc->fb for the normal framebuffer layer?

Or would/could a drm_plane also be used for main layer instead of
crtc->fb?  In this case, either userspace would have to know (which
doesn't seem like a good idea for things like plymouth which use drm
interface a bit generically).  Or the driver would have to internally
automatically hook up a drm_plane if it sees that userspace hasn't
done this.

I was thinking perhaps that if we let userspace DRM_IOCTL_MODE_SETCRTC
pass in -1 for fb_id, followed by one or more
DRM_IOCTL_MODE_SETPLANE's, to set things up the "new" way (explicitly
specify the drm_plane's).  Or if _SETCRTC passes in a valid fb_id, we
know it is the old way, and driver automatically picks a drm_plane.

BR,
-R

> Thanks,
> Jesse
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFC] Updated plane support v3
  2011-06-21 11:21 ` Rob Clark
@ 2011-06-21 13:16   ` Rob Clark
  2011-06-21 16:19   ` Jesse Barnes
  1 sibling, 0 replies; 27+ messages in thread
From: Rob Clark @ 2011-06-21 13:16 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: intel-gfx, dri-devel

On Tue, Jun 21, 2011 at 6:21 AM, Rob Clark <robdclark@gmail.com> wrote:
> On Mon, Jun 20, 2011 at 3:11 PM, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
>> This version adds both source and dest rect params to the set_plane
>> ioctl, and makes the source fixed point to support hardware that needs
>> it.
>>
>> I haven't changed the name of the SNB implementation yet (per Chris's
>> suggestions) but will before it gets upstream.
>>
>> I'd be interested to see whether these interfaces will work for other
>> hardware, so please take a close look at them and ideally implement them
>> on your hardware to make sure (see my userspace example code from
>> earlier posts if you want something to crib from).
>
> Cool, thanks for this
>
> I'm just thinking through how I'd implement the driver part in omap
> drm driver.. so please bear with me if I'm misunderstanding..
>
> In particular I'm thinking about being able to use a given video pipe
> (basically like a dma channel) as either framebuffer layer or overlay
> at various points in time, depending on how many displays are
> attached.  Is the idea to use drm_plane *only* for overlay layer, and
> still use crtc->fb for the normal framebuffer layer?
>
> Or would/could a drm_plane also be used for main layer instead of
> crtc->fb?  In this case, either userspace would have to know (which
> doesn't seem like a good idea for things like plymouth which use drm
> interface a bit generically).  Or the driver would have to internally
> automatically hook up a drm_plane if it sees that userspace hasn't
> done this.
>
> I was thinking perhaps that if we let userspace DRM_IOCTL_MODE_SETCRTC
> pass in -1 for fb_id, followed by one or more
> DRM_IOCTL_MODE_SETPLANE's, to set things up the "new" way (explicitly
> specify the drm_plane's).  Or if _SETCRTC passes in a valid fb_id, we
> know it is the old way, and driver automatically picks a drm_plane.

just thinking through this a bit more..  the idea is that for drivers
w/ DRM_SUPPORTS_PLANES[1], there is no fb hooked directly to crtc.
And support for userspace that is not aware of planes could be, I
think, mostly in the kms core, although I'm just thinking through how
disruptive that would be..

I think if we add a crtc->funcs->get_primary_plane() to be implemented
by drivers that use planes in cases where userspace does not know
about planes.  It would be used to get (and if necessary, assign) a
drm_plane to a drm_crtc, then we can do things like:

handle _SETCRTC from userspace that doesn't understand planes:
---------
@@ -1580,7 +1580,14 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
        set.mode = mode;
        set.connectors = connector_set;
        set.num_connectors = crtc_req->count_connectors;
-       set.fb = fb;
+       if (fb & (dev->driver->driver_features & DRM_SUPPORTS_PLANES)) {
+               /* pass fb to the primary plane for compatibility */
+               struct drm_plane *plane =
+                               crtc->funcs->get_primary_plane(crtc);
+               set.plane = plane;
+               plane->funcs->set_config(&set);
+       } else {
+               set.fb = fb;
+       }
        ret = crtc->funcs->set_config(&set);

 out:
---------

or page flip ioctl from userspace that doesn't understand planes:

---------
@@ -2645,7 +2652,14 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
                        (void (*) (struct drm_pending_event *)) kfree;
        }

-       ret = crtc->funcs->page_flip(crtc, fb, e);
+       if (dev->driver->driver_features & DRM_SUPPORTS_PLANES) {
+               struct drm_plane *plane =
+                               crtc->funcs->get_primary_plane(crtc);
+               ret = plane->funcs->page_flip(plane, fb, e);
+       } else {
+               ret = crtc->funcs->page_flip(crtc, fb, e);
+       }
+
        if (ret) {
                spin_lock_irqsave(&dev->event_lock, flags);
                file_priv->event_space += sizeof e->event;
---------

It doesn't look like there are *that* many places where crtc->fb is
reference, but I've not gone through all of them..  I'm not sure if
this sort of change would be too intrusive.

BR,
-R

--
[1] or maybe DRM_MANDATORY_PLANES if there are some drivers that would
use a hybrid model of fb either direct to drm_crtc, or indirect via a
drm_plane

BR,
-R

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFC] Updated plane support v3
  2011-06-21  8:55 ` [RFC] Updated plane support v3 Marcus Lorentzon
  2011-06-21  9:12   ` Daniel Vetter
@ 2011-06-21 16:13   ` Jesse Barnes
  1 sibling, 0 replies; 27+ messages in thread
From: Jesse Barnes @ 2011-06-21 16:13 UTC (permalink / raw)
  To: Marcus Lorentzon; +Cc: intel-gfx, Alan, dri-devel

On Tue, 21 Jun 2011 10:55:39 +0200
Marcus Lorentzon <marcus.xm.lorentzon@stericsson.com> wrote:

> On 06/20/2011 10:11 PM, Jesse Barnes wrote:
> > This version adds both source and dest rect params to the set_plane
> > ioctl, and makes the source fixed point to support hardware that needs
> > it.
> >
> > I haven't changed the name of the SNB implementation yet (per Chris's
> > suggestions) but will before it gets upstream.
> >
> > I'd be interested to see whether these interfaces will work for other
> > hardware, so please take a close look at them and ideally implement them
> > on your hardware to make sure (see my userspace example code from
> > earlier posts if you want something to crib from).
> >
> > Thanks,
> > Jesse
> >
> >    
> Is it possible to position a plane above and below the "normal" crtc 
> framebuffer? Plane z-order is unsigned, and I would assume 0 is default 
> z-order.
> Applications will need to position planes above and below crtc normal 
> framebuffer. Below when using a translucent or color keyed framebuffer, 
> and above if framebuffer is opaque.

I was thinking 0 would be the bottom layer.  But either way we don't
have a way of getting the primary plane z position atm, so it'll be
hard to position a new plane above or below the main plane...  I'm ok
with a signed value here, but the real meaning will be defined by a new
ioctl we use to get plane blending restrictions, z order, and such.

> So maybe add a one liner comment about z-order meaning and make it 
> signed unless ordering should be solved in another way.
> 
> And should it be possible to only define planes with no crtc framebuffer 
> at all? Use case, for example letter boxed video on black background 
> with small UI controls/subtitles. In this case it's not power efficient 
> to have a fullscreen fb with mostly if not all transparent pixels.

A particular driver may be able to expose that somehow, maybe by
allowing clients to define a special fb handle that can be used to
indicate no plane should be bound to the CRTC as the "primary" plane.

-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFC] Updated plane support v3
  2011-06-21 11:21 ` Rob Clark
  2011-06-21 13:16   ` Rob Clark
@ 2011-06-21 16:19   ` Jesse Barnes
  2011-06-22  1:09     ` Rob Clark
  1 sibling, 1 reply; 27+ messages in thread
From: Jesse Barnes @ 2011-06-21 16:19 UTC (permalink / raw)
  To: Rob Clark; +Cc: intel-gfx, dri-devel

On Tue, 21 Jun 2011 06:21:11 -0500
Rob Clark <robdclark@gmail.com> wrote:

> On Mon, Jun 20, 2011 at 3:11 PM, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> > This version adds both source and dest rect params to the set_plane
> > ioctl, and makes the source fixed point to support hardware that needs
> > it.
> >
> > I haven't changed the name of the SNB implementation yet (per Chris's
> > suggestions) but will before it gets upstream.
> >
> > I'd be interested to see whether these interfaces will work for other
> > hardware, so please take a close look at them and ideally implement them
> > on your hardware to make sure (see my userspace example code from
> > earlier posts if you want something to crib from).
> 
> Cool, thanks for this
> 
> I'm just thinking through how I'd implement the driver part in omap
> drm driver.. so please bear with me if I'm misunderstanding..
> 
> In particular I'm thinking about being able to use a given video pipe
> (basically like a dma channel) as either framebuffer layer or overlay
> at various points in time, depending on how many displays are
> attached.  Is the idea to use drm_plane *only* for overlay layer, and
> still use crtc->fb for the normal framebuffer layer?

Given the structure of the current KMS API, a CRTC implies a plane of
some sort, but I don't think the driver is restricted to using the same
plane for a given CRTC forever; it could allocate and switch them
around depending on usage, with planes beyond what's currently
associated with the CRTC exposed through this interface.

> I was thinking perhaps that if we let userspace DRM_IOCTL_MODE_SETCRTC
> pass in -1 for fb_id, followed by one or more
> DRM_IOCTL_MODE_SETPLANE's, to set things up the "new" way (explicitly
> specify the drm_plane's).  Or if _SETCRTC passes in a valid fb_id, we
> know it is the old way, and driver automatically picks a drm_plane.

Yeah that might work; we'd probably want a new GETPARAM flag to
indicate support for this...  The tough part is doing it in such a way
that we don't break existing userspace.

-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFC] Updated plane support v3
  2011-06-21 16:19   ` Jesse Barnes
@ 2011-06-22  1:09     ` Rob Clark
  2011-06-22  9:16       ` Marcus Lorentzon
  0 siblings, 1 reply; 27+ messages in thread
From: Rob Clark @ 2011-06-22  1:09 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: intel-gfx, dri-devel

On Tue, Jun 21, 2011 at 11:19 AM, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> On Tue, 21 Jun 2011 06:21:11 -0500
> Rob Clark <robdclark@gmail.com> wrote:
>
>> On Mon, Jun 20, 2011 at 3:11 PM, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
>> > This version adds both source and dest rect params to the set_plane
>> > ioctl, and makes the source fixed point to support hardware that needs
>> > it.
>> >
>> > I haven't changed the name of the SNB implementation yet (per Chris's
>> > suggestions) but will before it gets upstream.
>> >
>> > I'd be interested to see whether these interfaces will work for other
>> > hardware, so please take a close look at them and ideally implement them
>> > on your hardware to make sure (see my userspace example code from
>> > earlier posts if you want something to crib from).
>>
>> Cool, thanks for this
>>
>> I'm just thinking through how I'd implement the driver part in omap
>> drm driver.. so please bear with me if I'm misunderstanding..
>>
>> In particular I'm thinking about being able to use a given video pipe
>> (basically like a dma channel) as either framebuffer layer or overlay
>> at various points in time, depending on how many displays are
>> attached.  Is the idea to use drm_plane *only* for overlay layer, and
>> still use crtc->fb for the normal framebuffer layer?
>
> Given the structure of the current KMS API, a CRTC implies a plane of
> some sort, but I don't think the driver is restricted to using the same
> plane for a given CRTC forever; it could allocate and switch them
> around depending on usage, with planes beyond what's currently
> associated with the CRTC exposed through this interface.

The awkward thing is how do you express to userspace that if it isn't
using some CRTC(s) that it has an extra plane(s) available, if each
crtc even though it is not enabled, is assumed to consume a plane
(video pipe)..

That said if OMAP is the only hw like this, one possible solution is
that you just need to have userspace know.. ie. the main one taking
advantage of this feature would be the xorg driver, and it already
knows what DRM driver it is talking to.  Generic things like splash
screen won't need to be using all the video planes.

But I'm at least under the impression that some of the other SoC's
have similar flexibility to use video planes as either primary or
overlay layers.  So I figure it is at least worth trying to handle
this in a more generic way if it doesn't cause too much ugliness to
KMS core.

>> I was thinking perhaps that if we let userspace DRM_IOCTL_MODE_SETCRTC
>> pass in -1 for fb_id, followed by one or more
>> DRM_IOCTL_MODE_SETPLANE's, to set things up the "new" way (explicitly
>> specify the drm_plane's).  Or if _SETCRTC passes in a valid fb_id, we
>> know it is the old way, and driver automatically picks a drm_plane.
>
> Yeah that might work; we'd probably want a new GETPARAM flag to
> indicate support for this...  The tough part is doing it in such a way
> that we don't break existing userspace.

fwiw, Daniel and I discussed a bit on IRC earlier today, and he had an
interesting idea about having a simple drm_plane shim+helpers to keep
things similar for existing drivers. I think it should be possible to
support both old and new userspace semantics this way without too much
if(driver_features & SUPPORTS_PLANES) sort of stuff.

BR,
-R

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFC] Updated plane support v3
  2011-06-22  1:09     ` Rob Clark
@ 2011-06-22  9:16       ` Marcus Lorentzon
  0 siblings, 0 replies; 27+ messages in thread
From: Marcus Lorentzon @ 2011-06-22  9:16 UTC (permalink / raw)
  To: Rob Clark; +Cc: dri-devel

On 06/22/2011 03:09 AM, Rob Clark wrote:
> But I'm at least under the impression that some of the other SoC's
> have similar flexibility to use video planes as either primary or
> overlay layers.  So I figure it is at least worth trying to handle
> this in a more generic way if it doesn't cause too much ugliness to
> KMS core.
>    
Yes, our DSS have similar flexibility. That is, we don't have a special 
fullscreen framebuffer for the crtc. Instead we have generic "overlays" 
for all framebuffers that can be positioned anywhere and have any 
format, all on a background color of choice. So we are happy with a more 
generic approach where current implementation use a default plane for 
crtc fb. But it should not hog HW resources when not used. If a plane is 
used, I think it should be a "normal" plane that the user can control 
and enumerate.

/BR
/Marcus

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/4] drm: add plane support
  2011-06-20 20:11   ` Jesse Barnes
  (?)
@ 2011-07-21 10:30   ` Joonyoung Shim
  2011-07-21 17:14     ` Jesse Barnes
  -1 siblings, 1 reply; 27+ messages in thread
From: Joonyoung Shim @ 2011-07-21 10:30 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: inki.dae, intel-gfx, kyungmin.park, dri-devel

Hi,

simple questions :)

2011/6/21 Jesse Barnes <jbarnes@virtuousgeek.org>:
> Planes are a bit like half-CRTCs.  They have a location and fb, but
> don't drive outputs directly.  Add support for handling them to the core
> KMS code.
>
> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> ---
>  drivers/gpu/drm/drm_crtc.c |  235 +++++++++++++++++++++++++++++++++++++++++++-
>  drivers/gpu/drm/drm_drv.c  |    3 +
>  include/drm/drm.h          |    3 +
>  include/drm/drm_crtc.h     |   73 ++++++++++++++-
>  include/drm/drm_mode.h     |   35 +++++++
>  5 files changed, 346 insertions(+), 3 deletions(-)
>

snip

> diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
> index c4961ea..fa6d348 100644
> --- a/include/drm/drm_mode.h
> +++ b/include/drm/drm_mode.h
> @@ -120,6 +120,41 @@ struct drm_mode_crtc {
>        struct drm_mode_modeinfo mode;
>  };
>
> +/* Planes blend with or override other bits on the CRTC */
> +struct drm_mode_set_plane {
> +       __u32 plane_id;
> +       __u32 crtc_id;
> +       __u32 fb_id; /* fb object contains surface format type */
> +
> +       /* Signed dest location allows it to be partially off screen */
> +       __s32 crtc_x, crtc_y;

Is this location offset from base(0, 0) of fb for plane, or from base
of crtc(mode)?

> +       __u32 crtc_w, crtc_h;

What is it for? size of plane?

> +
> +       /* Source values are 16.16 fixed point */
> +       __u32 src_x, src_y;
> +       __u32 src_h, src_w;

What are these for?

> +
> +       __u32 zpos;

Is this for order of plane(overlay)?

> +};
> +
> +struct drm_mode_get_plane {
> +       __u64 format_type_ptr;
> +       __u32 plane_id;
> +
> +       __u32 crtc_id;
> +       __u32 fb_id;
> +
> +       __u32 possible_crtcs;
> +       __u32 gamma_size;
> +
> +       __u32 count_format_types;
> +};
> +
> +struct drm_mode_get_plane_res {
> +       __u64 plane_id_ptr;
> +       __u32 count_planes;
> +};
> +
>  #define DRM_MODE_ENCODER_NONE  0
>  #define DRM_MODE_ENCODER_DAC   1
>  #define DRM_MODE_ENCODER_TMDS  2
> --
> 1.7.4.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>



-- 
- Joonyoung Shim

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/4] drm: add plane support
  2011-07-21 10:30   ` Joonyoung Shim
@ 2011-07-21 17:14     ` Jesse Barnes
  2011-07-25  8:18       ` Joonyoung Shim
  0 siblings, 1 reply; 27+ messages in thread
From: Jesse Barnes @ 2011-07-21 17:14 UTC (permalink / raw)
  To: Joonyoung Shim; +Cc: inki.dae, intel-gfx, kyungmin.park, dri-devel

On Thu, 21 Jul 2011 19:30:00 +0900
Joonyoung Shim <dofmind@gmail.com> wrote:

> Hi,
> 
> simple questions :)
> 
> 2011/6/21 Jesse Barnes <jbarnes@virtuousgeek.org>:
> > Planes are a bit like half-CRTCs.  They have a location and fb, but
> > don't drive outputs directly.  Add support for handling them to the core
> > KMS code.
> >
> > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> > ---
> >  drivers/gpu/drm/drm_crtc.c |  235 +++++++++++++++++++++++++++++++++++++++++++-
> >  drivers/gpu/drm/drm_drv.c  |    3 +
> >  include/drm/drm.h          |    3 +
> >  include/drm/drm_crtc.h     |   73 ++++++++++++++-
> >  include/drm/drm_mode.h     |   35 +++++++
> >  5 files changed, 346 insertions(+), 3 deletions(-)
> >
> 
> snip
> 
> > diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
> > index c4961ea..fa6d348 100644
> > --- a/include/drm/drm_mode.h
> > +++ b/include/drm/drm_mode.h
> > @@ -120,6 +120,41 @@ struct drm_mode_crtc {
> >        struct drm_mode_modeinfo mode;
> >  };
> >
> > +/* Planes blend with or override other bits on the CRTC */
> > +struct drm_mode_set_plane {
> > +       __u32 plane_id;
> > +       __u32 crtc_id;
> > +       __u32 fb_id; /* fb object contains surface format type */
> > +
> > +       /* Signed dest location allows it to be partially off screen */
> > +       __s32 crtc_x, crtc_y;
> 
> Is this location offset from base(0, 0) of fb for plane, or from base
> of crtc(mode)?

This is the offset on the crtc specifically (which could be displaying
a nonzero offset of a given fb).

> 
> > +       __u32 crtc_w, crtc_h;
> 
> What is it for? size of plane?

These are the size of the rect on the crtc.  It's possible to have say
a small source fb that gets scaled to a different size on the crtc by
the plane blender or display hardware.

> 
> > +
> > +       /* Source values are 16.16 fixed point */
> > +       __u32 src_x, src_y;
> > +       __u32 src_h, src_w;
> 
> What are these for?

These specify the offset and size of the rect used for the source
area.  This allows the sprite hardware to send a subregion to the plane
blender for display on the crtc.

> > +
> > +       __u32 zpos;
> 
> Is this for order of plane(overlay)?

Yes.

Hope that helps; most of the above came out of earlier review comments
since some display hardware allows a lot of flexibility when displaying
overlay planes.

-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/4] drm: add plane support
  2011-06-20 20:11   ` Jesse Barnes
  (?)
  (?)
@ 2011-07-22 13:52   ` Rob Clark
  2011-07-22 15:30     ` Jesse Barnes
  2011-07-22 22:18     ` Alan Cox
  -1 siblings, 2 replies; 27+ messages in thread
From: Rob Clark @ 2011-07-22 13:52 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: intel-gfx, dri-devel

On Mon, Jun 20, 2011 at 3:11 PM, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
>  /**
> + * drm_plane_funcs - driver plane control functions
> + * @update_plane: update the plane configuration
> + */
> +struct drm_plane_funcs {
> +       int (*update_plane)(struct drm_plane *plane,
> +                           struct drm_crtc *crtc, struct drm_framebuffer *fb,
> +                           int crtc_x, int crtc_y,
> +                           unsigned int crtc_w, unsigned int crtc_h,
> +                           uint32_t src_x, uint32_t src_y,
> +                           uint32_t src_w, uint32_t src_h);
> +       void (*disable_plane)(struct drm_plane *plane);
> +};
> +


would it freak anyone out too much to ask about multi-planar formats?
Ie. say you have an overlay that could display I420 w/ separate Y, U,
& V addresses or NV12 w/ separate Y and UV addresses.  Some of the
SoC's out there require that chroma and luma is in different memory
banks.  In omap4xxx case we don't have this requirement, but we do
have different tiling for Y and UV  (NV12).

Not something that directly affects this patchset.. I'm thinking more
along the lines of having a way to create a drm_framebuffer w/ more
than one GEM buffer, one per color plane.  The other option is to bury
this all behind a single GEM buffer.. although that seems like it
could get ugly/hacky.

Am I opening a can of worms here?  ;-)

BR,
-R

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/4] drm: add plane support
  2011-07-22 13:52   ` Rob Clark
@ 2011-07-22 15:30     ` Jesse Barnes
  2011-07-22 15:57       ` Rob Clark
  2011-07-22 22:18     ` Alan Cox
  1 sibling, 1 reply; 27+ messages in thread
From: Jesse Barnes @ 2011-07-22 15:30 UTC (permalink / raw)
  To: Rob Clark; +Cc: intel-gfx, dri-devel

On Fri, 22 Jul 2011 08:52:52 -0500
Rob Clark <robdclark@gmail.com> wrote:

> On Mon, Jun 20, 2011 at 3:11 PM, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> >  /**
> > + * drm_plane_funcs - driver plane control functions
> > + * @update_plane: update the plane configuration
> > + */
> > +struct drm_plane_funcs {
> > +       int (*update_plane)(struct drm_plane *plane,
> > +                           struct drm_crtc *crtc, struct drm_framebuffer *fb,
> > +                           int crtc_x, int crtc_y,
> > +                           unsigned int crtc_w, unsigned int crtc_h,
> > +                           uint32_t src_x, uint32_t src_y,
> > +                           uint32_t src_w, uint32_t src_h);
> > +       void (*disable_plane)(struct drm_plane *plane);
> > +};
> > +
> 
> 
> would it freak anyone out too much to ask about multi-planar formats?
> Ie. say you have an overlay that could display I420 w/ separate Y, U,
> & V addresses or NV12 w/ separate Y and UV addresses.  Some of the
> SoC's out there require that chroma and luma is in different memory
> banks.  In omap4xxx case we don't have this requirement, but we do
> have different tiling for Y and UV  (NV12).
> 
> Not something that directly affects this patchset.. I'm thinking more
> along the lines of having a way to create a drm_framebuffer w/ more
> than one GEM buffer, one per color plane.  The other option is to bury
> this all behind a single GEM buffer.. although that seems like it
> could get ugly/hacky.
> 
> Am I opening a can of worms here?  ;-)

Yes. :)

Given the format constraints for planar, multi-buffer configs, it might
be best to expose those as driver specific ioctls.  It's a big ugly to
have a driver specific addfb (only because we don't have one currently)
but should be doable for funkier things like this.

-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/4] drm: add plane support
  2011-07-22 15:30     ` Jesse Barnes
@ 2011-07-22 15:57       ` Rob Clark
  0 siblings, 0 replies; 27+ messages in thread
From: Rob Clark @ 2011-07-22 15:57 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: intel-gfx, dri-devel

On Fri, Jul 22, 2011 at 10:30 AM, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> On Fri, 22 Jul 2011 08:52:52 -0500
> Rob Clark <robdclark@gmail.com> wrote:
>
>> On Mon, Jun 20, 2011 at 3:11 PM, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
>> >  /**
>> > + * drm_plane_funcs - driver plane control functions
>> > + * @update_plane: update the plane configuration
>> > + */
>> > +struct drm_plane_funcs {
>> > +       int (*update_plane)(struct drm_plane *plane,
>> > +                           struct drm_crtc *crtc, struct drm_framebuffer *fb,
>> > +                           int crtc_x, int crtc_y,
>> > +                           unsigned int crtc_w, unsigned int crtc_h,
>> > +                           uint32_t src_x, uint32_t src_y,
>> > +                           uint32_t src_w, uint32_t src_h);
>> > +       void (*disable_plane)(struct drm_plane *plane);
>> > +};
>> > +
>>
>>
>> would it freak anyone out too much to ask about multi-planar formats?
>> Ie. say you have an overlay that could display I420 w/ separate Y, U,
>> & V addresses or NV12 w/ separate Y and UV addresses.  Some of the
>> SoC's out there require that chroma and luma is in different memory
>> banks.  In omap4xxx case we don't have this requirement, but we do
>> have different tiling for Y and UV  (NV12).
>>
>> Not something that directly affects this patchset.. I'm thinking more
>> along the lines of having a way to create a drm_framebuffer w/ more
>> than one GEM buffer, one per color plane.  The other option is to bury
>> this all behind a single GEM buffer.. although that seems like it
>> could get ugly/hacky.
>>
>> Am I opening a can of worms here?  ;-)
>
> Yes. :)
>
> Given the format constraints for planar, multi-buffer configs, it might
> be best to expose those as driver specific ioctls.  It's a big ugly to
> have a driver specific addfb (only because we don't have one currently)
> but should be doable for funkier things like this.
>

I'm ok with this.. we can always add a common ioctl later if we end up
with multiple drivers doing things the same way

BR,
-R

> --
> Jesse Barnes, Intel Open Source Technology Center
>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/4] drm: add plane support
  2011-07-22 13:52   ` Rob Clark
  2011-07-22 15:30     ` Jesse Barnes
@ 2011-07-22 22:18     ` Alan Cox
  1 sibling, 0 replies; 27+ messages in thread
From: Alan Cox @ 2011-07-22 22:18 UTC (permalink / raw)
  To: Rob Clark; +Cc: intel-gfx, dri-devel

> Not something that directly affects this patchset.. I'm thinking more
> along the lines of having a way to create a drm_framebuffer w/ more
> than one GEM buffer, one per color plane.  The other option is to bury
> this all behind a single GEM buffer.. although that seems like it
> could get ugly/hacky.

My own guess is that it will be best to have a possibly specialist
function to allocate the object, but to give it a single GEM handle. For
the most part its a list of pinned pages somewhere and while picking the
pages to use is special I am thinking that the rest of the behaviour is
probably not.

It also then means on the client side that it's a single buffer, a single
mmap and can be wrapped easily in things like libkms.

Alan

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/4] drm: add plane support
  2011-07-21 17:14     ` Jesse Barnes
@ 2011-07-25  8:18       ` Joonyoung Shim
  2011-07-25 14:57         ` Rob Clark
  0 siblings, 1 reply; 27+ messages in thread
From: Joonyoung Shim @ 2011-07-25  8:18 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: inki.dae, intel-gfx, kyungmin.park, dri-devel

2011/7/22 Jesse Barnes <jbarnes@virtuousgeek.org>:
> On Thu, 21 Jul 2011 19:30:00 +0900
> Joonyoung Shim <dofmind@gmail.com> wrote:
>
>> Hi,
>>
>> simple questions :)
>>
>> 2011/6/21 Jesse Barnes <jbarnes@virtuousgeek.org>:
>> > Planes are a bit like half-CRTCs.  They have a location and fb, but
>> > don't drive outputs directly.  Add support for handling them to the core
>> > KMS code.
>> >
>> > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
>> > ---
>> >  drivers/gpu/drm/drm_crtc.c |  235 +++++++++++++++++++++++++++++++++++++++++++-
>> >  drivers/gpu/drm/drm_drv.c  |    3 +
>> >  include/drm/drm.h          |    3 +
>> >  include/drm/drm_crtc.h     |   73 ++++++++++++++-
>> >  include/drm/drm_mode.h     |   35 +++++++
>> >  5 files changed, 346 insertions(+), 3 deletions(-)
>> >
>>
>> snip
>>
>> > diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
>> > index c4961ea..fa6d348 100644
>> > --- a/include/drm/drm_mode.h
>> > +++ b/include/drm/drm_mode.h
>> > @@ -120,6 +120,41 @@ struct drm_mode_crtc {
>> >        struct drm_mode_modeinfo mode;
>> >  };
>> >
>> > +/* Planes blend with or override other bits on the CRTC */
>> > +struct drm_mode_set_plane {
>> > +       __u32 plane_id;
>> > +       __u32 crtc_id;
>> > +       __u32 fb_id; /* fb object contains surface format type */
>> > +
>> > +       /* Signed dest location allows it to be partially off screen */
>> > +       __s32 crtc_x, crtc_y;
>>
>> Is this location offset from base(0, 0) of fb for plane, or from base
>> of crtc(mode)?
>
> This is the offset on the crtc specifically (which could be displaying
> a nonzero offset of a given fb).
>

Then if i want to use the specific area of a given fb for overlay, how
can we know the offset on a given fb?
In other words, can we use the specific offset from fb to origin(base
pointer) of plane? or can we use each overlays from each specific
offsets of one fb?

Thanks.

-- 
- Joonyoung Shim

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/4] drm: add plane support
  2011-07-25  8:18       ` Joonyoung Shim
@ 2011-07-25 14:57         ` Rob Clark
  2011-07-26  4:21           ` Joonyoung Shim
  0 siblings, 1 reply; 27+ messages in thread
From: Rob Clark @ 2011-07-25 14:57 UTC (permalink / raw)
  To: Joonyoung Shim; +Cc: inki.dae, intel-gfx, dri-devel, kyungmin.park

On Mon, Jul 25, 2011 at 3:18 AM, Joonyoung Shim <dofmind@gmail.com> wrote:
> 2011/7/22 Jesse Barnes <jbarnes@virtuousgeek.org>:
>> On Thu, 21 Jul 2011 19:30:00 +0900
>> Joonyoung Shim <dofmind@gmail.com> wrote:
>>
>>> Hi,
>>>
>>> simple questions :)
>>>
>>> 2011/6/21 Jesse Barnes <jbarnes@virtuousgeek.org>:
>>> > Planes are a bit like half-CRTCs.  They have a location and fb, but
>>> > don't drive outputs directly.  Add support for handling them to the core
>>> > KMS code.
>>> >
>>> > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
>>> > ---
>>> >  drivers/gpu/drm/drm_crtc.c |  235 +++++++++++++++++++++++++++++++++++++++++++-
>>> >  drivers/gpu/drm/drm_drv.c  |    3 +
>>> >  include/drm/drm.h          |    3 +
>>> >  include/drm/drm_crtc.h     |   73 ++++++++++++++-
>>> >  include/drm/drm_mode.h     |   35 +++++++
>>> >  5 files changed, 346 insertions(+), 3 deletions(-)
>>> >
>>>
>>> snip
>>>
>>> > diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
>>> > index c4961ea..fa6d348 100644
>>> > --- a/include/drm/drm_mode.h
>>> > +++ b/include/drm/drm_mode.h
>>> > @@ -120,6 +120,41 @@ struct drm_mode_crtc {
>>> >        struct drm_mode_modeinfo mode;
>>> >  };
>>> >
>>> > +/* Planes blend with or override other bits on the CRTC */
>>> > +struct drm_mode_set_plane {
>>> > +       __u32 plane_id;
>>> > +       __u32 crtc_id;
>>> > +       __u32 fb_id; /* fb object contains surface format type */
>>> > +
>>> > +       /* Signed dest location allows it to be partially off screen */
>>> > +       __s32 crtc_x, crtc_y;
>>>
>>> Is this location offset from base(0, 0) of fb for plane, or from base
>>> of crtc(mode)?
>>
>> This is the offset on the crtc specifically (which could be displaying
>> a nonzero offset of a given fb).
>>
>
> Then if i want to use the specific area of a given fb for overlay, how
> can we know the offset on a given fb?
> In other words, can we use the specific offset from fb to origin(base
> pointer) of plane? or can we use each overlays from each specific
> offsets of one fb?

The x,y parameters give the position within the fb, the crtc_x,crtc_y
parameters give the position within the crtc (screen)..

So if you had full-screen video spanning two 1280x1024 displays, where
the video was 1080p.  Say the video was nearly but not completely
full-screen (say, 5 pixel border all around.. just to pick some #'s):

display one:
  plane:  x,y=0,0, crtc_x,crtc_y=5,5, crtc_w=1275, crtc_h=1014

display two:  (to right of display one)
  plane: x,y=960,0, crtc_x,crtc_y=0,5, crtc_w=1275, crtc_h=1014

(or at least that is my understanding..)

BR,
-R

> Thanks.
>
> --
> - Joonyoung Shim
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/4] drm: add plane support
  2011-07-25 14:57         ` Rob Clark
@ 2011-07-26  4:21           ` Joonyoung Shim
  0 siblings, 0 replies; 27+ messages in thread
From: Joonyoung Shim @ 2011-07-26  4:21 UTC (permalink / raw)
  To: Rob Clark; +Cc: inki.dae, intel-gfx, dri-devel, kyungmin.park

2011/7/25 Rob Clark <robdclark@gmail.com>:
> On Mon, Jul 25, 2011 at 3:18 AM, Joonyoung Shim <dofmind@gmail.com> wrote:
>> 2011/7/22 Jesse Barnes <jbarnes@virtuousgeek.org>:
>>> On Thu, 21 Jul 2011 19:30:00 +0900
>>> Joonyoung Shim <dofmind@gmail.com> wrote:
>>>
>>>> Hi,
>>>>
>>>> simple questions :)
>>>>
>>>> 2011/6/21 Jesse Barnes <jbarnes@virtuousgeek.org>:
>>>> > Planes are a bit like half-CRTCs.  They have a location and fb, but
>>>> > don't drive outputs directly.  Add support for handling them to the core
>>>> > KMS code.
>>>> >
>>>> > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
>>>> > ---
>>>> >  drivers/gpu/drm/drm_crtc.c |  235 +++++++++++++++++++++++++++++++++++++++++++-
>>>> >  drivers/gpu/drm/drm_drv.c  |    3 +
>>>> >  include/drm/drm.h          |    3 +
>>>> >  include/drm/drm_crtc.h     |   73 ++++++++++++++-
>>>> >  include/drm/drm_mode.h     |   35 +++++++
>>>> >  5 files changed, 346 insertions(+), 3 deletions(-)
>>>> >
>>>>
>>>> snip
>>>>
>>>> > diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
>>>> > index c4961ea..fa6d348 100644
>>>> > --- a/include/drm/drm_mode.h
>>>> > +++ b/include/drm/drm_mode.h
>>>> > @@ -120,6 +120,41 @@ struct drm_mode_crtc {
>>>> >        struct drm_mode_modeinfo mode;
>>>> >  };
>>>> >
>>>> > +/* Planes blend with or override other bits on the CRTC */
>>>> > +struct drm_mode_set_plane {
>>>> > +       __u32 plane_id;
>>>> > +       __u32 crtc_id;
>>>> > +       __u32 fb_id; /* fb object contains surface format type */
>>>> > +
>>>> > +       /* Signed dest location allows it to be partially off screen */
>>>> > +       __s32 crtc_x, crtc_y;
>>>>
>>>> Is this location offset from base(0, 0) of fb for plane, or from base
>>>> of crtc(mode)?
>>>
>>> This is the offset on the crtc specifically (which could be displaying
>>> a nonzero offset of a given fb).
>>>
>>
>> Then if i want to use the specific area of a given fb for overlay, how
>> can we know the offset on a given fb?
>> In other words, can we use the specific offset from fb to origin(base
>> pointer) of plane? or can we use each overlays from each specific
>> offsets of one fb?
>
> The x,y parameters give the position within the fb, the crtc_x,crtc_y
> parameters give the position within the crtc (screen)..
>

Hmm, i can't understand well, which x, y parameters? As you know,
struct drm_mode_set_plane hasn't x , y parameters for fb,
so how can know x, y parameters?

> So if you had full-screen video spanning two 1280x1024 displays, where
> the video was 1080p.  Say the video was nearly but not completely
> full-screen (say, 5 pixel border all around.. just to pick some #'s):
>
> display one:
>  plane:  x,y=0,0, crtc_x,crtc_y=5,5, crtc_w=1275, crtc_h=1014
>
> display two:  (to right of display one)
>  plane: x,y=960,0, crtc_x,crtc_y=0,5, crtc_w=1275, crtc_h=1014
>
> (or at least that is my understanding..)
>
> BR,
> -R
>
>> Thanks.
>>
>> --
>> - Joonyoung Shim
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>>
>

-- 
- Joonyoung Shim

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFC] Updated plane support v3
  2011-06-20 20:11 [RFC] Updated plane support v3 Jesse Barnes
                   ` (5 preceding siblings ...)
  2011-06-21 11:21 ` Rob Clark
@ 2011-09-19  8:03 ` Joonyoung Shim
  6 siblings, 0 replies; 27+ messages in thread
From: Joonyoung Shim @ 2011-09-19  8:03 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: intel-gfx, dri-devel

2011/6/21 Jesse Barnes <jbarnes@virtuousgeek.org>:
> This version adds both source and dest rect params to the set_plane
> ioctl, and makes the source fixed point to support hardware that needs
> it.
>
> I haven't changed the name of the SNB implementation yet (per Chris's
> suggestions) but will before it gets upstream.
>
> I'd be interested to see whether these interfaces will work for other
> hardware, so please take a close look at them and ideally implement them
> on your hardware to make sure (see my userspace example code from
> earlier posts if you want something to crib from).
>
> Thanks,
> Jesse
>

Hi, Jesse.

Could you have any posting plan for plane?

Thanks.

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2011-09-19  8:03 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-20 20:11 [RFC] Updated plane support v3 Jesse Barnes
2011-06-20 20:11 ` [PATCH 1/4] drm: add plane support Jesse Barnes
2011-06-20 20:11   ` Jesse Barnes
2011-07-21 10:30   ` Joonyoung Shim
2011-07-21 17:14     ` Jesse Barnes
2011-07-25  8:18       ` Joonyoung Shim
2011-07-25 14:57         ` Rob Clark
2011-07-26  4:21           ` Joonyoung Shim
2011-07-22 13:52   ` Rob Clark
2011-07-22 15:30     ` Jesse Barnes
2011-07-22 15:57       ` Rob Clark
2011-07-22 22:18     ` Alan Cox
2011-06-20 20:11 ` [PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format Jesse Barnes
2011-06-20 20:11   ` Jesse Barnes
2011-06-20 20:11 ` [PATCH 3/4] drm/i915: rename existing overlay support to "legacy" Jesse Barnes
2011-06-20 20:11   ` Jesse Barnes
2011-06-20 20:11 ` [PATCH 4/4] drm/i915: add SNB video sprite support Jesse Barnes
2011-06-20 20:11   ` Jesse Barnes
2011-06-21  8:55 ` [RFC] Updated plane support v3 Marcus Lorentzon
2011-06-21  9:12   ` Daniel Vetter
2011-06-21 16:13   ` Jesse Barnes
2011-06-21 11:21 ` Rob Clark
2011-06-21 13:16   ` Rob Clark
2011-06-21 16:19   ` Jesse Barnes
2011-06-22  1:09     ` Rob Clark
2011-06-22  9:16       ` Marcus Lorentzon
2011-09-19  8:03 ` Joonyoung Shim

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.