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>
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 981b1f1..50ae915 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6279,7 +6279,7 @@
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 @@
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 @@
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 @@
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;
@@ -7581,21 +7581,23 @@
if (obj->tiling_mode == I915_TILING_Y)
return -EINVAL;
- if (mode_cmd->pitch & 63)
+ if (mode_cmd->pitches[0] & 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 DRM_FOURCC_RGB332:
+ case DRM_FOURCC_RGB565:
+ case DRM_FOURCC_RGB24:
+ case DRM_INTEL_RGB30:
+ /* RGB formats are common across chipsets */
break;
-
- case 24:
- case 32:
+ case DRM_FOURCC_YUYV:
+ case DRM_FOURCC_UYVY:
+ case DRM_FOURCC_YVYU:
+ case DRM_FOURCC_VYUY:
break;
default:
+ DRM_ERROR("unsupported pixel format\n");
return -EINVAL;
}
@@ -7613,11 +7615,12 @@
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;
- obj = to_intel_bo(drm_gem_object_lookup(dev, filp, mode_cmd->handle));
+ obj = to_intel_bo(drm_gem_object_lookup(dev, filp,
+ mode_cmd->handles[0]));
if (&obj->base == NULL)
return ERR_PTR(-ENOENT);