diff options
Diffstat (limited to 'drivers/gpu/drm/omapdrm/omap_fb.c')
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_fb.c | 50 |
1 files changed, 23 insertions, 27 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c index 195ab4c86244..016aac9a7731 100644 --- a/drivers/gpu/drm/omapdrm/omap_fb.c +++ b/drivers/gpu/drm/omapdrm/omap_fb.c | |||
@@ -387,6 +387,7 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev, | |||
387 | struct omap_framebuffer *omap_fb = NULL; | 387 | struct omap_framebuffer *omap_fb = NULL; |
388 | struct drm_framebuffer *fb = NULL; | 388 | struct drm_framebuffer *fb = NULL; |
389 | enum omap_color_mode dss_format = 0; | 389 | enum omap_color_mode dss_format = 0; |
390 | unsigned int pitch = mode_cmd->pitches[0]; | ||
390 | int ret, i; | 391 | int ret, i; |
391 | 392 | ||
392 | DBG("create framebuffer: dev=%p, mode_cmd=%p (%dx%d@%4.4s)", | 393 | DBG("create framebuffer: dev=%p, mode_cmd=%p (%dx%d@%4.4s)", |
@@ -420,41 +421,36 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev, | |||
420 | omap_fb->dss_format = dss_format; | 421 | omap_fb->dss_format = dss_format; |
421 | mutex_init(&omap_fb->lock); | 422 | mutex_init(&omap_fb->lock); |
422 | 423 | ||
424 | /* | ||
425 | * The code below assumes that no format use more than two planes, and | ||
426 | * that the two planes of multiplane formats need the same number of | ||
427 | * bytes per pixel. | ||
428 | */ | ||
429 | if (format->num_planes == 2 && pitch != mode_cmd->pitches[1]) { | ||
430 | dev_err(dev->dev, "pitches differ between planes 0 and 1\n"); | ||
431 | ret = -EINVAL; | ||
432 | goto fail; | ||
433 | } | ||
434 | |||
435 | if (pitch % format->cpp[0]) { | ||
436 | dev_err(dev->dev, | ||
437 | "buffer pitch (%u bytes) is not a multiple of pixel size (%u bytes)\n", | ||
438 | pitch, format->cpp[0]); | ||
439 | ret = -EINVAL; | ||
440 | goto fail; | ||
441 | } | ||
442 | |||
423 | for (i = 0; i < format->num_planes; i++) { | 443 | for (i = 0; i < format->num_planes; i++) { |
424 | struct plane *plane = &omap_fb->planes[i]; | 444 | struct plane *plane = &omap_fb->planes[i]; |
425 | unsigned int pitch = mode_cmd->pitches[i]; | ||
426 | unsigned int hsub = i == 0 ? 1 : format->hsub; | ||
427 | unsigned int vsub = i == 0 ? 1 : format->vsub; | 445 | unsigned int vsub = i == 0 ? 1 : format->vsub; |
428 | unsigned int size; | 446 | unsigned int size; |
429 | 447 | ||
430 | if (pitch < mode_cmd->width * format->cpp[i] / hsub) { | ||
431 | dev_err(dev->dev, "provided buffer pitch is too small! %d < %d\n", | ||
432 | pitch, mode_cmd->width * format->cpp[i] / hsub); | ||
433 | ret = -EINVAL; | ||
434 | goto fail; | ||
435 | } | ||
436 | |||
437 | if (pitch % format->cpp[i] != 0) { | ||
438 | dev_err(dev->dev, | ||
439 | "buffer pitch (%d bytes) is not a multiple of pixel size (%d bytes)\n", | ||
440 | pitch, format->cpp[i]); | ||
441 | ret = -EINVAL; | ||
442 | goto fail; | ||
443 | } | ||
444 | |||
445 | size = pitch * mode_cmd->height / vsub; | 448 | size = pitch * mode_cmd->height / vsub; |
446 | 449 | ||
447 | if (size > (omap_gem_mmap_size(bos[i]) - mode_cmd->offsets[i])) { | 450 | if (size > omap_gem_mmap_size(bos[i]) - mode_cmd->offsets[i]) { |
448 | dev_err(dev->dev, "provided buffer object is too small! %d < %d\n", | ||
449 | bos[i]->size - mode_cmd->offsets[i], size); | ||
450 | ret = -EINVAL; | ||
451 | goto fail; | ||
452 | } | ||
453 | |||
454 | if (i > 0 && pitch != mode_cmd->pitches[i - 1]) { | ||
455 | dev_err(dev->dev, | 451 | dev_err(dev->dev, |
456 | "pitches are not the same between framebuffer planes %d != %d\n", | 452 | "provided buffer object is too small! %d < %d\n", |
457 | pitch, mode_cmd->pitches[i - 1]); | 453 | bos[i]->size - mode_cmd->offsets[i], size); |
458 | ret = -EINVAL; | 454 | ret = -EINVAL; |
459 | goto fail; | 455 | goto fail; |
460 | } | 456 | } |