11/03/2011 05:03 AM, Jesse Barnes ? ?: > 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 videodev2.h. > > Signed-off-by: Jesse Barnes<jbarnes at virtuousgeek.org> > --- > drivers/gpu/drm/drm_crtc.c | 105 > ++++++++++++++++++++++++++++- > drivers/gpu/drm/drm_crtc_helper.c | 50 +++++++++++++- > drivers/gpu/drm/drm_drv.c | 1 + > drivers/gpu/drm/i915/intel_display.c | 34 +++++----- > drivers/gpu/drm/i915/intel_drv.h | 2 +- > drivers/gpu/drm/i915/intel_fb.c | 11 ++-- > drivers/gpu/drm/nouveau/nouveau_display.c | 4 +- > drivers/gpu/drm/radeon/radeon_display.c | 4 +- > drivers/gpu/drm/radeon/radeon_fb.c | 18 +++-- > drivers/gpu/drm/radeon/radeon_mode.h | 2 +- > drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 2 +- > drivers/staging/gma500/framebuffer.c | 2 +- > include/drm/drm.h | 1 + > include/drm/drm_crtc.h | 7 ++- > include/drm/drm_crtc_helper.h | 4 +- > include/drm/drm_mode.h | 26 +++++++ > include/linux/videodev2.h | 1 + > 17 files changed, 231 insertions(+), 43 deletions(-) > > diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c > index 0e129b1..ff47554 100644 > --- a/drivers/gpu/drm/drm_crtc.c > +++ b/drivers/gpu/drm/drm_crtc.c > @@ -1889,6 +1889,42 @@ out: > return ret; > } > > +/* Original addfb only supported RGB formats, so figure out which one */ > +uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth) > +{ > + uint32_t fmt; > + > + switch (bpp) { > + case 8: > + fmt = V4L2_PIX_FMT_RGB332; > + break; > + case 16: > + if (depth == 15) > + fmt = V4L2_PIX_FMT_RGB555; > + else > + fmt = V4L2_PIX_FMT_RGB565; > + break; > + case 24: > + fmt = V4L2_PIX_FMT_RGB24; > + break; > + case 32: > + if (depth == 24) > + fmt = V4L2_PIX_FMT_RGB24; > + else if (depth == 30) > + fmt = V4L2_PIX_FMT_INTC_RGB30; > + else > + fmt = V4L2_PIX_FMT_RGB32; > + break; > + default: > + DRM_ERROR("bad bpp, assuming RGB24 pixel format\n"); > + fmt = V4L2_PIX_FMT_RGB24; > + break; > + } > + > + return fmt; > +} > +EXPORT_SYMBOL(drm_mode_legacy_fb_format); > + > /** > * drm_mode_addfb - add an FB to the graphics configuration > * @inode: inode from the ioctl > @@ -1909,7 +1945,74 @@ out: > int drm_mode_addfb(struct drm_device *dev, > void *data, struct drm_file *file_priv) > { > - struct drm_mode_fb_cmd *r = data; > + struct drm_mode_fb_cmd *or = data; > + struct drm_mode_fb_cmd2 r; > + struct drm_mode_config *config =&dev->mode_config; > + struct drm_framebuffer *fb; > + int ret = 0; > + > + /* Use new struct with format internally */ > + r.fb_id = or->fb_id; > + r.width = or->width; > + r.height = or->height; > + r.pitches[0] = or->pitch; > + r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth); > + r.handle = or->handle; > + > + if (!drm_core_check_feature(dev, DRIVER_MODESET)) > + return -EINVAL; > + > + if ((config->min_width> r.width) || (r.width> config->max_width)) { > + DRM_ERROR("mode new framebuffer width not within limits\n"); > + return -EINVAL; > + } > + if ((config->min_height> r.height) || (r.height> config->max_height)) > { > + DRM_ERROR("mode new framebuffer height not within limits\n"); > + return -EINVAL; > + } > + > + mutex_lock(&dev->mode_config.mutex); > + > + /* TODO check buffer is sufficiently large */ > + /* TODO setup destructor callback */ > + > + fb = dev->mode_config.funcs->fb_create(dev, file_priv,&r); > + if (IS_ERR(fb)) { > + DRM_ERROR("could not create framebuffer\n"); > + ret = PTR_ERR(fb); > + goto out; > + } > + > + or->fb_id = fb->base.id; > + list_add(&fb->filp_head,&file_priv->fbs); > + DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); > + > +out: > + mutex_unlock(&dev->mode_config.mutex); > + return ret; > +} > + > +/** > + * drm_mode_addfb2 - add an FB to the graphics configuration > + * @inode: inode from the ioctl > + * @filp: file * from the ioctl > + * @cmd: cmd from ioctl > + * @arg: arg from ioctl > + * > + * LOCKING: > + * Takes mode config lock. > + * > + * Add a new FB to the specified CRTC, given a user request with format. > + * > + * Called by the user via ioctl. > + * > + * RETURNS: > + * Zero on success, errno on failure. > + */ > +int drm_mode_addfb2(struct drm_device *dev, > + void *data, struct drm_file *file_priv) > +{ > + struct drm_mode_fb_cmd2 *r = data; > struct drm_mode_config *config =&dev->mode_config; > struct drm_framebuffer *fb; > int ret = 0; > diff --git a/drivers/gpu/drm/drm_crtc_helper.c > b/drivers/gpu/drm/drm_crtc_helper.c > index f88a9b2..0573f12 100644 > --- a/drivers/gpu/drm/drm_crtc_helper.c > +++ b/drivers/gpu/drm/drm_crtc_helper.c > @@ -805,14 +805,56 @@ void drm_helper_connector_dpms(struct drm_connector > *connector, int mode) > } > EXPORT_SYMBOL(drm_helper_connector_dpms); > > +/* > + * Just need to support RGB formats here for compat with code that doesn't > + * use pixel formats directly yet. > + */ > +void drm_helper_get_fb_bpp_depth(uint32_t format, unsigned int *depth, > + int *bpp) > +{ > + switch (format) { > + case V4L2_PIX_FMT_RGB332: > + *depth = 8; > + *bpp = 8; > + break; > + case V4L2_PIX_FMT_RGB555: > + *depth = 15; > + *bpp = 16; > + break; > + case V4L2_PIX_FMT_RGB565: > + *depth = 16; > + *bpp = 16; > + break; > + case V4L2_PIX_FMT_RGB24: > + *depth = 24; > + *bpp = 24; > + break;
In the depth = 24 and bpp = 32 case also the pixed_format is V4L2_PIX_FMT_RGB24, but above function cannot detect it. > + case V4L2_PIX_FMT_INTC_RGB30: > + *depth = 30; > + *bpp = 32; > + break; > + case V4L2_PIX_FMT_RGB32: > + *depth = 32; > + *bpp = 32; > + break; > + default: > + DRM_DEBUG_KMS("unsupported pixel format\n"); > + *depth = 0; > + *bpp = 0; > + break; > + } > +} > +EXPORT_SYMBOL(drm_helper_get_fb_bpp_depth); > + > int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, > - struct drm_mode_fb_cmd *mode_cmd) > + struct drm_mode_fb_cmd2 *mode_cmd) > { > fb->width = mode_cmd->width; > fb->height = mode_cmd->height; > - fb->pitch = mode_cmd->pitch; > - fb->bits_per_pixel = mode_cmd->bpp; > - fb->depth = mode_cmd->depth; > + fb->pitch = mode_cmd->pitches[0]; > + drm_helper_get_fb_bpp_depth(mode_cmd->pixel_format,&fb->depth, > + &fb->bits_per_pixel); > + fb->pixel_format = mode_cmd->pixel_format; > > return 0; > } > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c > index 15da618..f24b9b6 100644 > --- a/drivers/gpu/drm/drm_drv.c > +++ b/drivers/gpu/drm/drm_drv.c > @@ -152,6 +152,7 @@ static struct drm_ioctl_desc drm_ioctls[] = { > DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, > DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), > DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, > DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), > DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, > DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), > + DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, > DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), > DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, > DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), > DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, > DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), > 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 981b1f1..0727fc8 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 = { > > static struct drm_framebuffer * > intel_framebuffer_create(struct drm_device *dev, > - struct drm_mode_fb_cmd *mode_cmd, > + struct drm_mode_fb_cmd2 *mode_cmd, > struct drm_i915_gem_object *obj) > { > struct intel_framebuffer *intel_fb; > @@ -6321,7 +6321,7 @@ intel_framebuffer_create_for_mode(struct drm_device > *dev, > int depth, int bpp) > { > struct drm_i915_gem_object *obj; > - struct drm_mode_fb_cmd mode_cmd; > + struct drm_mode_fb_cmd2 mode_cmd; > > obj = i915_gem_alloc_object(dev, > intel_framebuffer_size_for_mode(mode, bpp)); > @@ -6330,9 +6330,9 @@ intel_framebuffer_create_for_mode(struct drm_device > *dev, > > mode_cmd.width = mode->hdisplay; > mode_cmd.height = mode->vdisplay; > - mode_cmd.depth = depth; > - mode_cmd.bpp = bpp; > - mode_cmd.pitch = intel_framebuffer_pitch_for_width(mode_cmd.width, bpp); > + mode_cmd.pitches[0] = intel_framebuffer_pitch_for_width(mode_cmd.width, > + bpp); > + mode_cmd.pixel_format = 0; > > return intel_framebuffer_create(dev,&mode_cmd, obj); > } > @@ -7573,7 +7573,7 @@ static const struct drm_framebuffer_funcs > intel_fb_funcs = { > > int intel_framebuffer_init(struct drm_device *dev, > struct intel_framebuffer *intel_fb, > - struct drm_mode_fb_cmd *mode_cmd, > + struct drm_mode_fb_cmd2 *mode_cmd, > struct drm_i915_gem_object *obj) > { > int ret; > @@ -7584,18 +7584,20 @@ int intel_framebuffer_init(struct drm_device *dev, > if (mode_cmd->pitch& 63) > return -EINVAL; > > - switch (mode_cmd->bpp) { > - case 8: > - case 16: > - /* Only pre-ILK can handle 5:5:5 */ > - if (mode_cmd->depth == 15&& !HAS_PCH_SPLIT(dev)) > - return -EINVAL; > + switch (mode_cmd->pixel_format) { > + case V4L2_PIX_FMT_RGB332: > + case V4L2_PIX_FMT_RGB565: > + case V4L2_PIX_FMT_RGB24: > + case V4L2_PIX_FMT_INTC_RGB30: > + /* RGB formats are common across chipsets */ > break; > - > - case 24: > - case 32: > + case V4L2_PIX_FMT_YUYV: > + case V4L2_PIX_FMT_UYVY: > + case V4L2_PIX_FMT_YVYU: > + case V4L2_PIX_FMT_VYUY: > break; > default: > + DRM_ERROR("unsupported pixel format\n"); > return -EINVAL; > } > > @@ -7613,7 +7615,7 @@ int intel_framebuffer_init(struct drm_device *dev, > static struct drm_framebuffer * > intel_user_framebuffer_create(struct drm_device *dev, > struct drm_file *filp, > - struct drm_mode_fb_cmd *mode_cmd) > + struct drm_mode_fb_cmd2 *mode_cmd) > { > struct drm_i915_gem_object *obj; > > diff --git a/drivers/gpu/drm/i915/intel_drv.h > b/drivers/gpu/drm/i915/intel_drv.h > index bd9a604..23c5622 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, > > extern int intel_framebuffer_init(struct drm_device *dev, > struct intel_framebuffer *ifb, > - struct drm_mode_fb_cmd *mode_cmd, > + struct drm_mode_fb_cmd2 *mode_cmd, > struct drm_i915_gem_object *obj); > extern int intel_fbdev_init(struct drm_device *dev); > extern 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 ec49bae..dc1db4f 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, > struct drm_i915_private *dev_priv = dev->dev_private; > struct fb_info *info; > struct drm_framebuffer *fb; > - struct drm_mode_fb_cmd mode_cmd; > + struct drm_mode_fb_cmd2 mode_cmd; > struct drm_i915_gem_object *obj; > struct device *device =&dev->pdev->dev; > int size, ret; > @@ -77,11 +77,12 @@ static int intelfb_create(struct intel_fbdev *ifbdev, > mode_cmd.width = sizes->surface_width; > mode_cmd.height = sizes->surface_height; > > - mode_cmd.bpp = sizes->surface_bpp; > - mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 7) / 8), 64); > - mode_cmd.depth = sizes->surface_depth; > + mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((sizes->surface_bpp + 7) / > + 8), 64); > + mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, > + sizes->surface_depth); > > - size = mode_cmd.pitch * mode_cmd.height; > + size = mode_cmd.pitches[0] * mode_cmd.height; > size = ALIGN(size, PAGE_SIZE); > obj = i915_gem_alloc_object(dev, size); > if (!obj) { > diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c > b/drivers/gpu/drm/nouveau/nouveau_display.c > index ddbabef..7a428a9 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 = { > int > nouveau_framebuffer_init(struct drm_device *dev, > struct nouveau_framebuffer *nv_fb, > - struct drm_mode_fb_cmd *mode_cmd, > + struct drm_mode_fb_cmd2 *mode_cmd, > struct nouveau_bo *nvbo) > { > struct drm_nouveau_private *dev_priv = dev->dev_private; > @@ -124,7 +124,7 @@ nouveau_framebuffer_init(struct drm_device *dev, > static struct drm_framebuffer * > nouveau_user_framebuffer_create(struct drm_device *dev, > struct drm_file *file_priv, > - struct drm_mode_fb_cmd *mode_cmd) > + struct drm_mode_fb_cmd2 *mode_cmd) > { > struct nouveau_framebuffer *nouveau_fb; > struct drm_gem_object *gem; > diff --git a/drivers/gpu/drm/radeon/radeon_display.c > b/drivers/gpu/drm/radeon/radeon_display.c > index 6cc17fb..ae803f8 100644 > --- a/drivers/gpu/drm/radeon/radeon_display.c > +++ b/drivers/gpu/drm/radeon/radeon_display.c > @@ -1113,7 +1113,7 @@ static const struct drm_framebuffer_funcs > radeon_fb_funcs = { > void > radeon_framebuffer_init(struct drm_device *dev, > struct radeon_framebuffer *rfb, > - struct drm_mode_fb_cmd *mode_cmd, > + struct drm_mode_fb_cmd2 *mode_cmd, > struct drm_gem_object *obj) > { > rfb->obj = obj; > @@ -1124,7 +1124,7 @@ radeon_framebuffer_init(struct drm_device *dev, > static struct drm_framebuffer * > radeon_user_framebuffer_create(struct drm_device *dev, > struct drm_file *file_priv, > - struct drm_mode_fb_cmd *mode_cmd) > + struct drm_mode_fb_cmd2 *mode_cmd) > { > struct drm_gem_object *obj; > struct radeon_framebuffer *radeon_fb; > diff --git a/drivers/gpu/drm/radeon/radeon_fb.c > b/drivers/gpu/drm/radeon/radeon_fb.c > index 0b7b486..ea110ad 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) > } > > static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev, > - struct drm_mode_fb_cmd *mode_cmd, > + struct drm_mode_fb_cmd2 *mode_cmd, > struct drm_gem_object **gobj_p) > { > struct radeon_device *rdev = rfbdev->rdev; > @@ -114,13 +114,17 @@ static int radeonfb_create_pinned_object(struct > radeon_fbdev *rfbdev, > int ret; > int aligned_size, size; > int height = mode_cmd->height; > + u32 bpp, depth; > + > + drm_helper_get_fb_bpp_depth(mode_cmd->pixel_format,&depth,&bpp); > > /* need to align pitch with crtc limits */ > - mode_cmd->pitch = radeon_align_pitch(rdev, mode_cmd->width, > mode_cmd->bpp, fb_tiled) * ((mode_cmd->bpp + 1) / 8); > + mode_cmd->pitches[0] = radeon_align_pitch(rdev, mode_cmd->width, bpp, > + fb_tiled) * ((bpp + 1) / 8); > > if (rdev->family>= CHIP_R600) > height = ALIGN(mode_cmd->height, 8); > - size = mode_cmd->pitch * height; > + size = mode_cmd->pitches[0] * height; > aligned_size = ALIGN(size, PAGE_SIZE); > ret = radeon_gem_object_create(rdev, aligned_size, 0, > RADEON_GEM_DOMAIN_VRAM, > @@ -151,7 +155,7 @@ static int radeonfb_create_pinned_object(struct > radeon_fbdev *rfbdev, > if (tiling_flags) { > ret = radeon_bo_set_tiling_flags(rbo, > tiling_flags | > RADEON_TILING_SURFACE, > - mode_cmd->pitch); > + mode_cmd->pitches[0]); > if (ret) > dev_err(rdev->dev, "FB failed to set tiling flags\n"); > } > @@ -187,7 +191,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev, > struct radeon_device *rdev = rfbdev->rdev; > struct fb_info *info; > struct drm_framebuffer *fb = NULL; > - struct drm_mode_fb_cmd mode_cmd; > + struct drm_mode_fb_cmd2 mode_cmd; > struct drm_gem_object *gobj = NULL; > struct radeon_bo *rbo = NULL; > struct device *device =&rdev->pdev->dev; > @@ -201,8 +205,8 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev, > if ((sizes->surface_bpp == 24)&& ASIC_IS_AVIVO(rdev)) > sizes->surface_bpp = 32; > > - mode_cmd.bpp = sizes->surface_bpp; > - mode_cmd.depth = sizes->surface_depth; > + mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, > + sizes->surface_depth); > > ret = radeonfb_create_pinned_object(rfbdev,&mode_cmd,&gobj); > 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 68820f5..227f595 100644 > --- a/drivers/gpu/drm/radeon/radeon_mode.h > +++ b/drivers/gpu/drm/radeon/radeon_mode.h > @@ -644,7 +644,7 @@ extern void radeon_crtc_fb_gamma_get(struct drm_crtc > *crtc, u16 *red, u16 *green > u16 *blue, int regno); > void radeon_framebuffer_init(struct drm_device *dev, > struct radeon_framebuffer *rfb, > - struct drm_mode_fb_cmd *mode_cmd, > + struct drm_mode_fb_cmd2 *mode_cmd, > struct drm_gem_object *obj); > > int 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 1a4c84c..2a1b802 100644 > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c > @@ -839,7 +839,7 @@ out_err1: > > static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, > struct drm_file *file_priv, > - struct drm_mode_fb_cmd > *mode_cmd) > + struct drm_mode_fb_cmd2 > *mode_cmd) > { > struct vmw_private *dev_priv = vmw_priv(dev); > struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; > diff --git a/drivers/staging/gma500/framebuffer.c > b/drivers/staging/gma500/framebuffer.c > index ebfde13..85f47d5 100644 > --- a/drivers/staging/gma500/framebuffer.c > +++ b/drivers/staging/gma500/framebuffer.c > @@ -487,7 +487,7 @@ out_err1: > */ > static struct drm_framebuffer *psb_user_framebuffer_create > (struct drm_device *dev, struct drm_file *filp, > - struct drm_mode_fb_cmd *cmd) > + struct drm_mode_fb_cmd2 *cmd) > { > struct gtt_range *r; > struct drm_gem_object *obj; > diff --git a/include/drm/drm.h b/include/drm/drm.h > index 2897967..49d94ed 100644 > --- a/include/drm/drm.h > +++ b/include/drm/drm.h > @@ -717,6 +717,7 @@ struct drm_get_cap { > #define DRM_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xB5, struct > drm_mode_get_plane_res) > #define DRM_IOCTL_MODE_GETPLANE DRM_IOWR(0xB6, struct > drm_mode_get_plane) > #define DRM_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct > drm_mode_set_plane) > +#define DRM_IOCTL_MODE_ADDFB2 DRM_IOWR(0xB8, struct > drm_mode_fb_cmd2) > > /** > * 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 b4519f8..f65ec08 100644 > --- a/include/drm/drm_crtc.h > +++ b/include/drm/drm_crtc.h > @@ -29,6 +29,7 @@ > #include<linux/spinlock.h> > #include<linux/types.h> > #include<linux/idr.h> > +#include<linux/videodev2.h> /* for plane formats */ > > #include<linux/fb.h> > > @@ -246,6 +247,7 @@ struct drm_framebuffer { > unsigned int depth; > int bits_per_pixel; > int flags; > + uint32_t pixel_format; /* fourcc format */ > struct list_head filp_head; > /* if you are using the helper */ > void *helper_private; > @@ -620,7 +622,7 @@ struct drm_mode_set { > * struct drm_mode_config_funcs - configure CRTCs for a given screen layout > */ > struct drm_mode_config_funcs { > - struct drm_framebuffer *(*fb_create)(struct drm_device *dev, struct > drm_file *file_priv, struct drm_mode_fb_cmd *mode_cmd); > + struct drm_framebuffer *(*fb_create)(struct drm_device *dev, struct > drm_file *file_priv, struct drm_mode_fb_cmd2 *mode_cmd); > void (*output_poll_changed)(struct drm_device *dev); > }; > > @@ -838,6 +840,9 @@ extern int drm_mode_cursor_ioctl(struct drm_device *dev, > void *data, struct drm_file *file_priv); > extern int drm_mode_addfb(struct drm_device *dev, > void *data, struct drm_file *file_priv); > +extern int drm_mode_addfb2(struct drm_device *dev, > + void *data, struct drm_file *file_priv); > +extern uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth); > extern int drm_mode_rmfb(struct drm_device *dev, > void *data, struct drm_file *file_priv); > extern 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 73b0712..b4abb33 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); > > extern void drm_helper_connector_dpms(struct drm_connector *connector, int > mode); > > +extern void drm_helper_get_fb_bpp_depth(uint32_t format, unsigned int *depth, > + int *bpp); > extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, > - struct drm_mode_fb_cmd *mode_cmd); > + struct drm_mode_fb_cmd2 *mode_cmd); > > static inline void drm_crtc_helper_add(struct drm_crtc *crtc, > const struct drm_crtc_helper_funcs > *funcs) > diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h > index 07711b0..69f8ece 100644 > --- a/include/drm/drm_mode.h > +++ b/include/drm/drm_mode.h > @@ -27,6 +27,8 @@ > #ifndef _DRM_MODE_H > #define _DRM_MODE_H > > +#include<linux/videodev2.h> > + > #define DRM_DISPLAY_INFO_LEN 32 > #define DRM_CONNECTOR_NAME_LEN 32 > #define DRM_DISPLAY_MODE_LEN 32 > @@ -262,6 +264,30 @@ struct drm_mode_fb_cmd { > __u32 handle; > }; > > +struct drm_mode_fb_cmd2 { > + __u32 fb_id; > + __u32 width, height; > + __u32 pixel_format; /* fourcc code from videodev2.h */ > + > + /* > + * In case of planar formats, this ioctl allows one > + * buffer object with offets and pitches per plane. > + * The pitch and offset order is dictated by the fourcc, > + * e.g. NV12 (http://fourcc.org/yuv.php#NV12) is described as: > + * > + * YUV 4:2:0 image with a plane of 8 bit Y samples > + * followed by an interleaved U/V plane containing > + * 8 bit 2x2 subsampled colour difference samples. > + * > + * So it would consist of Y as offset[0] and UV as > + * offeset[1]. Note that offset[0] will generally > + * be 0. > + */ > + __u32 handle; > + __u32 pitches[4]; /* pitch for each plane */ > + __u32 offsets[4]; /* offset of each plane */ > +}; > + > #define DRM_MODE_FB_DIRTY_ANNOTATE_COPY 0x01 > #define DRM_MODE_FB_DIRTY_ANNOTATE_FILL 0x02 > #define DRM_MODE_FB_DIRTY_FLAGS 0x03 > diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h > index fca24cc..6da4ab4 100644 > --- a/include/linux/videodev2.h > +++ b/include/linux/videodev2.h > @@ -412,6 +412,7 @@ struct v4l2_pix_format { > #define V4L2_PIX_FMT_KONICA420 v4l2_fourcc('K', 'O', 'N', 'I') /* YUV420 > planar in blocks of 256 pixels */ > #define V4L2_PIX_FMT_JPGL v4l2_fourcc('J', 'P', 'G', 'L') /* JPEG-Lite */ > #define V4L2_PIX_FMT_SE401 v4l2_fourcc('S', '4', '0', '1') /* se401 > janggu compressed rgb */ > +#define V4L2_PIX_FMT_INTC_RGB30 v4l2_fourcc('R', 'G', 'B', '0') /* RGB > x:10:10:10 */ > > /* > * F O R M A T E N U M E R A T I O N