aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--include/drm/drm.h1
-rw-r--r--include/drm/drm_crtc.h9
-rw-r--r--include/drm/drm_crtc_helper.h4
-rw-r--r--include/drm/drm_fourcc.h63
-rw-r--r--include/drm/drm_mode.h27
20 files changed, 327 insertions, 66 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;
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 28979677f94e..49d94ede2ec2 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -717,6 +717,7 @@ struct drm_get_cap {
717#define DRM_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xB5, struct drm_mode_get_plane_res) 717#define DRM_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xB5, struct drm_mode_get_plane_res)
718#define DRM_IOCTL_MODE_GETPLANE DRM_IOWR(0xB6, struct drm_mode_get_plane) 718#define DRM_IOCTL_MODE_GETPLANE DRM_IOWR(0xB6, struct drm_mode_get_plane)
719#define DRM_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct drm_mode_set_plane) 719#define DRM_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct drm_mode_set_plane)
720#define DRM_IOCTL_MODE_ADDFB2 DRM_IOWR(0xB8, struct drm_mode_fb_cmd2)
720 721
721/** 722/**
722 * Device specific ioctls should only be in their respective headers 723 * Device specific ioctls should only be in their respective headers
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index e20867ed7c90..a2fbf3399682 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -29,9 +29,10 @@
29#include <linux/spinlock.h> 29#include <linux/spinlock.h>
30#include <linux/types.h> 30#include <linux/types.h>
31#include <linux/idr.h> 31#include <linux/idr.h>
32
33#include <linux/fb.h> 32#include <linux/fb.h>
34 33
34#include <drm/drm_fourcc.h>
35
35struct drm_device; 36struct drm_device;
36struct drm_mode_set; 37struct drm_mode_set;
37struct drm_framebuffer; 38struct drm_framebuffer;
@@ -246,6 +247,7 @@ struct drm_framebuffer {
246 unsigned int depth; 247 unsigned int depth;
247 int bits_per_pixel; 248 int bits_per_pixel;
248 int flags; 249 int flags;
250 uint32_t pixel_format; /* fourcc format */
249 struct list_head filp_head; 251 struct list_head filp_head;
250 /* if you are using the helper */ 252 /* if you are using the helper */
251 void *helper_private; 253 void *helper_private;
@@ -619,7 +621,7 @@ struct drm_mode_set {
619 * struct drm_mode_config_funcs - configure CRTCs for a given screen layout 621 * struct drm_mode_config_funcs - configure CRTCs for a given screen layout
620 */ 622 */
621struct drm_mode_config_funcs { 623struct drm_mode_config_funcs {
622 struct drm_framebuffer *(*fb_create)(struct drm_device *dev, struct drm_file *file_priv, struct drm_mode_fb_cmd *mode_cmd); 624 struct drm_framebuffer *(*fb_create)(struct drm_device *dev, struct drm_file *file_priv, struct drm_mode_fb_cmd2 *mode_cmd);
623 void (*output_poll_changed)(struct drm_device *dev); 625 void (*output_poll_changed)(struct drm_device *dev);
624}; 626};
625 627
@@ -837,6 +839,9 @@ extern int drm_mode_cursor_ioctl(struct drm_device *dev,
837 void *data, struct drm_file *file_priv); 839 void *data, struct drm_file *file_priv);
838extern int drm_mode_addfb(struct drm_device *dev, 840extern int drm_mode_addfb(struct drm_device *dev,
839 void *data, struct drm_file *file_priv); 841 void *data, struct drm_file *file_priv);
842extern int drm_mode_addfb2(struct drm_device *dev,
843 void *data, struct drm_file *file_priv);
844extern uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
840extern int drm_mode_rmfb(struct drm_device *dev, 845extern int drm_mode_rmfb(struct drm_device *dev,
841 void *data, struct drm_file *file_priv); 846 void *data, struct drm_file *file_priv);
842extern int drm_mode_getfb(struct drm_device *dev, 847extern int drm_mode_getfb(struct drm_device *dev,
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index 73b071203dcc..b4abb33dbcd8 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -116,8 +116,10 @@ extern bool drm_helper_encoder_in_use(struct drm_encoder *encoder);
116 116
117extern void drm_helper_connector_dpms(struct drm_connector *connector, int mode); 117extern void drm_helper_connector_dpms(struct drm_connector *connector, int mode);
118 118
119extern void drm_helper_get_fb_bpp_depth(uint32_t format, unsigned int *depth,
120 int *bpp);
119extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, 121extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
120 struct drm_mode_fb_cmd *mode_cmd); 122 struct drm_mode_fb_cmd2 *mode_cmd);
121 123
122static inline void drm_crtc_helper_add(struct drm_crtc *crtc, 124static inline void drm_crtc_helper_add(struct drm_crtc *crtc,
123 const struct drm_crtc_helper_funcs *funcs) 125 const struct drm_crtc_helper_funcs *funcs)
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
new file mode 100644
index 000000000000..48c3d107a8fa
--- /dev/null
+++ b/include/drm/drm_fourcc.h
@@ -0,0 +1,63 @@
1/*
2 * Copyright 2011 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24#ifndef DRM_FOURCC_H
25#define DRM_FOURCC_H
26
27/*
28 * We don't use the V4L header because
29 * 1) the fourcc codes are well defined and trivial to construct
30 * 2) we don't want user apps to have to pull in v4l headers just for fourcc
31 * 3) the v4l fourcc codes are mixed up with a bunch of other code and are
32 * part of the v4l API, so changing them to something linux-generic isn't
33 * feasible
34 *
35 * So the below includes the fourcc codes used by the DRM and its drivers,
36 * along with potential device specific codes.
37 */
38
39#include <linux/types.h>
40
41#define fourcc_code(a,b,c,d) ((u32)(a) | ((u32)(b) << 8) | \
42 ((u32)(c) << 16) | ((u32)(d) << 24))
43
44/* RGB codes */
45#define DRM_FOURCC_RGB332 fourcc_code('R','G','B','1')
46#define DRM_FOURCC_RGB555 fourcc_code('R','G','B','O')
47#define DRM_FOURCC_RGB565 fourcc_code('R','G','B','P')
48#define DRM_FOURCC_RGB24 fourcc_code('R','G','B','3')
49#define DRM_FOURCC_RGB32 fourcc_code('R','G','B','4')
50
51#define DRM_FOURCC_BGR24 fourcc_code('B','G','R','3')
52#define DRM_FOURCC_BGR32 fourcc_code('B','G','R','4')
53
54/* YUV codes */
55#define DRM_FOURCC_YUYV fourcc_code('Y', 'U', 'Y', 'V')
56#define DRM_FOURCC_YVYU fourcc_code('Y', 'V', 'Y', 'U')
57#define DRM_FOURCC_UYVY fourcc_code('U', 'Y', 'V', 'Y')
58#define DRM_FOURCC_VYUY fourcc_code('V', 'Y', 'U', 'Y')
59
60/* DRM specific codes */
61#define DRM_INTEL_RGB30 fourcc_code('R','G','B','0') /* RGB x:10:10:10 */
62
63#endif /* DRM_FOURCC_H */
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index 44576a54dc3b..95d7aad5cad3 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -268,6 +268,33 @@ struct drm_mode_fb_cmd {
268 __u32 handle; 268 __u32 handle;
269}; 269};
270 270
271#define DRM_MODE_FB_INTERLACED (1<<0 /* for interlaced framebuffers */
272
273struct drm_mode_fb_cmd2 {
274 __u32 fb_id;
275 __u32 width, height;
276 __u32 pixel_format; /* fourcc code from drm_fourcc.h */
277 __u32 flags; /* see above flags */
278
279 /*
280 * In case of planar formats, this ioctl allows up to 4
281 * buffer objects with offets and pitches per plane.
282 * The pitch and offset order is dictated by the fourcc,
283 * e.g. NV12 (http://fourcc.org/yuv.php#NV12) is described as:
284 *
285 * YUV 4:2:0 image with a plane of 8 bit Y samples
286 * followed by an interleaved U/V plane containing
287 * 8 bit 2x2 subsampled colour difference samples.
288 *
289 * So it would consist of Y as offset[0] and UV as
290 * offeset[1]. Note that offset[0] will generally
291 * be 0.
292 */
293 __u32 handles[4];
294 __u32 pitches[4]; /* pitch for each plane */
295 __u32 offsets[4]; /* offset of each plane */
296};
297
271#define DRM_MODE_FB_DIRTY_ANNOTATE_COPY 0x01 298#define DRM_MODE_FB_DIRTY_ANNOTATE_COPY 0x01
272#define DRM_MODE_FB_DIRTY_ANNOTATE_FILL 0x02 299#define DRM_MODE_FB_DIRTY_ANNOTATE_FILL 0x02
273#define DRM_MODE_FB_DIRTY_FLAGS 0x03 300#define DRM_MODE_FB_DIRTY_FLAGS 0x03