[PATCH 1/2] drm: add plane support v2

2011-11-15 Thread Ville Syrjälä
On Tue, Nov 15, 2011 at 12:40:43PM +1000, Ben Skeggs wrote:
> On Mon, 2011-11-14 at 12:21 -0800, Jesse Barnes wrote:
> > Planes are a bit like half-CRTCs.  They have a location and fb, but
> > don't drive outputs directly.  Add support for handling them to the core
> > KMS code.
> Out of curiosity, lets say you have a *really* stupid hardware overlay
> that can't do scaling (or even, has limited scaling capabilities),
> should we provide some way to expose this to userspace?

I think yes. In fact I'd like drm_plane to replace drm_crtc as far as
scanout is concerned. That's how a lot of embedded hardware is laid
out already, and I think it's a lot cleaner approach than what we
have currently. Stuff like borders then become a simple matter or
positioning the "CRTC plane" within the larger active video area,
and panel fitters could be exposed through drm_plane scaling.

Se either we need to think ahead more with the GETPLANE ioctl
structure, or we could add a PLANE_CAPS ioctl later to expose
additional details about the hardware.

-- 
Ville Syrj?l?
Intel OTC


[PATCH 1/2] drm: add plane support v2

2011-11-15 Thread Ben Skeggs
On Mon, 2011-11-14 at 12:21 -0800, Jesse Barnes wrote:
> Planes are a bit like half-CRTCs.  They have a location and fb, but
> don't drive outputs directly.  Add support for handling them to the core
> KMS code.
Out of curiosity, lets say you have a *really* stupid hardware overlay
that can't do scaling (or even, has limited scaling capabilities),
should we provide some way to expose this to userspace?

I've recently looked at the hardware overlay on recent NVIDIA GPUs with
the intention of implementing this API in nouveau.  However, while there
is indeed an overlay, it only accepts a couple of RGB formats and does
simple clipping - and *no* scaling that I've found so far.



[PATCH 1/2] drm: add plane support v2

2011-11-15 Thread Jesse Barnes
On Tue, 15 Nov 2011 13:42:40 +0200
Ville Syrj?l?  wrote:

> On Tue, Nov 15, 2011 at 12:40:43PM +1000, Ben Skeggs wrote:
> > On Mon, 2011-11-14 at 12:21 -0800, Jesse Barnes wrote:
> > > Planes are a bit like half-CRTCs.  They have a location and fb, but
> > > don't drive outputs directly.  Add support for handling them to the core
> > > KMS code.
> > Out of curiosity, lets say you have a *really* stupid hardware overlay
> > that can't do scaling (or even, has limited scaling capabilities),
> > should we provide some way to expose this to userspace?
> 
> I think yes. In fact I'd like drm_plane to replace drm_crtc as far as
> scanout is concerned. That's how a lot of embedded hardware is laid
> out already, and I think it's a lot cleaner approach than what we
> have currently. Stuff like borders then become a simple matter or
> positioning the "CRTC plane" within the larger active video area,
> and panel fitters could be exposed through drm_plane scaling.
> 
> Se either we need to think ahead more with the GETPLANE ioctl
> structure, or we could add a PLANE_CAPS ioctl later to expose
> additional details about the hardware.

There are going to be all sorts of device specific bits we can expose
with driver ioctls too (e.g. the alpha blend with restrictions on Intel
stuff).

But overall, yes you can definitely support overlays w/o scalers with
these interfaces.  We could add a plane property to expose the scaling
factors supported if that helps, otherwise you could just return
-ENOSUPP for any configuration where the crtc size and source size
don't match.

-- 
Jesse Barnes, Intel Open Source Technology Center
-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: 



Re: [PATCH 1/2] drm: add plane support v2

2011-11-15 Thread Jesse Barnes
On Tue, 15 Nov 2011 13:42:40 +0200
Ville Syrjälä  wrote:

> On Tue, Nov 15, 2011 at 12:40:43PM +1000, Ben Skeggs wrote:
> > On Mon, 2011-11-14 at 12:21 -0800, Jesse Barnes wrote:
> > > Planes are a bit like half-CRTCs.  They have a location and fb, but
> > > don't drive outputs directly.  Add support for handling them to the core
> > > KMS code.
> > Out of curiosity, lets say you have a *really* stupid hardware overlay
> > that can't do scaling (or even, has limited scaling capabilities),
> > should we provide some way to expose this to userspace?
> 
> I think yes. In fact I'd like drm_plane to replace drm_crtc as far as
> scanout is concerned. That's how a lot of embedded hardware is laid
> out already, and I think it's a lot cleaner approach than what we
> have currently. Stuff like borders then become a simple matter or
> positioning the "CRTC plane" within the larger active video area,
> and panel fitters could be exposed through drm_plane scaling.
> 
> Se either we need to think ahead more with the GETPLANE ioctl
> structure, or we could add a PLANE_CAPS ioctl later to expose
> additional details about the hardware.

There are going to be all sorts of device specific bits we can expose
with driver ioctls too (e.g. the alpha blend with restrictions on Intel
stuff).

But overall, yes you can definitely support overlays w/o scalers with
these interfaces.  We could add a plane property to expose the scaling
factors supported if that helps, otherwise you could just return
-ENOSUPP for any configuration where the crtc size and source size
don't match.

-- 
Jesse Barnes, Intel Open Source Technology Center


signature.asc
Description: PGP signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/2] drm: add plane support v2

2011-11-15 Thread Ville Syrjälä
On Tue, Nov 15, 2011 at 12:40:43PM +1000, Ben Skeggs wrote:
> On Mon, 2011-11-14 at 12:21 -0800, Jesse Barnes wrote:
> > Planes are a bit like half-CRTCs.  They have a location and fb, but
> > don't drive outputs directly.  Add support for handling them to the core
> > KMS code.
> Out of curiosity, lets say you have a *really* stupid hardware overlay
> that can't do scaling (or even, has limited scaling capabilities),
> should we provide some way to expose this to userspace?

I think yes. In fact I'd like drm_plane to replace drm_crtc as far as
scanout is concerned. That's how a lot of embedded hardware is laid
out already, and I think it's a lot cleaner approach than what we
have currently. Stuff like borders then become a simple matter or
positioning the "CRTC plane" within the larger active video area,
and panel fitters could be exposed through drm_plane scaling.

Se either we need to think ahead more with the GETPLANE ioctl
structure, or we could add a PLANE_CAPS ioctl later to expose
additional details about the hardware.

-- 
Ville Syrjälä
Intel OTC
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/2] drm: add plane support v2

2011-11-14 Thread Ben Skeggs
On Mon, 2011-11-14 at 12:21 -0800, Jesse Barnes wrote:
> Planes are a bit like half-CRTCs.  They have a location and fb, but
> don't drive outputs directly.  Add support for handling them to the core
> KMS code.
Out of curiosity, lets say you have a *really* stupid hardware overlay
that can't do scaling (or even, has limited scaling capabilities),
should we provide some way to expose this to userspace?

