diff options
Diffstat (limited to 'drivers/gpu/drm/drm_plane.c')
-rw-r--r-- | drivers/gpu/drm/drm_plane.c | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 2c90519576a3..6d2a6e428a3e 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -104,7 +104,7 @@ static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane if (IS_ERR(blob)) return -1; - blob_data = (struct drm_format_modifier_blob *)blob->data; + blob_data = blob->data; blob_data->version = FORMAT_BLOB_CURRENT; blob_data->count_formats = plane->format_count; blob_data->formats_offset = sizeof(struct drm_format_modifier_blob); @@ -173,6 +173,10 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, unsigned int format_modifier_count = 0; int ret; + /* plane index is used with 32bit bitmasks */ + if (WARN_ON(config->num_total_plane >= 32)) + return -EINVAL; + ret = drm_mode_object_add(dev, &plane->base, DRM_MODE_OBJECT_PLANE); if (ret) return ret; @@ -545,16 +549,33 @@ int drm_mode_getplane(struct drm_device *dev, void *data, return 0; } -int drm_plane_check_pixel_format(const struct drm_plane *plane, u32 format) +int drm_plane_check_pixel_format(struct drm_plane *plane, + u32 format, u64 modifier) { unsigned int i; for (i = 0; i < plane->format_count; i++) { if (format == plane->format_types[i]) - return 0; + break; + } + if (i == plane->format_count) + return -EINVAL; + + if (!plane->modifier_count) + return 0; + + for (i = 0; i < plane->modifier_count; i++) { + if (modifier == plane->modifiers[i]) + break; } + if (i == plane->modifier_count) + return -EINVAL; - return -EINVAL; + if (plane->funcs->format_mod_supported && + !plane->funcs->format_mod_supported(plane, format, modifier)) + return -EINVAL; + + return 0; } /* @@ -598,12 +619,14 @@ static int __setplane_internal(struct drm_plane *plane, } /* Check whether this plane supports the fb pixel format. */ - ret = drm_plane_check_pixel_format(plane, fb->format->format); + ret = drm_plane_check_pixel_format(plane, fb->format->format, + fb->modifier); if (ret) { struct drm_format_name_buf format_name; - DRM_DEBUG_KMS("Invalid pixel format %s\n", - drm_get_format_name(fb->format->format, - &format_name)); + DRM_DEBUG_KMS("Invalid pixel format %s, modifier 0x%llx\n", + drm_get_format_name(fb->format->format, + &format_name), + fb->modifier); goto out; } @@ -944,7 +967,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, if (r) return r; - current_vblank = drm_crtc_vblank_count(crtc); + current_vblank = (u32)drm_crtc_vblank_count(crtc); switch (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) { case DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE: |