* [PATCH 01/11] drm: add plane support
2011-10-25 9:46 DRM planes and new fb creation ioctl Jesse Barnes
@ 2011-10-25 9:46 ` Jesse Barnes
2011-10-25 10:53 ` Joonyoung Shim
` (3 more replies)
2011-10-25 9:46 ` [PATCH 02/11] drm: add an fb creation ioctl that takes a pixel format Jesse Barnes
` (12 subsequent siblings)
13 siblings, 4 replies; 41+ messages in thread
From: Jesse Barnes @ 2011-10-25 9:46 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 | 236 +++++++++++++++++++++++++++++++++++++++++++-
drivers/gpu/drm/drm_drv.c | 3 +
include/drm/drm.h | 3 +
include/drm/drm_crtc.h | 71 +++++++++++++-
include/drm/drm_mode.h | 33 ++++++
5 files changed, 343 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index fe738f0..0e129b1 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -535,6 +535,48 @@ 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);
+ kfree(plane->format_types);
+ 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
@@ -866,6 +908,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);
@@ -1466,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
@@ -1688,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 8020798..d7f03aa 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;
@@ -278,6 +279,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
@@ -536,6 +538,58 @@ 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);
+ int (*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;
+
+ 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
@@ -589,6 +643,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;
@@ -641,6 +697,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,
@@ -660,6 +717,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);
@@ -753,13 +817,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..07711b0 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -120,6 +120,39 @@ 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;
+};
+
+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] 41+ messages in thread* Re: [PATCH 01/11] drm: add plane support
2011-10-25 9:46 ` [PATCH 01/11] drm: add plane support Jesse Barnes
@ 2011-10-25 10:53 ` Joonyoung Shim
2011-10-25 11:18 ` Jesse Barnes
2011-10-25 11:58 ` Daniel Vetter
` (2 subsequent siblings)
3 siblings, 1 reply; 41+ messages in thread
From: Joonyoung Shim @ 2011-10-25 10:53 UTC (permalink / raw)
To: Jesse Barnes
Cc: intel-gfx,
"kyungmin.park@samsung.com >> 박경민",
dri-devel
10/25/2011 06:46 PM, 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 | 236 +++++++++++++++++++++++++++++++++++++++++++-
> drivers/gpu/drm/drm_drv.c | 3 +
> include/drm/drm.h | 3 +
> include/drm/drm_crtc.h | 71 +++++++++++++-
> include/drm/drm_mode.h | 33 ++++++
> 5 files changed, 343 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index fe738f0..0e129b1 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -535,6 +535,48 @@ 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);
> + kfree(plane->format_types);
> + 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
> @@ -866,6 +908,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);
> @@ -1466,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
> @@ -1688,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 8020798..d7f03aa 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;
> @@ -278,6 +279,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
> @@ -536,6 +538,58 @@ 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);
> + int (*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
Above 4 members don't be used.
> + * @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;
> +
> + 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
> @@ -589,6 +643,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;
> @@ -641,6 +697,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,
> @@ -660,6 +717,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);
> @@ -753,13 +817,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..07711b0 100644
> --- a/include/drm/drm_mode.h
> +++ b/include/drm/drm_mode.h
> @@ -120,6 +120,39 @@ 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;
> +};
> +
> +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;
> +};
I wonder why doesn't give to user crtc_x, crtc_y, crtc_w, crtc_h
information?
> +
> +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
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [PATCH 01/11] drm: add plane support
2011-10-25 10:53 ` Joonyoung Shim
@ 2011-10-25 11:18 ` Jesse Barnes
2011-10-26 0:19 ` Joonyoung Shim
0 siblings, 1 reply; 41+ messages in thread
From: Jesse Barnes @ 2011-10-25 11:18 UTC (permalink / raw)
To: Joonyoung Shim
Cc: intel-gfx,
kyungmin.park@samsung.com >> 박경민,
dri-devel
On Tue, 25 Oct 2011 19:53:02 +0900
Joonyoung Shim <jy0922.shim@samsung.com> wrote:
> > +/**
> > + * 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
> Above 4 members don't be used.
Oops yeah, I'll fix up the comments.
> > +
> > +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;
> > +};
>
> I wonder why doesn't give to user crtc_x, crtc_y, crtc_w, crtc_h
> information?
It could, but the caller should already know was my thinking. Would
you like those bits returned?
Jesse
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [PATCH 01/11] drm: add plane support
2011-10-25 11:18 ` Jesse Barnes
@ 2011-10-26 0:19 ` Joonyoung Shim
0 siblings, 0 replies; 41+ messages in thread
From: Joonyoung Shim @ 2011-10-26 0:19 UTC (permalink / raw)
To: Jesse Barnes
Cc: intel-gfx,
"kyungmin.park@samsung.com >> 박경민",
dri-devel
10/25/2011 08:18 PM, Jesse Barnes 쓴 글:
> On Tue, 25 Oct 2011 19:53:02 +0900
> Joonyoung Shim<jy0922.shim@samsung.com> wrote:
>>> +/**
>>> + * 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
>> Above 4 members don't be used.
> Oops yeah, I'll fix up the comments.
>
>>> +
>>> +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;
>>> +};
>> I wonder why doesn't give to user crtc_x, crtc_y, crtc_w, crtc_h
>> information?
> It could, but the caller should already know was my thinking. Would
> you like those bits returned?
I saw such codes in initial your RFC patch version so i just have
wondered why it is removed. It can be added later if needs.
Thanks.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 01/11] drm: add plane support
2011-10-25 9:46 ` [PATCH 01/11] drm: add plane support Jesse Barnes
2011-10-25 10:53 ` Joonyoung Shim
@ 2011-10-25 11:58 ` Daniel Vetter
2011-10-25 12:26 ` Jesse Barnes
2011-10-25 13:26 ` Alan Cox
2011-10-25 14:09 ` Jesse Barnes
2011-10-26 5:40 ` Joonyoung Shim
3 siblings, 2 replies; 41+ messages in thread
From: Daniel Vetter @ 2011-10-25 11:58 UTC (permalink / raw)
To: Jesse Barnes; +Cc: intel-gfx, dri-devel
On Tue, Oct 25, 2011 at 11:46:56AM +0200, Jesse Barnes wrote:
> 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>
As discussed with Jesse on irc, drm fb handling is fragile. Current rules:
- fbs are not reference counted, hence when destroying we need to disable
all crtcs (and now also planes) that use them. drm_framebuffer_cleanup
does that atm
- drivers that hold onto fbs after the kms core drops the corresponding
pointer needs to hold a ref onto the underlying backing storage (like
e.g. for pageflip on the to-be-flipped-out fb as long as it might still
be scanned out).
We need proper refcounting for these ... But for now this patch is missing
the plane cleanup in drm_framebuffer_cleanup.
Otherwise I think going with just the src and dst rect for set_plane is
about the only sensible thing given the crazy hw out there. But I lack the
knowledge about that kind of hw (and video stuff in general), so I'll
refrain from slapping my r-b on these two.
Cheers, Daniel
--
Daniel Vetter
Mail: daniel@ffwll.ch
Mobile: +41 (0)79 365 57 48
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 01/11] drm: add plane support
2011-10-25 11:58 ` Daniel Vetter
@ 2011-10-25 12:26 ` Jesse Barnes
2011-10-25 13:26 ` Alan Cox
1 sibling, 0 replies; 41+ messages in thread
From: Jesse Barnes @ 2011-10-25 12:26 UTC (permalink / raw)
To: Daniel Vetter
On Tue, 25 Oct 2011 13:58:55 +0200
Daniel Vetter <daniel@ffwll.ch> wrote:
> On Tue, Oct 25, 2011 at 11:46:56AM +0200, Jesse Barnes wrote:
> > 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>
>
> As discussed with Jesse on irc, drm fb handling is fragile. Current
> rules:
> - fbs are not reference counted, hence when destroying we need to
> disable all crtcs (and now also planes) that use them.
> drm_framebuffer_cleanup does that atm
> - drivers that hold onto fbs after the kms core drops the
> corresponding pointer needs to hold a ref onto the underlying backing
> storage (like e.g. for pageflip on the to-be-flipped-out fb as long
> as it might still be scanned out).
>
> We need proper refcounting for these ... But for now this patch is
> missing the plane cleanup in drm_framebuffer_cleanup.
Ah yeah that's a better place for the disable plane call I currently
have in the intel specific code... I'll fix up and test.
> Otherwise I think going with just the src and dst rect for set_plane
> is about the only sensible thing given the crazy hw out there. But I
> lack the knowledge about that kind of hw (and video stuff in
> general), so I'll refrain from slapping my r-b on these two.
Yeah, I think the drivers just need to be able to calculate the scaling
level from the params and program them into whatever regs they happen
to have (on Intel fortunately the scaling is figured out by hw when we
program in the source & dest values, subject to some restrictions).
Thanks,
Jesse
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 01/11] drm: add plane support
2011-10-25 11:58 ` Daniel Vetter
2011-10-25 12:26 ` Jesse Barnes
@ 2011-10-25 13:26 ` Alan Cox
2011-10-25 13:32 ` Jesse Barnes
2011-10-25 13:42 ` Daniel Vetter
1 sibling, 2 replies; 41+ messages in thread
From: Alan Cox @ 2011-10-25 13:26 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx, dri-devel
> As discussed with Jesse on irc, drm fb handling is fragile. Current rules:
> - fbs are not reference counted, hence when destroying we need to disable
> all crtcs (and now also planes) that use them. drm_framebuffer_cleanup
> does that atm
> - drivers that hold onto fbs after the kms core drops the corresponding
> pointer needs to hold a ref onto the underlying backing storage (like
> e.g. for pageflip on the to-be-flipped-out fb as long as it might still
> be scanned out).
>
> We need proper refcounting for these ... But for now this patch is missing
> the plane cleanup in drm_framebuffer_cleanup.
I'd rather we fixed the framebuffer kref stuff as part of doing this
rather than have a poorer API because of something we have to fix anyway.
It shouldn't be *that* hard to fix, at least for this kind of use
case. Resize locking, fb moving etc are ugly issues, refcount shouldn't
be, and the tty layer also refcounts so we can only have the fb objects
themselves to worry about as we can defer fb destruction to tty close or
drm last unref even for those with consoles on them.
Alan
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 01/11] drm: add plane support
2011-10-25 13:26 ` Alan Cox
@ 2011-10-25 13:32 ` Jesse Barnes
2011-10-25 13:42 ` Daniel Vetter
1 sibling, 0 replies; 41+ messages in thread
From: Jesse Barnes @ 2011-10-25 13:32 UTC (permalink / raw)
To: Alan Cox; +Cc: intel-gfx, dri-devel
On Tue, 25 Oct 2011 14:26:07 +0100
Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
> > As discussed with Jesse on irc, drm fb handling is fragile. Current
> > rules:
> > - fbs are not reference counted, hence when destroying we need to
> > disable all crtcs (and now also planes) that use them.
> > drm_framebuffer_cleanup does that atm
> > - drivers that hold onto fbs after the kms core drops the
> > corresponding pointer needs to hold a ref onto the underlying
> > backing storage (like e.g. for pageflip on the to-be-flipped-out fb
> > as long as it might still be scanned out).
> >
> > We need proper refcounting for these ... But for now this patch is
> > missing the plane cleanup in drm_framebuffer_cleanup.
>
> I'd rather we fixed the framebuffer kref stuff as part of doing this
> rather than have a poorer API because of something we have to fix
> anyway.
>
> It shouldn't be *that* hard to fix, at least for this kind of use
> case. Resize locking, fb moving etc are ugly issues, refcount
> shouldn't be, and the tty layer also refcounts so we can only have
> the fb objects themselves to worry about as we can defer fb
> destruction to tty close or drm last unref even for those with
> consoles on them.
Oh it doesn't affect the userspace API so I don't think it's urgent.
But I agree, it would be nice to clean up fb management a bit... Any
volunteers? :)
Thanks,
Jesse
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 01/11] drm: add plane support
2011-10-25 13:26 ` Alan Cox
2011-10-25 13:32 ` Jesse Barnes
@ 2011-10-25 13:42 ` Daniel Vetter
1 sibling, 0 replies; 41+ messages in thread
From: Daniel Vetter @ 2011-10-25 13:42 UTC (permalink / raw)
To: Alan Cox; +Cc: dri-devel, intel-gfx
On Tue, Oct 25, 2011 at 02:26:07PM +0100, Alan Cox wrote:
> > As discussed with Jesse on irc, drm fb handling is fragile. Current rules:
> > - fbs are not reference counted, hence when destroying we need to disable
> > all crtcs (and now also planes) that use them. drm_framebuffer_cleanup
> > does that atm
> > - drivers that hold onto fbs after the kms core drops the corresponding
> > pointer needs to hold a ref onto the underlying backing storage (like
> > e.g. for pageflip on the to-be-flipped-out fb as long as it might still
> > be scanned out).
> >
> > We need proper refcounting for these ... But for now this patch is missing
> > the plane cleanup in drm_framebuffer_cleanup.
>
> I'd rather we fixed the framebuffer kref stuff as part of doing this
> rather than have a poorer API because of something we have to fix anyway.
Imo we should do things piece by piece. Fixing up drm fb refcounting is
imo a rather low-prio thing for core drm. And I've already asked Rob
Clarke whether he can clean up some of the confiusion in the kms
framebuffer->destroy() functions.
> It shouldn't be *that* hard to fix, at least for this kind of use
> case. Resize locking, fb moving etc are ugly issues, refcount shouldn't
> be, and the tty layer also refcounts so we can only have the fb objects
> themselves to worry about as we can defer fb destruction to tty close or
I'm talking solely about kms framebuffers. I.e. completely orthogonal to
any issues you're seeing wrt kms<->linux fb subsystem integration. Or I'm
completely misunderstanding you here ...
-Daniel
--
Daniel Vetter
Mail: daniel@ffwll.ch
Mobile: +41 (0)79 365 57 48
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 01/11] drm: add plane support
2011-10-25 9:46 ` [PATCH 01/11] drm: add plane support Jesse Barnes
2011-10-25 10:53 ` Joonyoung Shim
2011-10-25 11:58 ` Daniel Vetter
@ 2011-10-25 14:09 ` Jesse Barnes
2011-10-25 16:43 ` Rob Clark
2011-10-26 5:40 ` Joonyoung Shim
3 siblings, 1 reply; 41+ messages in thread
From: Jesse Barnes @ 2011-10-25 14:09 UTC (permalink / raw)
Cc: intel-gfx, dri-devel
Here's a diff I can roll in if it looks ok. It adds the ability to
specify multiple handles for a single fb to better accommodate planar
configs. I think Rob has convinced me that this is a good idea...
comments appreciated.
Thanks,
Jesse
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index a30b9d4..0cc2077 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1923,7 +1923,8 @@ int drm_mode_addfb(struct drm_device *dev,
r.bpp = or->bpp;
r.depth = or->depth;
r.pixel_format = 0;
- r.handle = or->handle;
+ r.handle_count = 1;
+ r.handles = (u64)&or->handle;
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index cd7e04d..2c7f200 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7619,8 +7619,9 @@ intel_user_framebuffer_create(struct drm_device *dev,
struct drm_mode_fb_cmd2 *mode_cmd)
{
struct drm_i915_gem_object *obj;
+ u32 *handles = (u32 *)mode_cmd->handles;
- obj = to_intel_bo(drm_gem_object_lookup(dev, filp, mode_cmd->handle));
+ obj = to_intel_bo(drm_gem_object_lookup(dev, filp, handles[0]));
if (&obj->base == NULL)
return ERR_PTR(-ENOENT);
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 7a428a9..cb9b868 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -128,9 +128,10 @@ nouveau_user_framebuffer_create(struct drm_device *dev,
{
struct nouveau_framebuffer *nouveau_fb;
struct drm_gem_object *gem;
+ u32 *handles = (u32 *)mode_cmd->handles;
int ret;
- gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
+ gem = drm_gem_object_lookup(dev, file_priv, handles);
if (!gem)
return ERR_PTR(-ENOENT);
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index ae803f8..63a6d91 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -1128,11 +1128,12 @@ radeon_user_framebuffer_create(struct drm_device *dev,
{
struct drm_gem_object *obj;
struct radeon_framebuffer *radeon_fb;
+ u32 *handles = (u32 *)mode_cmd->handles;
- obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
+ obj = drm_gem_object_lookup(dev, file_priv, handles[0]);
if (obj == NULL) {
dev_err(&dev->pdev->dev, "No GEM object associated to handle 0x%08X, "
- "can't create framebuffer\n", mode_cmd->handle);
+ "can't create framebuffer\n", handles[0]);
return ERR_PTR(-ENOENT);
}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 2a1b802..0ad7456 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -866,7 +866,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
*/
ret = vmw_user_surface_lookup_handle(dev_priv, tfile,
- mode_cmd->handle, &surface);
+ mode_cmd->handles[0], &surface);
if (ret)
goto try_dmabuf;
diff --git a/drivers/staging/gma500/framebuffer.c b/drivers/staging/gma500/framebuffer.c
index 85f47d5..ee91ffe 100644
--- a/drivers/staging/gma500/framebuffer.c
+++ b/drivers/staging/gma500/framebuffer.c
@@ -496,7 +496,7 @@ static struct drm_framebuffer *psb_user_framebuffer_create
* Find the GEM object and thus the gtt range object that is
* to back this space
*/
- obj = drm_gem_object_lookup(dev, filp, cmd->handle);
+ obj = drm_gem_object_lookup(dev, filp, cmd->handles[0]);
if (obj == NULL)
return ERR_PTR(-ENOENT);
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index 34a0d22..dafe8df 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -272,8 +272,9 @@ struct drm_mode_fb_cmd2 {
__u32 bpp;
__u32 depth;
__u32 pixel_format; /* fourcc code from videodev2.h */
- /* driver specific handle */
- __u32 handle;
+ __u32 handle_count;
+ /* driver specific buffer object handle array */
+ __u64 handles;
};
#define DRM_MODE_FB_DIRTY_ANNOTATE_COPY 0x01
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [PATCH 01/11] drm: add plane support
2011-10-25 14:09 ` Jesse Barnes
@ 2011-10-25 16:43 ` Rob Clark
2011-10-25 19:41 ` Daniel Vetter
0 siblings, 1 reply; 41+ messages in thread
From: Rob Clark @ 2011-10-25 16:43 UTC (permalink / raw)
To: Jesse Barnes; +Cc: intel-gfx, dri-devel
On Tue, Oct 25, 2011 at 9:09 AM, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
> index 34a0d22..dafe8df 100644
> --- a/include/drm/drm_mode.h
> +++ b/include/drm/drm_mode.h
> @@ -272,8 +272,9 @@ struct drm_mode_fb_cmd2 {
> __u32 bpp;
> __u32 depth;
> __u32 pixel_format; /* fourcc code from videodev2.h */
> - /* driver specific handle */
> - __u32 handle;
> + __u32 handle_count;
> + /* driver specific buffer object handle array */
> + __u64 handles;
> };
Ok, after a bit of discussion with Jakob on IRC, this is what we arrived at:
1) It would be nice to have the option for multi-planar formats to be
able to use one single buffer object, or one buffer object per plane.
In the case of one buffer per plane, the order is dictated by the
fourcc.
2) We do need per-plane stride for some formats, in particular I420
which is a bit ambiguous otherwise (ie. is the stride of the U and V
planes half the stride as the Y plane, or the same?)
3) Maybe we need per-plane offsets, but I think this case could be
handled by just using one bo per plane, so left it out
4) bpp/depth are redundant w/ the pixel_format. Just in case, as a
future placeholder, and inspired by 'struct v4l2_pix_format', add a
priv field. Although making the field big enough to hold a pointer if
absolutely really needed.
struct drm_mode_fb_cmd2 {
__u32 fb_id;
__u32 width, height;
__u32 pixel_format; /* fourcc code from videodev2.h */
__u64 priv; /* private data, depends on pixelformat */
/* in case of planar formats, either one buffer object,
* or one buffer object per plane, is allowed. In the
* case per-plane bo's, the order is dictated by the
* fourcc.. ie. NV12 (http://fourcc.org/yuv.php#NV12)
* is described as:
*
* YUV 4:2:0 image with a plane of 8 bit Y samples
* followed by an interleaved U/V plane containing
* 8 bit 2x2 subsampled colour difference samples.
*
* So it would consist of Y as first buffer and UV as
* second buffer. In the case that only a single bo
* is used then buffer[1].handle should be zero. (But
* a plane specific pitch could still be specified.)
*/
struct {
__u32 pitch;
/* driver specific handle */
__u32 handle;
} buffer[16];
};
BR,
-R
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [PATCH 01/11] drm: add plane support
2011-10-25 16:43 ` Rob Clark
@ 2011-10-25 19:41 ` Daniel Vetter
2011-10-25 20:14 ` Rob Clark
2011-10-27 14:05 ` SW Kim
0 siblings, 2 replies; 41+ messages in thread
From: Daniel Vetter @ 2011-10-25 19:41 UTC (permalink / raw)
To: Rob Clark; +Cc: intel-gfx, dri-devel
On Tue, Oct 25, 2011 at 11:43:09AM -0500, Rob Clark wrote:
> On Tue, Oct 25, 2011 at 9:09 AM, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> > diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
> > index 34a0d22..dafe8df 100644
> > --- a/include/drm/drm_mode.h
> > +++ b/include/drm/drm_mode.h
> > @@ -272,8 +272,9 @@ struct drm_mode_fb_cmd2 {
> > __u32 bpp;
> > __u32 depth;
> > __u32 pixel_format; /* fourcc code from videodev2.h */
> > - /* driver specific handle */
> > - __u32 handle;
> > + __u32 handle_count;
> > + /* driver specific buffer object handle array */
> > + __u64 handles;
> > };
>
>
> Ok, after a bit of discussion with Jakob on IRC, this is what we arrived at:
>
> 1) It would be nice to have the option for multi-planar formats to be
> able to use one single buffer object, or one buffer object per plane.
> In the case of one buffer per plane, the order is dictated by the
> fourcc.
>
> 2) We do need per-plane stride for some formats, in particular I420
> which is a bit ambiguous otherwise (ie. is the stride of the U and V
> planes half the stride as the Y plane, or the same?)
>
> 3) Maybe we need per-plane offsets, but I think this case could be
> handled by just using one bo per plane, so left it out
>
> 4) bpp/depth are redundant w/ the pixel_format. Just in case, as a
> future placeholder, and inspired by 'struct v4l2_pix_format', add a
> priv field. Although making the field big enough to hold a pointer if
> absolutely really needed.
>
> struct drm_mode_fb_cmd2 {
> __u32 fb_id;
> __u32 width, height;
> __u32 pixel_format; /* fourcc code from videodev2.h */
> __u64 priv; /* private data, depends on pixelformat */
>
> /* in case of planar formats, either one buffer object,
> * or one buffer object per plane, is allowed. In the
> * case per-plane bo's, the order is dictated by the
> * fourcc.. ie. NV12 (http://fourcc.org/yuv.php#NV12)
> * is described as:
> *
> * YUV 4:2:0 image with a plane of 8 bit Y samples
> * followed by an interleaved U/V plane containing
> * 8 bit 2x2 subsampled colour difference samples.
> *
> * So it would consist of Y as first buffer and UV as
> * second buffer. In the case that only a single bo
> * is used then buffer[1].handle should be zero. (But
> * a plane specific pitch could still be specified.)
> */
> struct {
> __u32 pitch;
> /* driver specific handle */
> __u32 handle;
Why not just add a
__u32 offset;
__u32 rsvd;
and call it a day. This thing is pretty big already, so that bloat doesn't
matter that much. Maybe spec that buffer[0].offset must be zero. With that
you can also do I420 with the following layout
+-------+
|YYYYYYY|
|YYYYYYY|
|YYYYYYY|
|YYYYYYY|
+---+---+
|UUU|VVV|
|UUU|VVV|
+---+---+
i.e. stride_U == stride_V, with their lines meshed into one line.
-Daniel
> } buffer[16];
> };
>
>
> BR,
> -R
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
--
Daniel Vetter
Mail: daniel@ffwll.ch
Mobile: +41 (0)79 365 57 48
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [PATCH 01/11] drm: add plane support
2011-10-25 19:41 ` Daniel Vetter
@ 2011-10-25 20:14 ` Rob Clark
2011-10-27 14:05 ` SW Kim
1 sibling, 0 replies; 41+ messages in thread
From: Rob Clark @ 2011-10-25 20:14 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx, dri-devel
On Tue, Oct 25, 2011 at 2:41 PM, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Tue, Oct 25, 2011 at 11:43:09AM -0500, Rob Clark wrote:
>> On Tue, Oct 25, 2011 at 9:09 AM, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
>> > diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
>> > index 34a0d22..dafe8df 100644
>> > --- a/include/drm/drm_mode.h
>> > +++ b/include/drm/drm_mode.h
>> > @@ -272,8 +272,9 @@ struct drm_mode_fb_cmd2 {
>> > __u32 bpp;
>> > __u32 depth;
>> > __u32 pixel_format; /* fourcc code from videodev2.h */
>> > - /* driver specific handle */
>> > - __u32 handle;
>> > + __u32 handle_count;
>> > + /* driver specific buffer object handle array */
>> > + __u64 handles;
>> > };
>>
>>
>> Ok, after a bit of discussion with Jakob on IRC, this is what we arrived at:
>>
>> 1) It would be nice to have the option for multi-planar formats to be
>> able to use one single buffer object, or one buffer object per plane.
>> In the case of one buffer per plane, the order is dictated by the
>> fourcc.
>>
>> 2) We do need per-plane stride for some formats, in particular I420
>> which is a bit ambiguous otherwise (ie. is the stride of the U and V
>> planes half the stride as the Y plane, or the same?)
>>
>> 3) Maybe we need per-plane offsets, but I think this case could be
>> handled by just using one bo per plane, so left it out
>>
>> 4) bpp/depth are redundant w/ the pixel_format. Just in case, as a
>> future placeholder, and inspired by 'struct v4l2_pix_format', add a
>> priv field. Although making the field big enough to hold a pointer if
>> absolutely really needed.
>>
>> struct drm_mode_fb_cmd2 {
>> __u32 fb_id;
>> __u32 width, height;
>> __u32 pixel_format; /* fourcc code from videodev2.h */
>> __u64 priv; /* private data, depends on pixelformat */
>>
>> /* in case of planar formats, either one buffer object,
>> * or one buffer object per plane, is allowed. In the
>> * case per-plane bo's, the order is dictated by the
>> * fourcc.. ie. NV12 (http://fourcc.org/yuv.php#NV12)
>> * is described as:
>> *
>> * YUV 4:2:0 image with a plane of 8 bit Y samples
>> * followed by an interleaved U/V plane containing
>> * 8 bit 2x2 subsampled colour difference samples.
>> *
>> * So it would consist of Y as first buffer and UV as
>> * second buffer. In the case that only a single bo
>> * is used then buffer[1].handle should be zero. (But
>> * a plane specific pitch could still be specified.)
>> */
>> struct {
>> __u32 pitch;
>> /* driver specific handle */
>> __u32 handle;
>
> Why not just add a
> __u32 offset;
> __u32 rsvd;
> and call it a day. This thing is pretty big already, so that bloat doesn't
> matter that much. Maybe spec that buffer[0].offset must be zero. With that
> you can also do I420 with the following layout
> +-------+
> |YYYYYYY|
> |YYYYYYY|
> |YYYYYYY|
> |YYYYYYY|
> +---+---+
> |UUU|VVV|
> |UUU|VVV|
> +---+---+
>
> i.e. stride_U == stride_V, with their lines meshed into one line.
> -Daniel
>
I've no objection to an offset field.. I was mostly just trying to
avoid that we keep adding things until we get XvImageFormatValues..
We should either add an offset plus pad field as Daniel suggested, or
at least add a u64 reserved field which could be made into made into
an offset field later if needed.
OTOH, is the format you described *really* still I420?
BR,
-R
>> } buffer[16];
>> };
>>
>>
>> BR,
>> -R
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
> --
> Daniel Vetter
> Mail: daniel@ffwll.ch
> Mobile: +41 (0)79 365 57 48
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [PATCH 01/11] drm: add plane support
2011-10-25 19:41 ` Daniel Vetter
2011-10-25 20:14 ` Rob Clark
@ 2011-10-27 14:05 ` SW Kim
2011-10-31 11:40 ` Inki Dae
1 sibling, 1 reply; 41+ messages in thread
From: SW Kim @ 2011-10-27 14:05 UTC (permalink / raw)
To: intel-gfx
Daniel Vetter <daniel <at> ffwll.ch> writes:
[snip]
> > struct drm_mode_fb_cmd2 {
> > __u32 fb_id;
> > __u32 width, height;
> > __u32 pixel_format; /* fourcc code from videodev2.h */
> > __u64 priv; /* private data, depends on pixelformat */
> >
[snip]
> > struct {
> > __u32 pitch;
> > /* driver specific handle */
> > __u32 handle;
>
> Why not just add a
> __u32 offset;
> __u32 rsvd;
For normal NV12 format, I agree that just offset is enough.
But considering more specific format like NV12M, that has two separated memory
spaces, IMHO, it needs handle per each plane.
Each plane of NV12M has it own base address and space between these two memory
spaces can be used by others.
You can refer following link about NV12M used by V4L2.
http://linuxtv.org/downloads/v4l-dvb-apis/V4L2-PIX-FMT-NV12M.html
> and call it a day. This thing is pretty big already, so that bloat doesn't
> matter that much. Maybe spec that buffer[0].offset must be zero. With that
> you can also do I420 with the following layout
> +-------+
> |YYYYYYY|
> |YYYYYYY|
> |YYYYYYY|
> |YYYYYYY|
> +---+---+
> |UUU|VVV|
> |UUU|VVV|
> +---+---+
>
> i.e. stride_U == stride_V, with their lines meshed into one line.
> -Daniel
>
> > } buffer[16];
and just question, is there any meaning about buffer array size 16?
> > };
[snip]
Thanks and Regards,
- SW Kim
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [PATCH 01/11] drm: add plane support
2011-10-27 14:05 ` SW Kim
@ 2011-10-31 11:40 ` Inki Dae
2011-10-31 16:52 ` Jesse Barnes
0 siblings, 1 reply; 41+ messages in thread
From: Inki Dae @ 2011-10-31 11:40 UTC (permalink / raw)
To: intel-gfx
Hi, all.
SW Kim <devusr.opensw <at> gmail.com> writes:
>
> Daniel Vetter <daniel <at> ffwll.ch> writes:
>
> [snip]
>
> > > struct drm_mode_fb_cmd2 {
> > > __u32 fb_id;
> > > __u32 width, height;
> > > __u32 pixel_format; /* fourcc code from videodev2.h */
> > > __u64 priv; /* private data, depends on pixelformat */
> > >
>
> [snip]
>
> > > struct {
> > > __u32 pitch;
> > > /* driver specific handle */
> > > __u32 handle;
> >
> > Why not just add a
> > __u32 offset;
> > __u32 rsvd;
>
> For normal NV12 format, I agree that just offset is enough.
> But considering more specific format like NV12M, that has two separated
memory
> spaces, IMHO, it needs handle per each plane.
>
> Each plane of NV12M has it own base address and space between these two
memory
> spaces can be used by others.
>
> You can refer following link about NV12M used by V4L2.
> http://linuxtv.org/downloads/v4l-dvb-apis/V4L2-PIX-FMT-NV12M.html
>
> > and call it a day. This thing is pretty big already, so that bloat doesn't
> > matter that much. Maybe spec that buffer[0].offset must be zero. With that
> > you can also do I420 with the following layout
> > +-------+
> > |YYYYYYY|
> > |YYYYYYY|
> > |YYYYYYY|
> > |YYYYYYY|
> > +---+---+
> > |UUU|VVV|
> > |UUU|VVV|
> > +---+---+
> >
> > i.e. stride_U == stride_V, with their lines meshed into one line.
> > -Daniel
> >
> > > } buffer[16];
>
> and just question, is there any meaning about buffer array size 16?
>
> > > };
>
> [snip]
>
> Thanks and Regards,
> - SW Kim
>
I have a opinion for multi planer. before that, I'd like to mention some
considerations.
I think adding any variables such as offset or handle(as plane count) to
drm_mode_fb_cmd2 structure could occurs that in application point of view,
user could be confused because with the ways above, user needs to allocate
buffers as plane count(it depends on pixel format) and also user should know
buffer size according to pixel format. so I think it's good way that user sets
only pixel format and resolution(width, height) and then specific gem
framework allocates buffers according to pixel format as plane count and then
user sets the gem handle to drm_mode_fb_cmd2 structure. specific gem framework
could get all buffers through only the gem handle.
below is my simple idea.
1. user requests buffer allocation with pixel format and resolution through
gem framework.
2. gem framework checks pixel format.
3. specific gem framework allocates buffers as plane count according to the
pixel format. (please, know that gem framework provides just interface so
acctual implementation would be done at specific gem framework)
4. user gets the gem handle from gem framework.
5. user sets the gem handle to specific drm framebuffer through
drm_mode_addfb2 function.
6. user requests setcrtc with fb id and crtc id.
7. drm framework sets framebuffer(corresponding to fb id) to drm_mode_set.
8. crtc calls set_config callbacks to configure hardware.
9. specific crtc framework gets all buffers through framebuffer(actually, it
would be specific framebuffer)and sets them to overlay registers of hardware
appropriately.
like this, how about using framebuffer and gem framework instead of plane? I'd
be glad to give me your opinions.
Thank you,
Inki Dae.
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [PATCH 01/11] drm: add plane support
2011-10-31 11:40 ` Inki Dae
@ 2011-10-31 16:52 ` Jesse Barnes
2011-11-02 2:20 ` Inki Dae
0 siblings, 1 reply; 41+ messages in thread
From: Jesse Barnes @ 2011-10-31 16:52 UTC (permalink / raw)
To: Inki Dae; +Cc: intel-gfx
[-- Attachment #1.1: Type: text/plain, Size: 1853 bytes --]
On Mon, 31 Oct 2011 11:40:57 +0000 (UTC)
Inki Dae <daeinki@gmail.com> wrote:
> below is my simple idea.
> 1. user requests buffer allocation with pixel format and resolution through
> gem framework.
> 2. gem framework checks pixel format.
> 3. specific gem framework allocates buffers as plane count according to the
> pixel format. (please, know that gem framework provides just interface so
> acctual implementation would be done at specific gem framework)
> 4. user gets the gem handle from gem framework.
> 5. user sets the gem handle to specific drm framebuffer through
> drm_mode_addfb2 function.
> 6. user requests setcrtc with fb id and crtc id.
> 7. drm framework sets framebuffer(corresponding to fb id) to drm_mode_set.
> 8. crtc calls set_config callbacks to configure hardware.
> 9. specific crtc framework gets all buffers through framebuffer(actually, it
> would be specific framebuffer)and sets them to overlay registers of hardware
> appropriately.
>
>
> like this, how about using framebuffer and gem framework instead of plane? I'd
> be glad to give me your opinions.
I'm not opposed to pushing the multi-object stuff into GEM instead, but
I don't think step (9) will be enough to avoid having a separate plane
object. Say the user passes in 3 RGB buffers. How do you know which
one is the primary and which are overlays? Or are you saying the fb
would have that information as well? If so, it would be a little
harder to specify things like blending options or colorspace correction
on a per-plane basis...
But maybe I'm missing some part of things; do you have any patches to
illustrate what you mean? I can see how it might work, but I don't
know if it would be any simpler or cleaner than exposing plane objects.
Thanks,
--
Jesse Barnes, Intel Open Source Technology Center
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 01/11] drm: add plane support
2011-10-31 16:52 ` Jesse Barnes
@ 2011-11-02 2:20 ` Inki Dae
2011-11-02 15:57 ` Jesse Barnes
0 siblings, 1 reply; 41+ messages in thread
From: Inki Dae @ 2011-11-02 2:20 UTC (permalink / raw)
To: intel-gfx
Hi, Jesse.
Jesse Barnes <jbarnes <at> virtuousgeek.org> writes:
>
> On Mon, 31 Oct 2011 11:40:57 +0000 (UTC)
> Inki Dae <daeinki <at> gmail.com> wrote:
> > below is my simple idea.
> > 1. user requests buffer allocation with pixel format and resolution
through
> > gem framework.
> > 2. gem framework checks pixel format.
> > 3. specific gem framework allocates buffers as plane count according to
the
> > pixel format. (please, know that gem framework provides just interface so
> > acctual implementation would be done at specific gem framework)
> > 4. user gets the gem handle from gem framework.
> > 5. user sets the gem handle to specific drm framebuffer through
> > drm_mode_addfb2 function.
> > 6. user requests setcrtc with fb id and crtc id.
> > 7. drm framework sets framebuffer(corresponding to fb id) to drm_mode_set.
> > 8. crtc calls set_config callbacks to configure hardware.
> > 9. specific crtc framework gets all buffers through framebuffer(actually,
it
> > would be specific framebuffer)and sets them to overlay registers of
hardware
> > appropriately.
> >
> >
> > like this, how about using framebuffer and gem framework instead of plane?
I'd
> > be glad to give me your opinions.
>
> I'm not opposed to pushing the multi-object stuff into GEM instead, but
> I don't think step (9) will be enough to avoid having a separate plane
> object. Say the user passes in 3 RGB buffers. How do you know which
> one is the primary and which are overlays? Or are you saying the fb
> would have that information as well? If so, it would be a little
> harder to specify things like blending options or colorspace correction
> on a per-plane basis...
>
> But maybe I'm missing some part of things; do you have any patches to
> illustrate what you mean? I can see how it might work, but I don't
> know if it would be any simpler or cleaner than exposing plane objects.
>
> Thanks,
Sorry, there is my missing point. please, ignor step 6 ~ 9.
if user requests setplane then drm_mode_setplane function gets fb and crtc
object to update the overlay corresponding to plane id. at that time I think
we could know which overlay should be set and how many buffers does the
overlay has through specific framebuffer object if specific framebuffer has
gem object.
in our case, specific framebuffer has gem object. and I would try to implement
multi planer the way I mentioned if need and I will post the patch. this work
takes about a week. I think the way that user allocates buffers for multi
planer only with pixel format and resolution(width, height) would be good. but
there could be more good ways then this way.
please give me your opinion and advices.
Thank you,
Inki Dae.
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 01/11] drm: add plane support
2011-11-02 2:20 ` Inki Dae
@ 2011-11-02 15:57 ` Jesse Barnes
0 siblings, 0 replies; 41+ messages in thread
From: Jesse Barnes @ 2011-11-02 15:57 UTC (permalink / raw)
To: Inki Dae; +Cc: intel-gfx
[-- Attachment #1.1: Type: text/plain, Size: 1325 bytes --]
On Wed, 2 Nov 2011 02:20:58 +0000 (UTC)
Inki Dae <daeinki@gmail.com> wrote:
> Sorry, there is my missing point. please, ignor step 6 ~ 9.
> if user requests setplane then drm_mode_setplane function gets fb and crtc
> object to update the overlay corresponding to plane id. at that time I think
> we could know which overlay should be set and how many buffers does the
> overlay has through specific framebuffer object if specific framebuffer has
> gem object.
Right, that's the goal anyway.
> in our case, specific framebuffer has gem object. and I would try to implement
> multi planer the way I mentioned if need and I will post the patch. this work
> takes about a week. I think the way that user allocates buffers for multi
> planer only with pixel format and resolution(width, height) would be good. but
> there could be more good ways then this way.
Ok, that would help. Rob and Daniel also wanted the addfb2 ioctl to be
extended a bit more to handle planar formats and also to specify
surface offsets. Now that I have the X driver working well enough to
do clipping and multi-pipe, I'll update addfb2 and post an updated
patchset today. You can see if it will address what you're trying to
do with planar formats.
Thanks,
--
Jesse Barnes, Intel Open Source Technology Center
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 01/11] drm: add plane support
2011-10-25 9:46 ` [PATCH 01/11] drm: add plane support Jesse Barnes
` (2 preceding siblings ...)
2011-10-25 14:09 ` Jesse Barnes
@ 2011-10-26 5:40 ` Joonyoung Shim
2011-10-27 15:31 ` Jesse Barnes
3 siblings, 1 reply; 41+ messages in thread
From: Joonyoung Shim @ 2011-10-26 5:40 UTC (permalink / raw)
To: Jesse Barnes; +Cc: intel-gfx, dri-devel
10/25/2011 06:46 PM, Jesse Barnes 쓴 글:
[snip]
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 8020798..d7f03aa 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;
> @@ -278,6 +279,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
> @@ -536,6 +538,58 @@ 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);
> + int (*disable_plane)(struct drm_plane *plane);
> +};
How about add destroy() function and call it in
drm_mode_config_cleanup()?
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [PATCH 01/11] drm: add plane support
2011-10-26 5:40 ` Joonyoung Shim
@ 2011-10-27 15:31 ` Jesse Barnes
0 siblings, 0 replies; 41+ messages in thread
From: Jesse Barnes @ 2011-10-27 15:31 UTC (permalink / raw)
To: Joonyoung Shim; +Cc: intel-gfx, dri-devel
[-- Attachment #1.1: Type: text/plain, Size: 1637 bytes --]
On Wed, 26 Oct 2011 14:40:07 +0900
Joonyoung Shim <jy0922.shim@samsung.com> wrote:
> 10/25/2011 06:46 PM, Jesse Barnes 쓴 글:
>
> [snip]
> > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> > index 8020798..d7f03aa 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;
> > @@ -278,6 +279,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
> > @@ -536,6 +538,58 @@ 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);
> > + int (*disable_plane)(struct drm_plane *plane);
> > +};
>
> How about add destroy() function and call it in
> drm_mode_config_cleanup()?
Oh good idea; destroy will be needed for hot plug.
--
Jesse Barnes, Intel Open Source Technology Center
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 02/11] drm: add an fb creation ioctl that takes a pixel format
2011-10-25 9:46 DRM planes and new fb creation ioctl Jesse Barnes
2011-10-25 9:46 ` [PATCH 01/11] drm: add plane support Jesse Barnes
@ 2011-10-25 9:46 ` Jesse Barnes
2011-10-25 9:46 ` [PATCH 03/11] drm/i915: rename existing overlay support to "legacy" Jesse Barnes
` (11 subsequent siblings)
13 siblings, 0 replies; 41+ messages in thread
From: Jesse Barnes @ 2011-10-25 9:46 UTC (permalink / raw)
To: dri-devel; +Cc: intel-gfx
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/framebuffer.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 0e129b1..a30b9d4 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 f88a9b2..77c7293 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -806,13 +806,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 981b1f1..b1ae70b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6279,7 +6279,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;
@@ -6321,7 +6321,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));
@@ -6333,6 +6333,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);
}
@@ -7573,7 +7574,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;
@@ -7613,7 +7614,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 bd9a604..23c5622 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -359,7 +359,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 ddbabef..7a428a9 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;
@@ -124,7 +124,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 6cc17fb..ae803f8 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -1113,7 +1113,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;
@@ -1124,7 +1124,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 68820f5..227f595 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -644,7 +644,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 1a4c84c..2a1b802 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -839,7 +839,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/framebuffer.c b/drivers/staging/gma500/framebuffer.c
index ebfde13..85f47d5 100644
--- a/drivers/staging/gma500/framebuffer.c
+++ b/drivers/staging/gma500/framebuffer.c
@@ -487,7 +487,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 d7f03aa..9a7b2de 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>
@@ -246,6 +247,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;
@@ -615,7 +617,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);
};
@@ -833,6 +835,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 07711b0..34a0d22 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
@@ -262,6 +264,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] 41+ messages in thread* [PATCH 03/11] drm/i915: rename existing overlay support to "legacy"
2011-10-25 9:46 DRM planes and new fb creation ioctl Jesse Barnes
2011-10-25 9:46 ` [PATCH 01/11] drm: add plane support Jesse Barnes
2011-10-25 9:46 ` [PATCH 02/11] drm: add an fb creation ioctl that takes a pixel format Jesse Barnes
@ 2011-10-25 9:46 ` Jesse Barnes
2011-10-25 9:46 ` [PATCH 04/11] drm/i915: add SNB video sprite support Jesse Barnes
` (10 subsequent siblings)
13 siblings, 0 replies; 41+ messages in thread
From: Jesse Barnes @ 2011-10-25 9:46 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 8e95d66..b6d0bbc 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 06a37f4..b96c174 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -118,8 +118,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;
};
@@ -343,7 +343,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 */
@@ -1309,8 +1309,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 9ee2729..36f2837 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -998,7 +998,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 b1ae70b..e748338 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3180,7 +3180,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 23c5622..467fb4a 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;
@@ -370,7 +370,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 cdf17d4..6327da4 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;
@@ -782,7 +782,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;
@@ -792,14 +792,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;
@@ -842,9 +842,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;
@@ -858,7 +858,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;
@@ -867,30 +867,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;
@@ -906,7 +906,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;
@@ -930,7 +930,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;
@@ -1102,7 +1102,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;
@@ -1124,7 +1124,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);
@@ -1160,13 +1160,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;
@@ -1228,7 +1228,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;
@@ -1249,7 +1249,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);
@@ -1305,7 +1305,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;
@@ -1351,7 +1351,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;
@@ -1359,7 +1359,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))
@@ -1394,7 +1394,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;
@@ -1402,7 +1402,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;
@@ -1447,7 +1447,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_unpin_bo;
@@ -1455,7 +1455,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;
mutex_unlock(&dev->struct_mutex);
@@ -1492,7 +1492,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;
@@ -1500,7 +1500,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;
@@ -1514,7 +1514,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))
@@ -1522,12 +1522,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)
@@ -1544,12 +1544,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;
@@ -1559,7 +1559,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] 41+ messages in thread* [PATCH 04/11] drm/i915: add SNB video sprite support
2011-10-25 9:46 DRM planes and new fb creation ioctl Jesse Barnes
` (2 preceding siblings ...)
2011-10-25 9:46 ` [PATCH 03/11] drm/i915: rename existing overlay support to "legacy" Jesse Barnes
@ 2011-10-25 9:46 ` Jesse Barnes
2011-11-02 5:56 ` Inki Dae
2011-10-25 9:47 ` [PATCH 05/11] drm/i915: move pin & fence for plane past potential error paths Jesse Barnes
` (9 subsequent siblings)
13 siblings, 1 reply; 41+ messages in thread
From: Jesse Barnes @ 2011-10-25 9:46 UTC (permalink / raw)
To: dri-devel; +Cc: intel-gfx
The video sprites support various video surface formats natively and can
handle scaling as 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 | 25 +++-
drivers/gpu/drm/i915/intel_drv.h | 14 +++
drivers/gpu/drm/i915/intel_fb.c | 6 +
drivers/gpu/drm/i915/intel_overlay2.c | 203 +++++++++++++++++++++++++++++++++
6 files changed, 294 insertions(+), 7 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 5a09416..7b128d4 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2666,6 +2666,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 e748338..4f599ce 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -915,8 +915,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;
@@ -929,8 +929,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)
@@ -4439,7 +4437,8 @@ static void ironlake_update_wm(struct drm_device *dev)
ILK_LP0_CURSOR_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);
@@ -4453,7 +4452,8 @@ static void ironlake_update_wm(struct drm_device *dev)
ILK_LP0_CURSOR_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);
@@ -4587,6 +4587,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,
@@ -8692,7 +8697,7 @@ static void i915_disable_vga(struct drm_device *dev)
void intel_modeset_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- int i;
+ int i, ret;
drm_mode_config_init(dev);
@@ -8722,6 +8727,12 @@ 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)) {
+ ret = intel_plane_init(dev, i);
+ if (ret)
+ DRM_ERROR("plane %d init failed: %d\n",
+ i, ret);
+ }
}
/* 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 467fb4a..50b633b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -176,10 +176,18 @@ struct intel_crtc {
bool use_pll_a;
};
+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_HEADER_SIZE 5
@@ -289,6 +297,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 int 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,
@@ -379,6 +388,11 @@ 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);
extern void intel_write_eld(struct drm_encoder *encoder,
struct drm_display_mode *mode);
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..2e38b15
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_overlay2.c
@@ -0,0 +1,203 @@
+/*
+ * 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;
+
+ 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;
+ }
+
+ intel_plane->obj = obj;
+
+ 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 int
+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;
+ int ret = 0;
+
+ mutex_lock(&dev->struct_mutex);
+
+ ret = i915_gem_object_finish_gpu(intel_plane->obj);
+ if (ret)
+ goto out_unlock;
+ i915_gem_object_unpin(intel_plane->obj);
+
+out_unlock:
+ I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE);
+ I915_WRITE(DVSSURF(pipe), 0);
+ POSTING_READ(DVSSURF(pipe));
+
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+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,
+};
+
+int
+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 -ENODEV;
+ }
+
+ intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL);
+ if (!intel_plane)
+ return -ENOMEM;
+
+ 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));
+
+ return 0;
+}
+
--
1.7.4.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [PATCH 04/11] drm/i915: add SNB video sprite support
2011-10-25 9:46 ` [PATCH 04/11] drm/i915: add SNB video sprite support Jesse Barnes
@ 2011-11-02 5:56 ` Inki Dae
2011-11-02 15:58 ` Jesse Barnes
0 siblings, 1 reply; 41+ messages in thread
From: Inki Dae @ 2011-11-02 5:56 UTC (permalink / raw)
To: intel-gfx
Hi, Jesse.
drm_plane structure has format_types and format_conunt that they was set at
booting time. but they aren't used anywhere. at intel_update_plane(), I guess
they could be used to check if the format type(fb->pixel_format) from setplane
() is supported or not, comparing to plane->format_types[n]; otherwise, could
you please tell me about the purpose that format_types[] and format_count are
used?
Thank you,
Inki Dae.
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 04/11] drm/i915: add SNB video sprite support
2011-11-02 5:56 ` Inki Dae
@ 2011-11-02 15:58 ` Jesse Barnes
0 siblings, 0 replies; 41+ messages in thread
From: Jesse Barnes @ 2011-11-02 15:58 UTC (permalink / raw)
To: Inki Dae; +Cc: intel-gfx
[-- Attachment #1.1: Type: text/plain, Size: 871 bytes --]
On Wed, 2 Nov 2011 05:56:56 +0000 (UTC)
Inki Dae <daeinki@gmail.com> wrote:
> Hi, Jesse.
>
> drm_plane structure has format_types and format_conunt that they was set at
> booting time. but they aren't used anywhere. at intel_update_plane(), I guess
> they could be used to check if the format type(fb->pixel_format) from setplane
> () is supported or not, comparing to plane->format_types[n]; otherwise, could
> you please tell me about the purpose that format_types[] and format_count are
> used?
They're supposed to be used by application/library code to negotiate a
surface format to pass to the kernel.
So for example, libva could query the available surface formats then
choose an output format that it can decode to directly if possible, to
avoid any format conversion on the CPU.
--
Jesse Barnes, Intel Open Source Technology Center
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 05/11] drm/i915: move pin & fence for plane past potential error paths
2011-10-25 9:46 DRM planes and new fb creation ioctl Jesse Barnes
` (3 preceding siblings ...)
2011-10-25 9:46 ` [PATCH 04/11] drm/i915: add SNB video sprite support Jesse Barnes
@ 2011-10-25 9:47 ` Jesse Barnes
2011-10-25 9:47 ` [PATCH 06/11] drm/i915: plane teardown fixes Jesse Barnes
` (8 subsequent siblings)
13 siblings, 0 replies; 41+ messages in thread
From: Jesse Barnes @ 2011-10-25 9:47 UTC (permalink / raw)
To: dri-devel; +Cc: intel-gfx
This avoids the need to unpin on the error path.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/intel_overlay2.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_overlay2.c b/drivers/gpu/drm/i915/intel_overlay2.c
index 2e38b15..e583bd0 100644
--- a/drivers/gpu/drm/i915/intel_overlay2.c
+++ b/drivers/gpu/drm/i915/intel_overlay2.c
@@ -62,9 +62,6 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
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;
dvscntr = I915_READ(reg);
@@ -104,6 +101,10 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
goto out_unlock;
}
+ ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
+ if (ret)
+ goto out_unlock;
+
intel_plane->obj = obj;
dvscntr |= DVS_TILED;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH 06/11] drm/i915: plane teardown fixes
2011-10-25 9:46 DRM planes and new fb creation ioctl Jesse Barnes
` (4 preceding siblings ...)
2011-10-25 9:47 ` [PATCH 05/11] drm/i915: move pin & fence for plane past potential error paths Jesse Barnes
@ 2011-10-25 9:47 ` Jesse Barnes
2011-10-25 9:47 ` [PATCH 07/11] drm/i915: enable new overlay code on IVB too Jesse Barnes
` (7 subsequent siblings)
13 siblings, 0 replies; 41+ messages in thread
From: Jesse Barnes @ 2011-10-25 9:47 UTC (permalink / raw)
To: dri-devel; +Cc: intel-gfx
Make sure the object exists (it may not if the plane was previously disabled)
and make sure we zero it out in the disable path to avoid trouble later.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/intel_overlay2.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_overlay2.c b/drivers/gpu/drm/i915/intel_overlay2.c
index e583bd0..861e09e 100644
--- a/drivers/gpu/drm/i915/intel_overlay2.c
+++ b/drivers/gpu/drm/i915/intel_overlay2.c
@@ -149,12 +149,18 @@ intel_disable_plane(struct drm_plane *plane)
mutex_lock(&dev->struct_mutex);
+ if (!intel_plane->obj)
+ goto out_unlock;
+
ret = i915_gem_object_finish_gpu(intel_plane->obj);
if (ret)
goto out_unlock;
+
i915_gem_object_unpin(intel_plane->obj);
out_unlock:
+ intel_plane->obj = NULL;
+
I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE);
I915_WRITE(DVSSURF(pipe), 0);
POSTING_READ(DVSSURF(pipe));
--
1.7.4.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH 07/11] drm/i915: enable new overlay code on IVB too
2011-10-25 9:46 DRM planes and new fb creation ioctl Jesse Barnes
` (5 preceding siblings ...)
2011-10-25 9:47 ` [PATCH 06/11] drm/i915: plane teardown fixes Jesse Barnes
@ 2011-10-25 9:47 ` Jesse Barnes
2011-10-25 9:47 ` [PATCH 08/11] drm/i915: overlay watermark hack Jesse Barnes
` (6 subsequent siblings)
13 siblings, 0 replies; 41+ messages in thread
From: Jesse Barnes @ 2011-10-25 9:47 UTC (permalink / raw)
To: dri-devel; +Cc: intel-gfx
Split things out a little and add the IVB reg definitions.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/i915_reg.h | 59 ++++++++++++
drivers/gpu/drm/i915/intel_overlay2.c | 168 ++++++++++++++++++++++++++++++--
2 files changed, 216 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 7b128d4..71496b8 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2718,6 +2718,65 @@
#define DVSSCALE(pipe) _PIPE(pipe, _DVSASCALE, _DVSBSCALE)
#define DVSTILEOFF(pipe) _PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF)
+#define _SPRA_CTL 0x70280
+#define SPRITE_ENABLE (1<<31)
+#define SPRITE_GAMMA_ENABLE (1<<30)
+#define SPRITE_PIXFORMAT_MASK (7<<25)
+#define SPRITE_FORMAT_YUV422 (0<<25)
+#define SPRITE_FORMAT_RGBX101010 (1<<25)
+#define SPRITE_FORMAT_RGBX888 (2<<25)
+#define SPRITE_FORMAT_RGBX161616 (3<<25)
+#define SPRITE_FORMAT_YUV444 (4<<25)
+#define SPRITE_FORMAT_XBGR101010 (5<<25)
+#define SPRITE_CSC_ENABLE (1<<24)
+#define SPRITE_SOURCE_KEY (1<<22)
+#define SPRITE_RGB_ORDER_RGBX (1<<20) /* only for 888 and 161616 */
+#define SPRITE_YUV_TO_RGB_CSC_DISABLE (1<<19)
+#define SPRITE_YUV_CSC_FORMAT_BT709 (1<<18) /* 0 is BT601 */
+#define SPRITE_YUV_BYTE_ORDER_MASK (3<<16)
+#define SPRITE_YUV_ORDER_YUYV (0<<16)
+#define SPRITE_YUV_ORDER_UYVY (1<<16)
+#define SPRITE_YUV_ORDER_YVYU (2<<16)
+#define SPRITE_YUV_ORDER_VYUY (3<<16)
+#define SPRITE_TRICKLE_FEED_DISABLE (1<<14)
+#define SPRITE_INT_GAMMA_ENABLE (1<<13)
+#define SPRITE_TILED (1<<10)
+#define SPRITE_DEST_KEY (1<<2)
+#define _SPRA_STRIDE 0x70288
+#define _SPRA_POS 0x7028c
+#define _SPRA_SIZE 0x70290
+#define _SPRA_KEYVAL 0x70294
+#define _SPRA_KEYMSK 0x70298
+#define _SPRA_SURF 0x7029c
+#define _SPRA_KEYMAX 0x702a0
+#define _SPRA_TILEOFF 0x702a4
+#define _SPRA_SCALE 0x70304
+#define _SPRA_GAMC 0x70400
+
+#define _SPRB_CTL 0x70280
+#define _SPRB_STRIDE 0x70288
+#define _SPRB_POS 0x7028c
+#define _SPRB_SIZE 0x70290
+#define _SPRB_KEYVAL 0x70294
+#define _SPRB_KEYMSK 0x70298
+#define _SPRB_SURF 0x7029c
+#define _SPRB_KEYMAX 0x702a0
+#define _SPRB_TILEOFF 0x702a4
+#define _SPRB_SCALE 0x70304
+#define _SPRB_GAMC 0x70400
+
+#define SPRCTL(pipe) _PIPE(pipe, _SPRA_CTL, _SPRB_CTL)
+#define SPRSTRIDE(pipe) _PIPE(pipe, _SPRA_STRIDE, _SPRB_STRIDE)
+#define SPRPOS(pipe) _PIPE(pipe, _SPRA_POS, _SPRB_POS)
+#define SPRSIZE(pipe) _PIPE(pipe, _SPRA_SIZE, _SPRB_SIZE)
+#define SPRKEYVAL(pipe) _PIPE(pipe, _SPRA_KEYVAL, _SPRB_KEYVAL)
+#define SPRKEYMSK(pipe) _PIPE(pipe, _SPRA_KEYMSK, _SPRB_KEYMSK)
+#define SPRSURF(pipe) _PIPE(pipe, _SPRA_SURF, _SPRB_SURF)
+#define SPRKEYMAX(pipe) _PIPE(pipe, _SPRA_KEYMAX, _SPRB_KEYMAX)
+#define SPRTILEOFF(pipe) _PIPE(pipe, _SPRA_TILEOFF, _SPRB_TILEOFF)
+#define SPRSCALE(pipe) _PIPE(pipe, _SPRA_SCALE, _SPRB_SCALE)
+#define SPRGAMC(pipe) _PIPE(pipe, _SPRA_GAMC, _SPRB_GAMC)
+
/* VBIOS regs */
#define VGACNTRL 0x71400
# define VGA_DISP_DISABLE (1 << 31)
diff --git a/drivers/gpu/drm/i915/intel_overlay2.c b/drivers/gpu/drm/i915/intel_overlay2.c
index 861e09e..61b1a2f 100644
--- a/drivers/gpu/drm/i915/intel_overlay2.c
+++ b/drivers/gpu/drm/i915/intel_overlay2.c
@@ -36,7 +36,116 @@
#include "i915_drv.h"
static int
-intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
+ivb_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 sprctl;
+ u32 reg = SPRCTL(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);
+
+ sprctl = I915_READ(reg);
+
+ /* Mask out pixel format bits in case we change it */
+ sprctl &= ~(SPRITE_DEST_KEY | SPRITE_SOURCE_KEY);
+ sprctl &= ~SPRITE_PIXFORMAT_MASK;
+ sprctl &= ~SPRITE_RGB_ORDER_RGBX;
+ sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK;
+
+ switch (fb->pixel_format) {
+ case V4L2_PIX_FMT_BGR32:
+ sprctl |= SPRITE_FORMAT_RGBX888;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
+ break;
+ case V4L2_PIX_FMT_YVYU:
+ sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
+ break;
+ case V4L2_PIX_FMT_UYVY:
+ sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
+ break;
+ case V4L2_PIX_FMT_VYUY:
+ sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
+ break;
+ default:
+ ret = -EINVAL;
+ DRM_ERROR("bad pixel format\n");
+ goto out_unlock;
+ }
+
+ if (obj->tiling_mode != I915_TILING_X) {
+ DRM_ERROR("plane surfaces must be X tiled\n");
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
+ if (ret)
+ goto out_unlock;
+
+ intel_plane->obj = obj;
+
+ sprctl |= SPRITE_TILED;
+
+ /* must disable */
+ sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
+ sprctl |= SPRITE_ENABLE;
+
+ start = obj->gtt_offset;
+ offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
+
+ DRM_ERROR("enabling sprite, pos %d,%d, size %dx%d\n",
+ crtc_x, crtc_y, fb->width, fb->height);
+
+ I915_WRITE(SPRSTRIDE(pipe), fb->pitch);
+ I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
+ I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
+ I915_WRITE(SPRSIZE(pipe), (fb->height << 16) | fb->width);
+ I915_WRITE(SPRSCALE(pipe), 0);
+ I915_WRITE(reg, sprctl);
+ I915_WRITE(SPRSURF(pipe), start);
+ POSTING_READ(SPRSURF(pipe));
+
+ /* Adjust watermarks as needed */
+ I915_WRITE(WM1S_LP_ILK, 0x100);
+
+ /* 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 int
+snb_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,
@@ -66,6 +175,7 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
dvscntr = I915_READ(reg);
/* Mask out pixel format bits in case we change it */
+ dvscntr &= ~(DVS_DEST_KEY | DVS_SOURCE_KEY);
dvscntr &= ~DVS_PIXFORMAT_MASK;
dvscntr &= ~DVS_RGB_ORDER_RGBX;
dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK;
@@ -91,12 +201,12 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
break;
default:
ret = -EINVAL;
- DRM_DEBUG_KMS("bad pixel format\n");
+ DRM_ERROR("bad pixel format\n");
goto out_unlock;
}
if (obj->tiling_mode != I915_TILING_X) {
- DRM_DEBUG_KMS("plane surfaces must be X tiled\n");
+ DRM_ERROR("plane surfaces must be X tiled\n");
ret = -EINVAL;
goto out_unlock;
}
@@ -111,7 +221,6 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
/* must disable */
dvscntr |= DVS_TRICKLE_FEED_DISABLE;
- dvscntr |= DVS_DEST_KEY;
dvscntr |= DVS_ENABLE;
start = obj->gtt_offset;
@@ -139,7 +248,39 @@ out_unlock:
}
static int
-intel_disable_plane(struct drm_plane *plane)
+ivb_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;
+ int ret = 0;
+
+ mutex_lock(&dev->struct_mutex);
+
+ if (!intel_plane->obj)
+ goto out_unlock;
+#if 0
+ ret = i915_gem_object_finish_gpu(intel_plane->obj);
+ if (ret)
+ goto out_unlock;
+
+ i915_gem_object_unpin(intel_plane->obj);
+#endif
+out_unlock:
+ intel_plane->obj = NULL;
+
+ I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE);
+ I915_WRITE(SPRSURF(pipe), 0);
+ POSTING_READ(SPRSURF(pipe));
+
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+static int
+snb_disable_plane(struct drm_plane *plane)
{
struct drm_device *dev = plane->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -170,10 +311,7 @@ out_unlock:
return ret;
}
-static const struct drm_plane_funcs intel_plane_funcs = {
- .update_plane = intel_update_plane,
- .disable_plane = intel_disable_plane,
-};
+static struct drm_plane_funcs intel_plane_funcs;
static uint32_t snb_plane_formats[] = {
V4L2_PIX_FMT_BGR32,
@@ -190,8 +328,8 @@ 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");
+ if (!(IS_GEN6(dev) || IS_GEN7(dev))) {
+ DRM_ERROR("new plane code only for SNB+\n");
return -ENODEV;
}
@@ -199,6 +337,14 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe)
if (!intel_plane)
return -ENOMEM;
+ if (IS_GEN6(dev)) {
+ intel_plane_funcs.update_plane = snb_update_plane;
+ intel_plane_funcs.disable_plane = snb_disable_plane;
+ } else if (IS_GEN7(dev)) {
+ intel_plane_funcs.update_plane = ivb_update_plane;
+ intel_plane_funcs.disable_plane = ivb_disable_plane;
+ }
+
intel_plane->pipe = pipe;
possible_crtcs = (1 << pipe);
drm_plane_init(dev, &intel_plane->base, possible_crtcs,
--
1.7.4.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH 08/11] drm/i915: overlay watermark hack
2011-10-25 9:46 DRM planes and new fb creation ioctl Jesse Barnes
` (6 preceding siblings ...)
2011-10-25 9:47 ` [PATCH 07/11] drm/i915: enable new overlay code on IVB too Jesse Barnes
@ 2011-10-25 9:47 ` Jesse Barnes
2011-10-25 9:47 ` [PATCH 09/11] drm/i915: fix overlay fb object handling Jesse Barnes
` (5 subsequent siblings)
13 siblings, 0 replies; 41+ messages in thread
From: Jesse Barnes @ 2011-10-25 9:47 UTC (permalink / raw)
To: dri-devel; +Cc: intel-gfx
---
drivers/gpu/drm/i915/intel_display.c | 11 ++++-------
1 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 4f599ce..cd7e04d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4521,7 +4521,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);
@@ -4533,7 +4534,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);
@@ -4587,11 +4589,6 @@ 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,
--
1.7.4.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH 09/11] drm/i915: fix overlay fb object handling
2011-10-25 9:46 DRM planes and new fb creation ioctl Jesse Barnes
` (7 preceding siblings ...)
2011-10-25 9:47 ` [PATCH 08/11] drm/i915: overlay watermark hack Jesse Barnes
@ 2011-10-25 9:47 ` Jesse Barnes
2011-10-25 9:47 ` [PATCH 10/11] drm/i915: clamp sprite to viewable area Jesse Barnes
` (4 subsequent siblings)
13 siblings, 0 replies; 41+ messages in thread
From: Jesse Barnes @ 2011-10-25 9:47 UTC (permalink / raw)
To: dri-devel; +Cc: intel-gfx
To avoid the object being destroyed before our disable hook is called,
take a private reference on it. This will guarantee that we can still
access the object at disable time.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/intel_overlay2.c | 27 ++++++++++++++++++++++-----
1 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_overlay2.c b/drivers/gpu/drm/i915/intel_overlay2.c
index 61b1a2f..8876857 100644
--- a/drivers/gpu/drm/i915/intel_overlay2.c
+++ b/drivers/gpu/drm/i915/intel_overlay2.c
@@ -35,6 +35,18 @@
#include "i915_drm.h"
#include "i915_drv.h"
+/*
+ * Note on refcounting:
+ * When the user creates an fb for the GEM object to be used for the plane,
+ * a ref is taken on the object. However, if the application exits before
+ * disabling the plane, the DRM close handling will free all the fbs and
+ * unless we take a ref on the object, it will be destroyed before the
+ * plane disable hook is called, causing obvious trouble with our efforts
+ * to look up and unpin the object. So we take a ref after we move the
+ * object to the display plane so it won't be destroyed until our disable
+ * hook is called and we drop our private reference.
+ */
+
static int
ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
@@ -106,6 +118,8 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
if (ret)
goto out_unlock;
+ drm_gem_object_reference(&obj->base);
+
intel_plane->obj = obj;
sprctl |= SPRITE_TILED;
@@ -117,9 +131,6 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
start = obj->gtt_offset;
offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
- DRM_ERROR("enabling sprite, pos %d,%d, size %dx%d\n",
- crtc_x, crtc_y, fb->width, fb->height);
-
I915_WRITE(SPRSTRIDE(pipe), fb->pitch);
I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
@@ -215,6 +226,8 @@ snb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
if (ret)
goto out_unlock;
+ drm_gem_object_reference(&obj->base);
+
intel_plane->obj = obj;
dvscntr |= DVS_TILED;
@@ -260,13 +273,15 @@ ivb_disable_plane(struct drm_plane *plane)
if (!intel_plane->obj)
goto out_unlock;
-#if 0
+
ret = i915_gem_object_finish_gpu(intel_plane->obj);
if (ret)
goto out_unlock;
i915_gem_object_unpin(intel_plane->obj);
-#endif
+
+ drm_gem_object_reference(&intel_plane->obj->base);
+
out_unlock:
intel_plane->obj = NULL;
@@ -299,6 +314,8 @@ snb_disable_plane(struct drm_plane *plane)
i915_gem_object_unpin(intel_plane->obj);
+ drm_gem_object_reference(&intel_plane->obj->base);
+
out_unlock:
intel_plane->obj = NULL;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH 10/11] drm/i915: clamp sprite to viewable area
2011-10-25 9:46 DRM planes and new fb creation ioctl Jesse Barnes
` (8 preceding siblings ...)
2011-10-25 9:47 ` [PATCH 09/11] drm/i915: fix overlay fb object handling Jesse Barnes
@ 2011-10-25 9:47 ` Jesse Barnes
2011-10-25 9:47 ` [PATCH 11/11] drm/i915: add sprite scaling support Jesse Barnes
` (3 subsequent siblings)
13 siblings, 0 replies; 41+ messages in thread
From: Jesse Barnes @ 2011-10-25 9:47 UTC (permalink / raw)
To: dri-devel; +Cc: intel-gfx
If we try to scan a sprite outside of the parent CRTC area, the display
engine will underflow and potentially blank the framebuffer. So clamp
the position + size to the viewable area.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/intel_overlay2.c | 12 +++++++++++-
1 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_overlay2.c b/drivers/gpu/drm/i915/intel_overlay2.c
index 8876857..90c4f59 100644
--- a/drivers/gpu/drm/i915/intel_overlay2.c
+++ b/drivers/gpu/drm/i915/intel_overlay2.c
@@ -173,6 +173,7 @@ snb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
u32 reg = DVSCNTR(pipe);
int ret = 0;
int x = src_x >> 16, y = src_y >> 16;
+ int active_w = crtc->mode.hdisplay, active_h = crtc->mode.vdisplay;
assert_pipe_enabled(dev_priv, pipe);
@@ -181,6 +182,15 @@ snb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
old_obj = intel_plane->obj;
+ if (crtc_x >= active_w || crtc_y >= active_h)
+ return -EINVAL;
+
+ /* Clamp the width & height into the visible area */
+ if (crtc_x + crtc_w > active_w)
+ crtc_w = active_w - crtc_x - 1;
+ if (crtc_y + crtc_h > active_h)
+ crtc_h = active_h - crtc_y - 1;
+
mutex_lock(&dev->struct_mutex);
dvscntr = I915_READ(reg);
@@ -242,7 +252,7 @@ snb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
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(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
I915_WRITE(DVSSCALE(pipe), 0);
I915_WRITE(reg, dvscntr);
I915_WRITE(DVSSURF(pipe), start);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH 11/11] drm/i915: add sprite scaling support
2011-10-25 9:46 DRM planes and new fb creation ioctl Jesse Barnes
` (9 preceding siblings ...)
2011-10-25 9:47 ` [PATCH 10/11] drm/i915: clamp sprite to viewable area Jesse Barnes
@ 2011-10-25 9:47 ` Jesse Barnes
2011-10-25 10:47 ` DRM planes and new fb creation ioctl Joonyoung Shim
` (2 subsequent siblings)
13 siblings, 0 replies; 41+ messages in thread
From: Jesse Barnes @ 2011-10-25 9:47 UTC (permalink / raw)
To: dri-devel; +Cc: intel-gfx
If the source and destination size are different, try to scale the sprite on the
corresponding CRTC.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/i915_reg.h | 5 +++++
drivers/gpu/drm/i915/intel_overlay2.c | 14 ++++++++++++--
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 71496b8..8cbda0b 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2695,6 +2695,11 @@
#define _DVSATILEOFF 0x721a4
#define _DVSASURFLIVE 0x721ac
#define _DVSASCALE 0x72204
+#define DVS_SCALE_ENABLE (1<<31)
+#define DVS_FILTER_MASK (3<<29)
+#define DVS_FILTER_MEDIUM (0<<29)
+#define DVS_FILTER_ENHANCING (1<<29)
+#define DVS_FILTER_SOFTENING (2<<29)
#define _DVSAGAMC 0x72300
#define _DVSBCNTR 0x73180
diff --git a/drivers/gpu/drm/i915/intel_overlay2.c b/drivers/gpu/drm/i915/intel_overlay2.c
index 90c4f59..61594b6 100644
--- a/drivers/gpu/drm/i915/intel_overlay2.c
+++ b/drivers/gpu/drm/i915/intel_overlay2.c
@@ -169,7 +169,7 @@ snb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_i915_gem_object *obj, *old_obj;
int pipe = intel_plane->pipe;
unsigned long start, offset;
- u32 dvscntr;
+ u32 dvscntr, dvsscale = 0;
u32 reg = DVSCNTR(pipe);
int ret = 0;
int x = src_x >> 16, y = src_y >> 16;
@@ -185,6 +185,13 @@ snb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
if (crtc_x >= active_w || crtc_y >= active_h)
return -EINVAL;
+ /*
+ * We can take a larger source and scale it down, but
+ * only so much... 16x is the max on SNB.
+ */
+ if (((src_w * src_h) / (crtc_w * crtc_h)) > 16)
+ return -EINVAL;
+
/* Clamp the width & height into the visible area */
if (crtc_x + crtc_w > active_w)
crtc_w = active_w - crtc_x - 1;
@@ -249,11 +256,14 @@ snb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
start = obj->gtt_offset;
offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
+ if (crtc_w != src_w || crtc_h != src_h)
+ dvsscale = DVS_SCALE_ENABLE | (src_h << 16) | src_w;
+
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), (crtc_h << 16) | crtc_w);
- I915_WRITE(DVSSCALE(pipe), 0);
+ I915_WRITE(DVSSCALE(pipe), dvsscale);
I915_WRITE(reg, dvscntr);
I915_WRITE(DVSSURF(pipe), start);
POSTING_READ(DVSSURF(pipe));
--
1.7.4.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: DRM planes and new fb creation ioctl
2011-10-25 9:46 DRM planes and new fb creation ioctl Jesse Barnes
` (10 preceding siblings ...)
2011-10-25 9:47 ` [PATCH 11/11] drm/i915: add sprite scaling support Jesse Barnes
@ 2011-10-25 10:47 ` Joonyoung Shim
2011-10-25 11:13 ` Jesse Barnes
2011-10-25 11:20 ` Jesse Barnes
2011-10-25 11:22 ` [PATCH] drm/i915: add SNB video sprite support Jesse Barnes
13 siblings, 1 reply; 41+ messages in thread
From: Joonyoung Shim @ 2011-10-25 10:47 UTC (permalink / raw)
To: Jesse Barnes; +Cc: intel-gfx, 박경민, dri-devel
Hi, Jesse.
Thanks for posting.
10/25/2011 06:46 PM, Jesse Barnes 쓴 글:
> I've given up waiting for someone to implement support for these ioctls
> on another platform before they're merged, but I have received a lot of
> feedback on the interfaces, and it sounds like they're ok. I've also
> fixed all the remaining issues I'm aware of on SNB platforms and things
> are working well, so I'm just going to push them out. (Note IVB support
> is still missing a few bits for scaling and such; I'll fix those up when
> I get back home and can test on IVB again.)
>
> One change you may notice from the last set is that I've removed the
> 'zpos' parameter. Plane blending and z ordering is very chipset
> specific (it even varies between Intel chipsets), so exposing it through
> a device specific ioctl is probably a better plan.
But i think zpos is essential parameter of plane. If plane doesn't
support it, drm driver cannot know user wants to use which overlay,
so i wonder what it meant DRM_IOCTL_MODE_SETPLANE zpos is absent .
If use device specific ioctl, should implement device specific ioctl for
DRM_IOCTL_MODE_SETPLANE?
> By default, planes
> should just overlay the primary plane; a device specific ioctl (none
> available yet, but I have some planned for i915) can provide more
> flexibility.
Could you explain what is the primary plane? Is it same as the overlay
handled by crtc? It confuses a bit when one overlay is handled by crtc
and plane at the same time.
>
> To recap previous posts, this patchset provides a few new interfaces:
> - addfb2 - a new FB creation ioctl that lets you specify a surface
> format, as defined by a fourcc code from the video4linux headers
> (libdrm will wrap these in DRM_ macros for portability)
> - planes - ioctls for fetching plane info and attaching an fb to a
> plane; note there's no separate flip ioctl for planes, just use
> setplane to update the fb
>
> The testdisplay.c program in intel-gpu-tools has support for testing
> these interfaces, and I'll be fixing up and pushing the
> xf86-video-intel support soon as well, so you can use either as a
> reference for how the new interfaces work.
>
> Thanks,
> Jesse
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: DRM planes and new fb creation ioctl
2011-10-25 10:47 ` DRM planes and new fb creation ioctl Joonyoung Shim
@ 2011-10-25 11:13 ` Jesse Barnes
2011-10-26 1:04 ` Joonyoung Shim
0 siblings, 1 reply; 41+ messages in thread
From: Jesse Barnes @ 2011-10-25 11:13 UTC (permalink / raw)
To: Joonyoung Shim; +Cc: intel-gfx, 박경민, dri-devel
On Tue, 25 Oct 2011 19:47:13 +0900
Joonyoung Shim <jy0922.shim@samsung.com> wrote:
> 10/25/2011 06:46 PM, Jesse Barnes 쓴 글:
> > I've given up waiting for someone to implement support for these
> > ioctls on another platform before they're merged, but I have
> > received a lot of feedback on the interfaces, and it sounds like
> > they're ok. I've also fixed all the remaining issues I'm aware of
> > on SNB platforms and things are working well, so I'm just going to
> > push them out. (Note IVB support is still missing a few bits for
> > scaling and such; I'll fix those up when I get back home and can
> > test on IVB again.)
> >
> > One change you may notice from the last set is that I've removed the
> > 'zpos' parameter. Plane blending and z ordering is very chipset
> > specific (it even varies between Intel chipsets), so exposing it
> > through a device specific ioctl is probably a better plan.
>
> But i think zpos is essential parameter of plane. If plane doesn't
> support it, drm driver cannot know user wants to use which overlay,
> so i wonder what it meant DRM_IOCTL_MODE_SETPLANE zpos is absent .
Setplane is just for attaching a new fb. The order, keying, or
whatever else your plane blender can support can be set with a device
specific ioctl before or after the setplane call (probably before to
avoid any flashing or bad frames).
> If use device specific ioctl, should implement device specific ioctl
> for DRM_IOCTL_MODE_SETPLANE?
You could if you needed, but I don't think it's strictly necessary.
> > By default, planes
> > should just overlay the primary plane; a device specific ioctl (none
> > available yet, but I have some planned for i915) can provide more
> > flexibility.
>
> Could you explain what is the primary plane? Is it same as the overlay
> handled by crtc? It confuses a bit when one overlay is handled by crtc
> and plane at the same time.
Yeah, it is a little confusing. When I refer to the primary, I'm
referring to the plane bound to the CRTC. I'm fine if someone wants to
break that out, I think it would make sense. I just didn't want to
write the compat code that would be required for that scheme. :) But
these patches definitely don't preclude it, and I don't think these
interfaces will need changes if we ever move to a pipe/plane split at
the userland level.
Thanks,
Jesse
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: DRM planes and new fb creation ioctl
2011-10-25 11:13 ` Jesse Barnes
@ 2011-10-26 1:04 ` Joonyoung Shim
0 siblings, 0 replies; 41+ messages in thread
From: Joonyoung Shim @ 2011-10-26 1:04 UTC (permalink / raw)
To: Jesse Barnes; +Cc: intel-gfx, 박경민, dri-devel
10/25/2011 08:13 PM, Jesse Barnes 쓴 글:
> On Tue, 25 Oct 2011 19:47:13 +0900
> Joonyoung Shim<jy0922.shim@samsung.com> wrote:
>> 10/25/2011 06:46 PM, Jesse Barnes 쓴 글:
>>> I've given up waiting for someone to implement support for these
>>> ioctls on another platform before they're merged, but I have
>>> received a lot of feedback on the interfaces, and it sounds like
>>> they're ok. I've also fixed all the remaining issues I'm aware of
>>> on SNB platforms and things are working well, so I'm just going to
>>> push them out. (Note IVB support is still missing a few bits for
>>> scaling and such; I'll fix those up when I get back home and can
>>> test on IVB again.)
>>>
>>> One change you may notice from the last set is that I've removed the
>>> 'zpos' parameter. Plane blending and z ordering is very chipset
>>> specific (it even varies between Intel chipsets), so exposing it
>>> through a device specific ioctl is probably a better plan.
>> But i think zpos is essential parameter of plane. If plane doesn't
>> support it, drm driver cannot know user wants to use which overlay,
>> so i wonder what it meant DRM_IOCTL_MODE_SETPLANE zpos is absent .
> Setplane is just for attaching a new fb. The order, keying, or
> whatever else your plane blender can support can be set with a device
> specific ioctl before or after the setplane call (probably before to
> avoid any flashing or bad frames).
>
OK, i see.
Thanks.
>> If use device specific ioctl, should implement device specific ioctl
>> for DRM_IOCTL_MODE_SETPLANE?
> You could if you needed, but I don't think it's strictly necessary.
>
>>> By default, planes
>>> should just overlay the primary plane; a device specific ioctl (none
>>> available yet, but I have some planned for i915) can provide more
>>> flexibility.
>> Could you explain what is the primary plane? Is it same as the overlay
>> handled by crtc? It confuses a bit when one overlay is handled by crtc
>> and plane at the same time.
> Yeah, it is a little confusing. When I refer to the primary, I'm
> referring to the plane bound to the CRTC. I'm fine if someone wants to
> break that out, I think it would make sense. I just didn't want to
> write the compat code that would be required for that scheme. :) But
> these patches definitely don't preclude it, and I don't think these
> interfaces will need changes if we ever move to a pipe/plane split at
> the userland level.
Could you have the policy about fb of overlay? For example, user
attaches the fb of plane to the overlay already using by CRTC, then
output of overlay will be changed to the fb of plane from fb of CRTC.
And if user detaches the fb of plane, the overlay again should output
the fb of CRTC? or just be disabled?
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: DRM planes and new fb creation ioctl
2011-10-25 9:46 DRM planes and new fb creation ioctl Jesse Barnes
` (11 preceding siblings ...)
2011-10-25 10:47 ` DRM planes and new fb creation ioctl Joonyoung Shim
@ 2011-10-25 11:20 ` Jesse Barnes
2011-10-25 11:22 ` [PATCH] drm/i915: add SNB video sprite support Jesse Barnes
13 siblings, 0 replies; 41+ messages in thread
From: Jesse Barnes @ 2011-10-25 11:20 UTC (permalink / raw)
Cc: intel-gfx, dri-devel
On Tue, 25 Oct 2011 11:46:55 +0200
Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> I've given up waiting for someone to implement support for these
> ioctls on another platform before they're merged, but I have received
> a lot of feedback on the interfaces, and it sounds like they're ok.
> I've also fixed all the remaining issues I'm aware of on SNB
> platforms and things are working well, so I'm just going to push them
> out. (Note IVB support is still missing a few bits for scaling and
> such; I'll fix those up when I get back home and can test on IVB
> again.)
Btw, ignore 3-11, I forgot to collapse them when I collapsed the core
fixes. Updated intel specific patch will be coming shortly (with a fix
for the unpin vs disable ordering danvet pointed out).
Jesse
^ permalink raw reply [flat|nested] 41+ messages in thread* [PATCH] drm/i915: add SNB video sprite support
2011-10-25 9:46 DRM planes and new fb creation ioctl Jesse Barnes
` (12 preceding siblings ...)
2011-10-25 11:20 ` Jesse Barnes
@ 2011-10-25 11:22 ` Jesse Barnes
2011-10-25 11:30 ` Jesse Barnes
2011-11-01 14:11 ` Lan, Hai
13 siblings, 2 replies; 41+ messages in thread
From: Jesse Barnes @ 2011-10-25 11:22 UTC (permalink / raw)
Cc: intel-gfx, dri-devel
The video sprites support various video surface formats natively and can
handle scaling as well. So add support for them using the new DRM core
overlay support functions.
v2: collapse patches and fix plane disable vs unpin ordering bug
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/Makefile | 1 +
drivers/gpu/drm/i915/i915_reg.h | 116 ++++++++++
drivers/gpu/drm/i915/intel_display.c | 26 ++-
drivers/gpu/drm/i915/intel_drv.h | 14 ++
drivers/gpu/drm/i915/intel_fb.c | 6 +
drivers/gpu/drm/i915/intel_overlay2.c | 393 +++++++++++++++++++++++++++++++++
6 files changed, 547 insertions(+), 9 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 5a09416..8cbda0b 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2666,6 +2666,122 @@
#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 DVS_SCALE_ENABLE (1<<31)
+#define DVS_FILTER_MASK (3<<29)
+#define DVS_FILTER_MEDIUM (0<<29)
+#define DVS_FILTER_ENHANCING (1<<29)
+#define DVS_FILTER_SOFTENING (2<<29)
+#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)
+
+#define _SPRA_CTL 0x70280
+#define SPRITE_ENABLE (1<<31)
+#define SPRITE_GAMMA_ENABLE (1<<30)
+#define SPRITE_PIXFORMAT_MASK (7<<25)
+#define SPRITE_FORMAT_YUV422 (0<<25)
+#define SPRITE_FORMAT_RGBX101010 (1<<25)
+#define SPRITE_FORMAT_RGBX888 (2<<25)
+#define SPRITE_FORMAT_RGBX161616 (3<<25)
+#define SPRITE_FORMAT_YUV444 (4<<25)
+#define SPRITE_FORMAT_XBGR101010 (5<<25)
+#define SPRITE_CSC_ENABLE (1<<24)
+#define SPRITE_SOURCE_KEY (1<<22)
+#define SPRITE_RGB_ORDER_RGBX (1<<20) /* only for 888 and 161616 */
+#define SPRITE_YUV_TO_RGB_CSC_DISABLE (1<<19)
+#define SPRITE_YUV_CSC_FORMAT_BT709 (1<<18) /* 0 is BT601 */
+#define SPRITE_YUV_BYTE_ORDER_MASK (3<<16)
+#define SPRITE_YUV_ORDER_YUYV (0<<16)
+#define SPRITE_YUV_ORDER_UYVY (1<<16)
+#define SPRITE_YUV_ORDER_YVYU (2<<16)
+#define SPRITE_YUV_ORDER_VYUY (3<<16)
+#define SPRITE_TRICKLE_FEED_DISABLE (1<<14)
+#define SPRITE_INT_GAMMA_ENABLE (1<<13)
+#define SPRITE_TILED (1<<10)
+#define SPRITE_DEST_KEY (1<<2)
+#define _SPRA_STRIDE 0x70288
+#define _SPRA_POS 0x7028c
+#define _SPRA_SIZE 0x70290
+#define _SPRA_KEYVAL 0x70294
+#define _SPRA_KEYMSK 0x70298
+#define _SPRA_SURF 0x7029c
+#define _SPRA_KEYMAX 0x702a0
+#define _SPRA_TILEOFF 0x702a4
+#define _SPRA_SCALE 0x70304
+#define _SPRA_GAMC 0x70400
+
+#define _SPRB_CTL 0x70280
+#define _SPRB_STRIDE 0x70288
+#define _SPRB_POS 0x7028c
+#define _SPRB_SIZE 0x70290
+#define _SPRB_KEYVAL 0x70294
+#define _SPRB_KEYMSK 0x70298
+#define _SPRB_SURF 0x7029c
+#define _SPRB_KEYMAX 0x702a0
+#define _SPRB_TILEOFF 0x702a4
+#define _SPRB_SCALE 0x70304
+#define _SPRB_GAMC 0x70400
+
+#define SPRCTL(pipe) _PIPE(pipe, _SPRA_CTL, _SPRB_CTL)
+#define SPRSTRIDE(pipe) _PIPE(pipe, _SPRA_STRIDE, _SPRB_STRIDE)
+#define SPRPOS(pipe) _PIPE(pipe, _SPRA_POS, _SPRB_POS)
+#define SPRSIZE(pipe) _PIPE(pipe, _SPRA_SIZE, _SPRB_SIZE)
+#define SPRKEYVAL(pipe) _PIPE(pipe, _SPRA_KEYVAL, _SPRB_KEYVAL)
+#define SPRKEYMSK(pipe) _PIPE(pipe, _SPRA_KEYMSK, _SPRB_KEYMSK)
+#define SPRSURF(pipe) _PIPE(pipe, _SPRA_SURF, _SPRB_SURF)
+#define SPRKEYMAX(pipe) _PIPE(pipe, _SPRA_KEYMAX, _SPRB_KEYMAX)
+#define SPRTILEOFF(pipe) _PIPE(pipe, _SPRA_TILEOFF, _SPRB_TILEOFF)
+#define SPRSCALE(pipe) _PIPE(pipe, _SPRA_SCALE, _SPRB_SCALE)
+#define SPRGAMC(pipe) _PIPE(pipe, _SPRA_GAMC, _SPRB_GAMC)
+
/* 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 e748338..cd7e04d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -915,8 +915,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;
@@ -929,8 +929,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)
@@ -4439,7 +4437,8 @@ static void ironlake_update_wm(struct drm_device *dev)
ILK_LP0_CURSOR_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);
@@ -4453,7 +4452,8 @@ static void ironlake_update_wm(struct drm_device *dev)
ILK_LP0_CURSOR_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);
@@ -4521,7 +4521,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);
@@ -4533,7 +4534,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);
@@ -8692,7 +8694,7 @@ static void i915_disable_vga(struct drm_device *dev)
void intel_modeset_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- int i;
+ int i, ret;
drm_mode_config_init(dev);
@@ -8722,6 +8724,12 @@ 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)) {
+ ret = intel_plane_init(dev, i);
+ if (ret)
+ DRM_ERROR("plane %d init failed: %d\n",
+ i, ret);
+ }
}
/* 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 467fb4a..50b633b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -176,10 +176,18 @@ struct intel_crtc {
bool use_pll_a;
};
+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_HEADER_SIZE 5
@@ -289,6 +297,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 int 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,
@@ -379,6 +388,11 @@ 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);
extern void intel_write_eld(struct drm_encoder *encoder,
struct drm_display_mode *mode);
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..61594b6
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_overlay2.c
@@ -0,0 +1,393 @@
+/*
+ * 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"
+
+/*
+ * Note on refcounting:
+ * When the user creates an fb for the GEM object to be used for the plane,
+ * a ref is taken on the object. However, if the application exits before
+ * disabling the plane, the DRM close handling will free all the fbs and
+ * unless we take a ref on the object, it will be destroyed before the
+ * plane disable hook is called, causing obvious trouble with our efforts
+ * to look up and unpin the object. So we take a ref after we move the
+ * object to the display plane so it won't be destroyed until our disable
+ * hook is called and we drop our private reference.
+ */
+
+static int
+ivb_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 sprctl;
+ u32 reg = SPRCTL(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);
+
+ sprctl = I915_READ(reg);
+
+ /* Mask out pixel format bits in case we change it */
+ sprctl &= ~(SPRITE_DEST_KEY | SPRITE_SOURCE_KEY);
+ sprctl &= ~SPRITE_PIXFORMAT_MASK;
+ sprctl &= ~SPRITE_RGB_ORDER_RGBX;
+ sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK;
+
+ switch (fb->pixel_format) {
+ case V4L2_PIX_FMT_BGR32:
+ sprctl |= SPRITE_FORMAT_RGBX888;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
+ break;
+ case V4L2_PIX_FMT_YVYU:
+ sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
+ break;
+ case V4L2_PIX_FMT_UYVY:
+ sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
+ break;
+ case V4L2_PIX_FMT_VYUY:
+ sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
+ break;
+ default:
+ ret = -EINVAL;
+ DRM_ERROR("bad pixel format\n");
+ goto out_unlock;
+ }
+
+ if (obj->tiling_mode != I915_TILING_X) {
+ DRM_ERROR("plane surfaces must be X tiled\n");
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
+ if (ret)
+ goto out_unlock;
+
+ drm_gem_object_reference(&obj->base);
+
+ intel_plane->obj = obj;
+
+ sprctl |= SPRITE_TILED;
+
+ /* must disable */
+ sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
+ sprctl |= SPRITE_ENABLE;
+
+ start = obj->gtt_offset;
+ offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
+
+ I915_WRITE(SPRSTRIDE(pipe), fb->pitch);
+ I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
+ I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
+ I915_WRITE(SPRSIZE(pipe), (fb->height << 16) | fb->width);
+ I915_WRITE(SPRSCALE(pipe), 0);
+ I915_WRITE(reg, sprctl);
+ I915_WRITE(SPRSURF(pipe), start);
+ POSTING_READ(SPRSURF(pipe));
+
+ /* Adjust watermarks as needed */
+ I915_WRITE(WM1S_LP_ILK, 0x100);
+
+ /* 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 int
+snb_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, dvsscale = 0;
+ u32 reg = DVSCNTR(pipe);
+ int ret = 0;
+ int x = src_x >> 16, y = src_y >> 16;
+ int active_w = crtc->mode.hdisplay, active_h = crtc->mode.vdisplay;
+
+ assert_pipe_enabled(dev_priv, pipe);
+
+ intel_fb = to_intel_framebuffer(fb);
+ obj = intel_fb->obj;
+
+ old_obj = intel_plane->obj;
+
+ if (crtc_x >= active_w || crtc_y >= active_h)
+ return -EINVAL;
+
+ /*
+ * We can take a larger source and scale it down, but
+ * only so much... 16x is the max on SNB.
+ */
+ if (((src_w * src_h) / (crtc_w * crtc_h)) > 16)
+ return -EINVAL;
+
+ /* Clamp the width & height into the visible area */
+ if (crtc_x + crtc_w > active_w)
+ crtc_w = active_w - crtc_x - 1;
+ if (crtc_y + crtc_h > active_h)
+ crtc_h = active_h - crtc_y - 1;
+
+ mutex_lock(&dev->struct_mutex);
+
+ dvscntr = I915_READ(reg);
+
+ /* Mask out pixel format bits in case we change it */
+ dvscntr &= ~(DVS_DEST_KEY | DVS_SOURCE_KEY);
+ 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_ERROR("bad pixel format\n");
+ goto out_unlock;
+ }
+
+ if (obj->tiling_mode != I915_TILING_X) {
+ DRM_ERROR("plane surfaces must be X tiled\n");
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
+ if (ret)
+ goto out_unlock;
+
+ drm_gem_object_reference(&obj->base);
+
+ intel_plane->obj = obj;
+
+ dvscntr |= DVS_TILED;
+
+ /* must disable */
+ dvscntr |= DVS_TRICKLE_FEED_DISABLE;
+ dvscntr |= DVS_ENABLE;
+
+ start = obj->gtt_offset;
+ offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
+
+ if (crtc_w != src_w || crtc_h != src_h)
+ dvsscale = DVS_SCALE_ENABLE | (src_h << 16) | src_w;
+
+ 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), (crtc_h << 16) | crtc_w);
+ I915_WRITE(DVSSCALE(pipe), dvsscale);
+ 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 int
+ivb_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;
+ int ret = 0;
+
+ mutex_lock(&dev->struct_mutex);
+
+ if (!intel_plane->obj)
+ goto out_unlock;
+
+ ret = i915_gem_object_finish_gpu(intel_plane->obj);
+ if (ret)
+ goto out_unlock;
+
+ i915_gem_object_unpin(intel_plane->obj);
+
+ drm_gem_object_reference(&intel_plane->obj->base);
+
+out_unlock:
+ intel_plane->obj = NULL;
+
+ I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE);
+ I915_WRITE(SPRSURF(pipe), 0);
+ POSTING_READ(SPRSURF(pipe));
+
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+static int
+snb_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;
+ int ret = 0;
+
+ mutex_lock(&dev->struct_mutex);
+
+ if (!intel_plane->obj)
+ goto out_unlock;
+
+ ret = i915_gem_object_finish_gpu(intel_plane->obj);
+ if (ret)
+ goto out_unlock;
+
+ i915_gem_object_unpin(intel_plane->obj);
+
+ drm_gem_object_reference(&intel_plane->obj->base);
+
+out_unlock:
+ intel_plane->obj = NULL;
+
+ I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE);
+ I915_WRITE(DVSSURF(pipe), 0);
+ POSTING_READ(DVSSURF(pipe));
+
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+static struct drm_plane_funcs intel_plane_funcs;
+
+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,
+};
+
+int
+intel_plane_init(struct drm_device *dev, enum pipe pipe)
+{
+ struct intel_plane *intel_plane;
+ unsigned long possible_crtcs;
+
+ if (!(IS_GEN6(dev) || IS_GEN7(dev))) {
+ DRM_ERROR("new plane code only for SNB+\n");
+ return -ENODEV;
+ }
+
+ intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL);
+ if (!intel_plane)
+ return -ENOMEM;
+
+ if (IS_GEN6(dev)) {
+ intel_plane_funcs.update_plane = snb_update_plane;
+ intel_plane_funcs.disable_plane = snb_disable_plane;
+ } else if (IS_GEN7(dev)) {
+ intel_plane_funcs.update_plane = ivb_update_plane;
+ intel_plane_funcs.disable_plane = ivb_disable_plane;
+ }
+
+ 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));
+
+ return 0;
+}
+
--
1.7.4.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 41+ messages in thread* [PATCH] drm/i915: add SNB video sprite support
2011-10-25 11:22 ` [PATCH] drm/i915: add SNB video sprite support Jesse Barnes
@ 2011-10-25 11:30 ` Jesse Barnes
2011-11-01 14:11 ` Lan, Hai
1 sibling, 0 replies; 41+ messages in thread
From: Jesse Barnes @ 2011-10-25 11:30 UTC (permalink / raw)
Cc: intel-gfx, dri-devel
From 13efc0a405d522aad8250fce2dbd05fefb8b8ab0 Mon Sep 17 00:00:00 2001
From: Jesse Barnes <jbarnes@virtuousgeek.org>
Date: Fri, 22 Apr 2011 14:55:33 -0700
Subject: [PATCH] drm/i915: add SNB video sprite support
The video sprites support various video surface formats natively and can
handle scaling as well. So add support for them using the new DRM core
overlay support functions.
v2: collapse patches
v3: no really, fix disable ordering
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/Makefile | 1 +
drivers/gpu/drm/i915/i915_reg.h | 116 ++++++++++
drivers/gpu/drm/i915/intel_display.c | 26 ++-
drivers/gpu/drm/i915/intel_drv.h | 14 ++
drivers/gpu/drm/i915/intel_fb.c | 6 +
drivers/gpu/drm/i915/intel_overlay2.c | 395 +++++++++++++++++++++++++++++++++
6 files changed, 549 insertions(+), 9 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 5a09416..8cbda0b 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2666,6 +2666,122 @@
#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 DVS_SCALE_ENABLE (1<<31)
+#define DVS_FILTER_MASK (3<<29)
+#define DVS_FILTER_MEDIUM (0<<29)
+#define DVS_FILTER_ENHANCING (1<<29)
+#define DVS_FILTER_SOFTENING (2<<29)
+#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)
+
+#define _SPRA_CTL 0x70280
+#define SPRITE_ENABLE (1<<31)
+#define SPRITE_GAMMA_ENABLE (1<<30)
+#define SPRITE_PIXFORMAT_MASK (7<<25)
+#define SPRITE_FORMAT_YUV422 (0<<25)
+#define SPRITE_FORMAT_RGBX101010 (1<<25)
+#define SPRITE_FORMAT_RGBX888 (2<<25)
+#define SPRITE_FORMAT_RGBX161616 (3<<25)
+#define SPRITE_FORMAT_YUV444 (4<<25)
+#define SPRITE_FORMAT_XBGR101010 (5<<25)
+#define SPRITE_CSC_ENABLE (1<<24)
+#define SPRITE_SOURCE_KEY (1<<22)
+#define SPRITE_RGB_ORDER_RGBX (1<<20) /* only for 888 and 161616 */
+#define SPRITE_YUV_TO_RGB_CSC_DISABLE (1<<19)
+#define SPRITE_YUV_CSC_FORMAT_BT709 (1<<18) /* 0 is BT601 */
+#define SPRITE_YUV_BYTE_ORDER_MASK (3<<16)
+#define SPRITE_YUV_ORDER_YUYV (0<<16)
+#define SPRITE_YUV_ORDER_UYVY (1<<16)
+#define SPRITE_YUV_ORDER_YVYU (2<<16)
+#define SPRITE_YUV_ORDER_VYUY (3<<16)
+#define SPRITE_TRICKLE_FEED_DISABLE (1<<14)
+#define SPRITE_INT_GAMMA_ENABLE (1<<13)
+#define SPRITE_TILED (1<<10)
+#define SPRITE_DEST_KEY (1<<2)
+#define _SPRA_STRIDE 0x70288
+#define _SPRA_POS 0x7028c
+#define _SPRA_SIZE 0x70290
+#define _SPRA_KEYVAL 0x70294
+#define _SPRA_KEYMSK 0x70298
+#define _SPRA_SURF 0x7029c
+#define _SPRA_KEYMAX 0x702a0
+#define _SPRA_TILEOFF 0x702a4
+#define _SPRA_SCALE 0x70304
+#define _SPRA_GAMC 0x70400
+
+#define _SPRB_CTL 0x70280
+#define _SPRB_STRIDE 0x70288
+#define _SPRB_POS 0x7028c
+#define _SPRB_SIZE 0x70290
+#define _SPRB_KEYVAL 0x70294
+#define _SPRB_KEYMSK 0x70298
+#define _SPRB_SURF 0x7029c
+#define _SPRB_KEYMAX 0x702a0
+#define _SPRB_TILEOFF 0x702a4
+#define _SPRB_SCALE 0x70304
+#define _SPRB_GAMC 0x70400
+
+#define SPRCTL(pipe) _PIPE(pipe, _SPRA_CTL, _SPRB_CTL)
+#define SPRSTRIDE(pipe) _PIPE(pipe, _SPRA_STRIDE, _SPRB_STRIDE)
+#define SPRPOS(pipe) _PIPE(pipe, _SPRA_POS, _SPRB_POS)
+#define SPRSIZE(pipe) _PIPE(pipe, _SPRA_SIZE, _SPRB_SIZE)
+#define SPRKEYVAL(pipe) _PIPE(pipe, _SPRA_KEYVAL, _SPRB_KEYVAL)
+#define SPRKEYMSK(pipe) _PIPE(pipe, _SPRA_KEYMSK, _SPRB_KEYMSK)
+#define SPRSURF(pipe) _PIPE(pipe, _SPRA_SURF, _SPRB_SURF)
+#define SPRKEYMAX(pipe) _PIPE(pipe, _SPRA_KEYMAX, _SPRB_KEYMAX)
+#define SPRTILEOFF(pipe) _PIPE(pipe, _SPRA_TILEOFF, _SPRB_TILEOFF)
+#define SPRSCALE(pipe) _PIPE(pipe, _SPRA_SCALE, _SPRB_SCALE)
+#define SPRGAMC(pipe) _PIPE(pipe, _SPRA_GAMC, _SPRB_GAMC)
+
/* 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 e748338..cd7e04d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -915,8 +915,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;
@@ -929,8 +929,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)
@@ -4439,7 +4437,8 @@ static void ironlake_update_wm(struct drm_device *dev)
ILK_LP0_CURSOR_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);
@@ -4453,7 +4452,8 @@ static void ironlake_update_wm(struct drm_device *dev)
ILK_LP0_CURSOR_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);
@@ -4521,7 +4521,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);
@@ -4533,7 +4534,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);
@@ -8692,7 +8694,7 @@ static void i915_disable_vga(struct drm_device *dev)
void intel_modeset_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- int i;
+ int i, ret;
drm_mode_config_init(dev);
@@ -8722,6 +8724,12 @@ 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)) {
+ ret = intel_plane_init(dev, i);
+ if (ret)
+ DRM_ERROR("plane %d init failed: %d\n",
+ i, ret);
+ }
}
/* 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 467fb4a..50b633b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -176,10 +176,18 @@ struct intel_crtc {
bool use_pll_a;
};
+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_HEADER_SIZE 5
@@ -289,6 +297,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 int 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,
@@ -379,6 +388,11 @@ 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);
extern void intel_write_eld(struct drm_encoder *encoder,
struct drm_display_mode *mode);
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..7fb6f99
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_overlay2.c
@@ -0,0 +1,395 @@
+/*
+ * 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"
+
+/*
+ * Note on refcounting:
+ * When the user creates an fb for the GEM object to be used for the plane,
+ * a ref is taken on the object. However, if the application exits before
+ * disabling the plane, the DRM close handling will free all the fbs and
+ * unless we take a ref on the object, it will be destroyed before the
+ * plane disable hook is called, causing obvious trouble with our efforts
+ * to look up and unpin the object. So we take a ref after we move the
+ * object to the display plane so it won't be destroyed until our disable
+ * hook is called and we drop our private reference.
+ */
+
+static int
+ivb_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 sprctl;
+ u32 reg = SPRCTL(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);
+
+ sprctl = I915_READ(reg);
+
+ /* Mask out pixel format bits in case we change it */
+ sprctl &= ~(SPRITE_DEST_KEY | SPRITE_SOURCE_KEY);
+ sprctl &= ~SPRITE_PIXFORMAT_MASK;
+ sprctl &= ~SPRITE_RGB_ORDER_RGBX;
+ sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK;
+
+ switch (fb->pixel_format) {
+ case V4L2_PIX_FMT_BGR32:
+ sprctl |= SPRITE_FORMAT_RGBX888;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
+ break;
+ case V4L2_PIX_FMT_YVYU:
+ sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
+ break;
+ case V4L2_PIX_FMT_UYVY:
+ sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
+ break;
+ case V4L2_PIX_FMT_VYUY:
+ sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
+ break;
+ default:
+ ret = -EINVAL;
+ DRM_ERROR("bad pixel format\n");
+ goto out_unlock;
+ }
+
+ if (obj->tiling_mode != I915_TILING_X) {
+ DRM_ERROR("plane surfaces must be X tiled\n");
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
+ if (ret)
+ goto out_unlock;
+
+ drm_gem_object_reference(&obj->base);
+
+ intel_plane->obj = obj;
+
+ sprctl |= SPRITE_TILED;
+
+ /* must disable */
+ sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
+ sprctl |= SPRITE_ENABLE;
+
+ start = obj->gtt_offset;
+ offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
+
+ I915_WRITE(SPRSTRIDE(pipe), fb->pitch);
+ I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
+ I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
+ I915_WRITE(SPRSIZE(pipe), (fb->height << 16) | fb->width);
+ I915_WRITE(SPRSCALE(pipe), 0);
+ I915_WRITE(reg, sprctl);
+ I915_WRITE(SPRSURF(pipe), start);
+ POSTING_READ(SPRSURF(pipe));
+
+ /* Adjust watermarks as needed */
+ I915_WRITE(WM1S_LP_ILK, 0x100);
+
+ /* 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 int
+snb_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, dvsscale = 0;
+ u32 reg = DVSCNTR(pipe);
+ int ret = 0;
+ int x = src_x >> 16, y = src_y >> 16;
+ int active_w = crtc->mode.hdisplay, active_h = crtc->mode.vdisplay;
+
+ assert_pipe_enabled(dev_priv, pipe);
+
+ intel_fb = to_intel_framebuffer(fb);
+ obj = intel_fb->obj;
+
+ old_obj = intel_plane->obj;
+
+ if (crtc_x >= active_w || crtc_y >= active_h)
+ return -EINVAL;
+
+ /*
+ * We can take a larger source and scale it down, but
+ * only so much... 16x is the max on SNB.
+ */
+ if (((src_w * src_h) / (crtc_w * crtc_h)) > 16)
+ return -EINVAL;
+
+ /* Clamp the width & height into the visible area */
+ if (crtc_x + crtc_w > active_w)
+ crtc_w = active_w - crtc_x - 1;
+ if (crtc_y + crtc_h > active_h)
+ crtc_h = active_h - crtc_y - 1;
+
+ mutex_lock(&dev->struct_mutex);
+
+ dvscntr = I915_READ(reg);
+
+ /* Mask out pixel format bits in case we change it */
+ dvscntr &= ~(DVS_DEST_KEY | DVS_SOURCE_KEY);
+ 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_ERROR("bad pixel format\n");
+ goto out_unlock;
+ }
+
+ if (obj->tiling_mode != I915_TILING_X) {
+ DRM_ERROR("plane surfaces must be X tiled\n");
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
+ if (ret)
+ goto out_unlock;
+
+ drm_gem_object_reference(&obj->base);
+
+ intel_plane->obj = obj;
+
+ dvscntr |= DVS_TILED;
+
+ /* must disable */
+ dvscntr |= DVS_TRICKLE_FEED_DISABLE;
+ dvscntr |= DVS_ENABLE;
+
+ start = obj->gtt_offset;
+ offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
+
+ if (crtc_w != src_w || crtc_h != src_h)
+ dvsscale = DVS_SCALE_ENABLE | (src_h << 16) | src_w;
+
+ 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), (crtc_h << 16) | crtc_w);
+ I915_WRITE(DVSSCALE(pipe), dvsscale);
+ 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 int
+ivb_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;
+ int ret = 0;
+
+ mutex_lock(&dev->struct_mutex);
+
+ I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE);
+ I915_WRITE(SPRSURF(pipe), 0);
+ POSTING_READ(SPRSURF(pipe));
+ intel_wait_for_vblank(dev, pipe);
+
+ if (!intel_plane->obj)
+ goto out_unlock;
+
+ ret = i915_gem_object_finish_gpu(intel_plane->obj);
+ if (ret)
+ goto out_unlock;
+
+ i915_gem_object_unpin(intel_plane->obj);
+
+ drm_gem_object_reference(&intel_plane->obj->base);
+
+out_unlock:
+ intel_plane->obj = NULL;
+
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+static int
+snb_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;
+ int ret = 0;
+
+ mutex_lock(&dev->struct_mutex);
+
+ I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE);
+ I915_WRITE(DVSSURF(pipe), 0);
+ POSTING_READ(DVSSURF(pipe));
+ intel_wait_for_vblank(dev, pipe);
+
+ if (!intel_plane->obj)
+ goto out_unlock;
+
+ ret = i915_gem_object_finish_gpu(intel_plane->obj);
+ if (ret)
+ goto out_unlock;
+
+ i915_gem_object_unpin(intel_plane->obj);
+
+ drm_gem_object_reference(&intel_plane->obj->base);
+
+out_unlock:
+ intel_plane->obj = NULL;
+
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+static struct drm_plane_funcs intel_plane_funcs;
+
+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,
+};
+
+int
+intel_plane_init(struct drm_device *dev, enum pipe pipe)
+{
+ struct intel_plane *intel_plane;
+ unsigned long possible_crtcs;
+
+ if (!(IS_GEN6(dev) || IS_GEN7(dev))) {
+ DRM_ERROR("new plane code only for SNB+\n");
+ return -ENODEV;
+ }
+
+ intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL);
+ if (!intel_plane)
+ return -ENOMEM;
+
+ if (IS_GEN6(dev)) {
+ intel_plane_funcs.update_plane = snb_update_plane;
+ intel_plane_funcs.disable_plane = snb_disable_plane;
+ } else if (IS_GEN7(dev)) {
+ intel_plane_funcs.update_plane = ivb_update_plane;
+ intel_plane_funcs.disable_plane = ivb_disable_plane;
+ }
+
+ 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));
+
+ return 0;
+}
+
--
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] 41+ messages in thread* Re: [PATCH] drm/i915: add SNB video sprite support
2011-10-25 11:22 ` [PATCH] drm/i915: add SNB video sprite support Jesse Barnes
2011-10-25 11:30 ` Jesse Barnes
@ 2011-11-01 14:11 ` Lan, Hai
2011-11-03 18:44 ` [Intel-gfx] " Jesse Barnes
1 sibling, 1 reply; 41+ messages in thread
From: Lan, Hai @ 2011-11-01 14:11 UTC (permalink / raw)
To: Jesse Barnes
Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
Hi Jesse,
I hope the function of snb_update_plane can handle crtx_x<0 or crtc_y<0 just like my patch.
What do you think about it?
Thanks and best regards.
Hai Lan
>From 160c899739e7d07f273de889cc889316837d0790 Mon Sep 17 00:00:00 2001
From: Hai Lan <hai.lan@intel.com>
Date: Tue, 1 Nov 2011 21:30:08 -0400
Subject: [PATCH] drm/i915:add overlay support for crtc_x < 0 or crtc_y < 0
Signed-off-by: Hai Lan <hai.lan@intel.com>
---
drivers/gpu/drm/i915/intel_overlay2.c | 16 ++++++++++++++++
1 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_overlay2.c b/drivers/gpu/drm/i915/intel_overlay2.c
index ff9f0ea..7eba888 100644
--- a/drivers/gpu/drm/i915/intel_overlay2.c
+++ b/drivers/gpu/drm/i915/intel_overlay2.c
@@ -193,6 +193,22 @@ snb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
return -EINVAL;
/* Clamp the width & height into the visible area */
+ if ((crtc_x < 0) && ((crtc_x + crtc_w)>0)) {
+ crtc_w += crtc_x;
+ crtc_x = 0;
+ }
+ if ((crtc_y < 0) && ((crtc_y + crtc_h)>0)) {
+ crtc_h += crtc_y;
+ crtc_y = 0;
+ }
+ if ((crtc_x +crtc_w) < 0) {
+ crtc_w = 0;
+ crtc_x = 0;
+ }
+ if ((crtc_y +crtc_h) < 0) {
+ crtc_h = 0;
+ crtc_y = 0;
+ }
if (crtc_x + crtc_w > active_w)
crtc_w = active_w - crtc_x - 1;
if (crtc_y + crtc_h > active_h)
--
1.7.0.1
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [Intel-gfx] [PATCH] drm/i915: add SNB video sprite support
2011-11-01 14:11 ` Lan, Hai
@ 2011-11-03 18:44 ` Jesse Barnes
0 siblings, 0 replies; 41+ messages in thread
From: Jesse Barnes @ 2011-11-03 18:44 UTC (permalink / raw)
To: Lan, Hai; +Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
[-- Attachment #1.1: Type: text/plain, Size: 480 bytes --]
On Tue, 1 Nov 2011 22:11:43 +0800
"Lan, Hai" <hai.lan@intel.com> wrote:
> Hi Jesse,
> I hope the function of snb_update_plane can handle crtx_x<0 or crtc_y<0 just like my patch.
> What do you think about it?
> Thanks and best regards.
I don't think this is necessary with the latest code; I clamp things in
the top level function now. But take a look and see if I'm missing one
of the cases you cover here.
--
Jesse Barnes, Intel Open Source Technology Center
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 41+ messages in thread