I've recently looked at the hardware overlay on recent NVIDIA GPUs with
the intention of implementing this API in nouveau.  However, while there
is indeed an overlay, it only accepts a couple of RGB formats and does
simple clipping - and *no* scaling that I've found so far.

>From traces of VDPAU, NVIDIA themselves appear to do CSC and scaling via
some other method before passing the frame off to the overlay.

Rather disappointing, and seemingly not of too much use.  But, I'd like
to expose what functionality there is in any case.

Ben.

> 
> v2: fix ABI of get_plane - move format_type_ptr to the end
> 
> Acked-by: Alan Cox 
> Reviewed-by: Rob Clark 
> Reviewed-by: Daniel Vetter 
> Signed-off-by: Jesse Barnes 
> ---
>  drivers/gpu/drm/drm_crtc.c |  257 
> +++-
>  drivers/gpu/drm/drm_drv.c  |3 +
>  include/drm/drm.h  |3 +
>  include/drm/drm_crtc.h |   75 +-
>  include/drm/drm_mode.h |   33 ++
>  5 files changed, 368 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index fe738f0..804ef12 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -321,6 +321,7 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
>  {
>   struct drm_device *dev = fb->dev;
>   struct drm_crtc *crtc;
> + struct drm_plane *plane;
>   struct drm_mode_set set;
>   int ret;
>  
> @@ -337,6 +338,15 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
>   }
>   }
>  
> + list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
> + if (plane->fb == fb) {
> + /* should turn off the crtc */
> + ret = plane->funcs->disable_plane(plane);
> + if (ret)
> + DRM_ERROR("failed to disable plane with busy 
> fb\n");
> + }
> + }
> +
>   drm_mode_object_put(dev, &fb->base);
>   list_del(&fb->head);
>   dev->mode_config.num_fb--;
> @@ -535,6 +545,50 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
>  }
>  EXPORT_SYMBOL(drm_encoder_cleanup);
>  
> +int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
> +unsigned long possible_crtcs,
> +const struct drm_plane_funcs *funcs,
> +uint32_t *formats, uint32_t format_count)
> +{
> + mutex_lock(&dev->mode_config.mutex);
> +
> + plane->dev = dev;
> + drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
> + plane->funcs = funcs;
> + plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
> +   GFP_KERNEL);
> + if (!plane->format_types) {
> + DRM_DEBUG_KMS("out of memory when allocating plane\n");
> + drm_mode_object_put(dev, &plane->base);
> + return -ENOMEM;
> + }
> +
> + memcpy(plane->format_types, formats, format_count);
> + plane->format_count = format_count;
> + plane->possible_crtcs = possible_crtcs;
> +
> + list_add_tail(&plane->head, &dev->mode_config.plane_list);
> + dev->mode_config.num_plane++;
> +
> + mutex_unlock(&dev->mode_config.mutex);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(drm_plane_init);
> +
> +void drm_plane_cleanup(struct drm_plane *plane)
> +{
> + struct drm_device *dev = plane->dev;
> +
> + mutex_lock(&dev->mode_config.mutex);
> + kfree(plane->format_types);
> + drm_mode_object_put(dev, &plane->base);
> + list_del(&plane->head);
> + dev->mode_config.num_plane--;
> + mutex_unlock(&dev->mode_config.mutex);
> +}
> +EXPORT_SYMBOL(drm_plane_cleanup);
> +
>  /**
>   * drm_mode_create - create a new display mode
>   * @dev: DRM device
> @@ -866,6 +920,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);
> @@ -942,6 +997,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
>   struct drm_encoder *encoder, *enct;
>   struct drm_framebuffer *fb, *fbt;
>   struct drm_property *property, *pt;
> + struct drm_plane *plane, *plt;
>  
>   list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
>head) {
> @@ -966,6 +1022,10 @@ void drm

[PATCH 1/2] drm: add plane support v3

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

v2: fix ABI of get_plane - move format_type_ptr to the end
v3: add 'flags' field for interlaced support (from Ville)

Acked-by: Alan Cox 
Reviewed-by: Rob Clark 
Reviewed-by: Daniel Vetter 
Signed-off-by: Jesse Barnes 
---
 drivers/gpu/drm/drm_crtc.c |  257 +++-
 drivers/gpu/drm/drm_drv.c  |3 +
 include/drm/drm.h  |3 +
 include/drm/drm_crtc.h |   75 +-
 include/drm/drm_mode.h |   37 +++
 5 files changed, 372 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index fe738f0..804ef12 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -321,6 +321,7 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
 {
struct drm_device *dev = fb->dev;
struct drm_crtc *crtc;
+   struct drm_plane *plane;
struct drm_mode_set set;
int ret;
 
@@ -337,6 +338,15 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
}
}
 
+   list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+   if (plane->fb == fb) {
+   /* should turn off the crtc */
+   ret = plane->funcs->disable_plane(plane);
+   if (ret)
+   DRM_ERROR("failed to disable plane with busy 
fb\n");
+   }
+   }
+
drm_mode_object_put(dev, &fb->base);
list_del(&fb->head);
dev->mode_config.num_fb--;
@@ -535,6 +545,50 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
 }
 EXPORT_SYMBOL(drm_encoder_cleanup);
 
