diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 42 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 25 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 24 |
4 files changed, 45 insertions, 48 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 1f134570b759..f0ab6b2313bb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | |||
@@ -3729,7 +3729,7 @@ int vmw_validate_single_buffer(struct vmw_private *dev_priv, | |||
3729 | { | 3729 | { |
3730 | struct vmw_buffer_object *vbo = | 3730 | struct vmw_buffer_object *vbo = |
3731 | container_of(bo, struct vmw_buffer_object, base); | 3731 | container_of(bo, struct vmw_buffer_object, base); |
3732 | struct ttm_operation_ctx ctx = { interruptible, true }; | 3732 | struct ttm_operation_ctx ctx = { interruptible, false }; |
3733 | int ret; | 3733 | int ret; |
3734 | 3734 | ||
3735 | if (vbo->pin_count > 0) | 3735 | if (vbo->pin_count > 0) |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 23beff5d8e3c..6a712a8d59e9 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -1512,21 +1512,19 @@ static int vmw_kms_check_display_memory(struct drm_device *dev, | |||
1512 | struct drm_rect *rects) | 1512 | struct drm_rect *rects) |
1513 | { | 1513 | { |
1514 | struct vmw_private *dev_priv = vmw_priv(dev); | 1514 | struct vmw_private *dev_priv = vmw_priv(dev); |
1515 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
1516 | struct drm_rect bounding_box = {0}; | 1515 | struct drm_rect bounding_box = {0}; |
1517 | u64 total_pixels = 0, pixel_mem, bb_mem; | 1516 | u64 total_pixels = 0, pixel_mem, bb_mem; |
1518 | int i; | 1517 | int i; |
1519 | 1518 | ||
1520 | for (i = 0; i < num_rects; i++) { | 1519 | for (i = 0; i < num_rects; i++) { |
1521 | /* | 1520 | /* |
1522 | * Currently this check is limiting the topology within max | 1521 | * For STDU only individual screen (screen target) is limited by |
1523 | * texture/screentarget size. This should change in future when | 1522 | * SCREENTARGET_MAX_WIDTH/HEIGHT registers. |
1524 | * user-space support multiple fb with topology. | ||
1525 | */ | 1523 | */ |
1526 | if (rects[i].x1 < 0 || rects[i].y1 < 0 || | 1524 | if (dev_priv->active_display_unit == vmw_du_screen_target && |
1527 | rects[i].x2 > mode_config->max_width || | 1525 | (drm_rect_width(&rects[i]) > dev_priv->stdu_max_width || |
1528 | rects[i].y2 > mode_config->max_height) { | 1526 | drm_rect_height(&rects[i]) > dev_priv->stdu_max_height)) { |
1529 | DRM_ERROR("Invalid GUI layout.\n"); | 1527 | DRM_ERROR("Screen size not supported.\n"); |
1530 | return -EINVAL; | 1528 | return -EINVAL; |
1531 | } | 1529 | } |
1532 | 1530 | ||
@@ -1615,7 +1613,7 @@ static int vmw_kms_check_topology(struct drm_device *dev, | |||
1615 | struct drm_connector_state *conn_state; | 1613 | struct drm_connector_state *conn_state; |
1616 | struct vmw_connector_state *vmw_conn_state; | 1614 | struct vmw_connector_state *vmw_conn_state; |
1617 | 1615 | ||
1618 | if (!new_crtc_state->enable && old_crtc_state->enable) { | 1616 | if (!new_crtc_state->enable) { |
1619 | rects[i].x1 = 0; | 1617 | rects[i].x1 = 0; |
1620 | rects[i].y1 = 0; | 1618 | rects[i].y1 = 0; |
1621 | rects[i].x2 = 0; | 1619 | rects[i].x2 = 0; |
@@ -2216,12 +2214,16 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector, | |||
2216 | if (dev_priv->assume_16bpp) | 2214 | if (dev_priv->assume_16bpp) |
2217 | assumed_bpp = 2; | 2215 | assumed_bpp = 2; |
2218 | 2216 | ||
2217 | max_width = min(max_width, dev_priv->texture_max_width); | ||
2218 | max_height = min(max_height, dev_priv->texture_max_height); | ||
2219 | |||
2220 | /* | ||
2221 | * For STDU extra limit for a mode on SVGA_REG_SCREENTARGET_MAX_WIDTH/ | ||
2222 | * HEIGHT registers. | ||
2223 | */ | ||
2219 | if (dev_priv->active_display_unit == vmw_du_screen_target) { | 2224 | if (dev_priv->active_display_unit == vmw_du_screen_target) { |
2220 | max_width = min(max_width, dev_priv->stdu_max_width); | 2225 | max_width = min(max_width, dev_priv->stdu_max_width); |
2221 | max_width = min(max_width, dev_priv->texture_max_width); | ||
2222 | |||
2223 | max_height = min(max_height, dev_priv->stdu_max_height); | 2226 | max_height = min(max_height, dev_priv->stdu_max_height); |
2224 | max_height = min(max_height, dev_priv->texture_max_height); | ||
2225 | } | 2227 | } |
2226 | 2228 | ||
2227 | /* Add preferred mode */ | 2229 | /* Add preferred mode */ |
@@ -2376,6 +2378,7 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, | |||
2376 | struct drm_file *file_priv) | 2378 | struct drm_file *file_priv) |
2377 | { | 2379 | { |
2378 | struct vmw_private *dev_priv = vmw_priv(dev); | 2380 | struct vmw_private *dev_priv = vmw_priv(dev); |
2381 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
2379 | struct drm_vmw_update_layout_arg *arg = | 2382 | struct drm_vmw_update_layout_arg *arg = |
2380 | (struct drm_vmw_update_layout_arg *)data; | 2383 | (struct drm_vmw_update_layout_arg *)data; |
2381 | void __user *user_rects; | 2384 | void __user *user_rects; |
@@ -2421,6 +2424,21 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, | |||
2421 | drm_rects[i].y1 = curr_rect.y; | 2424 | drm_rects[i].y1 = curr_rect.y; |
2422 | drm_rects[i].x2 = curr_rect.x + curr_rect.w; | 2425 | drm_rects[i].x2 = curr_rect.x + curr_rect.w; |
2423 | drm_rects[i].y2 = curr_rect.y + curr_rect.h; | 2426 | drm_rects[i].y2 = curr_rect.y + curr_rect.h; |
2427 | |||
2428 | /* | ||
2429 | * Currently this check is limiting the topology within | ||
2430 | * mode_config->max (which actually is max texture size | ||
2431 | * supported by virtual device). This limit is here to address | ||
2432 | * window managers that create a big framebuffer for whole | ||
2433 | * topology. | ||
2434 | */ | ||
2435 | if (drm_rects[i].x1 < 0 || drm_rects[i].y1 < 0 || | ||
2436 | drm_rects[i].x2 > mode_config->max_width || | ||
2437 | drm_rects[i].y2 > mode_config->max_height) { | ||
2438 | DRM_ERROR("Invalid GUI layout.\n"); | ||
2439 | ret = -EINVAL; | ||
2440 | goto out_free; | ||
2441 | } | ||
2424 | } | 2442 | } |
2425 | 2443 | ||
2426 | ret = vmw_kms_check_display_memory(dev, arg->num_outputs, drm_rects); | 2444 | ret = vmw_kms_check_display_memory(dev, arg->num_outputs, drm_rects); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index 93f6b96ca7bb..f30e839f7bfd 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | |||
@@ -1600,31 +1600,6 @@ int vmw_kms_stdu_init_display(struct vmw_private *dev_priv) | |||
1600 | 1600 | ||
1601 | dev_priv->active_display_unit = vmw_du_screen_target; | 1601 | dev_priv->active_display_unit = vmw_du_screen_target; |
1602 | 1602 | ||
1603 | if (dev_priv->capabilities & SVGA_CAP_3D) { | ||
1604 | /* | ||
1605 | * For 3D VMs, display (scanout) buffer size is the smaller of | ||
1606 | * max texture and max STDU | ||
1607 | */ | ||
1608 | uint32_t max_width, max_height; | ||
1609 | |||
1610 | max_width = min(dev_priv->texture_max_width, | ||
1611 | dev_priv->stdu_max_width); | ||
1612 | max_height = min(dev_priv->texture_max_height, | ||
1613 | dev_priv->stdu_max_height); | ||
1614 | |||
1615 | dev->mode_config.max_width = max_width; | ||
1616 | dev->mode_config.max_height = max_height; | ||
1617 | } else { | ||
1618 | /* | ||
1619 | * Given various display aspect ratios, there's no way to | ||
1620 | * estimate these using prim_bb_mem. So just set these to | ||
1621 | * something arbitrarily large and we will reject any layout | ||
1622 | * that doesn't fit prim_bb_mem later | ||
1623 | */ | ||
1624 | dev->mode_config.max_width = 8192; | ||
1625 | dev->mode_config.max_height = 8192; | ||
1626 | } | ||
1627 | |||
1628 | vmw_kms_create_implicit_placement_property(dev_priv, false); | 1603 | vmw_kms_create_implicit_placement_property(dev_priv, false); |
1629 | 1604 | ||
1630 | for (i = 0; i < VMWGFX_NUM_DISPLAY_UNITS; ++i) { | 1605 | for (i = 0; i < VMWGFX_NUM_DISPLAY_UNITS; ++i) { |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index e125233e074b..80a01cd4c051 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | |||
@@ -1404,22 +1404,17 @@ int vmw_surface_gb_priv_define(struct drm_device *dev, | |||
1404 | *srf_out = NULL; | 1404 | *srf_out = NULL; |
1405 | 1405 | ||
1406 | if (for_scanout) { | 1406 | if (for_scanout) { |
1407 | uint32_t max_width, max_height; | ||
1408 | |||
1409 | if (!svga3dsurface_is_screen_target_format(format)) { | 1407 | if (!svga3dsurface_is_screen_target_format(format)) { |
1410 | DRM_ERROR("Invalid Screen Target surface format."); | 1408 | DRM_ERROR("Invalid Screen Target surface format."); |
1411 | return -EINVAL; | 1409 | return -EINVAL; |
1412 | } | 1410 | } |
1413 | 1411 | ||
1414 | max_width = min(dev_priv->texture_max_width, | 1412 | if (size.width > dev_priv->texture_max_width || |
1415 | dev_priv->stdu_max_width); | 1413 | size.height > dev_priv->texture_max_height) { |
1416 | max_height = min(dev_priv->texture_max_height, | ||
1417 | dev_priv->stdu_max_height); | ||
1418 | |||
1419 | if (size.width > max_width || size.height > max_height) { | ||
1420 | DRM_ERROR("%ux%u\n, exceeds max surface size %ux%u", | 1414 | DRM_ERROR("%ux%u\n, exceeds max surface size %ux%u", |
1421 | size.width, size.height, | 1415 | size.width, size.height, |
1422 | max_width, max_height); | 1416 | dev_priv->texture_max_width, |
1417 | dev_priv->texture_max_height); | ||
1423 | return -EINVAL; | 1418 | return -EINVAL; |
1424 | } | 1419 | } |
1425 | } else { | 1420 | } else { |
@@ -1495,8 +1490,17 @@ int vmw_surface_gb_priv_define(struct drm_device *dev, | |||
1495 | if (srf->flags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT) | 1490 | if (srf->flags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT) |
1496 | srf->res.backup_size += sizeof(SVGA3dDXSOState); | 1491 | srf->res.backup_size += sizeof(SVGA3dDXSOState); |
1497 | 1492 | ||
1493 | /* | ||
1494 | * Don't set SVGA3D_SURFACE_SCREENTARGET flag for a scanout surface with | ||
1495 | * size greater than STDU max width/height. This is really a workaround | ||
1496 | * to support creation of big framebuffer requested by some user-space | ||
1497 | * for whole topology. That big framebuffer won't really be used for | ||
1498 | * binding with screen target as during prepare_fb a separate surface is | ||
1499 | * created so it's safe to ignore SVGA3D_SURFACE_SCREENTARGET flag. | ||
1500 | */ | ||
1498 | if (dev_priv->active_display_unit == vmw_du_screen_target && | 1501 | if (dev_priv->active_display_unit == vmw_du_screen_target && |
1499 | for_scanout) | 1502 | for_scanout && size.width <= dev_priv->stdu_max_width && |
1503 | size.height <= dev_priv->stdu_max_height) | ||
1500 | srf->flags |= SVGA3D_SURFACE_SCREENTARGET; | 1504 | srf->flags |= SVGA3D_SURFACE_SCREENTARGET; |
1501 | 1505 | ||
1502 | /* | 1506 | /* |