diff mbox

[v2] allow 32bpp framebuffers for cirrus drm

Message ID 1414605864-28175-1-git-send-email-zachr@google.com (mailing list archive)
State New, archived
Headers show

Commit Message

Zach Reizner Oct. 29, 2014, 6:04 p.m. UTC
This patch allows framebuffers for cirrus to be created with
32bpp pixel formats provided that they do not violate certain
restrictions of the cirrus hardware.

v2: Use pci resource length for vram size.

Signed-off-by: Zach Reizner <zachr@google.com>
---
 drivers/gpu/drm/cirrus/cirrus_drv.h   |  3 +++
 drivers/gpu/drm/cirrus/cirrus_fbdev.c |  5 ++++-
 drivers/gpu/drm/cirrus/cirrus_main.c  | 27 +++++++++++++++++++++++----
 3 files changed, 30 insertions(+), 5 deletions(-)

Comments

Stéphane Marchesin Nov. 18, 2014, 12:39 a.m. UTC | #1
Dave, any objections to merging this?

Stéphane


On Wed, Oct 29, 2014 at 11:04 AM, Zach Reizner <zachr@google.com> wrote:
> This patch allows framebuffers for cirrus to be created with
> 32bpp pixel formats provided that they do not violate certain
> restrictions of the cirrus hardware.
>
> v2: Use pci resource length for vram size.
>
> Signed-off-by: Zach Reizner <zachr@google.com>
> ---
>  drivers/gpu/drm/cirrus/cirrus_drv.h   |  3 +++
>  drivers/gpu/drm/cirrus/cirrus_fbdev.c |  5 ++++-
>  drivers/gpu/drm/cirrus/cirrus_main.c  | 27 +++++++++++++++++++++++----
>  3 files changed, 30 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h
> index d44e69d..693a456 100644
> --- a/drivers/gpu/drm/cirrus/cirrus_drv.h
> +++ b/drivers/gpu/drm/cirrus/cirrus_drv.h
> @@ -210,6 +210,9 @@ int cirrus_framebuffer_init(struct drm_device *dev,
>                             struct drm_mode_fb_cmd2 *mode_cmd,
>                             struct drm_gem_object *obj);
>
> +bool cirrus_check_framebuffer(struct cirrus_device *cdev, int width, int height,
> +                             int bpp, int pitch);
> +
>                                 /* cirrus_display.c */
>  int cirrus_modeset_init(struct cirrus_device *cdev);
>  void cirrus_modeset_fini(struct cirrus_device *cdev);
> diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
> index d231b1c..502a89e 100644
> --- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
> +++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
> @@ -139,6 +139,7 @@ static int cirrusfb_create_object(struct cirrus_fbdev *afbdev,
>                                struct drm_gem_object **gobj_p)
>  {
>         struct drm_device *dev = afbdev->helper.dev;
> +       struct cirrus_device *cdev = dev->dev_private;
>         u32 bpp, depth;
>         u32 size;
>         struct drm_gem_object *gobj;
> @@ -146,8 +147,10 @@ static int cirrusfb_create_object(struct cirrus_fbdev *afbdev,
>         int ret = 0;
>         drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);
>
> -       if (bpp > 24)
> +       if (!cirrus_check_framebuffer(cdev, mode_cmd->width, mode_cmd->height,
> +                                     bpp, mode_cmd->pitches[0]))
>                 return -EINVAL;
> +
>         size = mode_cmd->pitches[0] * mode_cmd->height;
>         ret = cirrus_gem_create(dev, size, true, &gobj);
>         if (ret)
> diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c
> index 99c1983..d9590fc 100644
> --- a/drivers/gpu/drm/cirrus/cirrus_main.c
> +++ b/drivers/gpu/drm/cirrus/cirrus_main.c
> @@ -49,14 +49,16 @@ cirrus_user_framebuffer_create(struct drm_device *dev,
>                                struct drm_file *filp,
>                                struct drm_mode_fb_cmd2 *mode_cmd)
>  {
> +       struct cirrus_device *cdev = dev->dev_private;
>         struct drm_gem_object *obj;
>         struct cirrus_framebuffer *cirrus_fb;
>         int ret;
>         u32 bpp, depth;
>
>         drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);
> -       /* cirrus can't handle > 24bpp framebuffers at all */
> -       if (bpp > 24)
> +
> +       if (!cirrus_check_framebuffer(cdev, mode_cmd->width, mode_cmd->height,
> +                                     bpp, mode_cmd->pitches[0]))
>                 return ERR_PTR(-EINVAL);
>
>         obj = drm_gem_object_lookup(dev, filp, mode_cmd->handles[0]);
> @@ -96,8 +98,7 @@ static int cirrus_vram_init(struct cirrus_device *cdev)
>  {
>         /* BAR 0 is VRAM */
>         cdev->mc.vram_base = pci_resource_start(cdev->dev->pdev, 0);
> -       /* We have 4MB of VRAM */
> -       cdev->mc.vram_size = 4 * 1024 * 1024;
> +       cdev->mc.vram_size = pci_resource_len(cdev->dev->pdev, 0);
>
>         if (!request_mem_region(cdev->mc.vram_base, cdev->mc.vram_size,
>                                 "cirrusdrmfb_vram")) {
> @@ -307,3 +308,21 @@ out_unlock:
>         return ret;
>
>  }
> +
> +bool cirrus_check_framebuffer(struct cirrus_device *cdev, int width, int height,
> +                             int bpp, int pitch)
> +{
> +       const int max_pitch = 0x1FF << 3; /* (4096 - 1) & ~111b bytes */
> +       const int max_size = cdev->mc.vram_size;
> +
> +       if (bpp > 32)
> +               return false;
> +
> +       if (pitch > max_pitch)
> +               return false;
> +
> +       if (pitch * height > max_size)
> +               return false;
> +
> +       return true;
> +}
> --
> 2.1.0.rc2.206.gedb03e5
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
diff mbox

Patch

diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h
index d44e69d..693a456 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.h
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.h
@@ -210,6 +210,9 @@  int cirrus_framebuffer_init(struct drm_device *dev,
 			    struct drm_mode_fb_cmd2 *mode_cmd,
 			    struct drm_gem_object *obj);
 
+bool cirrus_check_framebuffer(struct cirrus_device *cdev, int width, int height,
+			      int bpp, int pitch);
+
 				/* cirrus_display.c */
 int cirrus_modeset_init(struct cirrus_device *cdev);
 void cirrus_modeset_fini(struct cirrus_device *cdev);
diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
index d231b1c..502a89e 100644
--- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
+++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
@@ -139,6 +139,7 @@  static int cirrusfb_create_object(struct cirrus_fbdev *afbdev,
 			       struct drm_gem_object **gobj_p)
 {
 	struct drm_device *dev = afbdev->helper.dev;
+	struct cirrus_device *cdev = dev->dev_private;
 	u32 bpp, depth;
 	u32 size;
 	struct drm_gem_object *gobj;
@@ -146,8 +147,10 @@  static int cirrusfb_create_object(struct cirrus_fbdev *afbdev,
 	int ret = 0;
 	drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);
 
-	if (bpp > 24)
+	if (!cirrus_check_framebuffer(cdev, mode_cmd->width, mode_cmd->height,
+				      bpp, mode_cmd->pitches[0]))
 		return -EINVAL;
+
 	size = mode_cmd->pitches[0] * mode_cmd->height;
 	ret = cirrus_gem_create(dev, size, true, &gobj);
 	if (ret)
diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c
index 99c1983..d9590fc 100644
--- a/drivers/gpu/drm/cirrus/cirrus_main.c
+++ b/drivers/gpu/drm/cirrus/cirrus_main.c
@@ -49,14 +49,16 @@  cirrus_user_framebuffer_create(struct drm_device *dev,
 			       struct drm_file *filp,
 			       struct drm_mode_fb_cmd2 *mode_cmd)
 {
+	struct cirrus_device *cdev = dev->dev_private;
 	struct drm_gem_object *obj;
 	struct cirrus_framebuffer *cirrus_fb;
 	int ret;
 	u32 bpp, depth;
 
 	drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);
-	/* cirrus can't handle > 24bpp framebuffers at all */
-	if (bpp > 24)
+
+	if (!cirrus_check_framebuffer(cdev, mode_cmd->width, mode_cmd->height,
+				      bpp, mode_cmd->pitches[0]))
 		return ERR_PTR(-EINVAL);
 
 	obj = drm_gem_object_lookup(dev, filp, mode_cmd->handles[0]);
@@ -96,8 +98,7 @@  static int cirrus_vram_init(struct cirrus_device *cdev)
 {
 	/* BAR 0 is VRAM */
 	cdev->mc.vram_base = pci_resource_start(cdev->dev->pdev, 0);
-	/* We have 4MB of VRAM */
-	cdev->mc.vram_size = 4 * 1024 * 1024;
+	cdev->mc.vram_size = pci_resource_len(cdev->dev->pdev, 0);
 
 	if (!request_mem_region(cdev->mc.vram_base, cdev->mc.vram_size,
 				"cirrusdrmfb_vram")) {
@@ -307,3 +308,21 @@  out_unlock:
 	return ret;
 
 }
+
+bool cirrus_check_framebuffer(struct cirrus_device *cdev, int width, int height,
+			      int bpp, int pitch)
+{
+	const int max_pitch = 0x1FF << 3; /* (4096 - 1) & ~111b bytes */
+	const int max_size = cdev->mc.vram_size;
+
+	if (bpp > 32)
+		return false;
+
+	if (pitch > max_pitch)
+		return false;
+
+	if (pitch * height > max_size)
+		return false;
+
+	return true;
+}