+int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
+  unsigned long possible_crtcs,
+  const struct drm_plane_funcs *funcs,
+  uint32_t *formats, uint32_t format_count)
+{
+   mutex_lock(&dev->mode_config.mutex);
+
+   plane->dev = dev;
+   drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
+   plane->funcs = funcs;
+   plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
+ GFP_KERNEL);
+   if (!plane->format_types) {
+   DRM_DEBUG_KMS("out of memory when allocating plane\n");
+   drm_mode_object_put(dev, &plane->base);
+   return -ENOMEM;
+   }
+
+   memcpy(plane->format_types, formats, format_count);
+   plane->format_count = format_count;
+   plane->possible_crtcs = possible_crtcs;
+
+   list_add_tail(&plane->head, &dev->mode_config.plane_list);
+   dev->mode_config.num_plane++;
+
+   mutex_unlock(&dev->mode_config.mutex);
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_plane_init);
+
+void drm_plane_cleanup(struct drm_plane *plane)
+{
+   struct drm_device *dev = plane->dev;
+
+   mutex_lock(&dev->mode_config.mutex);
+   kfree(plane->format_types);
+   drm_mode_object_put(dev, &plane->base);
+   list_del(&plane->head);
+   dev->mode_config.num_plane--;
+   mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_plane_cleanup);
+
 /**
  * drm_mode_create - create a new display mode
  * @dev: DRM device
@@ -866,6 +920,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);
@@ -942,6 +997,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
struct drm_encoder *encoder, *enct;
struct drm_framebuffer *fb, *fbt;
struct drm_property *property, *pt;
+   struct drm_plane *plane, *plt;
 
list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
 head) {
@@ -966,6 +1022,10 @@ void drm_mode_config_cleanup(struct drm_device *dev)
crtc->funcs->destroy(crtc);
}
 
+   list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
+head) {
+   plane->funcs->destroy(plane);
+   }
 }
 EXPORT_SYMBOL(drm_mode_config_cleanup);
 
@@ -1466,6 +1526,197 @@ 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;
+
+  

[PATCH 1/2] drm: add plane support v3

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

v2: fix ABI of get_plane - move format_type_ptr to the end
v3: add 'flags' field for interlaced support (from Ville)

Acked-by: Alan Cox 
Reviewed-by: Rob Clark 
Reviewed-by: Daniel Vetter 
Signed-off-by: Jesse Barnes 
---
 drivers/gpu/drm/drm_crtc.c |  257 +++-
 drivers/gpu/drm/drm_drv.c  |3 +
 include/drm/drm.h  |3 +
 include/drm/drm_crtc.h |   75 +-
 include/drm/drm_mode.h |   37 +++
 5 files changed, 372 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index fe738f0..804ef12 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -321,6 +321,7 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
 {
struct drm_device *dev = fb->dev;
struct drm_crtc *crtc;
+   struct drm_plane *plane;
struct drm_mode_set set;
int ret;

@@ -337,6 +338,15 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
}
}

+   list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+   if (plane->fb == fb) {
+   /* should turn off the crtc */
+   ret = plane->funcs->disable_plane(plane);
+   if (ret)
+   DRM_ERROR("failed to disable plane with busy 
fb\n");
+   }
+   }
+
drm_mode_object_put(dev, &fb->base);
list_del(&fb->head);
dev->mode_config.num_fb--;
@@ -535,6 +545,50 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
 }
 EXPORT_SYMBOL(drm_encoder_cleanup);

+int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
+  unsigned long possible_crtcs,
+  const struct drm_plane_funcs *funcs,
+  uint32_t *formats, uint32_t format_count)
+{
+   mutex_lock(&dev->mode_config.mutex);
+
+   plane->dev = dev;
+   drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
+   plane->funcs = funcs;
+   plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
+ GFP_KERNEL);
+   if (!plane->format_types) {
+   DRM_DEBUG_KMS("out of memory when allocating plane\n");
+   drm_mode_object_put(dev, &plane->base);
+   return -ENOMEM;
+   }
+
+   memcpy(plane->format_types, formats, format_count);
+   plane->format_count = format_count;
+   plane->possible_crtcs = possible_crtcs;
+
+   list_add_tail(&plane->head, &dev->mode_config.plane_list);
+   dev->mode_config.num_plane++;
+
+   mutex_unlock(&dev->mode_config.mutex);
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_plane_init);
+
+void drm_plane_cleanup(struct drm_plane *plane)
+{
+   struct drm_device *dev = plane->dev;
+
+   mutex_lock(&dev->mode_config.mutex);
+   kfree(plane->format_types);
+   drm_mode_object_put(dev, &plane->base);
+   list_del(&plane->head);
+   dev->mode_config.num_plane--;
+   mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_plane_cleanup);
+
 /**
  * drm_mode_create - create a new display mode
  * @dev: DRM device
@@ -866,6 +920,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);
@@ -942,6 +997,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
struct drm_encoder *encoder, *enct;
struct drm_framebuffer *fb, *fbt;
struct drm_property *property, *pt;
+   struct drm_plane *plane, *plt;

list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
 head) {
@@ -966,6 +1022,10 @@ void drm_mode_config_cleanup(struct drm_device *dev)
crtc->funcs->destroy(crtc);
}

+   list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
+head) {
+   plane->funcs->destroy(plane);
+   }
 }
 EXPORT_SYMBOL(drm_mode_config_cleanup);

@@ -1466,6 +1526,197 @@ 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 

[PATCH 1/2] drm: add plane support v2

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

v2: fix ABI of get_plane - move format_type_ptr to the end

Acked-by: Alan Cox 
Reviewed-by: Rob Clark 
Reviewed-by: Daniel Vetter 
Signed-off-by: Jesse Barnes 
---
 drivers/gpu/drm/drm_crtc.c |  257 +++-
 drivers/gpu/drm/drm_drv.c  |3 +
 include/drm/drm.h  |3 +
 include/drm/drm_crtc.h |   75 +-
 include/drm/drm_mode.h |   33 ++
 5 files changed, 368 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index fe738f0..804ef12 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -321,6 +321,7 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
 {
struct drm_device *dev = fb->dev;
struct drm_crtc *crtc;
+   struct drm_plane *plane;
struct drm_mode_set set;
int ret;
 
@@ -337,6 +338,15 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
}
}
 
+   list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+   if (plane->fb == fb) {
+   /* should turn off the crtc */
+   ret = plane->funcs->disable_plane(plane);
+   if (ret)
+   DRM_ERROR("failed to disable plane with busy 
fb\n");
+   }
+   }
+
drm_mode_object_put(dev, &fb->base);
list_del(&fb->head);
dev->mode_config.num_fb--;
@@ -535,6 +545,50 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
 }
 EXPORT_SYMBOL(drm_encoder_cleanup);
 
