diff options
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index ca69ed4a3926..8b8ae20ab62f 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -1077,9 +1077,8 @@ int vmw_kms_init(struct vmw_private *dev_priv) | |||
1077 | dev->mode_config.funcs = &vmw_kms_funcs; | 1077 | dev->mode_config.funcs = &vmw_kms_funcs; |
1078 | dev->mode_config.min_width = 1; | 1078 | dev->mode_config.min_width = 1; |
1079 | dev->mode_config.min_height = 1; | 1079 | dev->mode_config.min_height = 1; |
1080 | /* assumed largest fb size */ | 1080 | dev->mode_config.max_width = dev_priv->texture_max_width; |
1081 | dev->mode_config.max_width = 8192; | 1081 | dev->mode_config.max_height = dev_priv->texture_max_height; |
1082 | dev->mode_config.max_height = 8192; | ||
1083 | 1082 | ||
1084 | ret = vmw_kms_stdu_init_display(dev_priv); | 1083 | ret = vmw_kms_stdu_init_display(dev_priv); |
1085 | if (ret) { | 1084 | if (ret) { |
@@ -1580,6 +1579,7 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, | |||
1580 | unsigned rects_size; | 1579 | unsigned rects_size; |
1581 | int ret; | 1580 | int ret; |
1582 | int i; | 1581 | int i; |
1582 | u64 total_pixels = 0; | ||
1583 | struct drm_mode_config *mode_config = &dev->mode_config; | 1583 | struct drm_mode_config *mode_config = &dev->mode_config; |
1584 | struct drm_vmw_rect bounding_box = {0}; | 1584 | struct drm_vmw_rect bounding_box = {0}; |
1585 | 1585 | ||
@@ -1622,20 +1622,31 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, | |||
1622 | 1622 | ||
1623 | if (rects[i].y + rects[i].h > bounding_box.h) | 1623 | if (rects[i].y + rects[i].h > bounding_box.h) |
1624 | bounding_box.h = rects[i].y + rects[i].h; | 1624 | bounding_box.h = rects[i].y + rects[i].h; |
1625 | |||
1626 | total_pixels += (u64) rects[i].w * (u64) rects[i].h; | ||
1625 | } | 1627 | } |
1626 | 1628 | ||
1627 | /* | 1629 | if (dev_priv->active_display_unit == vmw_du_screen_target) { |
1628 | * For Screen Target Display Unit, all the displays must fit | 1630 | /* |
1629 | * inside of maximum texture size. | 1631 | * For Screen Targets, the limits for a toplogy are: |
1630 | */ | 1632 | * 1. Bounding box (assuming 32bpp) must be < prim_bb_mem |
1631 | if (dev_priv->active_display_unit == vmw_du_screen_target) | 1633 | * 2. Total pixels (assuming 32bpp) must be < prim_bb_mem |
1632 | if (bounding_box.w > dev_priv->texture_max_width || | 1634 | */ |
1633 | bounding_box.h > dev_priv->texture_max_height) { | 1635 | u64 bb_mem = bounding_box.w * bounding_box.h * 4; |
1634 | DRM_ERROR("Layout exceeds maximum texture size\n"); | 1636 | u64 pixel_mem = total_pixels * 4; |
1637 | |||
1638 | if (bb_mem > dev_priv->prim_bb_mem) { | ||
1639 | DRM_ERROR("Topology is beyond supported limits.\n"); | ||
1635 | ret = -EINVAL; | 1640 | ret = -EINVAL; |
1636 | goto out_free; | 1641 | goto out_free; |
1637 | } | 1642 | } |
1638 | 1643 | ||
1644 | if (pixel_mem > dev_priv->prim_bb_mem) { | ||
1645 | DRM_ERROR("Combined output size too large\n"); | ||
1646 | ret = -EINVAL; | ||
1647 | goto out_free; | ||
1648 | } | ||
1649 | } | ||
1639 | 1650 | ||
1640 | vmw_du_update_layout(dev_priv, arg->num_outputs, rects); | 1651 | vmw_du_update_layout(dev_priv, arg->num_outputs, rects); |
1641 | 1652 | ||