aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2011-11-14 17:51:28 -0500
committerDave Airlie <airlied@redhat.com>2011-11-15 14:53:23 -0500
commit308e5bcbdb10452e8aba31aa21432fb67ee46d72 (patch)
tree5e4eebef07685c4047f54d1727fc9bcbace8889d /drivers
parent8cf5c9177151537e73ff1816540e4ba24b174391 (diff)
drm: add an fb creation ioctl that takes a pixel format v5
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 the new drm_fourcc.h header file. Implement the fb creation hooks in terms of the new mode_fb_cmd2 using helpers where the old bpp/depth values are needed. v2: create DRM specific fourcc header file for sharing with libdrm etc v3: fix rebase failure and use DRM fourcc codes in intel_display.c and update commit message v4: make fb_cmd2 handle field into an array for multi-object formats pull in Ville's fix for the memcpy in drm_plane_init apply Ville's cleanup to zero out fb_cmd2 arg in drm_mode_addfb v5: add 'flags' field for interlaced support (from Ville) Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Alan Cox <alan@lxorguk.ukuu.org.uk> Reviewed-by: Rob Clark <rob.clark@linaro.org> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/drm_crtc.c111
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c51
-rw-r--r--drivers/gpu/drm/drm_drv.c1
-rw-r--r--drivers/gpu/drm/i915/intel_display.c39
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c11
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fb.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c13
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c18
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c22
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.h1
-rw-r--r--drivers/staging/gma500/framebuffer.c2
15 files changed, 226 insertions, 63 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 5e1df76c8f72..e54c0a6a3072 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -36,6 +36,7 @@
36#include "drmP.h" 36#include "drmP.h"
37#include "drm_crtc.h" 37#include "drm_crtc.h"
38#include "drm_edid.h" 38#include "drm_edid.h"
39#include "drm_fourcc.h"
39 40
40struct drm_prop_enum_list { 41struct drm_prop_enum_list {
41 int type; 42 int type;
@@ -568,7 +569,7 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
568 return -ENOMEM; 569 return -ENOMEM;
569 } 570 }
570 571
571 memcpy(plane->format_types, formats, format_count); 572 memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
572 plane->format_count = format_count; 573 plane->format_count = format_count;
573 plane->possible_crtcs = possible_crtcs; 574 plane->possible_crtcs = possible_crtcs;
574 575
@@ -1915,6 +1916,42 @@ out:
1915 return ret; 1916 return ret;
1916} 1917}
1917 1918
1919/* Original addfb only supported RGB formats, so figure out which one */
1920uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)
1921{
1922 uint32_t fmt;
1923
1924 switch (bpp) {
1925 case 8:
1926 fmt = DRM_FOURCC_RGB332;
1927 break;
1928 case 16:
1929 if (depth == 15)
1930 fmt = DRM_FOURCC_RGB555;
1931 else
1932 fmt = DRM_FOURCC_RGB565;
1933 break;
1934 case 24:
1935 fmt = DRM_FOURCC_RGB24;
1936 break;
1937 case 32:
1938 if (depth == 24)
1939 fmt = DRM_FOURCC_RGB24;
1940 else if (depth == 30)
1941 fmt = DRM_INTEL_RGB30;
1942 else
1943 fmt = DRM_FOURCC_RGB32;
1944 break;
1945 default:
1946 DRM_ERROR("bad bpp, assuming RGB24 pixel format\n");
1947 fmt = DRM_FOURCC_RGB24;
1948 break;
1949 }
1950
1951 return fmt;
1952}
1953EXPORT_SYMBOL(drm_mode_legacy_fb_format);
1954
1918/** 1955/**
1919 * drm_mode_addfb - add an FB to the graphics configuration 1956 * drm_mode_addfb - add an FB to the graphics configuration
1920 * @inode: inode from the ioctl 1957 * @inode: inode from the ioctl
@@ -1935,7 +1972,74 @@ out:
1935int drm_mode_addfb(struct drm_device *dev, 1972int drm_mode_addfb(struct drm_device *dev,
1936 void *data, struct drm_file *file_priv) 1973 void *data, struct drm_file *file_priv)
1937{ 1974{
1938 struct drm_mode_fb_cmd *r = data; 1975 struct drm_mode_fb_cmd *or = data;
1976 struct drm_mode_fb_cmd2 r = {};
1977 struct drm_mode_config *config = &dev->mode_config;
1978 struct drm_framebuffer *fb;
1979 int ret = 0;
1980
1981 /* Use new struct with format internally */
1982 r.fb_id = or->fb_id;
1983 r.width = or->width;
1984 r.height = or->height;
1985 r.pitches[0] = or->pitch;
1986 r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);
1987 r.handles[0] = or->handle;
1988
1989 if (!drm_core_check_feature(dev, DRIVER_MODESET))
1990 return -EINVAL;
1991
1992 if ((config->min_width > r.width) || (r.width > config->max_width)) {
1993 DRM_ERROR("mode new framebuffer width not within limits\n");
1994 return -EINVAL;
1995 }
1996 if ((config->min_height > r.height) || (r.height > config->max_height)) {
1997 DRM_ERROR("mode new framebuffer height not within limits\n");
1998 return -EINVAL;
1999 }
2000
2001 mutex_lock(&dev->mode_config.mutex);
2002
2003 /* TODO check buffer is sufficiently large */
2004 /* TODO setup destructor callback */
2005
2006 fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r);
2007 if (IS_ERR(fb)) {
2008 DRM_ERROR("could not create framebuffer\n");
2009 ret = PTR_ERR(fb);
2010 goto out;
2011 }
2012
2013 or->fb_id = fb->base.id;
2014 list_add(&fb->filp_head, &file_priv->fbs);
2015 DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
2016
2017out:
2018 mutex_unlock(&dev->mode_config.mutex);
2019 return ret;
2020}
2021
2022/**
2023 * drm_mode_addfb2 - add an FB to the graphics configuration
2024 * @inode: inode from the ioctl
2025 * @filp: file * from the ioctl
2026 * @cmd: cmd from ioctl
2027 * @arg: arg from ioctl
2028 *
2029 * LOCKING:
2030 * Takes mode config lock.
2031 *
2032 * Add a new FB to the specified CRTC, given a user request with format.
2033 *
2034 * Called by the user via ioctl.
2035 *
2036 * RETURNS:
2037 * Zero on success, errno on failure.
2038 */
2039int drm_mode_addfb2(struct drm_device *dev,
2040 void *data, struct drm_file *file_priv)
2041{
2042 struct drm_mode_fb_cmd2 *r = data;
1939 struct drm_mode_config *config = &dev->mode_config; 2043 struct drm_mode_config *config = &dev->mode_config;
1940 struct drm_framebuffer *fb; 2044 struct drm_framebuffer *fb;
1941 int ret = 0; 2045 int ret = 0;
@@ -1956,9 +2060,6 @@ int drm_mode_addfb(struct drm_device *dev,
1956 2060
1957 mutex_lock(&dev->mode_config.mutex); 2061 mutex_lock(&dev->mode_config.mutex);
1958 2062
1959 /* TODO check buffer is sufficiently large */
1960 /* TODO setup destructor callback */
1961
1962 fb = dev->mode_config.funcs->fb_create(dev, file_priv, r); 2063 fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
1963 if (IS_ERR(fb)) { 2064 if (IS_ERR(fb)) {
1964 DRM_ERROR("could not create framebuffer\n"); 2065 DRM_ERROR("could not create framebuffer\n");
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 2957636161e8..432d5391b93c 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -34,6 +34,7 @@
34 34
35#include "drmP.h" 35#include "drmP.h"
36#include "drm_crtc.h" 36#include "drm_crtc.h"
37#include "drm_fourcc.h"
37#include "drm_crtc_helper.h" 38#include "drm_crtc_helper.h"
38#include "drm_fb_helper.h" 39#include "drm_fb_helper.h"
39 40
@@ -810,14 +811,56 @@ void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
810} 811}
811EXPORT_SYMBOL(drm_helper_connector_dpms); 812EXPORT_SYMBOL(drm_helper_connector_dpms);
812 813
814/*
815 * Just need to support RGB formats here for compat with code that doesn't
816 * use pixel formats directly yet.
817 */
818void drm_helper_get_fb_bpp_depth(uint32_t format, unsigned int *depth,
819 int *bpp)
820{
821 switch (format) {
822 case DRM_FOURCC_RGB332:
823 *depth = 8;
824 *bpp = 8;
825 break;
826 case DRM_FOURCC_RGB555:
827 *depth = 15;
828 *bpp = 16;
829 break;
830 case DRM_FOURCC_RGB565:
831 *depth = 16;
832 *bpp = 16;
833 break;
834 case DRM_FOURCC_RGB24:
835 *depth = 24;
836 *bpp = 32;
837 break;
838 case DRM_INTEL_RGB30:
839 *depth = 30;
840 *bpp = 32;
841 break;
842 case DRM_FOURCC_RGB32:
843 *depth = 32;
844 *bpp = 32;
845 break;
846 default:
847 DRM_DEBUG_KMS("unsupported pixel format\n");
848 *depth = 0;
849 *bpp = 0;
850 break;
851 }
852}
853EXPORT_SYMBOL(drm_helper_get_fb_bpp_depth);
854
813int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, 855int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
814 struct drm_mode_fb_cmd *mode_cmd) 856 struct drm_mode_fb_cmd2 *mode_cmd)
815{ 857{
816 fb->width = mode_cmd->width; 858 fb->width = mode_cmd->width;
817 fb->height = mode_cmd->height; 859 fb->height = mode_cmd->height;
818 fb->pitch = mode_cmd->pitch; 860 fb->pitch = mode_cmd->pitches[0];
819 fb->bits_per_pixel = mode_cmd->bpp; 861 drm_helper_get_fb_bpp_depth(mode_cmd->pixel_format, &fb->depth,
820 fb->depth = mode_cmd->depth; 862 &fb->bits_per_pixel);
863 fb->pixel_format = mode_cmd->pixel_format;
821 864
822 return 0; 865 return 0;
823} 866}
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 4f25989b0d4a..eaf25ffd9a46 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -153,6 +153,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {
153 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 153 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
154 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 154 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
155 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 155 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
156 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
156 DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 157 DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
157 DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 158 DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
158 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 159 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 981b1f1c04d8..50ae9157befe 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6279,7 +6279,7 @@ static struct drm_display_mode load_detect_mode = {
6279 6279
6280static struct drm_framebuffer * 6280static struct drm_framebuffer *
6281intel_framebuffer_create(struct drm_device *dev, 6281intel_framebuffer_create(struct drm_device *dev,
6282 struct drm_mode_fb_cmd *mode_cmd, 6282 struct drm_mode_fb_cmd2 *mode_cmd,
6283 struct drm_i915_gem_object *obj) 6283 struct drm_i915_gem_object *obj)
6284{ 6284{
6285 struct intel_framebuffer *intel_fb; 6285 struct intel_framebuffer *intel_fb;
@@ -6321,7 +6321,7 @@ intel_framebuffer_create_for_mode(struct drm_device *dev,
6321 int depth, int bpp) 6321 int depth, int bpp)
6322{ 6322{
6323 struct drm_i915_gem_object *obj; 6323 struct drm_i915_gem_object *obj;
6324 struct drm_mode_fb_cmd mode_cmd; 6324 struct drm_mode_fb_cmd2 mode_cmd;
6325 6325
6326 obj = i915_gem_alloc_object(dev, 6326 obj = i915_gem_alloc_object(dev,
6327 intel_framebuffer_size_for_mode(mode, bpp)); 6327 intel_framebuffer_size_for_mode(mode, bpp));
@@ -6330,9 +6330,9 @@ intel_framebuffer_create_for_mode(struct drm_device *dev,
6330 6330
6331 mode_cmd.width = mode->hdisplay; 6331 mode_cmd.width = mode->hdisplay;
6332 mode_cmd.height = mode->vdisplay; 6332 mode_cmd.height = mode->vdisplay;
6333 mode_cmd.depth = depth; 6333 mode_cmd.pitches[0] = intel_framebuffer_pitch_for_width(mode_cmd.width,
6334 mode_cmd.bpp = bpp; 6334 bpp);
6335 mode_cmd.pitch = intel_framebuffer_pitch_for_width(mode_cmd.width, bpp); 6335 mode_cmd.pixel_format = 0;
6336 6336
6337 return intel_framebuffer_create(dev, &mode_cmd, obj); 6337 return intel_framebuffer_create(dev, &mode_cmd, obj);
6338} 6338}
@@ -7573,7 +7573,7 @@ static const struct drm_framebuffer_funcs intel_fb_funcs = {
7573 7573
7574int intel_framebuffer_init(struct drm_device *dev, 7574int intel_framebuffer_init(struct drm_device *dev,
7575 struct intel_framebuffer *intel_fb, 7575 struct intel_framebuffer *intel_fb,
7576 struct drm_mode_fb_cmd *mode_cmd, 7576 struct drm_mode_fb_cmd2 *mode_cmd,
7577 struct drm_i915_gem_object *obj) 7577 struct drm_i915_gem_object *obj)
7578{ 7578{
7579 int ret; 7579 int ret;
@@ -7581,21 +7581,23 @@ int intel_framebuffer_init(struct drm_device *dev,
7581 if (obj->tiling_mode == I915_TILING_Y) 7581 if (obj->tiling_mode == I915_TILING_Y)
7582 return -EINVAL; 7582 return -EINVAL;
7583 7583
7584 if (mode_cmd->pitch & 63) 7584 if (mode_cmd->pitches[0] & 63)
7585 return -EINVAL; 7585 return -EINVAL;
7586 7586
7587 switch (mode_cmd->bpp) { 7587 switch (mode_cmd->pixel_format) {
7588 case 8: 7588 case DRM_FOURCC_RGB332:
7589 case 16: 7589 case DRM_FOURCC_RGB565:
7590 /* Only pre-ILK can handle 5:5:5 */ 7590 case DRM_FOURCC_RGB24:
7591 if (mode_cmd->depth == 15 && !HAS_PCH_SPLIT(dev)) 7591 case DRM_INTEL_RGB30:
7592 return -EINVAL; 7592 /* RGB formats are common across chipsets */
7593 break; 7593 break;
7594 7594 case DRM_FOURCC_YUYV:
7595 case 24: 7595 case DRM_FOURCC_UYVY:
7596 case 32: 7596 case DRM_FOURCC_YVYU:
7597 case DRM_FOURCC_VYUY:
7597 break; 7598 break;
7598 default: 7599 default:
7600 DRM_ERROR("unsupported pixel format\n");
7599 return -EINVAL; 7601 return -EINVAL;
7600 } 7602 }
7601 7603
@@ -7613,11 +7615,12 @@ int intel_framebuffer_init(struct drm_device *dev,
7613static struct drm_framebuffer * 7615static struct drm_framebuffer *
7614intel_user_framebuffer_create(struct drm_device *dev, 7616intel_user_framebuffer_create(struct drm_device *dev,
7615 struct drm_file *filp, 7617 struct drm_file *filp,
7616 struct drm_mode_fb_cmd *mode_cmd) 7618 struct drm_mode_fb_cmd2 *mode_cmd)
7617{ 7619{
7618 struct drm_i915_gem_object *obj; 7620 struct drm_i915_gem_object *obj;
7619 7621
7620 obj = to_intel_bo(drm_gem_object_lookup(dev, filp, mode_cmd->handle)); 7622 obj = to_intel_bo(drm_gem_object_lookup(dev, filp,
7623 mode_cmd->handles[0]));
7621 if (&obj->base == NULL) 7624 if (&obj->base == NULL)
7622 return ERR_PTR(-ENOENT); 7625 return ERR_PTR(-ENOENT);
7623 7626
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index bd9a604b73da..23c56221fe8f 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -359,7 +359,7 @@ extern int intel_pin_and_fence_fb_obj(struct drm_device *dev,
359 359
360extern int intel_framebuffer_init(struct drm_device *dev, 360extern int intel_framebuffer_init(struct drm_device *dev,
361 struct intel_framebuffer *ifb, 361 struct intel_framebuffer *ifb,
362 struct drm_mode_fb_cmd *mode_cmd, 362 struct drm_mode_fb_cmd2 *mode_cmd,
363 struct drm_i915_gem_object *obj); 363 struct drm_i915_gem_object *obj);
364extern int intel_fbdev_init(struct drm_device *dev); 364extern int intel_fbdev_init(struct drm_device *dev);
365extern void intel_fbdev_fini(struct drm_device *dev); 365extern 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 ec49bae73382..dc1db4ff4245 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,
65 struct drm_i915_private *dev_priv = dev->dev_private; 65 struct drm_i915_private *dev_priv = dev->dev_private;
66 struct fb_info *info; 66 struct fb_info *info;
67 struct drm_framebuffer *fb; 67 struct drm_framebuffer *fb;
68 struct drm_mode_fb_cmd mode_cmd; 68 struct drm_mode_fb_cmd2 mode_cmd;
69 struct drm_i915_gem_object *obj; 69 struct drm_i915_gem_object *obj;
70 struct device *device = &dev->pdev->dev; 70 struct device *device = &dev->pdev->dev;
71 int size, ret; 71 int size, ret;
@@ -77,11 +77,12 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
77 mode_cmd.width = sizes->surface_width; 77 mode_cmd.width = sizes->surface_width;
78 mode_cmd.height = sizes->surface_height; 78 mode_cmd.height = sizes->surface_height;
79 79
80 mode_cmd.bpp = sizes->surface_bpp; 80 mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((sizes->surface_bpp + 7) /
81 mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 7) / 8), 64); 81 8), 64);
82 mode_cmd.depth = sizes->surface_depth; 82 mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
83 sizes->surface_depth);
83 84
84 size = mode_cmd.pitch * mode_cmd.height; 85 size = mode_cmd.pitches[0] * mode_cmd.height;
85 size = ALIGN(size, PAGE_SIZE); 86 size = ALIGN(size, PAGE_SIZE);
86 obj = i915_gem_alloc_object(dev, size); 87 obj = i915_gem_alloc_object(dev, size);
87 if (!obj) { 88 if (!obj) {
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index ddbabefb4273..7687a77f01d1 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 = {
64int 64int
65nouveau_framebuffer_init(struct drm_device *dev, 65nouveau_framebuffer_init(struct drm_device *dev,
66 struct nouveau_framebuffer *nv_fb, 66 struct nouveau_framebuffer *nv_fb,
67 struct drm_mode_fb_cmd *mode_cmd, 67 struct drm_mode_fb_cmd2 *mode_cmd,
68 struct nouveau_bo *nvbo) 68 struct nouveau_bo *nvbo)
69{ 69{
70 struct drm_nouveau_private *dev_priv = dev->dev_private; 70 struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -124,13 +124,13 @@ nouveau_framebuffer_init(struct drm_device *dev,
124static struct drm_framebuffer * 124static struct drm_framebuffer *
125nouveau_user_framebuffer_create(struct drm_device *dev, 125nouveau_user_framebuffer_create(struct drm_device *dev,
126 struct drm_file *file_priv, 126 struct drm_file *file_priv,
127 struct drm_mode_fb_cmd *mode_cmd) 127 struct drm_mode_fb_cmd2 *mode_cmd)
128{ 128{
129 struct nouveau_framebuffer *nouveau_fb; 129 struct nouveau_framebuffer *nouveau_fb;
130 struct drm_gem_object *gem; 130 struct drm_gem_object *gem;
131 int ret; 131 int ret;
132 132
133 gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle); 133 gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
134 if (!gem) 134 if (!gem)
135 return ERR_PTR(-ENOENT); 135 return ERR_PTR(-ENOENT);
136 136
diff --git a/drivers/gpu/drm/nouveau/nouveau_fb.h b/drivers/gpu/drm/nouveau/nouveau_fb.h
index 95c843e684bb..f4dd30150879 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fb.h
+++ b/drivers/gpu/drm/nouveau/nouveau_fb.h
@@ -45,5 +45,5 @@ nouveau_framebuffer(struct drm_framebuffer *fb)
45extern const struct drm_mode_config_funcs nouveau_mode_config_funcs; 45extern const struct drm_mode_config_funcs nouveau_mode_config_funcs;
46 46
47int nouveau_framebuffer_init(struct drm_device *dev, struct nouveau_framebuffer *nouveau_fb, 47int nouveau_framebuffer_init(struct drm_device *dev, struct nouveau_framebuffer *nouveau_fb,
48 struct drm_mode_fb_cmd *mode_cmd, struct nouveau_bo *nvbo); 48 struct drm_mode_fb_cmd2 *mode_cmd, struct nouveau_bo *nvbo);
49#endif /* __NOUVEAU_FB_H__ */ 49#endif /* __NOUVEAU_FB_H__ */
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 14a8627efe4d..d663065181bf 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -281,7 +281,7 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
281 struct nouveau_framebuffer *nouveau_fb; 281 struct nouveau_framebuffer *nouveau_fb;
282 struct nouveau_channel *chan; 282 struct nouveau_channel *chan;
283 struct nouveau_bo *nvbo; 283 struct nouveau_bo *nvbo;
284 struct drm_mode_fb_cmd mode_cmd; 284 struct drm_mode_fb_cmd2 mode_cmd;
285 struct pci_dev *pdev = dev->pdev; 285 struct pci_dev *pdev = dev->pdev;
286 struct device *device = &pdev->dev; 286 struct device *device = &pdev->dev;
287 int size, ret; 287 int size, ret;
@@ -289,12 +289,13 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
289 mode_cmd.width = sizes->surface_width; 289 mode_cmd.width = sizes->surface_width;
290 mode_cmd.height = sizes->surface_height; 290 mode_cmd.height = sizes->surface_height;
291 291
292 mode_cmd.bpp = sizes->surface_bpp; 292 mode_cmd.pitches[0] = mode_cmd.width * (sizes->surface_bpp >> 3);
293 mode_cmd.pitch = mode_cmd.width * (mode_cmd.bpp >> 3); 293 mode_cmd.pitches[0] = roundup(mode_cmd.pitches[0], 256);
294 mode_cmd.pitch = roundup(mode_cmd.pitch, 256);
295 mode_cmd.depth = sizes->surface_depth;
296 294
297 size = mode_cmd.pitch * mode_cmd.height; 295 mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
296 sizes->surface_depth);
297
298 size = mode_cmd.pitches[0] * mode_cmd.height;
298 size = roundup(size, PAGE_SIZE); 299 size = roundup(size, PAGE_SIZE);
299 300
300 ret = nouveau_gem_new(dev, size, 0, NOUVEAU_GEM_DOMAIN_VRAM, 301 ret = nouveau_gem_new(dev, size, 0, NOUVEAU_GEM_DOMAIN_VRAM,
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index a22d6e6a49a2..96d9ba96c87d 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -1081,7 +1081,7 @@ static const struct drm_framebuffer_funcs radeon_fb_funcs = {
1081void 1081void
1082radeon_framebuffer_init(struct drm_device *dev, 1082radeon_framebuffer_init(struct drm_device *dev,
1083 struct radeon_framebuffer *rfb, 1083 struct radeon_framebuffer *rfb,
1084 struct drm_mode_fb_cmd *mode_cmd, 1084 struct drm_mode_fb_cmd2 *mode_cmd,
1085 struct drm_gem_object *obj) 1085 struct drm_gem_object *obj)
1086{ 1086{
1087 rfb->obj = obj; 1087 rfb->obj = obj;
@@ -1092,15 +1092,15 @@ radeon_framebuffer_init(struct drm_device *dev,
1092static struct drm_framebuffer * 1092static struct drm_framebuffer *
1093radeon_user_framebuffer_create(struct drm_device *dev, 1093radeon_user_framebuffer_create(struct drm_device *dev,
1094 struct drm_file *file_priv, 1094 struct drm_file *file_priv,
1095 struct drm_mode_fb_cmd *mode_cmd) 1095 struct drm_mode_fb_cmd2 *mode_cmd)
1096{ 1096{
1097 struct drm_gem_object *obj; 1097 struct drm_gem_object *obj;
1098 struct radeon_framebuffer *radeon_fb; 1098 struct radeon_framebuffer *radeon_fb;
1099 1099
1100 obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle); 1100 obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
1101 if (obj == NULL) { 1101 if (obj == NULL) {
1102 dev_err(&dev->pdev->dev, "No GEM object associated to handle 0x%08X, " 1102 dev_err(&dev->pdev->dev, "No GEM object associated to handle 0x%08X, "
1103 "can't create framebuffer\n", mode_cmd->handle); 1103 "can't create framebuffer\n", mode_cmd->handles[0]);
1104 return ERR_PTR(-ENOENT); 1104 return ERR_PTR(-ENOENT);
1105 } 1105 }
1106 1106
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 0b7b486c97e8..ea110ad2a841 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)
103} 103}
104 104
105static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev, 105static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
106 struct drm_mode_fb_cmd *mode_cmd, 106 struct drm_mode_fb_cmd2 *mode_cmd,
107 struct drm_gem_object **gobj_p) 107 struct drm_gem_object **gobj_p)
108{ 108{
109 struct radeon_device *rdev = rfbdev->rdev; 109 struct radeon_device *rdev = rfbdev->rdev;
@@ -114,13 +114,17 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
114 int ret; 114 int ret;
115 int aligned_size, size; 115 int aligned_size, size;
116 int height = mode_cmd->height; 116 int height = mode_cmd->height;
117 u32 bpp, depth;
118
119 drm_helper_get_fb_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);
117 120
118 /* need to align pitch with crtc limits */ 121 /* need to align pitch with crtc limits */
119 mode_cmd->pitch = radeon_align_pitch(rdev, mode_cmd->width, mode_cmd->bpp, fb_tiled) * ((mode_cmd->bpp + 1) / 8); 122 mode_cmd->pitches[0] = radeon_align_pitch(rdev, mode_cmd->width, bpp,
123 fb_tiled) * ((bpp + 1) / 8);
120 124
121 if (rdev->family >= CHIP_R600) 125 if (rdev->family >= CHIP_R600)
122 height = ALIGN(mode_cmd->height, 8); 126 height = ALIGN(mode_cmd->height, 8);
123 size = mode_cmd->pitch * height; 127 size = mode_cmd->pitches[0] * height;
124 aligned_size = ALIGN(size, PAGE_SIZE); 128 aligned_size = ALIGN(size, PAGE_SIZE);
125 ret = radeon_gem_object_create(rdev, aligned_size, 0, 129 ret = radeon_gem_object_create(rdev, aligned_size, 0,
126 RADEON_GEM_DOMAIN_VRAM, 130 RADEON_GEM_DOMAIN_VRAM,
@@ -151,7 +155,7 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
151 if (tiling_flags) { 155 if (tiling_flags) {
152 ret = radeon_bo_set_tiling_flags(rbo, 156 ret = radeon_bo_set_tiling_flags(rbo,
153 tiling_flags | RADEON_TILING_SURFACE, 157 tiling_flags | RADEON_TILING_SURFACE,
154 mode_cmd->pitch); 158 mode_cmd->pitches[0]);
155 if (ret) 159 if (ret)
156 dev_err(rdev->dev, "FB failed to set tiling flags\n"); 160 dev_err(rdev->dev, "FB failed to set tiling flags\n");
157 } 161 }
@@ -187,7 +191,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
187 struct radeon_device *rdev = rfbdev->rdev; 191 struct radeon_device *rdev = rfbdev->rdev;
188 struct fb_info *info; 192 struct fb_info *info;
189 struct drm_framebuffer *fb = NULL; 193 struct drm_framebuffer *fb = NULL;
190 struct drm_mode_fb_cmd mode_cmd; 194 struct drm_mode_fb_cmd2 mode_cmd;
191 struct drm_gem_object *gobj = NULL; 195 struct drm_gem_object *gobj = NULL;
192 struct radeon_bo *rbo = NULL; 196 struct radeon_bo *rbo = NULL;
193 struct device *device = &rdev->pdev->dev; 197 struct device *device = &rdev->pdev->dev;
@@ -201,8 +205,8 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
201 if ((sizes->surface_bpp == 24) && ASIC_IS_AVIVO(rdev)) 205 if ((sizes->surface_bpp == 24) && ASIC_IS_AVIVO(rdev))
202 sizes->surface_bpp = 32; 206 sizes->surface_bpp = 32;
203 207
204 mode_cmd.bpp = sizes->surface_bpp; 208 mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
205 mode_cmd.depth = sizes->surface_depth; 209 sizes->surface_depth);
206 210
207 ret = radeonfb_create_pinned_object(rfbdev, &mode_cmd, &gobj); 211 ret = radeonfb_create_pinned_object(rfbdev, &mode_cmd, &gobj);
208 rbo = gem_to_radeon_bo(gobj); 212 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 2c2e75ef8a37..08ff857c8fd6 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -643,7 +643,7 @@ extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green
643 u16 *blue, int regno); 643 u16 *blue, int regno);
644void radeon_framebuffer_init(struct drm_device *dev, 644void radeon_framebuffer_init(struct drm_device *dev,
645 struct radeon_framebuffer *rfb, 645 struct radeon_framebuffer *rfb,
646 struct drm_mode_fb_cmd *mode_cmd, 646 struct drm_mode_fb_cmd2 *mode_cmd,
647 struct drm_gem_object *obj); 647 struct drm_gem_object *obj);
648 648
649int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb); 649int 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 03daefa73397..1beaa3f8dac2 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -990,7 +990,7 @@ out_err1:
990 990
991static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, 991static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
992 struct drm_file *file_priv, 992 struct drm_file *file_priv,
993 struct drm_mode_fb_cmd *mode_cmd) 993 struct drm_mode_fb_cmd2 *mode_cmd2)
994{ 994{
995 struct vmw_private *dev_priv = vmw_priv(dev); 995 struct vmw_private *dev_priv = vmw_priv(dev);
996 struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; 996 struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
@@ -998,16 +998,24 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
998 struct vmw_surface *surface = NULL; 998 struct vmw_surface *surface = NULL;
999 struct vmw_dma_buffer *bo = NULL; 999 struct vmw_dma_buffer *bo = NULL;
1000 struct ttm_base_object *user_obj; 1000 struct ttm_base_object *user_obj;
1001 struct drm_mode_fb_cmd mode_cmd;
1001 u64 required_size; 1002 u64 required_size;
1002 int ret; 1003 int ret;
1003 1004
1005 mode_cmd.width = mode_cmd2->width;
1006 mode_cmd.height = mode_cmd2->height;
1007 mode_cmd.pitch = mode_cmd2->pitches[0];
1008 mode_cmd.handle = mode_cmd2->handles[0];
1009 drm_helper_get_fb_bpp_depth(mode_cmd2->pixel_format, &mode_cmd.depth,
1010 &mode_cmd.bpp);
1011
1004 /** 1012 /**
1005 * This code should be conditioned on Screen Objects not being used. 1013 * This code should be conditioned on Screen Objects not being used.
1006 * If screen objects are used, we can allocate a GMR to hold the 1014 * If screen objects are used, we can allocate a GMR to hold the
1007 * requested framebuffer. 1015 * requested framebuffer.
1008 */ 1016 */
1009 1017
1010 required_size = mode_cmd->pitch * mode_cmd->height; 1018 required_size = mode_cmd.pitch * mode_cmd.height;
1011 if (unlikely(required_size > (u64) dev_priv->vram_size)) { 1019 if (unlikely(required_size > (u64) dev_priv->vram_size)) {
1012 DRM_ERROR("VRAM size is too small for requested mode.\n"); 1020 DRM_ERROR("VRAM size is too small for requested mode.\n");
1013 return ERR_PTR(-ENOMEM); 1021 return ERR_PTR(-ENOMEM);
@@ -1022,7 +1030,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
1022 * command stream using user-space handles. 1030 * command stream using user-space handles.
1023 */ 1031 */
1024 1032
1025 user_obj = ttm_base_object_lookup(tfile, mode_cmd->handle); 1033 user_obj = ttm_base_object_lookup(tfile, mode_cmd.handle);
1026 if (unlikely(user_obj == NULL)) { 1034 if (unlikely(user_obj == NULL)) {
1027 DRM_ERROR("Could not locate requested kms frame buffer.\n"); 1035 DRM_ERROR("Could not locate requested kms frame buffer.\n");
1028 return ERR_PTR(-ENOENT); 1036 return ERR_PTR(-ENOENT);
@@ -1033,7 +1041,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
1033 */ 1041 */
1034 1042
1035 ret = vmw_user_surface_lookup_handle(dev_priv, tfile, 1043 ret = vmw_user_surface_lookup_handle(dev_priv, tfile,
1036 mode_cmd->handle, &surface); 1044 mode_cmd.handle, &surface);
1037 if (ret) 1045 if (ret)
1038 goto try_dmabuf; 1046 goto try_dmabuf;
1039 1047
@@ -1041,7 +1049,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
1041 goto err_not_scanout; 1049 goto err_not_scanout;
1042 1050
1043 ret = vmw_kms_new_framebuffer_surface(dev_priv, file_priv, surface, 1051 ret = vmw_kms_new_framebuffer_surface(dev_priv, file_priv, surface,
1044 &vfb, mode_cmd); 1052 &vfb, &mode_cmd);
1045 1053
1046 /* vmw_user_surface_lookup takes one ref so does new_fb */ 1054 /* vmw_user_surface_lookup takes one ref so does new_fb */
1047 vmw_surface_unreference(&surface); 1055 vmw_surface_unreference(&surface);
@@ -1057,14 +1065,14 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
1057try_dmabuf: 1065try_dmabuf:
1058 DRM_INFO("%s: trying buffer\n", __func__); 1066 DRM_INFO("%s: trying buffer\n", __func__);
1059 1067
1060 ret = vmw_user_dmabuf_lookup(tfile, mode_cmd->handle, &bo); 1068 ret = vmw_user_dmabuf_lookup(tfile, mode_cmd.handle, &bo);
1061 if (ret) { 1069 if (ret) {
1062 DRM_ERROR("failed to find buffer: %i\n", ret); 1070 DRM_ERROR("failed to find buffer: %i\n", ret);
1063 return ERR_PTR(-ENOENT); 1071 return ERR_PTR(-ENOENT);
1064 } 1072 }
1065 1073
1066 ret = vmw_kms_new_framebuffer_dmabuf(dev_priv, bo, &vfb, 1074 ret = vmw_kms_new_framebuffer_dmabuf(dev_priv, bo, &vfb,
1067 mode_cmd); 1075 &mode_cmd);
1068 1076
1069 /* vmw_user_dmabuf_lookup takes one ref so does new_fb */ 1077 /* vmw_user_dmabuf_lookup takes one ref so does new_fb */
1070 vmw_dmabuf_unreference(&bo); 1078 vmw_dmabuf_unreference(&bo);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
index af8e6e5bd964..055b844bd80f 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
@@ -29,6 +29,7 @@
29#define VMWGFX_KMS_H_ 29#define VMWGFX_KMS_H_
30 30
31#include "drmP.h" 31#include "drmP.h"
32#include "drm_crtc_helper.h"
32#include "vmwgfx_drv.h" 33#include "vmwgfx_drv.h"
33 34
34#define VMWGFX_NUM_DISPLAY_UNITS 8 35#define VMWGFX_NUM_DISPLAY_UNITS 8
diff --git a/drivers/staging/gma500/framebuffer.c b/drivers/staging/gma500/framebuffer.c
index 3f39a37456fc..1e77229b2e23 100644
--- a/drivers/staging/gma500/framebuffer.c
+++ b/drivers/staging/gma500/framebuffer.c
@@ -546,7 +546,7 @@ out_err1:
546 */ 546 */
547static struct drm_framebuffer *psb_user_framebuffer_create 547static struct drm_framebuffer *psb_user_framebuffer_create
548 (struct drm_device *dev, struct drm_file *filp, 548 (struct drm_device *dev, struct drm_file *filp,
549 struct drm_mode_fb_cmd *cmd) 549 struct drm_mode_fb_cmd2 *cmd)
550{ 550{
551 struct gtt_range *r; 551 struct gtt_range *r;
552 struct drm_gem_object *obj; 552 struct drm_gem_object *obj;