+int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
+  unsigned long possible_crtcs,
+  const struct drm_plane_funcs *funcs,
+  uint32_t *formats, uint32_t format_count)
+{
+   mutex_lock(&dev->mode_config.mutex);
+
+   plane->dev = dev;
+   drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
+   plane->funcs = funcs;
+   plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
+ GFP_KERNEL);
+   if (!plane->format_types) {
+   DRM_DEBUG_KMS("out of memory when allocating plane\n");
+   drm_mode_object_put(dev, &plane->base);
+   return -ENOMEM;
+   }
+
+   memcpy(plane->format_types, formats, format_count);
+   plane->format_count = format_count;
+   plane->possible_crtcs = possible_crtcs;
+
+   list_add_tail(&plane->head, &dev->mode_config.plane_list);
+   dev->mode_config.num_plane++;
+
+   mutex_unlock(&dev->mode_config.mutex);
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_plane_init);
+
+void drm_plane_cleanup(struct drm_plane *plane)
+{
+   struct drm_device *dev = plane->dev;
+
+   mutex_lock(&dev->mode_config.mutex);
+   kfree(plane->format_types);
+   drm_mode_object_put(dev, &plane->base);
+   list_del(&plane->head);
+   dev->mode_config.num_plane--;
+   mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_plane_cleanup);
+
 /**
  * drm_mode_create - create a new display mode
  * @dev: DRM device
@@ -866,6 +920,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);
@@ -942,6 +997,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
struct drm_encoder *encoder, *enct;
struct drm_framebuffer *fb, *fbt;
struct drm_property *property, *pt;
+   struct drm_plane *plane, *plt;
 
list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
 head) {
@@ -966,6 +1022,10 @@ void drm_mode_config_cleanup(struct drm_device *dev)
crtc->funcs->destroy(crtc);
}
 
+   list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
+head) {
+   plane->funcs->destroy(plane);
+   }
 }
 EXPORT_SYMBOL(drm_mode_config_cleanup);
 
@@ -1466,6 +1526,197 @@ 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))
+   

[PATCH 1/2] drm: add plane support v2

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

v2: fix ABI of get_plane - move format_type_ptr to the end

Acked-by: Alan Cox 
Reviewed-by: Rob Clark 
Reviewed-by: Daniel Vetter 
Signed-off-by: Jesse Barnes 
---
 drivers/gpu/drm/drm_crtc.c |  257 +++-
 drivers/gpu/drm/drm_drv.c  |3 +
 include/drm/drm.h  |3 +
 include/drm/drm_crtc.h |   75 +-
 include/drm/drm_mode.h |   33 ++
 5 files changed, 368 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index fe738f0..804ef12 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -321,6 +321,7 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
 {
struct drm_device *dev = fb->dev;
struct drm_crtc *crtc;
+   struct drm_plane *plane;
struct drm_mode_set set;
int ret;

@@ -337,6 +338,15 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
}
}

+   list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+   if (plane->fb == fb) {
+   /* should turn off the crtc */
+   ret = plane->funcs->disable_plane(plane);
+   if (ret)
+   DRM_ERROR("failed to disable plane with busy 
fb\n");
+   }
+   }
+
drm_mode_object_put(dev, &fb->base);
list_del(&fb->head);
dev->mode_config.num_fb--;
@@ -535,6 +545,50 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
 }
 EXPORT_SYMBOL(drm_encoder_cleanup);

+int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
+  unsigned long possible_crtcs,
+  const struct drm_plane_funcs *funcs,
+  uint32_t *formats, uint32_t format_count)
+{
+   mutex_lock(&dev->mode_config.mutex);
+
+   plane->dev = dev;
+   drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
+   plane->funcs = funcs;
+   plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
+ GFP_KERNEL);
+   if (!plane->format_types) {
+   DRM_DEBUG_KMS("out of memory when allocating plane\n");
+   drm_mode_object_put(dev, &plane->base);
+   return -ENOMEM;
+   }
+
+   memcpy(plane->format_types, formats, format_count);
+   plane->format_count = format_count;
+   plane->possible_crtcs = possible_crtcs;
+
+   list_add_tail(&plane->head, &dev->mode_config.plane_list);
+   dev->mode_config.num_plane++;
+
+   mutex_unlock(&dev->mode_config.mutex);
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_plane_init);
+
+void drm_plane_cleanup(struct drm_plane *plane)
+{
+   struct drm_device *dev = plane->dev;
+
+   mutex_lock(&dev->mode_config.mutex);
+   kfree(plane->format_types);
+   drm_mode_object_put(dev, &plane->base);
+   list_del(&plane->head);
+   dev->mode_config.num_plane--;
+   mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_plane_cleanup);
+
 /**
  * drm_mode_create - create a new display mode
  * @dev: DRM device
@@ -866,6 +920,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);
@@ -942,6 +997,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
struct drm_encoder *encoder, *enct;
struct drm_framebuffer *fb, *fbt;
struct drm_property *property, *pt;
+   struct drm_plane *plane, *plt;

list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
 head) {
@@ -966,6 +1022,10 @@ void drm_mode_config_cleanup(struct drm_device *dev)
crtc->funcs->destroy(crtc);
}

+   list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
+head) {
+   plane->funcs->destroy(plane);
+   }
 }
 EXPORT_SYMBOL(drm_mode_config_cleanup);

@@ -1466,6 +1526,197 @@ 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))
+   

Re: [PATCH 1/2] drm: add plane support v2

2011-11-14 Thread Jesse Barnes
On Mon, 14 Nov 2011 11:47:06 -0800
Jesse Barnes  wrote:

> Planes are a bit like half-CRTCs.  They have a location and fb, but
> don't drive outputs directly.  Add support for handling them to the core
> KMS code.
> 
> v2: fix ABI of get_plane - move format_type_ptr to the end

Ok ignore these two; I botched the rebase and accidentally left in some
v4l stuff.

Since I had to re-post I confirmed with Rob about the multi-object API;
apparently a simple handle array will be enough, so that's included in
the next version.

I'll re-post one more time, this time with feeling.

-- 
Jesse Barnes, Intel Open Source Technology Center


signature.asc
Description: PGP signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 1/2] drm: add plane support v2

2011-11-14 Thread Jesse Barnes
On Mon, 14 Nov 2011 11:47:06 -0800
Jesse Barnes  wrote:

> Planes are a bit like half-CRTCs.  They have a location and fb, but
> don't drive outputs directly.  Add support for handling them to the core
> KMS code.
> 
> v2: fix ABI of get_plane - move format_type_ptr to the end

Ok ignore these two; I botched the rebase and accidentally left in some
v4l stuff.

Since I had to re-post I confirmed with Rob about the multi-object API;
apparently a simple handle array will be enough, so that's included in
the next version.

I'll re-post one more time, this time with feeling.

-- 
Jesse Barnes, Intel Open Source Technology Center
-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: 



[PATCH 1/2] drm: add plane support v2

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

v2: fix ABI of get_plane - move format_type_ptr to the end

Acked-by: Alan Cox 
Reviewed-by: Rob Clark 
Reviewed-by: Daniel Vetter 
Signed-off-by: Jesse Barnes 
---
 drivers/gpu/drm/drm_crtc.c |  257 +++-
 drivers/gpu/drm/drm_drv.c  |3 +
 include/drm/drm.h  |3 +
 include/drm/drm_crtc.h |   75 +-
 include/drm/drm_mode.h |   33 ++
 5 files changed, 368 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index fe738f0..804ef12 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -321,6 +321,7 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
 {
struct drm_device *dev = fb->dev;
struct drm_crtc *crtc;
+   struct drm_plane *plane;
struct drm_mode_set set;
int ret;
 
@@ -337,6 +338,15 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
}
}
 
+   list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+   if (plane->fb == fb) {
+   /* should turn off the crtc */
+   ret = plane->funcs->disable_plane(plane);
+   if (ret)
+   DRM_ERROR("failed to disable plane with busy 
fb\n");
+   }
+   }
+
drm_mode_object_put(dev, &fb->base);
list_del(&fb->head);
dev->mode_config.num_fb--;
@@ -535,6 +545,50 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
 }
 EXPORT_SYMBOL(drm_encoder_cleanup);
 
