summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/cirrus/cirrus_main.c
diff options
context:
space:
mode:
authorZach Reizner2014-10-29 19:04:24 +0100
committerDave Airlie2014-11-20 02:42:46 +0100
commit8975626ea35adcca561f8a81dedccfbc5dd8ec72 (patch)
treeacf4290d5b83894212eb71dc51d2a5c088fa67b3 /drivers/gpu/drm/cirrus/cirrus_main.c
parentdrm/udl: add support to export a handle to a FD on UDL. (diff)
downloadkernel-qcow2-linux-8975626ea35adcca561f8a81dedccfbc5dd8ec72.tar.gz
kernel-qcow2-linux-8975626ea35adcca561f8a81dedccfbc5dd8ec72.tar.xz
kernel-qcow2-linux-8975626ea35adcca561f8a81dedccfbc5dd8ec72.zip
drm/cirrus: allow 32bpp framebuffers for cirrus drm
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> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/cirrus/cirrus_main.c')
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_main.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c
index ab7cb547c570..4c2d68e9102d 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")) {
@@ -312,3 +313,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;
+}