Message ID | 1414605864-28175-1-git-send-email-zachr@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
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 --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; +}
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(-)