+int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
+  unsigned long possible_crtcs,
+  const struct drm_plane_funcs *funcs,
+  uint32_t *formats, uint32_t format_count)
+{
+   mutex_lock(&dev->mode_config.mutex);
+
+   plane->dev = dev;
+   drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
+   plane->funcs = funcs;
+   plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
+ GFP_KERNEL);
+   if (!plane->format_types) {
+   DRM_DEBUG_KMS("out of memory when allocating plane\n");
+   drm_mode_object_put(dev, &plane->base);
+   return -ENOMEM;
+   }
+
+   memcpy(plane->format_types, formats, format_count);
+   plane->format_count = format_count;
+   plane->possible_crtcs = possible_crtcs;
+
+   list_add_tail(&plane->head, &dev->mode_config.plane_list);
+   dev->mode_config.num_plane++;
+
+   mutex_unlock(&dev->mode_config.mutex);
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_plane_init);
+
+void drm_plane_cleanup(struct drm_plane *plane)
+{
+   struct drm_device *dev = plane->dev;
+
+   mutex_lock(&dev->mode_config.mutex);
+   kfree(plane->format_types);
+   drm_mode_object_put(dev, &plane->base);
+   list_del(&plane->head);
+   dev->mode_config.num_plane--;
+   mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_plane_cleanup);
+
 /**
  * drm_mode_create - create a new display mode
  * @dev: DRM device
@@ -866,6 +920,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);
@@ -942,6 +997,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
struct drm_encoder *encoder, *enct;
struct drm_framebuffer *fb, *fbt;
struct drm_property *property, *pt;
+   struct drm_plane *plane, *plt;
 
list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
 head) {
@@ -966,6 +1022,10 @@ void drm_mode_config_cleanup(struct drm_device *dev)
crtc->funcs->destroy(crtc);
}
 
+   list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
+head) {
+   plane->funcs->destroy(plane);
+   }
 }
 EXPORT_SYMBOL(drm_mode_config_cleanup);
 
@@ -1466,6 +1526,197 @@ 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))
+   

[PATCH 1/2] drm: add plane support v2

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

v2: fix ABI of get_plane - move format_type_ptr to the end

Acked-by: Alan Cox 
Reviewed-by: Rob Clark 
Reviewed-by: Daniel Vetter 
Signed-off-by: Jesse Barnes 
---
 drivers/gpu/drm/drm_crtc.c |  257 +++-
 drivers/gpu/drm/drm_drv.c  |3 +
 include/drm/drm.h  |3 +
 include/drm/drm_crtc.h |   75 +-
 include/drm/drm_mode.h |   33 ++
 5 files changed, 368 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index fe738f0..804ef12 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -321,6 +321,7 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
 {
struct drm_device *dev = fb->dev;
struct drm_crtc *crtc;
+   struct drm_plane *plane;
struct drm_mode_set set;
int ret;

@@ -337,6 +338,15 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
}
}

+   list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+   if (plane->fb == fb) {
+   /* should turn off the crtc */
+   ret = plane->funcs->disable_plane(plane);
+   if (ret)
+   DRM_ERROR("failed to disable plane with busy 
fb\n");
+   }
+   }
+
drm_mode_object_put(dev, &fb->base);
list_del(&fb->head);
dev->mode_config.num_fb--;
@@ -535,6 +545,50 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
 }
 EXPORT_SYMBOL(drm_encoder_cleanup);

+int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
+  unsigned long possible_crtcs,
+  const struct drm_plane_funcs *funcs,
+  uint32_t *formats, uint32_t format_count)
+{
+   mutex_lock(&dev->mode_config.mutex);
+
+   plane->dev = dev;
+   drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
+   plane->funcs = funcs;
+   plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
+ GFP_KERNEL);
+   if (!plane->format_types) {
+   DRM_DEBUG_KMS("out of memory when allocating plane\n");
+   drm_mode_object_put(dev, &plane->base);
+   return -ENOMEM;
+   }
+
+   memcpy(plane->format_types, formats, format_count);
+   plane->format_count = format_count;
+   plane->possible_crtcs = possible_crtcs;
+
+   list_add_tail(&plane->head, &dev->mode_config.plane_list);
+   dev->mode_config.num_plane++;
+
+   mutex_unlock(&dev->mode_config.mutex);
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_plane_init);
+
+void drm_plane_cleanup(struct drm_plane *plane)
+{
+   struct drm_device *dev = plane->dev;
+
+   mutex_lock(&dev->mode_config.mutex);
+   kfree(plane->format_types);
+   drm_mode_object_put(dev, &plane->base);
+   list_del(&plane->head);
+   dev->mode_config.num_plane--;
+   mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_plane_cleanup);
+
 /**
  * drm_mode_create - create a new display mode
  * @dev: DRM device
@@ -866,6 +920,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);
@@ -942,6 +997,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
struct drm_encoder *encoder, *enct;
struct drm_framebuffer *fb, *fbt;
struct drm_property *property, *pt;
+   struct drm_plane *plane, *plt;

list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
 head) {
@@ -966,6 +1022,10 @@ void drm_mode_config_cleanup(struct drm_device *dev)
crtc->funcs->destroy(crtc);
}

+   list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
+head) {
+   plane->funcs->destroy(plane);
+   }
 }
 EXPORT_SYMBOL(drm_mode_config_cleanup);

@@ -1466,6 +1526,197 @@ 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))
+   

[PATCH 1/2] drm: add plane support

2011-11-08 Thread Chris Wilson
On Tue,  8 Nov 2011 13:18:33 -0800, Jesse Barnes  
wrote:
> Planes are a bit like half-CRTCs.  They have a location and fb, but
> don't drive outputs directly.  Add support for handling them to the core
> KMS code.
> 
> Acked-by: Alan Cox 
> Reviewed-by: Rob Clark 
> Reviewed-by: Daniel Vetter 
> Signed-off-by: Jesse Barnes 

Thanks for ammending the errors, fwiw
Reviewed-by: Chris Wilson 
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH 1/2] drm: add plane support

2011-11-08 Thread Chris Wilson
On Tue,  8 Nov 2011 09:38:52 -0800, Jesse Barnes  
wrote:
> +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;
> + }
We had begun to use ENOENT for failure to find the specified object to
give a little variation to our error codes. Still not very widespread,
but I think a good practice to encourage :)
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH 1/2] drm: add plane support

2011-11-08 Thread Chris Wilson
On Tue,  8 Nov 2011 09:38:52 -0800, Jesse Barnes  
wrote:
> Planes are a bit like half-CRTCs.  They have a location and fb, but
> don't drive outputs directly.  Add support for handling them to the core
> KMS code.
> 
> Acked-by: Alan Cox 
> Reviewed-by: Rob Clark 
> Reviewed-by: Daniel Vetter 
> Signed-off-by: Jesse Barnes 
> ---
>  drivers/gpu/drm/drm_crtc.c |  251 
> +++-
>  drivers/gpu/drm/drm_drv.c  |3 +
>  include/drm/drm.h  |3 +
>  include/drm/drm_crtc.h |   75 +-
>  include/drm/drm_mode.h |   33 ++
>  5 files changed, 362 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index fe738f0..fac8043 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -321,6 +321,7 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
>  {
>   struct drm_device *dev = fb->dev;
>   struct drm_crtc *crtc;
> + struct drm_plane *plane;
>   struct drm_mode_set set;
>   int ret;
>  
> @@ -337,6 +338,15 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
>   }
>   }
>  
> + list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
> + if (plane->fb == fb) {
> + /* should turn off the crtc */
> + ret = plane->funcs->disable_plane(plane);
> + if (ret)
> + DRM_ERROR("failed to disable plane with busy 
> fb\n");
> + }
> + }
> +
>   drm_mode_object_put(dev, &fb->base);
>   list_del(&fb->head);
>   dev->mode_config.num_fb--;
> @@ -535,6 +545,48 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
>  }
>  EXPORT_SYMBOL(drm_encoder_cleanup);
>  
> +void drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
> + unsigned long possible_crtcs,
> + const struct drm_plane_funcs *funcs,
> + uint32_t *formats, uint32_t format_count)
> +{
> + mutex_lock(&dev->mode_config.mutex);
> +
> + plane->dev = dev;
> + drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
> + plane->funcs = funcs;
> + plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
> +   GFP_KERNEL);
> + if (!plane->format_types) {
> + DRM_DEBUG_KMS("out of memory when allocating plane\n");
> + drm_mode_object_put(dev, &plane->base);
> + return;
This can fail, report it back to the caller so that he can tear down his
allocations and propagate onwards. Kthxbye.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


Re: [PATCH 1/2] drm: add plane support

2011-11-08 Thread Chris Wilson
On Tue,  8 Nov 2011 13:18:33 -0800, Jesse Barnes  
wrote:
> Planes are a bit like half-CRTCs.  They have a location and fb, but
> don't drive outputs directly.  Add support for handling them to the core
> KMS code.
> 
> Acked-by: Alan Cox 
> Reviewed-by: Rob Clark 
> Reviewed-by: Daniel Vetter 
> Signed-off-by: Jesse Barnes 

Thanks for ammending the errors, fwiw
Reviewed-by: Chris Wilson 
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 1/2] drm: add plane support

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

