aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c33
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