Merge branch 'vmwgfx-next' of git://people.freedesktop.org/~thomash/linux into drm...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / vmwgfx / vmwgfx_kms.c
index 05fb16733c5c1f171ec232de3d940dcf30f85086..dca04d4246ea8d826b2e31b6ce507b64c14f7bda 100644 (file)
@@ -1510,21 +1510,19 @@ static int vmw_kms_check_display_memory(struct drm_device *dev,
                                        struct drm_rect *rects)
 {
        struct vmw_private *dev_priv = vmw_priv(dev);
-       struct drm_mode_config *mode_config = &dev->mode_config;
        struct drm_rect bounding_box = {0};
        u64 total_pixels = 0, pixel_mem, bb_mem;
        int i;
 
        for (i = 0; i < num_rects; i++) {
                /*
-                * Currently this check is limiting the topology within max
-                * texture/screentarget size. This should change in future when
-                * user-space support multiple fb with topology.
+                * For STDU only individual screen (screen target) is limited by
+                * SCREENTARGET_MAX_WIDTH/HEIGHT registers.
                 */
-               if (rects[i].x1 < 0 ||  rects[i].y1 < 0 ||
-                   rects[i].x2 > mode_config->max_width ||
-                   rects[i].y2 > mode_config->max_height) {
-                       DRM_ERROR("Invalid GUI layout.\n");
+               if (dev_priv->active_display_unit == vmw_du_screen_target &&
+                   (drm_rect_width(&rects[i]) > dev_priv->stdu_max_width ||
+                    drm_rect_height(&rects[i]) > dev_priv->stdu_max_height)) {
+                       DRM_ERROR("Screen size not supported.\n");
                        return -EINVAL;
                }
 
@@ -1613,7 +1611,7 @@ static int vmw_kms_check_topology(struct drm_device *dev,
                struct drm_connector_state *conn_state;
                struct vmw_connector_state *vmw_conn_state;
 
-               if (!new_crtc_state->enable && old_crtc_state->enable) {
+               if (!new_crtc_state->enable) {
                        rects[i].x1 = 0;
                        rects[i].y1 = 0;
                        rects[i].x2 = 0;
@@ -2214,12 +2212,16 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector,
        if (dev_priv->assume_16bpp)
                assumed_bpp = 2;
 
+       max_width  = min(max_width,  dev_priv->texture_max_width);
+       max_height = min(max_height, dev_priv->texture_max_height);
+
+       /*
+        * For STDU extra limit for a mode on SVGA_REG_SCREENTARGET_MAX_WIDTH/
+        * HEIGHT registers.
+        */
        if (dev_priv->active_display_unit == vmw_du_screen_target) {
                max_width  = min(max_width,  dev_priv->stdu_max_width);
-               max_width  = min(max_width,  dev_priv->texture_max_width);
-
                max_height = min(max_height, dev_priv->stdu_max_height);
-               max_height = min(max_height, dev_priv->texture_max_height);
        }
 
        /* Add preferred mode */
@@ -2374,6 +2376,7 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
                                struct drm_file *file_priv)
 {
        struct vmw_private *dev_priv = vmw_priv(dev);
+       struct drm_mode_config *mode_config = &dev->mode_config;
        struct drm_vmw_update_layout_arg *arg =
                (struct drm_vmw_update_layout_arg *)data;
        void __user *user_rects;
@@ -2419,6 +2422,21 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
                drm_rects[i].y1 = curr_rect.y;
                drm_rects[i].x2 = curr_rect.x + curr_rect.w;
                drm_rects[i].y2 = curr_rect.y + curr_rect.h;
+
+               /*
+                * Currently this check is limiting the topology within
+                * mode_config->max (which actually is max texture size
+                * supported by virtual device). This limit is here to address
+                * window managers that create a big framebuffer for whole
+                * topology.
+                */
+               if (drm_rects[i].x1 < 0 ||  drm_rects[i].y1 < 0 ||
+                   drm_rects[i].x2 > mode_config->max_width ||
+                   drm_rects[i].y2 > mode_config->max_height) {
+                       DRM_ERROR("Invalid GUI layout.\n");
+                       ret = -EINVAL;
+                       goto out_free;
+               }
        }
 
        ret = vmw_kms_check_display_memory(dev, arg->num_outputs, drm_rects);