Acked-by: Alan Cox 
Reviewed-by: Rob Clark 
Reviewed-by: Daniel Vetter 
Signed-off-by: Jesse Barnes 
---
 drivers/gpu/drm/drm_crtc.c |  257 +++-
 drivers/gpu/drm/drm_drv.c  |3 +
 include/drm/drm.h  |3 +
 include/drm/drm_crtc.h |   75 +-
 include/drm/drm_mode.h |   33 ++
 5 files changed, 368 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index fe738f0..804ef12 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -321,6 +321,7 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
 {
struct drm_device *dev = fb->dev;
struct drm_crtc *crtc;
+   struct drm_plane *plane;
struct drm_mode_set set;
int ret;
 
@@ -337,6 +338,15 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
}
}
 
+   list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+   if (plane->fb == fb) {
+   /* should turn off the crtc */
+   ret = plane->funcs->disable_plane(plane);
+   if (ret)
+   DRM_ERROR("failed to disable plane with busy 
fb\n");
+   }
+   }
+
drm_mode_object_put(dev, &fb->base);
list_del(&fb->head);
dev->mode_config.num_fb--;
@@ -535,6 +545,50 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
 }
 EXPORT_SYMBOL(drm_encoder_cleanup);
 
+int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
+  unsigned long possible_crtcs,
+  const struct drm_plane_funcs *funcs,
+  uint32_t *formats, uint32_t format_count)
+{
+   mutex_lock(&dev->mode_config.mutex);
+
+   plane->dev = dev;
+   drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
+   plane->funcs = funcs;
+   plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
+ GFP_KERNEL);
+   if (!plane->format_types) {
+   DRM_DEBUG_KMS("out of memory when allocating plane\n");
+   drm_mode_object_put(dev, &plane->base);
+   return -ENOMEM;
+   }
+
+   memcpy(plane->format_types, formats, format_count);
+   plane->format_count = format_count;
+   plane->possible_crtcs = possible_crtcs;
+
+   list_add_tail(&plane->head, &dev->mode_config.plane_list);
+   dev->mode_config.num_plane++;
+
+   mutex_unlock(&dev->mode_config.mutex);
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_plane_init);
+
+void drm_plane_cleanup(struct drm_plane *plane)
+{
+   struct drm_device *dev = plane->dev;
+
+   mutex_lock(&dev->mode_config.mutex);
+   kfree(plane->format_types);
+   drm_mode_object_put(dev, &plane->base);
+   list_del(&plane->head);
+   dev->mode_config.num_plane--;
+   mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_plane_cleanup);
+
 /**
  * drm_mode_create - create a new display mode
  * @dev: DRM device
@@ -866,6 +920,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);
@@ -942,6 +997,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
struct drm_encoder *encoder, *enct;
struct drm_framebuffer *fb, *fbt;
struct drm_property *property, *pt;
+   struct drm_plane *plane, *plt;
 
list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
 head) {
@@ -966,6 +1022,10 @@ void drm_mode_config_cleanup(struct drm_device *dev)
crtc->funcs->destroy(crtc);
}
 
+   list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
+head) {
+   plane->funcs->destroy(plane);
+   }
 }
 EXPORT_SYMBOL(drm_mode_config_cleanup);
 
@@ -1466,6 +1526,197 @@ 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_

[PATCH 1/2] drm: add plane support

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

Acked-by: Alan Cox 
Reviewed-by: Rob Clark 
Reviewed-by: Daniel Vetter 
Signed-off-by: Jesse Barnes 
---
 drivers/gpu/drm/drm_crtc.c |  257 +++-
 drivers/gpu/drm/drm_drv.c  |3 +
 include/drm/drm.h  |3 +
 include/drm/drm_crtc.h |   75 +-
 include/drm/drm_mode.h |   33 ++
 5 files changed, 368 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index fe738f0..804ef12 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -321,6 +321,7 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
 {
struct drm_device *dev = fb->dev;
struct drm_crtc *crtc;
+   struct drm_plane *plane;
struct drm_mode_set set;
int ret;

@@ -337,6 +338,15 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
}
}

+   list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+   if (plane->fb == fb) {
+   /* should turn off the crtc */
+   ret = plane->funcs->disable_plane(plane);
+   if (ret)
+   DRM_ERROR("failed to disable plane with busy 
fb\n");
+   }
+   }
+
drm_mode_object_put(dev, &fb->base);
list_del(&fb->head);
dev->mode_config.num_fb--;
@@ -535,6 +545,50 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
 }
 EXPORT_SYMBOL(drm_encoder_cleanup);

