* [RFC] Updated DRM plane handling patches
@ 2011-06-07 20:07 Jesse Barnes
2011-06-07 20:07 ` [PATCH 1/4] drm: add plane support Jesse Barnes
` (4 more replies)
0 siblings, 5 replies; 22+ messages in thread
From: Jesse Barnes @ 2011-06-07 20:07 UTC (permalink / raw)
To: dri-devel; +Cc: intel-gfx
This patchset updates the previous one, incorporating the feedback I
received:
1) uses the v4l fourcc codes to communicate pixel format
2) adds a new addfb ioctl that takes a format
3) adds working SNB support for the new code
Comments welcome. I'll be pushing intel-gpu-tools testdisplay support
for this shortly if people want to play around with it. Next step is to
incorporate it into X and Wayland to see if the API is rich enough for
our needs.
Thanks,
Jesse
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 1/4] drm: add plane support
2011-06-07 20:07 [RFC] Updated DRM plane handling patches Jesse Barnes
@ 2011-06-07 20:07 ` Jesse Barnes
2011-06-07 21:01 ` Jesse Barnes
2011-06-07 21:05 ` Jesse Barnes
2011-06-07 20:07 ` [PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format Jesse Barnes
` (3 subsequent siblings)
4 siblings, 2 replies; 22+ messages in thread
From: Jesse Barnes @ 2011-06-07 20:07 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 | 230 ++++++++++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/drm_drv.c | 3 +
include/drm/drm.h | 3 +
include/drm/drm_crtc.h | 69 +++++++++++++-
include/drm/drm_mode.h | 39 ++++++++
5 files changed, 343 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 872747c..dd6d149 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -533,6 +533,45 @@ 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,
+ 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;
+
+ list_add_tail(&plane->head, &dev->mode_config.plane_list);
+ dev->mode_config.num_plane++;
+
+ mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_plane_init);
+
+void drm_plane_cleanup(struct drm_plane *plane)
+{
+ struct drm_device *dev = plane->dev;
+
+ mutex_lock(&dev->mode_config.mutex);
+ drm_mode_object_put(dev, &plane->base);
+ list_del(&plane->head);
+ dev->mode_config.num_plane--;
+ mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_plane_cleanup);
+
/**
* drm_mode_create - create a new display mode
* @dev: DRM device
@@ -864,6 +903,7 @@ void drm_mode_config_init(struct drm_device *dev)
INIT_LIST_HEAD(&dev->mode_config.encoder_list);
INIT_LIST_HEAD(&dev->mode_config.property_list);
INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
+ INIT_LIST_HEAD(&dev->mode_config.plane_list);
idr_init(&dev->mode_config.crtc_idr);
mutex_lock(&dev->mode_config.mutex);
@@ -1467,6 +1507,196 @@ 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;
+ plane_resp->crtc_x = plane->crtc_x;
+ plane_resp->crtc_y = plane->crtc_y;
+ plane_resp->x = plane->x;
+ plane_resp->y = plane->y;
+
+ /*
+ * 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->x, plane_req->y);
+
+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
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 93a112d..15da618 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -135,8 +135,11 @@ static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 4be33b4..2897967 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -714,6 +714,9 @@ struct drm_get_cap {
#define DRM_IOCTL_MODE_CREATE_DUMB DRM_IOWR(0xB2, struct drm_mode_create_dumb)
#define DRM_IOCTL_MODE_MAP_DUMB DRM_IOWR(0xB3, struct drm_mode_map_dumb)
#define DRM_IOCTL_MODE_DESTROY_DUMB DRM_IOWR(0xB4, struct drm_mode_destroy_dumb)
+#define DRM_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xB5, struct drm_mode_get_plane_res)
+#define DRM_IOCTL_MODE_GETPLANE DRM_IOWR(0xB6, struct drm_mode_get_plane)
+#define DRM_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct drm_mode_set_plane)
/**
* Device specific ioctls should only be in their respective headers
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 9573e0c..c357678 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -44,6 +44,7 @@ struct drm_framebuffer;
#define DRM_MODE_OBJECT_PROPERTY 0xb0b0b0b0
#define DRM_MODE_OBJECT_FB 0xfbfbfbfb
#define DRM_MODE_OBJECT_BLOB 0xbbbbbbbb
+#define DRM_MODE_OBJECT_PLANE 0xeeeeeeee
struct drm_mode_object {
uint32_t id;
@@ -276,6 +277,7 @@ struct drm_crtc;
struct drm_connector;
struct drm_encoder;
struct drm_pending_vblank_event;
+struct drm_plane;
/**
* drm_crtc_funcs - control CRTCs for a given device
@@ -523,6 +525,57 @@ 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, int x, int y);
+ void (*disable_plane)(struct drm_plane *plane);
+};
+
+/**
+ * drm_plane - central DRM plane control structure
+ * @dev: DRM device this plane belongs to
+ * @kdev: kernel device
+ * @attr: kdev attributes
+ * @head: for list management
+ * @base: base mode object
+ * @crtc_x: x position of plane (relative to pipe base)
+ * @crtc_y: y position of plane
+ * @x: x offset into fb
+ * @y: y offset into fb
+ * @crtc: CRTC this plane is feeding
+ */
+struct drm_plane {
+ struct drm_device *dev;
+ struct device kdev;
+ struct device_attribute *attr;
+ struct list_head head;
+
+ struct drm_mode_object base;
+
+ int crtc_x, crtc_y;
+ int x, y;
+ uint32_t possible_crtcs;
+ uint32_t *format_types;
+ uint32_t format_count;
+
+ struct drm_crtc *crtc;
+ struct drm_framebuffer *fb;
+
+ /* CRTC gamma size for reporting to userspace */
+ uint32_t gamma_size;
+ uint16_t *gamma_store;
+
+ bool enabled;
+
+ const struct drm_plane_funcs *funcs;
+ void *helper_private;
+};
+
+/**
* struct drm_mode_set
*
* Represents a single crtc the connectors that it drives with what mode
@@ -576,6 +629,8 @@ struct drm_mode_config {
struct list_head connector_list;
int num_encoder;
struct list_head encoder_list;
+ int num_plane;
+ struct list_head plane_list;
int num_crtc;
struct list_head crtc_list;
@@ -628,6 +683,7 @@ struct drm_mode_config {
#define obj_to_fb(x) container_of(x, struct drm_framebuffer, base)
#define obj_to_property(x) container_of(x, struct drm_property, base)
#define obj_to_blob(x) container_of(x, struct drm_property_blob, base)
+#define obj_to_plane(x) container_of(x, struct drm_plane, base)
extern void drm_crtc_init(struct drm_device *dev,
@@ -647,6 +703,12 @@ 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,
+ const struct drm_plane_funcs *funcs,
+ uint32_t *formats, uint32_t format_count);
+extern void drm_plane_cleanup(struct drm_plane *plane);
+
extern void drm_encoder_cleanup(struct drm_encoder *encoder);
extern char *drm_get_connector_name(struct drm_connector *connector);
@@ -740,13 +802,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..106cf35 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -120,6 +120,45 @@ struct drm_mode_crtc {
struct drm_mode_modeinfo mode;
};
+#define DRM_MODE_PLANE_FORMAT_YUV422 1 /* YUV 4:2:2 packed */
+#define DRM_MODE_PLANE_FORMAT_RGBX101010 2 /* RGB 10bpc, ign. alpha */
+#define DRM_MODE_PLANE_FORMAT_RGBX888 3 /* Standard x:8:8:8 RGB */
+#define DRM_MODE_PLANE_FORMAT_RGBX161616 4 /* x:16:16:16 float RGB */
+
+/* Planes blend with or override other bits on the CRTC */
+struct drm_mode_set_plane {
+ __u32 plane_id;
+ __u32 crtc_id;
+ __u32 fb_id; /* contains surface format type */
+
+ __u32 crtc_x, crtc_y;
+ __u32 x, y;
+
+ /* FIXME: color key/mask, scaling, z-order, other? */
+};
+
+struct drm_mode_get_plane {
+ __u64 format_type_ptr;
+ __u32 plane_id;
+
+ __u32 crtc_id;
+ __u32 fb_id;
+
+ __u32 crtc_x, crtc_y;
+ __u32 x, y;
+
+ __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] 22+ messages in thread
* [PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
2011-06-07 20:07 [RFC] Updated DRM plane handling patches Jesse Barnes
2011-06-07 20:07 ` [PATCH 1/4] drm: add plane support Jesse Barnes
@ 2011-06-07 20:07 ` Jesse Barnes
2011-06-09 4:05 ` Dave Airlie
2011-06-07 20:07 ` [PATCH 3/4] drm/i915: rename existing overlay support to "legacy" Jesse Barnes
` (2 subsequent siblings)
4 siblings, 1 reply; 22+ messages in thread
From: Jesse Barnes @ 2011-06-07 20:07 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/psb_fb.c | 2 +-
include/drm/drm.h | 1 +
include/drm/drm_crtc.h | 6 ++-
include/drm/drm_crtc_helper.h | 2 +-
include/drm/drm_mode.h | 14 ++++++
16 files changed, 112 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index dd6d149..b499cbf 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1910,7 +1910,76 @@ out:
int drm_mode_addfb(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
- struct drm_mode_fb_cmd *r = data;
+ struct drm_mode_fb_cmd *or = data;
+ struct drm_mode_fb_cmd2 r;
+ struct drm_mode_config *config = &dev->mode_config;
+ struct drm_framebuffer *fb;
+ int ret = 0;
+
+ /* Use new struct with format internally */
+ r.fb_id = or->fb_id;
+ r.width = or->width;
+ r.height = or->height;
+ r.pitch = or->pitch;
+ r.bpp = or->bpp;
+ r.depth = or->depth;
+ r.pixel_format = 0;
+ r.handle = or->handle;
+
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+ return -EINVAL;
+
+ if ((config->min_width > r.width) || (r.width > config->max_width)) {
+ DRM_ERROR("mode new framebuffer width not within limits\n");
+ return -EINVAL;
+ }
+ if ((config->min_height > r.height) || (r.height > config->max_height)) {
+ DRM_ERROR("mode new framebuffer height not within limits\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&dev->mode_config.mutex);
+
+ /* TODO check buffer is sufficiently large */
+ /* TODO setup destructor callback */
+
+ fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r);
+ if (IS_ERR(fb)) {
+ DRM_ERROR("could not create framebuffer\n");
+ ret = PTR_ERR(fb);
+ goto out;
+ }
+
+ or->fb_id = fb->base.id;
+ list_add(&fb->filp_head, &file_priv->fbs);
+ DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
+
+out:
+ mutex_unlock(&dev->mode_config.mutex);
+ return ret;
+}
+
+/**
+ * drm_mode_addfb2 - add an FB to the graphics configuration
+ * @inode: inode from the ioctl
+ * @filp: file * from the ioctl
+ * @cmd: cmd from ioctl
+ * @arg: arg from ioctl
+ *
+ * LOCKING:
+ * Takes mode config lock.
+ *
+ * Add a new FB to the specified CRTC, given a user request with format.
+ *
+ * Called by the user via ioctl.
+ *
+ * RETURNS:
+ * Zero on success, errno on failure.
+ */
+int drm_mode_addfb2(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
+{
+ struct drm_mode_fb_cmd2 *r = data;
struct drm_mode_config *config = &dev->mode_config;
struct drm_framebuffer *fb;
int ret = 0;
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 9236965..5adab04 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -801,13 +801,14 @@ void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
EXPORT_SYMBOL(drm_helper_connector_dpms);
int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
- struct drm_mode_fb_cmd *mode_cmd)
+ struct drm_mode_fb_cmd2 *mode_cmd)
{
fb->width = mode_cmd->width;
fb->height = mode_cmd->height;
fb->pitch = mode_cmd->pitch;
fb->bits_per_pixel = mode_cmd->bpp;
fb->depth = mode_cmd->depth;
+ fb->pixel_format = mode_cmd->pixel_format;
return 0;
}
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 15da618..f24b9b6 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -152,6 +152,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 0b6fd36..8a6e3ab 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5803,7 +5803,7 @@ static struct drm_display_mode load_detect_mode = {
static struct drm_framebuffer *
intel_framebuffer_create(struct drm_device *dev,
- struct drm_mode_fb_cmd *mode_cmd,
+ struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_i915_gem_object *obj)
{
struct intel_framebuffer *intel_fb;
@@ -5845,7 +5845,7 @@ intel_framebuffer_create_for_mode(struct drm_device *dev,
int depth, int bpp)
{
struct drm_i915_gem_object *obj;
- struct drm_mode_fb_cmd mode_cmd;
+ struct drm_mode_fb_cmd2 mode_cmd;
obj = i915_gem_alloc_object(dev,
intel_framebuffer_size_for_mode(mode, bpp));
@@ -5857,6 +5857,7 @@ intel_framebuffer_create_for_mode(struct drm_device *dev,
mode_cmd.depth = depth;
mode_cmd.bpp = bpp;
mode_cmd.pitch = intel_framebuffer_pitch_for_width(mode_cmd.width, bpp);
+ mode_cmd.pixel_format = 0;
return intel_framebuffer_create(dev, &mode_cmd, obj);
}
@@ -6978,7 +6979,7 @@ static const struct drm_framebuffer_funcs intel_fb_funcs = {
int intel_framebuffer_init(struct drm_device *dev,
struct intel_framebuffer *intel_fb,
- struct drm_mode_fb_cmd *mode_cmd,
+ struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_i915_gem_object *obj)
{
int ret;
@@ -7013,7 +7014,7 @@ int intel_framebuffer_init(struct drm_device *dev,
static struct drm_framebuffer *
intel_user_framebuffer_create(struct drm_device *dev,
struct drm_file *filp,
- struct drm_mode_fb_cmd *mode_cmd)
+ struct drm_mode_fb_cmd2 *mode_cmd)
{
struct drm_i915_gem_object *obj;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 0dc9018..3cfc391 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -326,7 +326,7 @@ extern int intel_pin_and_fence_fb_obj(struct drm_device *dev,
extern int intel_framebuffer_init(struct drm_device *dev,
struct intel_framebuffer *ifb,
- struct drm_mode_fb_cmd *mode_cmd,
+ struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_i915_gem_object *obj);
extern int intel_fbdev_init(struct drm_device *dev);
extern void intel_fbdev_fini(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index ec49bae..11baa99 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -65,7 +65,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
struct drm_i915_private *dev_priv = dev->dev_private;
struct fb_info *info;
struct drm_framebuffer *fb;
- struct drm_mode_fb_cmd mode_cmd;
+ struct drm_mode_fb_cmd2 mode_cmd;
struct drm_i915_gem_object *obj;
struct device *device = &dev->pdev->dev;
int size, ret;
@@ -80,6 +80,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
mode_cmd.bpp = sizes->surface_bpp;
mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 7) / 8), 64);
mode_cmd.depth = sizes->surface_depth;
+ mode_cmd.pixel_format = 0;
size = mode_cmd.pitch * mode_cmd.height;
size = ALIGN(size, PAGE_SIZE);
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index eb514ea..b03df00 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -64,7 +64,7 @@ static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = {
int
nouveau_framebuffer_init(struct drm_device *dev,
struct nouveau_framebuffer *nv_fb,
- struct drm_mode_fb_cmd *mode_cmd,
+ struct drm_mode_fb_cmd2 *mode_cmd,
struct nouveau_bo *nvbo)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -121,7 +121,7 @@ nouveau_framebuffer_init(struct drm_device *dev,
static struct drm_framebuffer *
nouveau_user_framebuffer_create(struct drm_device *dev,
struct drm_file *file_priv,
- struct drm_mode_fb_cmd *mode_cmd)
+ struct drm_mode_fb_cmd2 *mode_cmd)
{
struct nouveau_framebuffer *nouveau_fb;
struct drm_gem_object *gem;
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index ae247ee..74ffab6 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -1122,7 +1122,7 @@ static const struct drm_framebuffer_funcs radeon_fb_funcs = {
void
radeon_framebuffer_init(struct drm_device *dev,
struct radeon_framebuffer *rfb,
- struct drm_mode_fb_cmd *mode_cmd,
+ struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_gem_object *obj)
{
rfb->obj = obj;
@@ -1133,7 +1133,7 @@ radeon_framebuffer_init(struct drm_device *dev,
static struct drm_framebuffer *
radeon_user_framebuffer_create(struct drm_device *dev,
struct drm_file *file_priv,
- struct drm_mode_fb_cmd *mode_cmd)
+ struct drm_mode_fb_cmd2 *mode_cmd)
{
struct drm_gem_object *obj;
struct radeon_framebuffer *radeon_fb;
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 0b7b486..06215ac 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -103,7 +103,7 @@ static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj)
}
static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
- struct drm_mode_fb_cmd *mode_cmd,
+ struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_gem_object **gobj_p)
{
struct radeon_device *rdev = rfbdev->rdev;
@@ -187,7 +187,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
struct radeon_device *rdev = rfbdev->rdev;
struct fb_info *info;
struct drm_framebuffer *fb = NULL;
- struct drm_mode_fb_cmd mode_cmd;
+ struct drm_mode_fb_cmd2 mode_cmd;
struct drm_gem_object *gobj = NULL;
struct radeon_bo *rbo = NULL;
struct device *device = &rdev->pdev->dev;
@@ -203,6 +203,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
mode_cmd.bpp = sizes->surface_bpp;
mode_cmd.depth = sizes->surface_depth;
+ mode_cmd.pixel_format = 0;
ret = radeonfb_create_pinned_object(rfbdev, &mode_cmd, &gobj);
rbo = gem_to_radeon_bo(gobj);
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 977a341..121eb56 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -637,7 +637,7 @@ extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green
u16 *blue, int regno);
void radeon_framebuffer_init(struct drm_device *dev,
struct radeon_framebuffer *rfb,
- struct drm_mode_fb_cmd *mode_cmd,
+ struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_gem_object *obj);
int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index dfe32e6..f6566a8 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -836,7 +836,7 @@ out_err1:
static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
struct drm_file *file_priv,
- struct drm_mode_fb_cmd *mode_cmd)
+ struct drm_mode_fb_cmd2 *mode_cmd)
{
struct vmw_private *dev_priv = vmw_priv(dev);
struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index 99c03a2..3cfa632 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -481,7 +481,7 @@ out_err1:
*/
static struct drm_framebuffer *psb_user_framebuffer_create
(struct drm_device *dev, struct drm_file *filp,
- struct drm_mode_fb_cmd *cmd)
+ struct drm_mode_fb_cmd2 *cmd)
{
struct gtt_range *r;
struct drm_gem_object *obj;
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 2897967..49d94ed 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -717,6 +717,7 @@ struct drm_get_cap {
#define DRM_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xB5, struct drm_mode_get_plane_res)
#define DRM_IOCTL_MODE_GETPLANE DRM_IOWR(0xB6, struct drm_mode_get_plane)
#define DRM_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct drm_mode_set_plane)
+#define DRM_IOCTL_MODE_ADDFB2 DRM_IOWR(0xB8, struct drm_mode_fb_cmd2)
/**
* Device specific ioctls should only be in their respective headers
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index c357678..e527e20 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -29,6 +29,7 @@
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/idr.h>
+#include <linux/videodev2.h> /* for plane formats */
#include <linux/fb.h>
@@ -244,6 +245,7 @@ struct drm_framebuffer {
unsigned int depth;
int bits_per_pixel;
int flags;
+ uint32_t pixel_format; /* fourcc format */
struct list_head filp_head;
/* if you are using the helper */
void *helper_private;
@@ -601,7 +603,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);
};
@@ -818,6 +820,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 106cf35..9bff586 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
@@ -268,6 +270,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] 22+ messages in thread
* [PATCH 3/4] drm/i915: rename existing overlay support to "legacy"
2011-06-07 20:07 [RFC] Updated DRM plane handling patches Jesse Barnes
2011-06-07 20:07 ` [PATCH 1/4] drm: add plane support Jesse Barnes
2011-06-07 20:07 ` [PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format Jesse Barnes
@ 2011-06-07 20:07 ` Jesse Barnes
2011-06-07 20:59 ` [Intel-gfx] " Chris Wilson
2011-06-07 20:07 ` [PATCH 4/4] drm/i915: add SNB video sprite support Jesse Barnes
2011-06-15 17:29 ` [RFC] Updated DRM plane handling patches Jesse Barnes
4 siblings, 1 reply; 22+ messages in thread
From: Jesse Barnes @ 2011-06-07 20:07 UTC (permalink / raw)
To: dri-devel; +Cc: intel-gfx
The old overlay block has all sorts of quirks and is very different than
ILK+ video sprites. So rename it to legacy to make that clear and clash
less with core overlay support.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/i915_debugfs.c | 2 +-
drivers/gpu/drm/i915/i915_drv.h | 12 ++--
drivers/gpu/drm/i915/i915_irq.c | 2 +-
drivers/gpu/drm/i915/intel_display.c | 2 +-
drivers/gpu/drm/i915/intel_drv.h | 4 +-
drivers/gpu/drm/i915/intel_overlay.c | 126 +++++++++++++++++-----------------
6 files changed, 74 insertions(+), 74 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 51c2257..c83ed15 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -825,7 +825,7 @@ static int i915_error_state(struct seq_file *m, void *unused)
}
if (error->overlay)
- intel_overlay_print_error_state(m, error->overlay);
+ intel_legacy_overlay_print_error_state(m, error->overlay);
if (error->display)
intel_display_print_error_state(m, dev, error->display);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 31e199f..062e80e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -117,8 +117,8 @@ struct intel_opregion {
};
#define OPREGION_SIZE (8*1024)
-struct intel_overlay;
-struct intel_overlay_error_state;
+struct intel_legacy_overlay;
+struct intel_legacy_overlay_error_state;
struct drm_i915_master_private {
drm_local_map_t *sarea;
@@ -191,7 +191,7 @@ struct drm_i915_error_state {
u32 cache_level:2;
} *active_bo, *pinned_bo;
u32 active_bo_count, pinned_bo_count;
- struct intel_overlay_error_state *overlay;
+ struct intel_legacy_overlay_error_state *overlay;
struct intel_display_error_state *display;
};
@@ -336,7 +336,7 @@ typedef struct drm_i915_private {
struct intel_opregion opregion;
/* overlay */
- struct intel_overlay *overlay;
+ struct intel_legacy_overlay *overlay;
/* LVDS info */
int backlight_level; /* restore backlight to this value */
@@ -1329,8 +1329,8 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
/* overlay */
#ifdef CONFIG_DEBUG_FS
-extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev);
-extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error);
+extern struct intel_legacy_overlay_error_state *intel_legacy_overlay_capture_error_state(struct drm_device *dev);
+extern void intel_legacy_overlay_print_error_state(struct seq_file *m, struct intel_legacy_overlay_error_state *error);
extern struct intel_display_error_state *intel_display_capture_error_state(struct drm_device *dev);
extern void intel_display_print_error_state(struct seq_file *m,
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b79619a..7a34167 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -991,7 +991,7 @@ static void i915_capture_error_state(struct drm_device *dev)
do_gettimeofday(&error->time);
- error->overlay = intel_overlay_capture_error_state(dev);
+ error->overlay = intel_legacy_overlay_capture_error_state(dev);
error->display = intel_display_capture_error_state(dev);
spin_lock_irqsave(&dev_priv->error_lock, flags);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8a6e3ab..7901f16 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2936,7 +2936,7 @@ static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
mutex_lock(&dev->struct_mutex);
dev_priv->mm.interruptible = false;
- (void) intel_overlay_switch_off(intel_crtc->overlay);
+ (void) intel_legacy_overlay_switch_off(intel_crtc->overlay);
dev_priv->mm.interruptible = true;
mutex_unlock(&dev->struct_mutex);
}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 3cfc391..d73e622 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -161,7 +161,7 @@ struct intel_crtc {
bool busy; /* is scanout buffer being updated frequently? */
struct timer_list idle_timer;
bool lowfreq_avail;
- struct intel_overlay *overlay;
+ struct intel_legacy_overlay *overlay;
struct intel_unpin_work *unpin_work;
int fdi_lanes;
@@ -337,7 +337,7 @@ extern void intel_finish_page_flip_plane(struct drm_device *dev, int plane);
extern void intel_setup_overlay(struct drm_device *dev);
extern void intel_cleanup_overlay(struct drm_device *dev);
-extern int intel_overlay_switch_off(struct intel_overlay *overlay);
+extern int intel_legacy_overlay_switch_off(struct intel_legacy_overlay *overlay);
extern int intel_overlay_put_image(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int intel_overlay_attrs(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index a670c00..42e6561 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -170,7 +170,7 @@ struct overlay_registers {
u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
};
-struct intel_overlay {
+struct intel_legacy_overlay {
struct drm_device *dev;
struct intel_crtc *crtc;
struct drm_i915_gem_object *vid_bo;
@@ -186,11 +186,11 @@ struct intel_overlay {
struct drm_i915_gem_object *reg_bo;
/* flip handling */
uint32_t last_flip_req;
- void (*flip_tail)(struct intel_overlay *);
+ void (*flip_tail)(struct intel_legacy_overlay *);
};
static struct overlay_registers *
-intel_overlay_map_regs(struct intel_overlay *overlay)
+intel_legacy_overlay_map_regs(struct intel_legacy_overlay *overlay)
{
drm_i915_private_t *dev_priv = overlay->dev->dev_private;
struct overlay_registers *regs;
@@ -204,16 +204,16 @@ intel_overlay_map_regs(struct intel_overlay *overlay)
return regs;
}
-static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
+static void intel_legacy_overlay_unmap_regs(struct intel_legacy_overlay *overlay,
struct overlay_registers *regs)
{
if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
io_mapping_unmap(regs);
}
-static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
+static int intel_legacy_overlay_do_wait_request(struct intel_legacy_overlay *overlay,
struct drm_i915_gem_request *request,
- void (*tail)(struct intel_overlay *))
+ void (*tail)(struct intel_legacy_overlay *))
{
struct drm_device *dev = overlay->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -284,7 +284,7 @@ i830_deactivate_pipe_a(struct drm_device *dev)
}
/* overlay needs to be disable in OCMD reg */
-static int intel_overlay_on(struct intel_overlay *overlay)
+static int intel_legacy_overlay_on(struct intel_legacy_overlay *overlay)
{
struct drm_device *dev = overlay->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -319,7 +319,7 @@ static int intel_overlay_on(struct intel_overlay *overlay)
OUT_RING(MI_NOOP);
ADVANCE_LP_RING();
- ret = intel_overlay_do_wait_request(overlay, request, NULL);
+ ret = intel_legacy_overlay_do_wait_request(overlay, request, NULL);
out:
if (pipe_a_quirk)
i830_deactivate_pipe_a(dev);
@@ -328,7 +328,7 @@ out:
}
/* overlay needs to be enabled in OCMD reg */
-static int intel_overlay_continue(struct intel_overlay *overlay,
+static int intel_legacy_overlay_continue(struct intel_legacy_overlay *overlay,
bool load_polyphase_filter)
{
struct drm_device *dev = overlay->dev;
@@ -371,7 +371,7 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
return 0;
}
-static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
+static void intel_legacy_overlay_release_old_vid_tail(struct intel_legacy_overlay *overlay)
{
struct drm_i915_gem_object *obj = overlay->old_vid_bo;
@@ -381,7 +381,7 @@ static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
overlay->old_vid_bo = NULL;
}
-static void intel_overlay_off_tail(struct intel_overlay *overlay)
+static void intel_legacy_overlay_off_tail(struct intel_legacy_overlay *overlay)
{
struct drm_i915_gem_object *obj = overlay->vid_bo;
@@ -398,7 +398,7 @@ static void intel_overlay_off_tail(struct intel_overlay *overlay)
}
/* overlay needs to be disabled in OCMD reg */
-static int intel_overlay_off(struct intel_overlay *overlay)
+static int intel_legacy_overlay_off(struct intel_legacy_overlay *overlay)
{
struct drm_device *dev = overlay->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -433,13 +433,13 @@ static int intel_overlay_off(struct intel_overlay *overlay)
OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
ADVANCE_LP_RING();
- return intel_overlay_do_wait_request(overlay, request,
- intel_overlay_off_tail);
+ return intel_legacy_overlay_do_wait_request(overlay, request,
+ intel_legacy_overlay_off_tail);
}
/* recover from an interruption due to a signal
* We have to be careful not to repeat work forever an make forward progess. */
-static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
+static int intel_legacy_overlay_recover_from_interrupt(struct intel_legacy_overlay *overlay)
{
struct drm_device *dev = overlay->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -461,9 +461,9 @@ static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
/* Wait for pending overlay flip and release old frame.
* Needs to be called before the overlay register are changed
- * via intel_overlay_(un)map_regs
+ * via intel_legacy_overlay_(un)map_regs
*/
-static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
+static int intel_legacy_overlay_release_old_vid(struct intel_legacy_overlay *overlay)
{
struct drm_device *dev = overlay->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -493,13 +493,13 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
OUT_RING(MI_NOOP);
ADVANCE_LP_RING();
- ret = intel_overlay_do_wait_request(overlay, request,
- intel_overlay_release_old_vid_tail);
+ ret = intel_legacy_overlay_do_wait_request(overlay, request,
+ intel_legacy_overlay_release_old_vid_tail);
if (ret)
return ret;
}
- intel_overlay_release_old_vid_tail(overlay);
+ intel_legacy_overlay_release_old_vid_tail(overlay);
return 0;
}
@@ -625,7 +625,7 @@ static void update_polyphase_filter(struct overlay_registers *regs)
memcpy(regs->UV_HCOEFS, uv_static_hcoeffs, sizeof(uv_static_hcoeffs));
}
-static bool update_scaling_factors(struct intel_overlay *overlay,
+static bool update_scaling_factors(struct intel_legacy_overlay *overlay,
struct overlay_registers *regs,
struct put_image_params *params)
{
@@ -682,7 +682,7 @@ static bool update_scaling_factors(struct intel_overlay *overlay,
return scale_changed;
}
-static void update_colorkey(struct intel_overlay *overlay,
+static void update_colorkey(struct intel_legacy_overlay *overlay,
struct overlay_registers *regs)
{
u32 key = overlay->color_key;
@@ -756,7 +756,7 @@ static u32 overlay_cmd_reg(struct put_image_params *params)
return cmd;
}
-static int intel_overlay_do_put_image(struct intel_overlay *overlay,
+static int intel_legacy_overlay_do_put_image(struct intel_legacy_overlay *overlay,
struct drm_i915_gem_object *new_bo,
struct put_image_params *params)
{
@@ -769,7 +769,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
BUG_ON(!overlay);
- ret = intel_overlay_release_old_vid(overlay);
+ ret = intel_legacy_overlay_release_old_vid(overlay);
if (ret != 0)
return ret;
@@ -786,7 +786,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
goto out_unpin;
if (!overlay->active) {
- regs = intel_overlay_map_regs(overlay);
+ regs = intel_legacy_overlay_map_regs(overlay);
if (!regs) {
ret = -ENOMEM;
goto out_unpin;
@@ -796,14 +796,14 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
regs->OCONFIG |= OCONF_CSC_MODE_BT709;
regs->OCONFIG |= overlay->crtc->pipe == 0 ?
OCONF_PIPE_A : OCONF_PIPE_B;
- intel_overlay_unmap_regs(overlay, regs);
+ intel_legacy_overlay_unmap_regs(overlay, regs);
- ret = intel_overlay_on(overlay);
+ ret = intel_legacy_overlay_on(overlay);
if (ret != 0)
goto out_unpin;
}
- regs = intel_overlay_map_regs(overlay);
+ regs = intel_legacy_overlay_map_regs(overlay);
if (!regs) {
ret = -ENOMEM;
goto out_unpin;
@@ -846,9 +846,9 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
regs->OCMD = overlay_cmd_reg(params);
- intel_overlay_unmap_regs(overlay, regs);
+ intel_legacy_overlay_unmap_regs(overlay, regs);
- ret = intel_overlay_continue(overlay, scale_changed);
+ ret = intel_legacy_overlay_continue(overlay, scale_changed);
if (ret)
goto out_unpin;
@@ -862,7 +862,7 @@ out_unpin:
return ret;
}
-int intel_overlay_switch_off(struct intel_overlay *overlay)
+int intel_legacy_overlay_switch_off(struct intel_legacy_overlay *overlay)
{
struct overlay_registers *regs;
struct drm_device *dev = overlay->dev;
@@ -871,30 +871,30 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
BUG_ON(!mutex_is_locked(&dev->struct_mutex));
BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
- ret = intel_overlay_recover_from_interrupt(overlay);
+ ret = intel_legacy_overlay_recover_from_interrupt(overlay);
if (ret != 0)
return ret;
if (!overlay->active)
return 0;
- ret = intel_overlay_release_old_vid(overlay);
+ ret = intel_legacy_overlay_release_old_vid(overlay);
if (ret != 0)
return ret;
- regs = intel_overlay_map_regs(overlay);
+ regs = intel_legacy_overlay_map_regs(overlay);
regs->OCMD = 0;
- intel_overlay_unmap_regs(overlay, regs);
+ intel_legacy_overlay_unmap_regs(overlay, regs);
- ret = intel_overlay_off(overlay);
+ ret = intel_legacy_overlay_off(overlay);
if (ret != 0)
return ret;
- intel_overlay_off_tail(overlay);
+ intel_legacy_overlay_off_tail(overlay);
return 0;
}
-static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
+static int check_overlay_possible_on_crtc(struct intel_legacy_overlay *overlay,
struct intel_crtc *crtc)
{
drm_i915_private_t *dev_priv = overlay->dev->dev_private;
@@ -910,7 +910,7 @@ static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
return 0;
}
-static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
+static void update_pfit_vscale_ratio(struct intel_legacy_overlay *overlay)
{
struct drm_device *dev = overlay->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -934,7 +934,7 @@ static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
overlay->pfit_vscale_ratio = ratio;
}
-static int check_overlay_dst(struct intel_overlay *overlay,
+static int check_overlay_dst(struct intel_legacy_overlay *overlay,
struct drm_intel_overlay_put_image *rec)
{
struct drm_display_mode *mode = &overlay->crtc->base.mode;
@@ -1106,7 +1106,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
{
struct drm_intel_overlay_put_image *put_image_rec = data;
drm_i915_private_t *dev_priv = dev->dev_private;
- struct intel_overlay *overlay;
+ struct intel_legacy_overlay *overlay;
struct drm_mode_object *drmmode_obj;
struct intel_crtc *crtc;
struct drm_i915_gem_object *new_bo;
@@ -1128,7 +1128,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
mutex_lock(&dev->mode_config.mutex);
mutex_lock(&dev->struct_mutex);
- ret = intel_overlay_switch_off(overlay);
+ ret = intel_legacy_overlay_switch_off(overlay);
mutex_unlock(&dev->struct_mutex);
mutex_unlock(&dev->mode_config.mutex);
@@ -1164,13 +1164,13 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
goto out_unlock;
}
- ret = intel_overlay_recover_from_interrupt(overlay);
+ ret = intel_legacy_overlay_recover_from_interrupt(overlay);
if (ret != 0)
goto out_unlock;
if (overlay->crtc != crtc) {
struct drm_display_mode *mode = &crtc->base.mode;
- ret = intel_overlay_switch_off(overlay);
+ ret = intel_legacy_overlay_switch_off(overlay);
if (ret != 0)
goto out_unlock;
@@ -1232,7 +1232,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
if (ret != 0)
goto out_unlock;
- ret = intel_overlay_do_put_image(overlay, new_bo, params);
+ ret = intel_legacy_overlay_do_put_image(overlay, new_bo, params);
if (ret != 0)
goto out_unlock;
@@ -1253,7 +1253,7 @@ out_free:
return ret;
}
-static void update_reg_attrs(struct intel_overlay *overlay,
+static void update_reg_attrs(struct intel_legacy_overlay *overlay,
struct overlay_registers *regs)
{
regs->OCLRC0 = (overlay->contrast << 18) | (overlay->brightness & 0xff);
@@ -1309,7 +1309,7 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
{
struct drm_intel_overlay_attrs *attrs = data;
drm_i915_private_t *dev_priv = dev->dev_private;
- struct intel_overlay *overlay;
+ struct intel_legacy_overlay *overlay;
struct overlay_registers *regs;
int ret;
@@ -1355,7 +1355,7 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
overlay->contrast = attrs->contrast;
overlay->saturation = attrs->saturation;
- regs = intel_overlay_map_regs(overlay);
+ regs = intel_legacy_overlay_map_regs(overlay);
if (!regs) {
ret = -ENOMEM;
goto out_unlock;
@@ -1363,7 +1363,7 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
update_reg_attrs(overlay, regs);
- intel_overlay_unmap_regs(overlay, regs);
+ intel_legacy_overlay_unmap_regs(overlay, regs);
if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
if (IS_GEN2(dev))
@@ -1398,7 +1398,7 @@ out_unlock:
void intel_setup_overlay(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
- struct intel_overlay *overlay;
+ struct intel_legacy_overlay *overlay;
struct drm_i915_gem_object *reg_bo;
struct overlay_registers *regs;
int ret;
@@ -1406,7 +1406,7 @@ void intel_setup_overlay(struct drm_device *dev)
if (!HAS_OVERLAY(dev))
return;
- overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL);
+ overlay = kzalloc(sizeof(struct intel_legacy_overlay), GFP_KERNEL);
if (!overlay)
return;
overlay->dev = dev;
@@ -1446,7 +1446,7 @@ void intel_setup_overlay(struct drm_device *dev)
overlay->contrast = 75;
overlay->saturation = 146;
- regs = intel_overlay_map_regs(overlay);
+ regs = intel_legacy_overlay_map_regs(overlay);
if (!regs)
goto out_free_bo;
@@ -1454,7 +1454,7 @@ void intel_setup_overlay(struct drm_device *dev)
update_polyphase_filter(regs);
update_reg_attrs(overlay, regs);
- intel_overlay_unmap_regs(overlay, regs);
+ intel_legacy_overlay_unmap_regs(overlay, regs);
dev_priv->overlay = overlay;
DRM_INFO("initialized overlay support\n");
@@ -1488,7 +1488,7 @@ void intel_cleanup_overlay(struct drm_device *dev)
#ifdef CONFIG_DEBUG_FS
#include <linux/seq_file.h>
-struct intel_overlay_error_state {
+struct intel_legacy_overlay_error_state {
struct overlay_registers regs;
unsigned long base;
u32 dovsta;
@@ -1496,7 +1496,7 @@ struct intel_overlay_error_state {
};
static struct overlay_registers *
-intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
+intel_legacy_overlay_map_regs_atomic(struct intel_legacy_overlay *overlay)
{
drm_i915_private_t *dev_priv = overlay->dev->dev_private;
struct overlay_registers *regs;
@@ -1510,7 +1510,7 @@ intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
return regs;
}
-static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
+static void intel_legacy_overlay_unmap_regs_atomic(struct intel_legacy_overlay *overlay,
struct overlay_registers *regs)
{
if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
@@ -1518,12 +1518,12 @@ static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
}
-struct intel_overlay_error_state *
-intel_overlay_capture_error_state(struct drm_device *dev)
+struct intel_legacy_overlay_error_state *
+intel_legacy_overlay_capture_error_state(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
- struct intel_overlay *overlay = dev_priv->overlay;
- struct intel_overlay_error_state *error;
+ struct intel_legacy_overlay *overlay = dev_priv->overlay;
+ struct intel_legacy_overlay_error_state *error;
struct overlay_registers __iomem *regs;
if (!overlay || !overlay->active)
@@ -1540,12 +1540,12 @@ intel_overlay_capture_error_state(struct drm_device *dev)
else
error->base = (long) overlay->reg_bo->gtt_offset;
- regs = intel_overlay_map_regs_atomic(overlay);
+ regs = intel_legacy_overlay_map_regs_atomic(overlay);
if (!regs)
goto err;
memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
- intel_overlay_unmap_regs_atomic(overlay, regs);
+ intel_legacy_overlay_unmap_regs_atomic(overlay, regs);
return error;
@@ -1555,7 +1555,7 @@ err:
}
void
-intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error)
+intel_legacy_overlay_print_error_state(struct seq_file *m, struct intel_legacy_overlay_error_state *error)
{
seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
error->dovsta, error->isr);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 4/4] drm/i915: add SNB video sprite support
2011-06-07 20:07 [RFC] Updated DRM plane handling patches Jesse Barnes
` (2 preceding siblings ...)
2011-06-07 20:07 ` [PATCH 3/4] drm/i915: rename existing overlay support to "legacy" Jesse Barnes
@ 2011-06-07 20:07 ` Jesse Barnes
2011-06-07 21:01 ` Chris Wilson
2011-06-15 17:29 ` [RFC] Updated DRM plane handling patches Jesse Barnes
4 siblings, 1 reply; 22+ messages in thread
From: Jesse Barnes @ 2011-06-07 20:07 UTC (permalink / raw)
To: dri-devel; +Cc: intel-gfx
The video sprites support video surface formats natively and can handle
scaling well. So add support for them using the new DRM core overlay
support functions.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/Makefile | 1 +
drivers/gpu/drm/i915/i915_reg.h | 52 ++++++++++
drivers/gpu/drm/i915/intel_display.c | 19 +++-
drivers/gpu/drm/i915/intel_drv.h | 13 +++
drivers/gpu/drm/i915/intel_fb.c | 6 +
drivers/gpu/drm/i915/intel_overlay2.c | 172 +++++++++++++++++++++++++++++++++
6 files changed, 257 insertions(+), 6 deletions(-)
create mode 100644 drivers/gpu/drm/i915/intel_overlay2.c
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 0ae6a7c..6193471 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -28,6 +28,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
intel_dvo.o \
intel_ringbuffer.o \
intel_overlay.o \
+ intel_overlay2.o \
intel_opregion.o \
dvo_ch7xxx.o \
dvo_ch7017.o \
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 2f967af..c81c4e7 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2627,6 +2627,58 @@
#define _DSPBSURF 0x7119C
#define _DSPBTILEOFF 0x711A4
+/* Sprite A control */
+#define _DVSACNTR 0x72180
+#define DVS_ENABLE (1<<31)
+#define DVS_GAMMA_ENABLE (1<<30)
+#define DVS_PIXFORMAT_MASK (3<<25)
+#define DVS_FORMAT_YUV422 (0<<25)
+#define DVS_FORMAT_RGBX101010 (1<<25)
+#define DVS_FORMAT_RGBX888 (2<<25)
+#define DVS_FORMAT_RGBX161616 (3<<25)
+#define DVS_SOURCE_KEY (1<<22)
+#define DVS_RGB_ORDER_RGBX (1<<20)
+#define DVS_YUV_BYTE_ORDER_MASK (3<<16)
+#define DVS_YUV_ORDER_YUYV (0<<16)
+#define DVS_YUV_ORDER_UYVY (1<<16)
+#define DVS_YUV_ORDER_YVYU (2<<16)
+#define DVS_YUV_ORDER_VYUY (3<<16)
+#define DVS_DEST_KEY (1<<2)
+#define DVS_TRICKLE_FEED_DISABLE (1<<14)
+#define DVS_TILED (1<<10)
+#define _DVSASTRIDE 0x72188
+#define _DVSAPOS 0x7218c
+#define _DVSASIZE 0x72190
+#define _DVSAKEYVAL 0x72194
+#define _DVSAKEYMSK 0x72198
+#define _DVSASURF 0x7219c
+#define _DVSAKEYMAXVAL 0x721a0
+#define _DVSATILEOFF 0x721a4
+#define _DVSASURFLIVE 0x721ac
+#define _DVSASCALE 0x72204
+#define _DVSAGAMC 0x72300
+
+#define _DVSBCNTR 0x73180
+#define _DVSBSTRIDE 0x73188
+#define _DVSBPOS 0x7318c
+#define _DVSBSIZE 0x73190
+#define _DVSBKEYVAL 0x73194
+#define _DVSBKEYMSK 0x73198
+#define _DVSBSURF 0x7319c
+#define _DVSBKEYMAXVAL 0x731a0
+#define _DVSBTILEOFF 0x731a4
+#define _DVSBSURFLIVE 0x731ac
+#define _DVSBSCALE 0x73204
+#define _DVSBGAMC 0x73300
+
+#define DVSCNTR(pipe) _PIPE(pipe, _DVSACNTR, _DVSBCNTR)
+#define DVSSTRIDE(pipe) _PIPE(pipe, _DVSASTRIDE, _DVSBSTRIDE)
+#define DVSPOS(pipe) _PIPE(pipe, _DVSAPOS, _DVSBPOS)
+#define DVSSURF(pipe) _PIPE(pipe, _DVSASURF, _DVSBSURF)
+#define DVSSIZE(pipe) _PIPE(pipe, _DVSASIZE, _DVSBSIZE)
+#define DVSSCALE(pipe) _PIPE(pipe, _DVSASCALE, _DVSBSCALE)
+#define DVSTILEOFF(pipe) _PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF)
+
/* VBIOS regs */
#define VGACNTRL 0x71400
# define VGA_DISP_DISABLE (1 << 31)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 7901f16..72a570a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -900,8 +900,8 @@ static void assert_panel_unlocked(struct drm_i915_private *dev_priv,
pipe_name(pipe));
}
-static void assert_pipe(struct drm_i915_private *dev_priv,
- enum pipe pipe, bool state)
+void assert_pipe(struct drm_i915_private *dev_priv,
+ enum pipe pipe, bool state)
{
int reg;
u32 val;
@@ -914,8 +914,6 @@ static void assert_pipe(struct drm_i915_private *dev_priv,
"pipe %c assertion failure (expected %s, current %s)\n",
pipe_name(pipe), state_string(state), state_string(cur_state));
}
-#define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
-#define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
static void assert_plane_enabled(struct drm_i915_private *dev_priv,
enum plane plane)
@@ -4319,7 +4317,8 @@ static void sandybridge_update_wm(struct drm_device *dev)
&sandybridge_cursor_wm_info, latency,
&plane_wm, &cursor_wm)) {
I915_WRITE(WM0_PIPEA_ILK,
- (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
+ (plane_wm << WM0_PIPE_PLANE_SHIFT) |
+ (plane_wm << WM0_PIPE_SPRITE_SHIFT) | cursor_wm);
DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
" plane %d, " "cursor: %d\n",
plane_wm, cursor_wm);
@@ -4331,7 +4330,8 @@ static void sandybridge_update_wm(struct drm_device *dev)
&sandybridge_cursor_wm_info, latency,
&plane_wm, &cursor_wm)) {
I915_WRITE(WM0_PIPEB_ILK,
- (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
+ (plane_wm << WM0_PIPE_PLANE_SHIFT) |
+ (plane_wm << WM0_PIPE_SPRITE_SHIFT) | cursor_wm);
DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
" plane %d, cursor: %d\n",
plane_wm, cursor_wm);
@@ -4371,6 +4371,11 @@ static void sandybridge_update_wm(struct drm_device *dev)
(plane_wm << WM1_LP_SR_SHIFT) |
cursor_wm);
+#if 0
+ I915_WRITE(WM1S_LP_ILK,
+ WM1S_LP_EN |
+#endif
+
/* WM2 */
if (!ironlake_compute_srwm(dev, 2, enabled,
SNB_READ_WM2_LATENCY() * 500,
@@ -8013,6 +8018,8 @@ void intel_modeset_init(struct drm_device *dev)
for (i = 0; i < dev_priv->num_pipe; i++) {
intel_crtc_init(dev, i);
+ if (HAS_PCH_SPLIT(dev))
+ intel_plane_init(dev, i);
}
/* Just disable it once at startup */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d73e622..f109f9e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -173,10 +173,17 @@ struct intel_crtc {
unsigned int bpp;
};
+struct intel_plane {
+ struct drm_plane base;
+ enum pipe pipe;
+ u32 lut_r[1024], lut_g[1024], lut_b[1024];
+};
+
#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
#define to_intel_connector(x) container_of(x, struct intel_connector, base)
#define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
#define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
+#define to_intel_plane(x) container_of(x, struct intel_plane, base)
#define DIP_TYPE_AVI 0x82
#define DIP_VERSION_AVI 0x2
@@ -255,6 +262,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
extern bool intel_dpd_is_edp(struct drm_device *dev);
extern void intel_edp_link_config (struct intel_encoder *, int *, int *);
extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder);
+extern void intel_plane_init(struct drm_device *dev, enum pipe pipe);
/* intel_panel.c */
extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
@@ -346,5 +354,10 @@ extern int intel_overlay_attrs(struct drm_device *dev, void *data,
extern void intel_fb_output_poll_changed(struct drm_device *dev);
extern void intel_fb_restore_mode(struct drm_device *dev);
+extern void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
+ bool state);
+#define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
+#define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
+
extern void intel_init_clock_gating(struct drm_device *dev);
#endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index 11baa99..513a40c 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -270,8 +270,14 @@ void intel_fb_restore_mode(struct drm_device *dev)
{
int ret;
drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_mode_config *config = &dev->mode_config;
+ struct drm_plane *plane;
ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper);
if (ret)
DRM_DEBUG("failed to restore crtc mode\n");
+
+ /* Be sure to shut off any planes that may be active */
+ list_for_each_entry(plane, &config->plane_list, head)
+ plane->funcs->disable_plane(plane);
}
diff --git a/drivers/gpu/drm/i915/intel_overlay2.c b/drivers/gpu/drm/i915/intel_overlay2.c
new file mode 100644
index 0000000..e029e05
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_overlay2.c
@@ -0,0 +1,172 @@
+/*
+ * 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,
+ int x, int y)
+{
+ 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;
+ int pipe = intel_plane->pipe;
+ unsigned long start, offset;
+ u32 dvscntr;
+ u32 reg = DVSCNTR(pipe);
+ int ret = 0;
+
+ assert_pipe_enabled(dev_priv, pipe);
+
+ intel_fb = to_intel_framebuffer(fb);
+ obj = intel_fb->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;
+ }
+
+ 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));
+
+out_unlock:
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+static void
+intel_disable_plane(struct drm_plane *plane)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ int pipe = intel_plane->pipe;
+
+ I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE);
+ I915_WRITE(DVSSURF(pipe), 0);
+ POSTING_READ(DVSSURF(pipe));
+}
+
+static const struct drm_plane_funcs intel_plane_funcs = {
+ .update_plane = intel_update_plane,
+ .disable_plane = intel_disable_plane,
+};
+
+static uint32_t snb_plane_formats[] = {
+ V4L2_PIX_FMT_BGR32,
+ V4L2_PIX_FMT_RGB32,
+ V4L2_PIX_FMT_YUYV,
+ V4L2_PIX_FMT_YVYU,
+ V4L2_PIX_FMT_UYVY,
+ V4L2_PIX_FMT_VYUY,
+};
+
+void
+intel_plane_init(struct drm_device *dev, enum pipe pipe)
+{
+ struct intel_plane *intel_plane;
+
+ if (!IS_GEN6(dev)) {
+ DRM_ERROR("new plane code only for SNB\n");
+ return;
+ }
+
+ intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL);
+ if (!intel_plane)
+ return;
+
+ intel_plane->pipe = pipe;
+ drm_plane_init(dev, &intel_plane->base, &intel_plane_funcs,
+ snb_plane_formats, ARRAY_SIZE(snb_plane_formats));
+}
+
--
1.7.4.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [Intel-gfx] [PATCH 3/4] drm/i915: rename existing overlay support to "legacy"
2011-06-07 20:07 ` [PATCH 3/4] drm/i915: rename existing overlay support to "legacy" Jesse Barnes
@ 2011-06-07 20:59 ` Chris Wilson
0 siblings, 0 replies; 22+ messages in thread
From: Chris Wilson @ 2011-06-07 20:59 UTC (permalink / raw)
To: Jesse Barnes, dri-devel; +Cc: intel-gfx
On Tue, 7 Jun 2011 13:07:41 -0700, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> 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>
> ---
> @@ -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;
We need to change the name here as well, unless you have some
differently name error struct up your sleeve.
struct intel_sprite_error_state?
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 3cfc391..d73e622 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -161,7 +161,7 @@ struct intel_crtc {
> bool busy; /* is scanout buffer being updated frequently? */
> struct timer_list idle_timer;
> bool lowfreq_avail;
> - struct intel_overlay *overlay;
> + struct intel_legacy_overlay *overlay;
> struct intel_unpin_work *unpin_work;
> int fdi_lanes;
And here. Give the old code longer names, we don't want to be touching
it ever again. ;-)
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 4/4] drm/i915: add SNB video sprite support
2011-06-07 20:07 ` [PATCH 4/4] drm/i915: add SNB video sprite support Jesse Barnes
@ 2011-06-07 21:01 ` Chris Wilson
0 siblings, 0 replies; 22+ messages in thread
From: Chris Wilson @ 2011-06-07 21:01 UTC (permalink / raw)
To: Jesse Barnes, dri-devel; +Cc: intel-gfx
On Tue, 7 Jun 2011 13:07:42 -0700, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> The video sprites support video surface formats natively and can handle
> scaling well. So add support for them using the new DRM core overlay
> support functions.
>
> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> ---
> drivers/gpu/drm/i915/Makefile | 1 +
> drivers/gpu/drm/i915/i915_reg.h | 52 ++++++++++
> drivers/gpu/drm/i915/intel_display.c | 19 +++-
> drivers/gpu/drm/i915/intel_drv.h | 13 +++
> drivers/gpu/drm/i915/intel_fb.c | 6 +
> drivers/gpu/drm/i915/intel_overlay2.c | 172 +++++++++++++++++++++++++++++++++
0 points for inspiration. intel_video_sprite?
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 1/4] drm: add plane support
2011-06-07 20:07 ` [PATCH 1/4] drm: add plane support Jesse Barnes
@ 2011-06-07 21:01 ` Jesse Barnes
2011-06-08 9:41 ` Marcus Lorentzon
2011-06-07 21:05 ` Jesse Barnes
1 sibling, 1 reply; 22+ messages in thread
From: Jesse Barnes @ 2011-06-07 21:01 UTC (permalink / raw)
To: dri-devel; +Cc: intel-gfx
On Tue, 7 Jun 2011 13:07:39 -0700
Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> +/* Planes blend with or override other bits on the CRTC */
> +struct drm_mode_set_plane {
> + __u32 plane_id;
> + __u32 crtc_id;
> + __u32 fb_id; /* contains surface format type */
> +
> + __u32 crtc_x, crtc_y;
> + __u32 x, y;
> +
> + /* FIXME: color key/mask, scaling, z-order, other? */
> +};
Forgot to add the scaling factors to this. Would:
__u32 scaling_x; /* fixed 16.16 format */
__u32 scaling_y;
work for people?
Color key and z-order can be specified through a new ioctl, as can any
atomic flip that we want to occur with other activity.
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 1/4] drm: add plane support
2011-06-07 20:07 ` [PATCH 1/4] drm: add plane support Jesse Barnes
2011-06-07 21:01 ` Jesse Barnes
@ 2011-06-07 21:05 ` Jesse Barnes
1 sibling, 0 replies; 22+ messages in thread
From: Jesse Barnes @ 2011-06-07 21:05 UTC (permalink / raw)
To: Jesse Barnes; +Cc: intel-gfx, dri-devel
On Tue, 7 Jun 2011 13:07:39 -0700
Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> +#define DRM_MODE_PLANE_FORMAT_YUV422 1 /* YUV 4:2:2 packed */
> +#define DRM_MODE_PLANE_FORMAT_RGBX101010 2 /* RGB 10bpc, ign. alpha */
> +#define DRM_MODE_PLANE_FORMAT_RGBX888 3 /* Standard x:8:8:8 RGB */
> +#define DRM_MODE_PLANE_FORMAT_RGBX161616 4 /* x:16:16:16 float RGB */
> +
Oops and ignore these, I knew I left some extras in there somewhere...
These are replaced by the V4L defines.
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 1/4] drm: add plane support
2011-06-07 21:01 ` Jesse Barnes
@ 2011-06-08 9:41 ` Marcus Lorentzon
2011-06-08 18:54 ` Jesse Barnes
0 siblings, 1 reply; 22+ messages in thread
From: Marcus Lorentzon @ 2011-06-08 9:41 UTC (permalink / raw)
To: Jesse Barnes
Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
On 06/07/2011 11:01 PM, Jesse Barnes wrote:
> On Tue, 7 Jun 2011 13:07:39 -0700
> Jesse Barnes<jbarnes@virtuousgeek.org> wrote:
>
>
>> +/* Planes blend with or override other bits on the CRTC */
>> +struct drm_mode_set_plane {
>> + __u32 plane_id;
>> + __u32 crtc_id;
>> + __u32 fb_id; /* contains surface format type */
>> +
>> + __u32 crtc_x, crtc_y;
>> + __u32 x, y;
>> +
>> + /* FIXME: color key/mask, scaling, z-order, other? */
>> +};
>>
> Forgot to add the scaling factors to this. Would:
> __u32 scaling_x; /* fixed 16.16 format */
> __u32 scaling_y;
> work for people?
>
If you want to pan around in zoomed in video/viewfinder/snapshots it
might be better to have a fixed 16.16 source rectangle and a integer
destination rectangle. That way you can move around the zoomed in source
rectangle in small increments and upscale it to destination rectangle
(and skip fractions if HW don't support it). For example, if you zoom 4x
and have only fixed 16.16 scaling factor, you still get the the integer
fb (x, y) position in the top left corner (crtc_x, crtc_y) of the
overlay. And when you pan in the overlay, you will have to move source
rectangle in 4 destination pixel increments. So what about this instead:
__u32 x, y, src_w, src_h; /* fixed 16.16 */
__u32 crtc_x, crtc_y, crtc_w, crtc_h;
Maybe rename x, y to src_x, src_y? crtc_w/h is needed to define zoom
factor (scaling_[wh] = crtc_[wh] / src_[wh]).
So the "zoom transform" would be defined by (src_x, src_y, src_w, src_h)
=> (crtc_x, crtc_y, crtc_w, crtc_h)
It also gets rid of how to handle corner cases where scaling factor
defines a source area outside source fb. Now you can just say both rect
has to be inside crtc/fb. And you can also animate/move/clip a zoomed
overlay off screen without picture jumping (fb and display coords don't
align when zoomed).
Summary, rectangles allow more precise representation of zoom factor,
and 16.16 source coords for stable image when moving overlay off screen
(clipping) or panning overlay content.
BTW. Why not just add "__s32 z;" too? drm_mode_set_plane seems to be
plane position setup.
/BR
/Marcus
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 1/4] drm: add plane support
2011-06-08 9:41 ` Marcus Lorentzon
@ 2011-06-08 18:54 ` Jesse Barnes
2011-06-09 9:16 ` Marcus Lorentzon
0 siblings, 1 reply; 22+ messages in thread
From: Jesse Barnes @ 2011-06-08 18:54 UTC (permalink / raw)
To: Marcus Lorentzon
Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
On Wed, 8 Jun 2011 11:41:17 +0200
Marcus Lorentzon <marcus.xm.lorentzon@stericsson.com> wrote:
> On 06/07/2011 11:01 PM, Jesse Barnes wrote:
> > On Tue, 7 Jun 2011 13:07:39 -0700
> > Jesse Barnes<jbarnes@virtuousgeek.org> wrote:
> >
> >
> >> +/* Planes blend with or override other bits on the CRTC */
> >> +struct drm_mode_set_plane {
> >> + __u32 plane_id;
> >> + __u32 crtc_id;
> >> + __u32 fb_id; /* contains surface format type */
> >> +
> >> + __u32 crtc_x, crtc_y;
> >> + __u32 x, y;
> >> +
> >> + /* FIXME: color key/mask, scaling, z-order, other? */
> >> +};
> >>
> > Forgot to add the scaling factors to this. Would:
> > __u32 scaling_x; /* fixed 16.16 format */
> > __u32 scaling_y;
> > work for people?
> >
>
> If you want to pan around in zoomed in video/viewfinder/snapshots it
> might be better to have a fixed 16.16 source rectangle and a integer
> destination rectangle. That way you can move around the zoomed in source
> rectangle in small increments and upscale it to destination rectangle
> (and skip fractions if HW don't support it). For example, if you zoom 4x
> and have only fixed 16.16 scaling factor, you still get the the integer
> fb (x, y) position in the top left corner (crtc_x, crtc_y) of the
> overlay. And when you pan in the overlay, you will have to move source
> rectangle in 4 destination pixel increments. So what about this instead:
>
> __u32 x, y, src_w, src_h; /* fixed 16.16 */
> __u32 crtc_x, crtc_y, crtc_w, crtc_h;
>
> Maybe rename x, y to src_x, src_y? crtc_w/h is needed to define zoom
> factor (scaling_[wh] = crtc_[wh] / src_[wh]).
>
> So the "zoom transform" would be defined by (src_x, src_y, src_w, src_h)
> => (crtc_x, crtc_y, crtc_w, crtc_h)
>
> It also gets rid of how to handle corner cases where scaling factor
> defines a source area outside source fb. Now you can just say both rect
> has to be inside crtc/fb. And you can also animate/move/clip a zoomed
> overlay off screen without picture jumping (fb and display coords don't
> align when zoomed).
>
> Summary, rectangles allow more precise representation of zoom factor,
> and 16.16 source coords for stable image when moving overlay off screen
> (clipping) or panning overlay content.
>
> BTW. Why not just add "__s32 z;" too? drm_mode_set_plane seems to be
> plane position setup.
Yeah, all good points. I was thinking the source info could be mostly
gleaned from the associated fb, but if you have hw that can source just
a rect and scale it, passing rects around makes the most sense.
And z-order is a trivial addition, so I have no problem with that. But
communicating plane blending restrictions (including z-order) still has
to be done with a separate ioctl. But that should probably be added by
someone who has crazy hardware and the ability to test it!
Thanks,
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
2011-06-07 20:07 ` [PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format Jesse Barnes
@ 2011-06-09 4:05 ` Dave Airlie
2011-06-09 8:21 ` Alan Cox
0 siblings, 1 reply; 22+ messages in thread
From: Dave Airlie @ 2011-06-09 4:05 UTC (permalink / raw)
To: Jesse Barnes; +Cc: dri-devel
On Tue, 2011-06-07 at 13:07 -0700, Jesse Barnes wrote:
> 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.
I'd rather we don't directly tie things like that, either create a
fourcc header that isn't V4L2 or DRM related and use that or generate
two headers one with DRM_ and one with V4L2 prefixes. Mainly so we can
keep the DRM interface in some way OS agnostic.
Dave.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
2011-06-09 4:05 ` Dave Airlie
@ 2011-06-09 8:21 ` Alan Cox
2011-06-09 10:40 ` Dave Airlie
0 siblings, 1 reply; 22+ messages in thread
From: Alan Cox @ 2011-06-09 8:21 UTC (permalink / raw)
To: Dave Airlie; +Cc: dri-devel
On Thu, 09 Jun 2011 14:05:59 +1000
Dave Airlie <airlied@redhat.com> wrote:
> On Tue, 2011-06-07 at 13:07 -0700, Jesse Barnes wrote:
> > 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.
>
> I'd rather we don't directly tie things like that, either create a
> fourcc header that isn't V4L2 or DRM related and use that or generate
> two headers one with DRM_ and one with V4L2 prefixes. Mainly so we can
> keep the DRM interface in some way OS agnostic.
It *is* OS agnostic (it started on the Amiga)
You also don't need a headwer with a complete list of fourcc names in it,
that is the half the point of FourCC.
Alan
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 1/4] drm: add plane support
2011-06-08 18:54 ` Jesse Barnes
@ 2011-06-09 9:16 ` Marcus Lorentzon
0 siblings, 0 replies; 22+ messages in thread
From: Marcus Lorentzon @ 2011-06-09 9:16 UTC (permalink / raw)
To: Jesse Barnes
Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
On 06/08/2011 08:54 PM, Jesse Barnes wrote:
> On Wed, 8 Jun 2011 11:41:17 +0200
> Marcus Lorentzon<marcus.xm.lorentzon@stericsson.com> wrote:
>
>
>> On 06/07/2011 11:01 PM, Jesse Barnes wrote:
>>
>>> On Tue, 7 Jun 2011 13:07:39 -0700
>>> Jesse Barnes<jbarnes@virtuousgeek.org> wrote:
>>>
>>>
>>>
>>>> +/* Planes blend with or override other bits on the CRTC */
>>>> +struct drm_mode_set_plane {
>>>> + __u32 plane_id;
>>>> + __u32 crtc_id;
>>>> + __u32 fb_id; /* contains surface format type */
>>>> +
>>>> + __u32 crtc_x, crtc_y;
>>>> + __u32 x, y;
>>>> +
>>>> + /* FIXME: color key/mask, scaling, z-order, other? */
>>>> +};
>>>>
>>>>
>>> Forgot to add the scaling factors to this. Would:
>>> __u32 scaling_x; /* fixed 16.16 format */
>>> __u32 scaling_y;
>>> work for people?
>>>
>>>
>> If you want to pan around in zoomed in video/viewfinder/snapshots it
>> might be better to have a fixed 16.16 source rectangle and a integer
>> destination rectangle. That way you can move around the zoomed in source
>> rectangle in small increments and upscale it to destination rectangle
>> (and skip fractions if HW don't support it). For example, if you zoom 4x
>> and have only fixed 16.16 scaling factor, you still get the the integer
>> fb (x, y) position in the top left corner (crtc_x, crtc_y) of the
>> overlay. And when you pan in the overlay, you will have to move source
>> rectangle in 4 destination pixel increments. So what about this instead:
>>
>> __u32 x, y, src_w, src_h; /* fixed 16.16 */
>> __u32 crtc_x, crtc_y, crtc_w, crtc_h;
>>
>> Maybe rename x, y to src_x, src_y? crtc_w/h is needed to define zoom
>> factor (scaling_[wh] = crtc_[wh] / src_[wh]).
>>
>> So the "zoom transform" would be defined by (src_x, src_y, src_w, src_h)
>> => (crtc_x, crtc_y, crtc_w, crtc_h)
>>
>> It also gets rid of how to handle corner cases where scaling factor
>> defines a source area outside source fb. Now you can just say both rect
>> has to be inside crtc/fb. And you can also animate/move/clip a zoomed
>> overlay off screen without picture jumping (fb and display coords don't
>> align when zoomed).
>>
>> Summary, rectangles allow more precise representation of zoom factor,
>> and 16.16 source coords for stable image when moving overlay off screen
>> (clipping) or panning overlay content.
>>
>> BTW. Why not just add "__s32 z;" too? drm_mode_set_plane seems to be
>> plane position setup.
>>
> Yeah, all good points. I was thinking the source info could be mostly
> gleaned from the associated fb, but if you have hw that can source just
> a rect and scale it, passing rects around makes the most sense.
>
> And z-order is a trivial addition, so I have no problem with that. But
> communicating plane blending restrictions (including z-order) still has
> to be done with a separate ioctl. But that should probably be added by
> someone who has crazy hardware and the ability to test it!
>
> Thanks,
>
After a nights sleep I think a better solution to the clipped jumping
image would be to actually allow to position the dest rect outside the
"crtc rect". That way the user never have to calculate any fixed point
position of the source rect in the non zoomed case. Instead the driver
can clip at the best possible position to limit the jumping. Because the
dest rect will always be aligned on integer pixels.
But it might still be worth keeping fixed position for source rect when
doing pan and zoom, to be used by capable HW.
So to allow simpler user code when moving/animating overlay off screen.
It would be good to allow off screen coord for dest rect. That is, make
crtc_[xy] into signed __s32.
Will try to add the commit and the blend ioctl later including tests,
but first I need to finish and push the base KMS driver :)
/BR
/Marcus
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
2011-06-09 8:21 ` Alan Cox
@ 2011-06-09 10:40 ` Dave Airlie
2011-06-09 11:55 ` Alan Cox
0 siblings, 1 reply; 22+ messages in thread
From: Dave Airlie @ 2011-06-09 10:40 UTC (permalink / raw)
To: Alan Cox; +Cc: dri-devel
On Thu, 2011-06-09 at 09:21 +0100, Alan Cox wrote:
> On Thu, 09 Jun 2011 14:05:59 +1000
> Dave Airlie <airlied@redhat.com> wrote:
>
> > On Tue, 2011-06-07 at 13:07 -0700, Jesse Barnes wrote:
> > > 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.
> >
> > I'd rather we don't directly tie things like that, either create a
> > fourcc header that isn't V4L2 or DRM related and use that or generate
> > two headers one with DRM_ and one with V4L2 prefixes. Mainly so we can
> > keep the DRM interface in some way OS agnostic.
>
> It *is* OS agnostic (it started on the Amiga)
>
> You also don't need a headwer with a complete list of fourcc names in it,
> that is the half the point of FourCC.
#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') /* 8
RGB-3-3-2 */
See that V4L2 and v4l2? I'd rather not have them used in the drm
interface, either a DRM_ variant or a FOURCC_ variant that removes the
V4L2. Also having it in a different include file to "videodev2.h", so
yes we can pass FOURCC values but I'd rather we gave people a drm
specific way to generate them or make a generic set of macros that don't
include the V4L2 headers.
Dave.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
2011-06-09 10:40 ` Dave Airlie
@ 2011-06-09 11:55 ` Alan Cox
2011-06-21 9:48 ` Laurent Pinchart
0 siblings, 1 reply; 22+ messages in thread
From: Alan Cox @ 2011-06-09 11:55 UTC (permalink / raw)
To: Dave Airlie; +Cc: dri-devel
> > You also don't need a headwer with a complete list of fourcc names in it,
> > that is the half the point of FourCC.
>
> #define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') /* 8
> RGB-3-3-2 */
>
> See that V4L2 and v4l2? I'd rather not have them used in the drm
They are just helpers. The only thing that fourcc is is a 4 byte packed
value of four symbols.
> interface, either a DRM_ variant or a FOURCC_ variant that removes the
> V4L2. Also having it in a different include file to "videodev2.h", so
> yes we can pass FOURCC values but I'd rather we gave people a drm
> specific way to generate them or make a generic set of macros that don't
> include the V4L2 headers.
You need a macro to assemble fourcc codes and that seems to be about it -
so just an equivalent of the v4l2_fourcc macro.
Alan
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC] Updated DRM plane handling patches
2011-06-07 20:07 [RFC] Updated DRM plane handling patches Jesse Barnes
` (3 preceding siblings ...)
2011-06-07 20:07 ` [PATCH 4/4] drm/i915: add SNB video sprite support Jesse Barnes
@ 2011-06-15 17:29 ` Jesse Barnes
2011-07-21 10:15 ` Joonyoung Shim
4 siblings, 1 reply; 22+ messages in thread
From: Jesse Barnes @ 2011-06-15 17:29 UTC (permalink / raw)
Cc: intel-gfx, dri-devel
On Tue, 7 Jun 2011 13:07:38 -0700
Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> This patchset updates the previous one, incorporating the feedback I
> received:
> 1) uses the v4l fourcc codes to communicate pixel format
> 2) adds a new addfb ioctl that takes a format
> 3) adds working SNB support for the new code
>
> Comments welcome. I'll be pushing intel-gpu-tools testdisplay support
> for this shortly if people want to play around with it. Next step is to
> incorporate it into X and Wayland to see if the API is rich enough for
> our needs.
And here's a very early & hackish DDX patch for this code in case other
people want to test things out. I still have to update it with the
scaling stuff we talked about and support various things (disabling
planes, controlling attributes, etc) but it's enough to get bits on the
screen at least.
Jesse
diff --git a/src/Makefile.am b/src/Makefile.am
index a7f219c..2aec5a8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -69,6 +69,7 @@ intel_drv_la_SOURCES = \
i965_reg.h \
i965_video.c \
i965_render.c \
+ intel_sprite.c \
$(NULL)
if DRI
diff --git a/src/intel.h b/src/intel.h
index 2b114c3..11d911a 100644
--- a/src/intel.h
+++ b/src/intel.h
@@ -334,6 +334,7 @@ typedef struct intel_screen_private {
int colorKey;
XF86VideoAdaptorPtr adaptor;
+ XF86VideoAdaptorPtr sprite_adaptor;
ScreenBlockHandlerProcPtr BlockHandler;
Bool overlayOn;
@@ -461,6 +462,7 @@ extern void intel_mode_fini(intel_screen_private *intel);
extern int intel_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, xf86CrtcPtr crtc);
extern int intel_crtc_id(xf86CrtcPtr crtc);
+extern int intel_crtc_to_sprite(xf86CrtcPtr crtc);
extern int intel_output_dpms_status(xf86OutputPtr output);
enum DRI2FrameEventType {
@@ -518,6 +520,7 @@ extern void I915EmitInvarientState(ScrnInfoPtr scrn);
extern void I830EmitFlush(ScrnInfoPtr scrn);
extern void I830InitVideo(ScreenPtr pScreen);
+extern XF86VideoAdaptorPtr intel_setup_sprite(ScreenPtr screen);
extern xf86CrtcPtr intel_covering_crtc(ScrnInfoPtr scrn, BoxPtr box,
xf86CrtcPtr desired, BoxPtr crtc_box_ret);
diff --git a/src/intel_display.c b/src/intel_display.c
index b55b110..4b032af 100644
--- a/src/intel_display.c
+++ b/src/intel_display.c
@@ -75,6 +75,7 @@ struct intel_crtc {
dri_bo *rotate_bo;
uint32_t rotate_pitch;
uint32_t rotate_fb_id;
+ uint32_t sprite_id;
xf86CrtcPtr crtc;
struct list link;
};
@@ -1564,9 +1565,50 @@ drm_wakeup_handler(pointer data, int err, pointer p)
drmHandleEvent(mode->fd, &mode->event_context);
}
+static void intel_crtc_find_plane(ScrnInfoPtr scrn, xf86CrtcPtr crtc)
+{
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ struct intel_crtc *intel_crtc = crtc->driver_private;
+ drmModePlaneRes *plane_resources;
+ drmModePlane *ovr;
+ uint32_t id = 0;
+ int i;
+
+ plane_resources = drmModeGetPlaneResources(intel->drmSubFD);
+ if (!plane_resources) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "failed to get plane resources: %s\n",
+ strerror(errno));
+ goto out;
+ }
+
+ for (i = 0; i < plane_resources->count_planes; i++) {
+ ovr = drmModeGetPlane(intel->drmSubFD,
+ plane_resources->planes[i]);
+ if (!ovr) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "failed to get plane info: %s\n",
+ strerror(errno));
+ continue;
+ }
+
+ if (ovr->possible_crtcs & (1 << intel_crtc_to_pipe(crtc))) {
+ id = ovr->plane_id;
+ drmModeFreePlane(ovr);
+ break;
+ }
+ drmModeFreePlane(ovr);
+ }
+
+ free(plane_resources);
+out:
+ intel_crtc->sprite_id = id;
+}
+
Bool intel_mode_pre_init(ScrnInfoPtr scrn, int fd, int cpp)
{
intel_screen_private *intel = intel_get_screen_private(scrn);
+ struct intel_crtc *intel_crtc;
struct drm_i915_getparam gp;
struct intel_mode *mode;
unsigned int i;
@@ -1597,6 +1639,9 @@ Bool intel_mode_pre_init(ScrnInfoPtr scrn, int fd, int cpp)
for (i = 0; i < mode->mode_res->count_crtcs; i++)
intel_crtc_init(scrn, mode, i);
+ list_for_each_entry(intel_crtc, &mode->crtcs, link)
+ intel_crtc_find_plane(scrn, intel_crtc->crtc);
+
for (i = 0; i < mode->mode_res->count_connectors; i++)
intel_output_init(scrn, mode, i);
@@ -1618,6 +1663,8 @@ Bool intel_mode_pre_init(ScrnInfoPtr scrn, int fd, int cpp)
}
intel->modes = mode;
+
+
return TRUE;
}
@@ -1687,3 +1734,9 @@ int intel_crtc_to_pipe(xf86CrtcPtr crtc)
struct intel_crtc *intel_crtc = crtc->driver_private;
return intel_crtc->pipe;
}
+
+int intel_crtc_to_sprite(xf86CrtcPtr crtc)
+{
+ struct intel_crtc *intel_crtc = crtc->driver_private;
+ return intel_crtc->sprite_id;
+}
diff --git a/src/intel_sprite.c b/src/intel_sprite.c
new file mode 100644
index 0000000..618a526
--- /dev/null
+++ b/src/intel_sprite.c
@@ -0,0 +1,291 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <inttypes.h>
+#include <math.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <xf86drmMode.h>
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "compiler.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86fbman.h"
+#include "regionstr.h"
+#include "randrstr.h"
+#include "windowstr.h"
+#include "damage.h"
+#include "intel.h"
+#include "intel_video.h"
+#include "i830_reg.h"
+#include "xf86xv.h"
+#include <X11/extensions/Xv.h>
+#include "dixstruct.h"
+#include "fourcc.h"
+
+#define IMAGE_MAX_WIDTH 2048
+#define IMAGE_MAX_HEIGHT 2048
+
+static XF86VideoFormatRec xv_formats[] = {
+ {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
+};
+
+static XF86ImageRec xv_images[] = {
+ XVIMAGE_YUY2,
+ XVIMAGE_UYVY,
+};
+
+static const XF86VideoEncodingRec xv_dummy_encoding[] = {
+ {
+ 0,
+ "XV_IMAGE",
+ IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
+ {1, 1}
+ }
+};
+
+static void intel_sprite_stop(ScrnInfoPtr scrn, pointer data, Bool shutdown)
+{
+}
+
+static int intel_sprite_set_attr(ScrnInfoPtr scrn, Atom attribute, INT32 value,
+ pointer data)
+{
+ return Success;
+}
+
+static int intel_sprite_get_attr(ScrnInfoPtr scrn, Atom attribute, INT32 *value,
+ pointer data)
+{
+ return Success;
+}
+
+static void intel_sprite_best_size(ScrnInfoPtr scrn, Bool motion, short vid_w,
+ short vid_h, short drw_w, short drw_h,
+ unsigned int *p_w, unsigned int *p_h,
+ pointer data)
+{
+ *p_w = vid_w;
+ *p_h = vid_h;
+}
+
+static int intel_sprite_put(ScrnInfoPtr scrn, short src_x, short src_y,
+ short drw_x, short drw_y, short src_w, short src_h,
+ short drw_w, short drw_h, int id,
+ unsigned char *buf, short width, short height,
+ Bool sync, RegionPtr clipBoxes, pointer data,
+ DrawablePtr drawable)
+{
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ intel_adaptor_private *adaptor_priv = intel_get_sprite_adaptor_private(intel);
+ dri_bo *new_frame;
+ unsigned char *src, *dst, *dst_base;
+ int pitch, i;
+ xf86CrtcPtr crtc;
+ BoxRec dst_box;
+ int ret, top, left, lines, pixel_width;
+ int plane_id;
+ uint32_t fb_id;
+ unsigned long alloc_pitch;
+
+ ret = intel_clip_video_helper(scrn, adaptor_priv, &crtc, &dst_box,
+ src_x, src_y, drw_x, drw_y,
+ src_w, src_h, drw_w, drw_h,
+ id, &top, &left, &pixel_width, &lines,
+ clipBoxes, width, height);
+ if (!ret)
+ return Success;
+
+ plane_id = intel_crtc_to_sprite(crtc);
+ if (!plane_id) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "no planes available for crtc\n");
+ return Success;
+ }
+
+ new_frame = adaptor_priv->buf;
+ pitch = ALIGN(pixel_width, 64);
+
+ if (!new_frame) {
+ uint32_t tiling_mode = I915_TILING_X;
+
+ new_frame = drm_intel_bo_alloc_tiled(intel->bufmgr,
+ "sprite buffer",
+ pixel_width, lines,
+ drawable->bitsPerPixel / 8,
+ &tiling_mode, &alloc_pitch,
+ BO_ALLOC_FOR_RENDER);
+ if (!new_frame) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "failed to create bo for video data: %s\n",
+ strerror(errno));
+ return BadAlloc;
+ }
+ adaptor_priv->reusable = TRUE;
+ adaptor_priv->buf = new_frame;
+ }
+
+ if (drm_intel_gem_bo_map_gtt(new_frame))
+ return BadAlloc;
+
+ dst_base = new_frame->virtual;
+ dst = dst_base + adaptor_priv->YBufOffset;
+
+ src = buf + (top * (width * 2)) + (left << 1);
+
+ for (i = 0; i < height; i++) {
+ memcpy(dst, src, width * 2);
+ src += width * 2;
+ dst += pitch;
+ }
+
+ drm_intel_gem_bo_unmap_gtt(new_frame);
+
+ ret = drmModeAddFB2(intel->drmSubFD, pixel_width, lines,
+ V4L2_PIX_FMT_RGB32, drawable->depth,
+ drawable->bitsPerPixel, alloc_pitch,
+ new_frame->handle, &fb_id);
+ if (ret) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "failed to add fb for video data: %s\n",
+ strerror(errno));
+ return BadAlloc;
+ }
+
+ ret = drmModeSetPlane(intel->drmSubFD, plane_id, intel_crtc_id(crtc),
+ fb_id, left, top, 0, 0);
+ if (ret) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "failed to enable plane for video data: %s\n",
+ strerror(errno));
+ return BadAlloc;
+ }
+
+ return Success;
+}
+
+static int intel_sprite_query_attrs(ScrnInfoPtr scrn, int id, unsigned short *w,
+ unsigned short *h, int *pitches,
+ int *offsets)
+{
+ int size;
+
+ if (*w > IMAGE_MAX_WIDTH)
+ *w = IMAGE_MAX_WIDTH;
+ if (*h > IMAGE_MAX_HEIGHT)
+ *h = IMAGE_MAX_HEIGHT;
+
+ *w = (*w + 1) & ~1;
+ if (offsets)
+ offsets[0] = 0;
+
+ switch (id) {
+ case FOURCC_YUY2:
+ default:
+ size = *w << 1;
+ if (pitches)
+ pitches[0] = size;
+ size *= *h;
+ break;
+ }
+
+ return size;
+}
+
+XF86VideoAdaptorPtr intel_setup_sprite(ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ XF86VideoAdaptorPtr adapt;
+ intel_adaptor_private *adaptor_priv;
+ drmModePlaneRes *plane_resources;
+ drmModePlane *planes;
+
+ adapt = calloc(1, sizeof(XF86VideoAdaptorRec) +
+ sizeof(intel_adaptor_private) + sizeof(DevUnion));
+ if (!adapt)
+ goto err;
+
+ plane_resources = drmModeGetPlaneResources(intel->drmSubFD);
+ if (!plane_resources) {
+ xf86DrvMsg(scrn->scrnIndex, X_INFO, "No sprite support\n");
+ goto err_free_adaptor;
+ }
+
+ planes = calloc(plane_resources->count_planes, sizeof(*planes));
+ if (!planes) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Out of memory in %s\n",
+ __func__);
+ goto err_free_res;
+ }
+
+ adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+ adapt->flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT */ ;
+ adapt->name = "Intel(R) Video Sprite";
+ adapt->nEncodings = ARRAY_SIZE(xv_dummy_encoding);
+ adapt->pEncodings = xnfalloc(sizeof(xv_dummy_encoding));
+ memcpy(adapt->pEncodings, xv_dummy_encoding, sizeof(xv_dummy_encoding));
+ adapt->nFormats = ARRAY_SIZE(xv_formats);
+ adapt->pFormats = xv_formats;
+ adapt->nPorts = 1;
+ adapt->pPortPrivates = (DevUnion *) (&adapt[1]);
+
+ adaptor_priv = (intel_adaptor_private *)&adapt->pPortPrivates[1];
+ adapt->pPortPrivates[0].ptr = (pointer) (adaptor_priv);
+
+ adapt->nAttributes = 0;
+ adapt->pAttributes = NULL;
+
+ adapt->nImages = ARRAY_SIZE(xv_images);
+ adapt->pImages = xv_images;
+
+ adapt->PutVideo = NULL;
+ adapt->PutStill = NULL;
+ adapt->GetVideo = NULL;
+ adapt->GetStill = NULL;
+ adapt->StopVideo = intel_sprite_stop;
+ adapt->SetPortAttribute = intel_sprite_set_attr;
+ adapt->GetPortAttribute = intel_sprite_get_attr;
+ adapt->QueryBestSize = intel_sprite_best_size;
+ adapt->PutImage = intel_sprite_put;
+ adapt->QueryImageAttributes = intel_sprite_query_attrs;
+
+ adaptor_priv->textured = FALSE;
+ adaptor_priv->colorKey = intel->colorKey & ((1 << scrn->depth) - 1);
+ adaptor_priv->brightness = -19; /* (255/219) * -16 */
+ adaptor_priv->contrast = 75; /* 255/219 * 64 */
+ adaptor_priv->saturation = 146; /* 128/112 * 128 */
+ adaptor_priv->desired_crtc = NULL;
+ adaptor_priv->buf = NULL;
+ adaptor_priv->old_buf[0] = NULL;
+ adaptor_priv->old_buf[1] = NULL;
+ adaptor_priv->gamma5 = 0xc0c0c0;
+ adaptor_priv->gamma4 = 0x808080;
+ adaptor_priv->gamma3 = 0x404040;
+ adaptor_priv->gamma2 = 0x202020;
+ adaptor_priv->gamma1 = 0x101010;
+ adaptor_priv->gamma0 = 0x080808;
+ adaptor_priv->planes = planes;
+
+ adaptor_priv->rotation = RR_Rotate_0;
+
+ /* gotta uninit this someplace */
+ REGION_NULL(screen, &adaptor_priv->clip);
+
+ intel->sprite_adaptor = adapt;
+
+ free(plane_resources);
+
+ return adapt;
+
+err_free_res:
+ free(plane_resources);
+err_free_adaptor:
+ free(adapt);
+err:
+ return NULL;
+}
diff --git a/src/intel_video.c b/src/intel_video.c
index 021ca5f..c873d34 100644
--- a/src/intel_video.c
+++ b/src/intel_video.c
@@ -337,7 +337,8 @@ void I830InitVideo(ScreenPtr screen)
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
intel_screen_private *intel = intel_get_screen_private(scrn);
XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
- XF86VideoAdaptorPtr overlayAdaptor = NULL, texturedAdaptor = NULL;
+ XF86VideoAdaptorPtr overlayAdaptor = NULL, texturedAdaptor = NULL,
+ spriteAdaptor = NULL;
int num_adaptors;
num_adaptors = xf86XVListGenericAdaptors(scrn, &adaptors);
@@ -345,7 +346,7 @@ void I830InitVideo(ScreenPtr screen)
* adaptors.
*/
newAdaptors =
- malloc((num_adaptors + 2) * sizeof(XF86VideoAdaptorPtr *));
+ malloc((num_adaptors + 3) * sizeof(XF86VideoAdaptorPtr *));
if (newAdaptors == NULL)
return;
@@ -388,6 +389,13 @@ void I830InitVideo(ScreenPtr screen)
}
}
+
+ spriteAdaptor = intel_setup_sprite(screen);
+ if (spriteAdaptor) {
+ xf86DrvMsg(scrn->scrnIndex, X_INFO, "Set up video sprite\n");
+ adaptors[num_adaptors++] = spriteAdaptor;
+ }
+
if (overlayAdaptor && intel->XvPreferOverlay)
adaptors[num_adaptors++] = overlayAdaptor;
@@ -405,10 +413,9 @@ void I830InitVideo(ScreenPtr screen)
intel->XvEnabled = FALSE;
}
-#ifdef INTEL_XVMC
if (texturedAdaptor)
intel_xvmc_adaptor_init(screen);
-#endif
+
free(adaptors);
}
@@ -1226,7 +1233,7 @@ intel_display_overlay(ScrnInfoPtr scrn, xf86CrtcPtr crtc,
src_w, src_h, drw_w, drw_h);
}
-static Bool
+Bool
intel_clip_video_helper(ScrnInfoPtr scrn,
intel_adaptor_private *adaptor_priv,
xf86CrtcPtr * crtc_ret,
diff --git a/src/intel_video.h b/src/intel_video.h
index f405d40..6dd7f88 100644
--- a/src/intel_video.h
+++ b/src/intel_video.h
@@ -55,6 +55,8 @@ typedef struct {
drm_intel_bo *buf, *old_buf[2];
Bool reusable;
+ struct _drmModePlane *planes;
+
Bool textured;
Rotation rotation; /* should remove intel->rotation later */
@@ -67,6 +69,12 @@ intel_get_adaptor_private(intel_screen_private *intel)
return intel->adaptor->pPortPrivates[0].ptr;
}
+static inline intel_adaptor_private *
+intel_get_sprite_adaptor_private(intel_screen_private *intel)
+{
+ return intel->sprite_adaptor->pPortPrivates[0].ptr;
+}
+
void I915DisplayVideoTextured(ScrnInfoPtr scrn,
intel_adaptor_private *adaptor_priv,
int id, RegionPtr dstRegion, short width,
@@ -93,3 +101,16 @@ void i965_free_video(ScrnInfoPtr scrn);
int is_planar_fourcc(int id);
void intel_video_block_handler(intel_screen_private *intel);
+
+extern Bool intel_clip_video_helper(ScrnInfoPtr scrn,
+ intel_adaptor_private *adaptor_priv,
+ xf86CrtcPtr * crtc_ret,
+ BoxPtr dst,
+ short src_x, short src_y,
+ short drw_x, short drw_y,
+ short src_w, short src_h,
+ short drw_w, short drw_h,
+ int id,
+ int *top, int* left, int* npixels,
+ int *nlines,
+ RegionPtr reg, INT32 width, INT32 height);
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 4/4] drm/i915: add SNB video sprite support
2011-06-20 20:11 [RFC] Updated plane support v3 Jesse Barnes
@ 2011-06-20 20:11 ` Jesse Barnes
0 siblings, 0 replies; 22+ messages in thread
From: Jesse Barnes @ 2011-06-20 20:11 UTC (permalink / raw)
To: dri-devel; +Cc: intel-gfx
The video sprites support video surface formats natively and can handle
scaling well. So add support for them using the new DRM core overlay
support functions.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/Makefile | 1 +
drivers/gpu/drm/i915/i915_reg.h | 52 +++++++++
drivers/gpu/drm/i915/intel_display.c | 19 +++-
drivers/gpu/drm/i915/intel_drv.h | 14 +++
drivers/gpu/drm/i915/intel_fb.c | 6 +
drivers/gpu/drm/i915/intel_overlay2.c | 188 +++++++++++++++++++++++++++++++++
6 files changed, 274 insertions(+), 6 deletions(-)
create mode 100644 drivers/gpu/drm/i915/intel_overlay2.c
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 0ae6a7c..6193471 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -28,6 +28,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
intel_dvo.o \
intel_ringbuffer.o \
intel_overlay.o \
+ intel_overlay2.o \
intel_opregion.o \
dvo_ch7xxx.o \
dvo_ch7017.o \
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 2f967af..c81c4e7 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2627,6 +2627,58 @@
#define _DSPBSURF 0x7119C
#define _DSPBTILEOFF 0x711A4
+/* Sprite A control */
+#define _DVSACNTR 0x72180
+#define DVS_ENABLE (1<<31)
+#define DVS_GAMMA_ENABLE (1<<30)
+#define DVS_PIXFORMAT_MASK (3<<25)
+#define DVS_FORMAT_YUV422 (0<<25)
+#define DVS_FORMAT_RGBX101010 (1<<25)
+#define DVS_FORMAT_RGBX888 (2<<25)
+#define DVS_FORMAT_RGBX161616 (3<<25)
+#define DVS_SOURCE_KEY (1<<22)
+#define DVS_RGB_ORDER_RGBX (1<<20)
+#define DVS_YUV_BYTE_ORDER_MASK (3<<16)
+#define DVS_YUV_ORDER_YUYV (0<<16)
+#define DVS_YUV_ORDER_UYVY (1<<16)
+#define DVS_YUV_ORDER_YVYU (2<<16)
+#define DVS_YUV_ORDER_VYUY (3<<16)
+#define DVS_DEST_KEY (1<<2)
+#define DVS_TRICKLE_FEED_DISABLE (1<<14)
+#define DVS_TILED (1<<10)
+#define _DVSASTRIDE 0x72188
+#define _DVSAPOS 0x7218c
+#define _DVSASIZE 0x72190
+#define _DVSAKEYVAL 0x72194
+#define _DVSAKEYMSK 0x72198
+#define _DVSASURF 0x7219c
+#define _DVSAKEYMAXVAL 0x721a0
+#define _DVSATILEOFF 0x721a4
+#define _DVSASURFLIVE 0x721ac
+#define _DVSASCALE 0x72204
+#define _DVSAGAMC 0x72300
+
+#define _DVSBCNTR 0x73180
+#define _DVSBSTRIDE 0x73188
+#define _DVSBPOS 0x7318c
+#define _DVSBSIZE 0x73190
+#define _DVSBKEYVAL 0x73194
+#define _DVSBKEYMSK 0x73198
+#define _DVSBSURF 0x7319c
+#define _DVSBKEYMAXVAL 0x731a0
+#define _DVSBTILEOFF 0x731a4
+#define _DVSBSURFLIVE 0x731ac
+#define _DVSBSCALE 0x73204
+#define _DVSBGAMC 0x73300
+
+#define DVSCNTR(pipe) _PIPE(pipe, _DVSACNTR, _DVSBCNTR)
+#define DVSSTRIDE(pipe) _PIPE(pipe, _DVSASTRIDE, _DVSBSTRIDE)
+#define DVSPOS(pipe) _PIPE(pipe, _DVSAPOS, _DVSBPOS)
+#define DVSSURF(pipe) _PIPE(pipe, _DVSASURF, _DVSBSURF)
+#define DVSSIZE(pipe) _PIPE(pipe, _DVSASIZE, _DVSBSIZE)
+#define DVSSCALE(pipe) _PIPE(pipe, _DVSASCALE, _DVSBSCALE)
+#define DVSTILEOFF(pipe) _PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF)
+
/* VBIOS regs */
#define VGACNTRL 0x71400
# define VGA_DISP_DISABLE (1 << 31)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 7901f16..72a570a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -900,8 +900,8 @@ static void assert_panel_unlocked(struct drm_i915_private *dev_priv,
pipe_name(pipe));
}
-static void assert_pipe(struct drm_i915_private *dev_priv,
- enum pipe pipe, bool state)
+void assert_pipe(struct drm_i915_private *dev_priv,
+ enum pipe pipe, bool state)
{
int reg;
u32 val;
@@ -914,8 +914,6 @@ static void assert_pipe(struct drm_i915_private *dev_priv,
"pipe %c assertion failure (expected %s, current %s)\n",
pipe_name(pipe), state_string(state), state_string(cur_state));
}
-#define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
-#define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
static void assert_plane_enabled(struct drm_i915_private *dev_priv,
enum plane plane)
@@ -4319,7 +4317,8 @@ static void sandybridge_update_wm(struct drm_device *dev)
&sandybridge_cursor_wm_info, latency,
&plane_wm, &cursor_wm)) {
I915_WRITE(WM0_PIPEA_ILK,
- (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
+ (plane_wm << WM0_PIPE_PLANE_SHIFT) |
+ (plane_wm << WM0_PIPE_SPRITE_SHIFT) | cursor_wm);
DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
" plane %d, " "cursor: %d\n",
plane_wm, cursor_wm);
@@ -4331,7 +4330,8 @@ static void sandybridge_update_wm(struct drm_device *dev)
&sandybridge_cursor_wm_info, latency,
&plane_wm, &cursor_wm)) {
I915_WRITE(WM0_PIPEB_ILK,
- (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
+ (plane_wm << WM0_PIPE_PLANE_SHIFT) |
+ (plane_wm << WM0_PIPE_SPRITE_SHIFT) | cursor_wm);
DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
" plane %d, cursor: %d\n",
plane_wm, cursor_wm);
@@ -4371,6 +4371,11 @@ static void sandybridge_update_wm(struct drm_device *dev)
(plane_wm << WM1_LP_SR_SHIFT) |
cursor_wm);
+#if 0
+ I915_WRITE(WM1S_LP_ILK,
+ WM1S_LP_EN |
+#endif
+
/* WM2 */
if (!ironlake_compute_srwm(dev, 2, enabled,
SNB_READ_WM2_LATENCY() * 500,
@@ -8013,6 +8018,8 @@ void intel_modeset_init(struct drm_device *dev)
for (i = 0; i < dev_priv->num_pipe; i++) {
intel_crtc_init(dev, i);
+ if (HAS_PCH_SPLIT(dev))
+ intel_plane_init(dev, i);
}
/* Just disable it once at startup */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d73e622..232d797 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -173,10 +173,18 @@ struct intel_crtc {
unsigned int bpp;
};
+struct intel_plane {
+ struct drm_plane base;
+ enum pipe pipe;
+ struct drm_i915_gem_object *obj;
+ u32 lut_r[1024], lut_g[1024], lut_b[1024];
+};
+
#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
#define to_intel_connector(x) container_of(x, struct intel_connector, base)
#define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
#define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
+#define to_intel_plane(x) container_of(x, struct intel_plane, base)
#define DIP_TYPE_AVI 0x82
#define DIP_VERSION_AVI 0x2
@@ -255,6 +263,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
extern bool intel_dpd_is_edp(struct drm_device *dev);
extern void intel_edp_link_config (struct intel_encoder *, int *, int *);
extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder);
+extern void intel_plane_init(struct drm_device *dev, enum pipe pipe);
/* intel_panel.c */
extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
@@ -346,5 +355,10 @@ extern int intel_overlay_attrs(struct drm_device *dev, void *data,
extern void intel_fb_output_poll_changed(struct drm_device *dev);
extern void intel_fb_restore_mode(struct drm_device *dev);
+extern void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
+ bool state);
+#define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
+#define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
+
extern void intel_init_clock_gating(struct drm_device *dev);
#endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index 11baa99..513a40c 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -270,8 +270,14 @@ void intel_fb_restore_mode(struct drm_device *dev)
{
int ret;
drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_mode_config *config = &dev->mode_config;
+ struct drm_plane *plane;
ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper);
if (ret)
DRM_DEBUG("failed to restore crtc mode\n");
+
+ /* Be sure to shut off any planes that may be active */
+ list_for_each_entry(plane, &config->plane_list, head)
+ plane->funcs->disable_plane(plane);
}
diff --git a/drivers/gpu/drm/i915/intel_overlay2.c b/drivers/gpu/drm/i915/intel_overlay2.c
new file mode 100644
index 0000000..19fd76f
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_overlay2.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Jesse Barnes <jbarnes@virtuousgeek.org>
+ *
+ * New plane/sprite handling.
+ *
+ * The older chips had a separate interface for programming plane related
+ * registers; newer ones are much simpler and we can use the new DRM plane
+ * support.
+ */
+#include "drmP.h"
+#include "drm_crtc.h"
+#include "intel_drv.h"
+#include "i915_drm.h"
+#include "i915_drv.h"
+
+static int
+intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
+ struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+ unsigned int crtc_w, unsigned int crtc_h,
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ struct intel_framebuffer *intel_fb;
+ struct drm_i915_gem_object *obj, *old_obj;
+ int pipe = intel_plane->pipe;
+ unsigned long start, offset;
+ u32 dvscntr;
+ u32 reg = DVSCNTR(pipe);
+ int ret = 0;
+ int x = src_x >> 16, y = src_y >> 16;
+
+ assert_pipe_enabled(dev_priv, pipe);
+
+ intel_fb = to_intel_framebuffer(fb);
+ obj = intel_fb->obj;
+
+ old_obj = intel_plane->obj;
+
+ mutex_lock(&dev->struct_mutex);
+ ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
+ if (ret)
+ goto out_unlock;
+
+ intel_plane->obj = obj;
+
+ dvscntr = I915_READ(reg);
+
+ /* Mask out pixel format bits in case we change it */
+ dvscntr &= ~DVS_PIXFORMAT_MASK;
+ dvscntr &= ~DVS_RGB_ORDER_RGBX;
+ dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK;
+
+ switch (fb->pixel_format) {
+ case V4L2_PIX_FMT_BGR32:
+ dvscntr |= DVS_FORMAT_RGBX888;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_RGBX;
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
+ break;
+ case V4L2_PIX_FMT_YVYU:
+ dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
+ break;
+ case V4L2_PIX_FMT_UYVY:
+ dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
+ break;
+ case V4L2_PIX_FMT_VYUY:
+ dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
+ break;
+ default:
+ ret = -EINVAL;
+ DRM_DEBUG_KMS("bad pixel format\n");
+ goto out_unlock;
+ }
+
+ if (obj->tiling_mode != I915_TILING_X) {
+ DRM_DEBUG_KMS("plane surfaces must be X tiled\n");
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ dvscntr |= DVS_TILED;
+
+ /* must disable */
+ dvscntr |= DVS_TRICKLE_FEED_DISABLE;
+ dvscntr |= DVS_DEST_KEY;
+ dvscntr |= DVS_ENABLE;
+
+ start = obj->gtt_offset;
+ offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
+
+ I915_WRITE(DVSSTRIDE(pipe), fb->pitch);
+ I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
+ I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x);
+ I915_WRITE(DVSSIZE(pipe), (fb->height << 16) | fb->width);
+ I915_WRITE(DVSSCALE(pipe), 0);
+ I915_WRITE(reg, dvscntr);
+ I915_WRITE(DVSSURF(pipe), start);
+ POSTING_READ(DVSSURF(pipe));
+
+ /* Unpin old obj after new one is active to avoid ugliness */
+ if (old_obj) {
+ intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe);
+ i915_gem_object_unpin(old_obj);
+ }
+
+out_unlock:
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+static void
+intel_disable_plane(struct drm_plane *plane)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ int pipe = intel_plane->pipe;
+
+ I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE);
+ I915_WRITE(DVSSURF(pipe), 0);
+ POSTING_READ(DVSSURF(pipe));
+}
+
+static const struct drm_plane_funcs intel_plane_funcs = {
+ .update_plane = intel_update_plane,
+ .disable_plane = intel_disable_plane,
+};
+
+static uint32_t snb_plane_formats[] = {
+ V4L2_PIX_FMT_BGR32,
+ V4L2_PIX_FMT_RGB32,
+ V4L2_PIX_FMT_YUYV,
+ V4L2_PIX_FMT_YVYU,
+ V4L2_PIX_FMT_UYVY,
+ V4L2_PIX_FMT_VYUY,
+};
+
+void
+intel_plane_init(struct drm_device *dev, enum pipe pipe)
+{
+ struct intel_plane *intel_plane;
+ unsigned long possible_crtcs;
+
+ if (!IS_GEN6(dev)) {
+ DRM_ERROR("new plane code only for SNB\n");
+ return;
+ }
+
+ intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL);
+ if (!intel_plane)
+ return;
+
+ intel_plane->pipe = pipe;
+ possible_crtcs = (1 << pipe);
+ drm_plane_init(dev, &intel_plane->base, possible_crtcs,
+ &intel_plane_funcs, snb_plane_formats,
+ ARRAY_SIZE(snb_plane_formats));
+}
+
--
1.7.4.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 4/4] drm/i915: add SNB video sprite support
@ 2011-06-20 20:11 ` Jesse Barnes
0 siblings, 0 replies; 22+ messages in thread
From: Jesse Barnes @ 2011-06-20 20:11 UTC (permalink / raw)
To: dri-devel; +Cc: intel-gfx, Marcus Lorentzon, Alan Cox, Jesse Barnes
The video sprites support video surface formats natively and can handle
scaling well. So add support for them using the new DRM core overlay
support functions.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/Makefile | 1 +
drivers/gpu/drm/i915/i915_reg.h | 52 +++++++++
drivers/gpu/drm/i915/intel_display.c | 19 +++-
drivers/gpu/drm/i915/intel_drv.h | 14 +++
drivers/gpu/drm/i915/intel_fb.c | 6 +
drivers/gpu/drm/i915/intel_overlay2.c | 188 +++++++++++++++++++++++++++++++++
6 files changed, 274 insertions(+), 6 deletions(-)
create mode 100644 drivers/gpu/drm/i915/intel_overlay2.c
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 0ae6a7c..6193471 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -28,6 +28,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
intel_dvo.o \
intel_ringbuffer.o \
intel_overlay.o \
+ intel_overlay2.o \
intel_opregion.o \
dvo_ch7xxx.o \
dvo_ch7017.o \
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 2f967af..c81c4e7 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2627,6 +2627,58 @@
#define _DSPBSURF 0x7119C
#define _DSPBTILEOFF 0x711A4
+/* Sprite A control */
+#define _DVSACNTR 0x72180
+#define DVS_ENABLE (1<<31)
+#define DVS_GAMMA_ENABLE (1<<30)
+#define DVS_PIXFORMAT_MASK (3<<25)
+#define DVS_FORMAT_YUV422 (0<<25)
+#define DVS_FORMAT_RGBX101010 (1<<25)
+#define DVS_FORMAT_RGBX888 (2<<25)
+#define DVS_FORMAT_RGBX161616 (3<<25)
+#define DVS_SOURCE_KEY (1<<22)
+#define DVS_RGB_ORDER_RGBX (1<<20)
+#define DVS_YUV_BYTE_ORDER_MASK (3<<16)
+#define DVS_YUV_ORDER_YUYV (0<<16)
+#define DVS_YUV_ORDER_UYVY (1<<16)
+#define DVS_YUV_ORDER_YVYU (2<<16)
+#define DVS_YUV_ORDER_VYUY (3<<16)
+#define DVS_DEST_KEY (1<<2)
+#define DVS_TRICKLE_FEED_DISABLE (1<<14)
+#define DVS_TILED (1<<10)
+#define _DVSASTRIDE 0x72188
+#define _DVSAPOS 0x7218c
+#define _DVSASIZE 0x72190
+#define _DVSAKEYVAL 0x72194
+#define _DVSAKEYMSK 0x72198
+#define _DVSASURF 0x7219c
+#define _DVSAKEYMAXVAL 0x721a0
+#define _DVSATILEOFF 0x721a4
+#define _DVSASURFLIVE 0x721ac
+#define _DVSASCALE 0x72204
+#define _DVSAGAMC 0x72300
+
+#define _DVSBCNTR 0x73180
+#define _DVSBSTRIDE 0x73188
+#define _DVSBPOS 0x7318c
+#define _DVSBSIZE 0x73190
+#define _DVSBKEYVAL 0x73194
+#define _DVSBKEYMSK 0x73198
+#define _DVSBSURF 0x7319c
+#define _DVSBKEYMAXVAL 0x731a0
+#define _DVSBTILEOFF 0x731a4
+#define _DVSBSURFLIVE 0x731ac
+#define _DVSBSCALE 0x73204
+#define _DVSBGAMC 0x73300
+
+#define DVSCNTR(pipe) _PIPE(pipe, _DVSACNTR, _DVSBCNTR)
+#define DVSSTRIDE(pipe) _PIPE(pipe, _DVSASTRIDE, _DVSBSTRIDE)
+#define DVSPOS(pipe) _PIPE(pipe, _DVSAPOS, _DVSBPOS)
+#define DVSSURF(pipe) _PIPE(pipe, _DVSASURF, _DVSBSURF)
+#define DVSSIZE(pipe) _PIPE(pipe, _DVSASIZE, _DVSBSIZE)
+#define DVSSCALE(pipe) _PIPE(pipe, _DVSASCALE, _DVSBSCALE)
+#define DVSTILEOFF(pipe) _PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF)
+
/* VBIOS regs */
#define VGACNTRL 0x71400
# define VGA_DISP_DISABLE (1 << 31)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 7901f16..72a570a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -900,8 +900,8 @@ static void assert_panel_unlocked(struct drm_i915_private *dev_priv,
pipe_name(pipe));
}
-static void assert_pipe(struct drm_i915_private *dev_priv,
- enum pipe pipe, bool state)
+void assert_pipe(struct drm_i915_private *dev_priv,
+ enum pipe pipe, bool state)
{
int reg;
u32 val;
@@ -914,8 +914,6 @@ static void assert_pipe(struct drm_i915_private *dev_priv,
"pipe %c assertion failure (expected %s, current %s)\n",
pipe_name(pipe), state_string(state), state_string(cur_state));
}
-#define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
-#define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
static void assert_plane_enabled(struct drm_i915_private *dev_priv,
enum plane plane)
@@ -4319,7 +4317,8 @@ static void sandybridge_update_wm(struct drm_device *dev)
&sandybridge_cursor_wm_info, latency,
&plane_wm, &cursor_wm)) {
I915_WRITE(WM0_PIPEA_ILK,
- (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
+ (plane_wm << WM0_PIPE_PLANE_SHIFT) |
+ (plane_wm << WM0_PIPE_SPRITE_SHIFT) | cursor_wm);
DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
" plane %d, " "cursor: %d\n",
plane_wm, cursor_wm);
@@ -4331,7 +4330,8 @@ static void sandybridge_update_wm(struct drm_device *dev)
&sandybridge_cursor_wm_info, latency,
&plane_wm, &cursor_wm)) {
I915_WRITE(WM0_PIPEB_ILK,
- (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
+ (plane_wm << WM0_PIPE_PLANE_SHIFT) |
+ (plane_wm << WM0_PIPE_SPRITE_SHIFT) | cursor_wm);
DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
" plane %d, cursor: %d\n",
plane_wm, cursor_wm);
@@ -4371,6 +4371,11 @@ static void sandybridge_update_wm(struct drm_device *dev)
(plane_wm << WM1_LP_SR_SHIFT) |
cursor_wm);
+#if 0
+ I915_WRITE(WM1S_LP_ILK,
+ WM1S_LP_EN |
+#endif
+
/* WM2 */
if (!ironlake_compute_srwm(dev, 2, enabled,
SNB_READ_WM2_LATENCY() * 500,
@@ -8013,6 +8018,8 @@ void intel_modeset_init(struct drm_device *dev)
for (i = 0; i < dev_priv->num_pipe; i++) {
intel_crtc_init(dev, i);
+ if (HAS_PCH_SPLIT(dev))
+ intel_plane_init(dev, i);
}
/* Just disable it once at startup */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d73e622..232d797 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -173,10 +173,18 @@ struct intel_crtc {
unsigned int bpp;
};
+struct intel_plane {
+ struct drm_plane base;
+ enum pipe pipe;
+ struct drm_i915_gem_object *obj;
+ u32 lut_r[1024], lut_g[1024], lut_b[1024];
+};
+
#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
#define to_intel_connector(x) container_of(x, struct intel_connector, base)
#define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
#define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
+#define to_intel_plane(x) container_of(x, struct intel_plane, base)
#define DIP_TYPE_AVI 0x82
#define DIP_VERSION_AVI 0x2
@@ -255,6 +263,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
extern bool intel_dpd_is_edp(struct drm_device *dev);
extern void intel_edp_link_config (struct intel_encoder *, int *, int *);
extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder);
+extern void intel_plane_init(struct drm_device *dev, enum pipe pipe);
/* intel_panel.c */
extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
@@ -346,5 +355,10 @@ extern int intel_overlay_attrs(struct drm_device *dev, void *data,
extern void intel_fb_output_poll_changed(struct drm_device *dev);
extern void intel_fb_restore_mode(struct drm_device *dev);
+extern void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
+ bool state);
+#define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
+#define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
+
extern void intel_init_clock_gating(struct drm_device *dev);
#endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index 11baa99..513a40c 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -270,8 +270,14 @@ void intel_fb_restore_mode(struct drm_device *dev)
{
int ret;
drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_mode_config *config = &dev->mode_config;
+ struct drm_plane *plane;
ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper);
if (ret)
DRM_DEBUG("failed to restore crtc mode\n");
+
+ /* Be sure to shut off any planes that may be active */
+ list_for_each_entry(plane, &config->plane_list, head)
+ plane->funcs->disable_plane(plane);
}
diff --git a/drivers/gpu/drm/i915/intel_overlay2.c b/drivers/gpu/drm/i915/intel_overlay2.c
new file mode 100644
index 0000000..19fd76f
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_overlay2.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Jesse Barnes <jbarnes@virtuousgeek.org>
+ *
+ * New plane/sprite handling.
+ *
+ * The older chips had a separate interface for programming plane related
+ * registers; newer ones are much simpler and we can use the new DRM plane
+ * support.
+ */
+#include "drmP.h"
+#include "drm_crtc.h"
+#include "intel_drv.h"
+#include "i915_drm.h"
+#include "i915_drv.h"
+
+static int
+intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
+ struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+ unsigned int crtc_w, unsigned int crtc_h,
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ struct intel_framebuffer *intel_fb;
+ struct drm_i915_gem_object *obj, *old_obj;
+ int pipe = intel_plane->pipe;
+ unsigned long start, offset;
+ u32 dvscntr;
+ u32 reg = DVSCNTR(pipe);
+ int ret = 0;
+ int x = src_x >> 16, y = src_y >> 16;
+
+ assert_pipe_enabled(dev_priv, pipe);
+
+ intel_fb = to_intel_framebuffer(fb);
+ obj = intel_fb->obj;
+
+ old_obj = intel_plane->obj;
+
+ mutex_lock(&dev->struct_mutex);
+ ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
+ if (ret)
+ goto out_unlock;
+
+ intel_plane->obj = obj;
+
+ dvscntr = I915_READ(reg);
+
+ /* Mask out pixel format bits in case we change it */
+ dvscntr &= ~DVS_PIXFORMAT_MASK;
+ dvscntr &= ~DVS_RGB_ORDER_RGBX;
+ dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK;
+
+ switch (fb->pixel_format) {
+ case V4L2_PIX_FMT_BGR32:
+ dvscntr |= DVS_FORMAT_RGBX888;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_RGBX;
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
+ break;
+ case V4L2_PIX_FMT_YVYU:
+ dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
+ break;
+ case V4L2_PIX_FMT_UYVY:
+ dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
+ break;
+ case V4L2_PIX_FMT_VYUY:
+ dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
+ break;
+ default:
+ ret = -EINVAL;
+ DRM_DEBUG_KMS("bad pixel format\n");
+ goto out_unlock;
+ }
+
+ if (obj->tiling_mode != I915_TILING_X) {
+ DRM_DEBUG_KMS("plane surfaces must be X tiled\n");
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ dvscntr |= DVS_TILED;
+
+ /* must disable */
+ dvscntr |= DVS_TRICKLE_FEED_DISABLE;
+ dvscntr |= DVS_DEST_KEY;
+ dvscntr |= DVS_ENABLE;
+
+ start = obj->gtt_offset;
+ offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
+
+ I915_WRITE(DVSSTRIDE(pipe), fb->pitch);
+ I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
+ I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x);
+ I915_WRITE(DVSSIZE(pipe), (fb->height << 16) | fb->width);
+ I915_WRITE(DVSSCALE(pipe), 0);
+ I915_WRITE(reg, dvscntr);
+ I915_WRITE(DVSSURF(pipe), start);
+ POSTING_READ(DVSSURF(pipe));
+
+ /* Unpin old obj after new one is active to avoid ugliness */
+ if (old_obj) {
+ intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe);
+ i915_gem_object_unpin(old_obj);
+ }
+
+out_unlock:
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+static void
+intel_disable_plane(struct drm_plane *plane)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ int pipe = intel_plane->pipe;
+
+ I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE);
+ I915_WRITE(DVSSURF(pipe), 0);
+ POSTING_READ(DVSSURF(pipe));
+}
+
+static const struct drm_plane_funcs intel_plane_funcs = {
+ .update_plane = intel_update_plane,
+ .disable_plane = intel_disable_plane,
+};
+
+static uint32_t snb_plane_formats[] = {
+ V4L2_PIX_FMT_BGR32,
+ V4L2_PIX_FMT_RGB32,
+ V4L2_PIX_FMT_YUYV,
+ V4L2_PIX_FMT_YVYU,
+ V4L2_PIX_FMT_UYVY,
+ V4L2_PIX_FMT_VYUY,
+};
+
+void
+intel_plane_init(struct drm_device *dev, enum pipe pipe)
+{
+ struct intel_plane *intel_plane;
+ unsigned long possible_crtcs;
+
+ if (!IS_GEN6(dev)) {
+ DRM_ERROR("new plane code only for SNB\n");
+ return;
+ }
+
+ intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL);
+ if (!intel_plane)
+ return;
+
+ intel_plane->pipe = pipe;
+ possible_crtcs = (1 << pipe);
+ drm_plane_init(dev, &intel_plane->base, possible_crtcs,
+ &intel_plane_funcs, snb_plane_formats,
+ ARRAY_SIZE(snb_plane_formats));
+}
+
--
1.7.4.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
2011-06-09 11:55 ` Alan Cox
@ 2011-06-21 9:48 ` Laurent Pinchart
0 siblings, 0 replies; 22+ messages in thread
From: Laurent Pinchart @ 2011-06-21 9:48 UTC (permalink / raw)
To: dri-devel; +Cc: Dave Airlie
(Looping linux-media in)
On Thursday 09 June 2011 13:55:13 Alan Cox wrote:
> > > You also don't need a headwer with a complete list of fourcc names in
> > > it, that is the half the point of FourCC.
> >
> > #define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') /* 8
> > RGB-3-3-2 */
> >
> > See that V4L2 and v4l2? I'd rather not have them used in the drm
>
> They are just helpers. The only thing that fourcc is is a 4 byte packed
> value of four symbols.
>
> > interface, either a DRM_ variant or a FOURCC_ variant that removes the
> > V4L2. Also having it in a different include file to "videodev2.h", so
> > yes we can pass FOURCC values but I'd rather we gave people a drm
> > specific way to generate them or make a generic set of macros that don't
> > include the V4L2 headers.
>
> You need a macro to assemble fourcc codes and that seems to be about it -
> so just an equivalent of the v4l2_fourcc macro.
Given that I plan to use the V4L2 FOURCCs in fbdev as well, it might indeed be
a good idea to split them from videodev2.h into their own header file.
Renaming the macros to make them V4L2-agnostic is a no-go, as that would break
the API. Manually maintaining separate sets of identical FOURCCs accross
subsystems also doesn't sound like a very good idea to me. We could create a
header that contains V4L2-agnostic FOURCC #define's, and generate a V4L2
header with the V4L2_ prefix, but I'm not sure it would be a good idea either.
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC] Updated DRM plane handling patches
2011-06-15 17:29 ` [RFC] Updated DRM plane handling patches Jesse Barnes
@ 2011-07-21 10:15 ` Joonyoung Shim
2011-07-21 17:15 ` Jesse Barnes
0 siblings, 1 reply; 22+ messages in thread
From: Joonyoung Shim @ 2011-07-21 10:15 UTC (permalink / raw)
To: Jesse Barnes; +Cc: intel-gfx, dri-devel
Hi,
2011/6/16 Jesse Barnes <jbarnes@virtuousgeek.org>:
> On Tue, 7 Jun 2011 13:07:38 -0700
> Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
>
>> This patchset updates the previous one, incorporating the feedback I
>> received:
>> 1) uses the v4l fourcc codes to communicate pixel format
>> 2) adds a new addfb ioctl that takes a format
>> 3) adds working SNB support for the new code
>>
>> Comments welcome. I'll be pushing intel-gpu-tools testdisplay support
>> for this shortly if people want to play around with it. Next step is to
>> incorporate it into X and Wayland to see if the API is rich enough for
>> our needs.
>
> And here's a very early & hackish DDX patch for this code in case other
> people want to test things out. I still have to update it with the
> scaling stuff we talked about and support various things (disabling
> planes, controlling attributes, etc) but it's enough to get bits on the
> screen at least.
>
Could you share libdrm patch for drm plane?
--
- Joonyoung Shim
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC] Updated DRM plane handling patches
2011-07-21 10:15 ` Joonyoung Shim
@ 2011-07-21 17:15 ` Jesse Barnes
0 siblings, 0 replies; 22+ messages in thread
From: Jesse Barnes @ 2011-07-21 17:15 UTC (permalink / raw)
To: Joonyoung Shim; +Cc: intel-gfx, dri-devel
On Thu, 21 Jul 2011 19:15:24 +0900
Joonyoung Shim <dofmind@gmail.com> wrote:
> Hi,
>
> 2011/6/16 Jesse Barnes <jbarnes@virtuousgeek.org>:
> > On Tue, 7 Jun 2011 13:07:38 -0700
> > Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> >
> >> This patchset updates the previous one, incorporating the feedback I
> >> received:
> >> 1) uses the v4l fourcc codes to communicate pixel format
> >> 2) adds a new addfb ioctl that takes a format
> >> 3) adds working SNB support for the new code
> >>
> >> Comments welcome. I'll be pushing intel-gpu-tools testdisplay support
> >> for this shortly if people want to play around with it. Next step is to
> >> incorporate it into X and Wayland to see if the API is rich enough for
> >> our needs.
> >
> > And here's a very early & hackish DDX patch for this code in case other
> > people want to test things out. I still have to update it with the
> > scaling stuff we talked about and support various things (disabling
> > planes, controlling attributes, etc) but it's enough to get bits on the
> > screen at least.
> >
>
> Could you share libdrm patch for drm plane?
>
Sure, see below. You'll also need to update the copy of the libdrm
headers from the patched sources.
--
Jesse Barnes, Intel Open Source Technology Center
>From 38e64d416a6d1ae41b7a0867e4d4c2c44ea42941 Mon Sep 17 00:00:00 2001
From: Jesse Barnes <jbarnes@virtuousgeek.org>
Date: Fri, 29 Apr 2011 08:54:25 -0700
Subject: [PATCH 2/2] libdrm: add plane handling functions & structs
---
include/drm/drm.h | 7 +-
include/drm/drm_mode.h | 33 +++++++----
xf86drmMode.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++
xf86drmMode.h | 29 +++++++++
4 files changed, 201 insertions(+), 16 deletions(-)
diff --git a/include/drm/drm.h b/include/drm/drm.h
index cd384f2..bb2dea8 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -718,9 +718,10 @@ 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_GETOVERLAYRESOURCES DRM_IOWR(0xB5, struct drm_mode_get_overlay_res)
-#define DRM_IOCTL_MODE_GETOVERLAY DRM_IOWR(0xB6, struct drm_mode_get_overlay)
-#define DRM_IOCTL_MODE_SETOVERLAY DRM_IOWR(0xB7, struct drm_mode_set_overlay)
+#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_mode.h b/include/drm/drm_mode.h
index 349052a..4c5f01f 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -120,14 +120,9 @@ struct drm_mode_crtc {
struct drm_mode_modeinfo mode;
};
-#define DRM_MODE_OVERLAY_FORMAT_YUV422 1 /* YUV 4:2:2 packed */
-#define DRM_MODE_OVERLAY_FORMAT_RGBX101010 2 /* RGB 10bpc, ign. alpha */
-#define DRM_MODE_OVERLAY_FORMAT_RGBX888 3 /* Standard x:8:8:8 RGB */
-#define DRM_MODE_OVERLAY_FORMAT_RGBX161616 4 /* x:16:16:16 float RGB */
-
-/* Overlays blend with or override other bits on the CRTC */
-struct drm_mode_set_overlay {
- __u32 overlay_id;
+/* Planes blend with or override other bits on the CRTC */
+struct drm_mode_set_plane {
+ __u32 plane_id;
__u32 crtc_id;
__u32 fb_id; /* contains surface format type */
@@ -137,9 +132,9 @@ struct drm_mode_set_overlay {
/* FIXME: color key/mask, scaling, z-order, other? */
};
-struct drm_mode_get_overlay {
+struct drm_mode_get_plane {
__u64 format_type_ptr;
- __u32 overlay_id;
+ __u32 plane_id;
__u32 crtc_id;
__u32 fb_id;
@@ -154,9 +149,9 @@ struct drm_mode_get_overlay {
};
-struct drm_mode_get_overlay_res {
- __u64 overlay_id_ptr;
- __u32 count_overlays;
+struct drm_mode_get_plane_res {
+ __u64 plane_id_ptr;
+ __u32 count_planes;
};
#define DRM_MODE_ENCODER_NONE 0
@@ -268,6 +263,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
diff --git a/xf86drmMode.c b/xf86drmMode.c
index 0d268fc..cf62412 100644
--- a/xf86drmMode.c
+++ b/xf86drmMode.c
@@ -255,6 +255,28 @@ int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
return 0;
}
+int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
+ uint32_t pixel_format, uint8_t depth, uint8_t bpp,
+ uint32_t pitch, uint32_t bo_handle, uint32_t *buf_id)
+{
+ struct drm_mode_fb_cmd2 f;
+ int ret;
+
+ f.width = width;
+ f.height = height;
+ f.pitch = pitch;
+ f.bpp = bpp;
+ f.depth = depth;
+ f.pixel_format = pixel_format;
+ f.handle = bo_handle;
+
+ if ((ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ADDFB2, &f)))
+ return ret;
+
+ *buf_id = f.fb_id;
+ return 0;
+}
+
int drmModeRmFB(int fd, uint32_t bufferId)
{
return DRM_IOCTL(fd, DRM_IOCTL_MODE_RMFB, &bufferId);
@@ -806,3 +828,129 @@ int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,
return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip);
}
+
+int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id,
+ uint32_t fb_id, uint32_t crtc_x, uint32_t crtc_y,
+ uint32_t x, uint32_t y)
+
+{
+ struct drm_mode_set_plane s;
+
+ s.plane_id = plane_id;
+ s.crtc_id = crtc_id;
+ s.fb_id = fb_id;
+ s.crtc_x = crtc_x;
+ s.crtc_y = crtc_y;
+ s.x = x;
+ s.y = y;
+
+ return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETPLANE, &s);
+}
+
+
+drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id)
+{
+ struct drm_mode_get_plane ovr, counts;
+ drmModePlanePtr r = 0;
+
+retry:
+ memset(&ovr, 0, sizeof(struct drm_mode_get_plane));
+ ovr.plane_id = plane_id;
+ if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr))
+ return 0;
+
+ counts = ovr;
+
+ if (ovr.count_format_types) {
+ ovr.format_type_ptr = VOID2U64(drmMalloc(ovr.count_format_types *
+ sizeof(uint32_t)));
+ if (!ovr.format_type_ptr)
+ goto err_allocs;
+ }
+
+ if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr))
+ goto err_allocs;
+
+ if (counts.count_format_types < ovr.count_format_types) {
+ drmFree(U642VOID(ovr.format_type_ptr));
+ goto retry;
+ }
+
+ if (!(r = drmMalloc(sizeof(*r))))
+ goto err_allocs;
+
+ r->count_formats = ovr.count_format_types;
+ r->plane_id = ovr.plane_id;
+ r->crtc_id = ovr.crtc_id;
+ r->fb_id = ovr.fb_id;
+ r->crtc_x = ovr.crtc_x;
+ r->crtc_y = ovr.crtc_y;
+ r->x = ovr.x;
+ r->y = ovr.y;
+ r->possible_crtcs = ovr.possible_crtcs;
+ r->gamma_size = ovr.gamma_size;
+ r->formats = drmAllocCpy(U642VOID(ovr.format_type_ptr),
+ ovr.count_format_types, sizeof(uint32_t));
+ if (ovr.count_format_types && !r->formats) {
+ drmFree(r->formats);
+ r = 0;
+ }
+
+err_allocs:
+ drmFree(U642VOID(ovr.format_type_ptr));
+
+ return r;
+}
+
+void drmModeFreePlane(drmModePlanePtr ptr)
+{
+ if (!ptr)
+ return;
+
+ drmFree(ptr->formats);
+ drmFree(ptr);
+}
+
+drmModePlaneResPtr drmModeGetPlaneResources(int fd)
+{
+ struct drm_mode_get_plane_res res, counts;
+ drmModePlaneResPtr r = 0;
+
+retry:
+ memset(&res, 0, sizeof(struct drm_mode_get_plane_res));
+ if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &res))
+ return 0;
+
+ counts = res;
+
+ if (res.count_planes) {
+ res.plane_id_ptr = VOID2U64(drmMalloc(res.count_planes *
+ sizeof(uint32_t)));
+ if (!res.plane_id_ptr)
+ goto err_allocs;
+ }
+
+ if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &res))
+ goto err_allocs;
+
+ if (counts.count_planes < res.count_planes) {
+ drmFree(U642VOID(res.plane_id_ptr));
+ goto retry;
+ }
+
+ if (!(r = drmMalloc(sizeof(*r))))
+ goto err_allocs;
+
+ r->count_planes = res.count_planes;
+ r->planes = drmAllocCpy(U642VOID(res.plane_id_ptr),
+ res.count_planes, sizeof(uint32_t));
+ if (res.count_planes && !r->planes) {
+ drmFree(r->planes);
+ r = 0;
+ }
+
+err_allocs:
+ drmFree(U642VOID(res.plane_id_ptr));
+
+ return r;
+}
diff --git a/xf86drmMode.h b/xf86drmMode.h
index ee7c454..5d36ba5 100644
--- a/xf86drmMode.h
+++ b/xf86drmMode.h
@@ -33,6 +33,7 @@
*
*/
+#include <linux/videodev2.h>
#include <drm.h>
/*
@@ -274,7 +275,25 @@ typedef struct _drmModeConnector {
uint32_t *encoders; /**< List of encoder ids */
} drmModeConnector, *drmModeConnectorPtr;
+typedef struct _drmModePlane {
+ uint32_t count_formats;
+ uint32_t *formats;
+ uint32_t plane_id;
+ uint32_t crtc_id;
+ uint32_t fb_id;
+
+ uint32_t crtc_x, crtc_y;
+ uint32_t x, y;
+
+ uint32_t possible_crtcs;
+ uint32_t gamma_size;
+} drmModePlane, *drmModePlanePtr;
+
+typedef struct _drmModePlaneRes {
+ uint32_t count_planes;
+ uint32_t *planes;
+} drmModePlaneRes, *drmModePlaneResPtr;
extern void drmModeFreeModeInfo( drmModeModeInfoPtr ptr );
extern void drmModeFreeResources( drmModeResPtr ptr );
@@ -282,6 +301,7 @@ extern void drmModeFreeFB( drmModeFBPtr ptr );
extern void drmModeFreeCrtc( drmModeCrtcPtr ptr );
extern void drmModeFreeConnector( drmModeConnectorPtr ptr );
extern void drmModeFreeEncoder( drmModeEncoderPtr ptr );
+extern void drmModeFreePlane( drmModePlanePtr ptr );
/**
* Retrives all of the resources associated with a card.
@@ -303,6 +323,10 @@ extern drmModeFBPtr drmModeGetFB(int fd, uint32_t bufferId);
extern int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
uint32_t *buf_id);
+/* ...with a specific pixel format */
+extern int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
+ uint32_t pixel_format, uint8_t depth, uint8_t bpp,
+ uint32_t pitch, uint32_t bo_handle, uint32_t *buf_id);
/**
* Destroies the given framebuffer.
*/
@@ -386,3 +410,8 @@ extern int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
uint16_t *red, uint16_t *green, uint16_t *blue);
extern int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,
uint32_t flags, void *user_data);
+extern drmModePlaneResPtr drmModeGetPlaneResources(int fd);
+extern drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id);
+extern int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id,
+ uint32_t fb_id, uint32_t crtc_x, uint32_t crtc_y,
+ uint32_t x, uint32_t y);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
end of thread, other threads:[~2011-07-21 17:15 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-06-07 20:07 [RFC] Updated DRM plane handling patches Jesse Barnes
2011-06-07 20:07 ` [PATCH 1/4] drm: add plane support Jesse Barnes
2011-06-07 21:01 ` Jesse Barnes
2011-06-08 9:41 ` Marcus Lorentzon
2011-06-08 18:54 ` Jesse Barnes
2011-06-09 9:16 ` Marcus Lorentzon
2011-06-07 21:05 ` Jesse Barnes
2011-06-07 20:07 ` [PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format Jesse Barnes
2011-06-09 4:05 ` Dave Airlie
2011-06-09 8:21 ` Alan Cox
2011-06-09 10:40 ` Dave Airlie
2011-06-09 11:55 ` Alan Cox
2011-06-21 9:48 ` Laurent Pinchart
2011-06-07 20:07 ` [PATCH 3/4] drm/i915: rename existing overlay support to "legacy" Jesse Barnes
2011-06-07 20:59 ` [Intel-gfx] " Chris Wilson
2011-06-07 20:07 ` [PATCH 4/4] drm/i915: add SNB video sprite support Jesse Barnes
2011-06-07 21:01 ` Chris Wilson
2011-06-15 17:29 ` [RFC] Updated DRM plane handling patches Jesse Barnes
2011-07-21 10:15 ` Joonyoung Shim
2011-07-21 17:15 ` Jesse Barnes
-- strict thread matches above, loose matches on Subject: below --
2011-06-20 20:11 [RFC] Updated plane support v3 Jesse Barnes
2011-06-20 20:11 ` [PATCH 4/4] drm/i915: add SNB video sprite support Jesse Barnes
2011-06-20 20:11 ` Jesse Barnes
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.