+int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
+  unsigned long possible_crtcs,
+  const struct drm_plane_funcs *funcs,
+  uint32_t *formats, uint32_t format_count)
+{
+   mutex_lock(&dev->mode_config.mutex);
+
+   plane->dev = dev;
+   drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
+   plane->funcs = funcs;
+   plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
+ GFP_KERNEL);
+   if (!plane->format_types) {
+   DRM_DEBUG_KMS("out of memory when allocating plane\n");
+   drm_mode_object_put(dev, &plane->base);
+   return -ENOMEM;
+   }
+
+   memcpy(plane->format_types, formats, format_count);
+   plane->format_count = format_count;
+   plane->possible_crtcs = possible_crtcs;
+
+   list_add_tail(&plane->head, &dev->mode_config.plane_list);
+   dev->mode_config.num_plane++;
+
+   mutex_unlock(&dev->mode_config.mutex);
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_plane_init);
+
+void drm_plane_cleanup(struct drm_plane *plane)
+{
+   struct drm_device *dev = plane->dev;
+
+   mutex_lock(&dev->mode_config.mutex);
+   kfree(plane->format_types);
+   drm_mode_object_put(dev, &plane->base);
+   list_del(&plane->head);
+   dev->mode_config.num_plane--;
+   mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_plane_cleanup);
+
 /**
  * drm_mode_create - create a new display mode
  * @dev: DRM device
@@ -866,6 +920,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);
@@ -942,6 +997,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
struct drm_encoder *encoder, *enct;
struct drm_framebuffer *fb, *fbt;
struct drm_property *property, *pt;
+   struct drm_plane *plane, *plt;

list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
 head) {
@@ -966,6 +1022,10 @@ void drm_mode_config_cleanup(struct drm_device *dev)
crtc->funcs->destroy(crtc);
}

+   list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
+head) {
+   plane->funcs->destroy(plane);
+   }
 }
 EXPORT_SYMBOL(drm_mode_config_cleanup);

@@ -1466,6 +1526,197 @@ 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.m

Re: [PATCH 1/2] drm: add plane support

2011-11-08 Thread Jesse Barnes
On Tue, 08 Nov 2011 17:50:51 +
Chris Wilson  wrote:

> On Tue,  8 Nov 2011 09:38:52 -0800, Jesse Barnes  
> wrote:
> > +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;
> > +   }
> We had begun to use ENOENT for failure to find the specified object to
> give a little variation to our error codes. Still not very widespread,
> but I think a good practice to encourage :)

Ok both good comments; fixed in the latest update.

-- 
Jesse Barnes, Intel Open Source Technology Center


signature.asc
Description: PGP signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 1/2] drm: add plane support

2011-11-08 Thread Jesse Barnes
On Tue, 08 Nov 2011 17:50:51 +
Chris Wilson  wrote:

> On Tue,  8 Nov 2011 09:38:52 -0800, Jesse Barnes  virtuousgeek.org> wrote:
> > +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;
> > +   }
> We had begun to use ENOENT for failure to find the specified object to
> give a little variation to our error codes. Still not very widespread,
> but I think a good practice to encourage :)

Ok both good comments; fixed in the latest update.

-- 
Jesse Barnes, Intel Open Source Technology Center
-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: 



Re: [PATCH 1/2] drm: add plane support

2011-11-08 Thread Chris Wilson
On Tue,  8 Nov 2011 09:38:52 -0800, Jesse Barnes  
wrote:
> +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;
> + }
We had begun to use ENOENT for failure to find the specified object to
give a little variation to our error codes. Still not very widespread,
but I think a good practice to encourage :)
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/2] drm: add plane support

2011-11-08 Thread Chris Wilson
On Tue,  8 Nov 2011 09:38:52 -0800, Jesse Barnes  
wrote:
> Planes are a bit like half-CRTCs.  They have a location and fb, but
> don't drive outputs directly.  Add support for handling them to the core
> KMS code.
> 
> Acked-by: Alan Cox 
> Reviewed-by: Rob Clark 
> Reviewed-by: Daniel Vetter 
> Signed-off-by: Jesse Barnes 
> ---
>  drivers/gpu/drm/drm_crtc.c |  251 
> +++-
>  drivers/gpu/drm/drm_drv.c  |3 +
>  include/drm/drm.h  |3 +
>  include/drm/drm_crtc.h |   75 +-
>  include/drm/drm_mode.h |   33 ++
>  5 files changed, 362 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index fe738f0..fac8043 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -321,6 +321,7 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
>  {
>   struct drm_device *dev = fb->dev;
>   struct drm_crtc *crtc;
> + struct drm_plane *plane;
>   struct drm_mode_set set;
>   int ret;
>  
> @@ -337,6 +338,15 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
>   }
>   }
>  
> + list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
> + if (plane->fb == fb) {
> + /* should turn off the crtc */
> + ret = plane->funcs->disable_plane(plane);
> + if (ret)
> + DRM_ERROR("failed to disable plane with busy 
> fb\n");
> + }
> + }
> +
>   drm_mode_object_put(dev, &fb->base);
>   list_del(&fb->head);
>   dev->mode_config.num_fb--;
> @@ -535,6 +545,48 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
>  }
>  EXPORT_SYMBOL(drm_encoder_cleanup);
>  
> +void drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
> + unsigned long possible_crtcs,
> + const struct drm_plane_funcs *funcs,
> + uint32_t *formats, uint32_t format_count)
> +{
> + mutex_lock(&dev->mode_config.mutex);
> +
> + plane->dev = dev;
> + drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
> + plane->funcs = funcs;
> + plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
> +   GFP_KERNEL);
> + if (!plane->format_types) {
> + DRM_DEBUG_KMS("out of memory when allocating plane\n");
> + drm_mode_object_put(dev, &plane->base);
> + return;
This can fail, report it back to the caller so that he can tear down his
allocations and propagate onwards. Kthxbye.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 1/2] drm: add plane support

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

Acked-by: Alan Cox 
Reviewed-by: Rob Clark 
Reviewed-by: Daniel Vetter 
Signed-off-by: Jesse Barnes 
---
 drivers/gpu/drm/drm_crtc.c |  251 +++-
 drivers/gpu/drm/drm_drv.c  |3 +
 include/drm/drm.h  |3 +
 include/drm/drm_crtc.h |   75 +-
 include/drm/drm_mode.h |   33 ++
 5 files changed, 362 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index fe738f0..fac8043 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -321,6 +321,7 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
 {
struct drm_device *dev = fb->dev;
struct drm_crtc *crtc;
+   struct drm_plane *plane;
struct drm_mode_set set;
int ret;
 
@@ -337,6 +338,15 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
}
}
 
+   list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+   if (plane->fb == fb) {
+   /* should turn off the crtc */
+   ret = plane->funcs->disable_plane(plane);
+   if (ret)
+   DRM_ERROR("failed to disable plane with busy 
fb\n");
+   }
+   }
+
drm_mode_object_put(dev, &fb->base);
list_del(&fb->head);
dev->mode_config.num_fb--;
@@ -535,6 +545,48 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
 }
 EXPORT_SYMBOL(drm_encoder_cleanup);
 
+void drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
+   unsigned long possible_crtcs,
+   const struct drm_plane_funcs *funcs,
+   uint32_t *formats, uint32_t format_count)
+{
+   mutex_lock(&dev->mode_config.mutex);
+
+   plane->dev = dev;
+   drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
+   plane->funcs = funcs;
+   plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
+ GFP_KERNEL);
+   if (!plane->format_types) {
+   DRM_DEBUG_KMS("out of memory when allocating plane\n");
+   drm_mode_object_put(dev, &plane->base);
+   return;
+   }
+
+   memcpy(plane->format_types, formats, format_count);
+   plane->format_count = format_count;
+   plane->possible_crtcs = possible_crtcs;
+
+   list_add_tail(&plane->head, &dev->mode_config.plane_list);
+   dev->mode_config.num_plane++;
+
+   mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_plane_init);
+
+void drm_plane_cleanup(struct drm_plane *plane)
+{
+   struct drm_device *dev = plane->dev;
+
+   mutex_lock(&dev->mode_config.mutex);
+   kfree(plane->format_types);
+   drm_mode_object_put(dev, &plane->base);
+   list_del(&plane->head);
+   dev->mode_config.num_plane--;
+   mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_plane_cleanup);
+
 /**
  * drm_mode_create - create a new display mode
  * @dev: DRM device
@@ -866,6 +918,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);
@@ -942,6 +995,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
struct drm_encoder *encoder, *enct;
struct drm_framebuffer *fb, *fbt;
struct drm_property *property, *pt;
+   struct drm_plane *plane, *plt;
 
list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
 head) {
@@ -966,6 +1020,10 @@ void drm_mode_config_cleanup(struct drm_device *dev)
crtc->funcs->destroy(crtc);
}
 
+   list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
+head) {
+   plane->funcs->destroy(plane);
+   }
 }
 EXPORT_SYMBOL(drm_mode_config_cleanup);
 
@@ -1466,6 +1524,193 @@ out:
 }
 
 /**
+ * drm_mode_getplane_res - get plane info
+ * @dev: DRM device
+ * @data: ioctl data
+ * @file_priv: DRM file info
+ *
+ * Return an plane count and set of IDs.
+ */
+int drm_mode_getplane_res(struct drm_device *dev, void *data,
+   struct drm_file *file_priv)
+{
+   struct drm_mode_get_plane_res *plane_resp = data;
+   struct drm_mode_config *config;
+   struct drm_plane *plane;
+   uint32_t __user *plane_ptr;
+   int copied = 0, ret = 0;
+
+   if (!drm_core_check_feature(dev, DRIVER_MODESET))
+   return -EINVAL;
+
+   mutex_lock(&dev->mode_config.mutex);
+   c

[PATCH 1/2] drm: add plane support

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

Acked-by: Alan Cox 
Reviewed-by: Rob Clark 
Reviewed-by: Daniel Vetter 
Signed-off-by: Jesse Barnes 
---
 drivers/gpu/drm/drm_crtc.c |  251 +++-
 drivers/gpu/drm/drm_drv.c  |3 +
 include/drm/drm.h  |3 +
 include/drm/drm_crtc.h |   75 +-
 include/drm/drm_mode.h |   33 ++
 5 files changed, 362 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index fe738f0..fac8043 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -321,6 +321,7 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
 {
struct drm_device *dev = fb->dev;
struct drm_crtc *crtc;
+   struct drm_plane *plane;
struct drm_mode_set set;
int ret;

@@ -337,6 +338,15 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
}
}

+   list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+   if (plane->fb == fb) {
+   /* should turn off the crtc */
+   ret = plane->funcs->disable_plane(plane);
+   if (ret)
+   DRM_ERROR("failed to disable plane with busy 
fb\n");
+   }
+   }
+
drm_mode_object_put(dev, &fb->base);
list_del(&fb->head);
dev->mode_config.num_fb--;
@@ -535,6 +545,48 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
 }
 EXPORT_SYMBOL(drm_encoder_cleanup);

+void drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
+   unsigned long possible_crtcs,
+   const struct drm_plane_funcs *funcs,
+   uint32_t *formats, uint32_t format_count)
+{
+   mutex_lock(&dev->mode_config.mutex);
+
+   plane->dev = dev;
+   drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
+   plane->funcs = funcs;
+   plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
+ GFP_KERNEL);
+   if (!plane->format_types) {
+   DRM_DEBUG_KMS("out of memory when allocating plane\n");
+   drm_mode_object_put(dev, &plane->base);
+   return;
+   }
+
+   memcpy(plane->format_types, formats, format_count);
+   plane->format_count = format_count;
+   plane->possible_crtcs = possible_crtcs;
+
+   list_add_tail(&plane->head, &dev->mode_config.plane_list);
+   dev->mode_config.num_plane++;
+
+   mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_plane_init);
+
+void drm_plane_cleanup(struct drm_plane *plane)
+{
+   struct drm_device *dev = plane->dev;
+
+   mutex_lock(&dev->mode_config.mutex);
+   kfree(plane->format_types);
+   drm_mode_object_put(dev, &plane->base);
+   list_del(&plane->head);
+   dev->mode_config.num_plane--;
+   mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_plane_cleanup);
+
 /**
  * drm_mode_create - create a new display mode
  * @dev: DRM device
@@ -866,6 +918,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);
@@ -942,6 +995,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
struct drm_encoder *encoder, *enct;
struct drm_framebuffer *fb, *fbt;
struct drm_property *property, *pt;
+   struct drm_plane *plane, *plt;

list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
 head) {
@@ -966,6 +1020,10 @@ void drm_mode_config_cleanup(struct drm_device *dev)
crtc->funcs->destroy(crtc);
}

+   list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
+head) {
+   plane->funcs->destroy(plane);
+   }
 }
 EXPORT_SYMBOL(drm_mode_config_cleanup);

@@ -1466,6 +1524,193 @@ out:
 }

 /**
+ * drm_mode_getplane_res - get plane info
+ * @dev: DRM device
+ * @data: ioctl data
+ * @file_priv: DRM file info
+ *
+ * Return an plane count and set of IDs.
+ */
+int drm_mode_getplane_res(struct drm_device *dev, void *data,
+   struct drm_file *file_priv)
+{
+   struct drm_mode_get_plane_res *plane_resp = data;
+   struct drm_mode_config *config;
+   struct drm_plane *plane;
+   uint32_t __user *plane_ptr;
+   int copied = 0, ret = 0;
+
+   if (!drm_core_check_feature(dev, DRIVER_MODESET))
+   return -EINVAL;
+
+   mutex_lock(&dev->mode_config.mutex);
+   config =