Commit 35c05125 authored by Sinclair Yeh's avatar Sinclair Yeh Committed by Thomas Hellstrom

drm/vmwgfx: Implement screen targets

Add support for the screen target device interface.
Add a getparam parameter and bump minor to signal availability.
Signed-off-by: default avatarSinclair Yeh <syeh@vmware.com>
Signed-off-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
parent c9146cd9
...@@ -7,6 +7,6 @@ vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \ ...@@ -7,6 +7,6 @@ vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \
vmwgfx_overlay.o vmwgfx_marker.o vmwgfx_gmrid_manager.o \ vmwgfx_overlay.o vmwgfx_marker.o vmwgfx_gmrid_manager.o \
vmwgfx_fence.o vmwgfx_dmabuf.o vmwgfx_scrn.o vmwgfx_context.o \ vmwgfx_fence.o vmwgfx_dmabuf.o vmwgfx_scrn.o vmwgfx_context.o \
vmwgfx_surface.o vmwgfx_prime.o vmwgfx_mob.o vmwgfx_shader.o \ vmwgfx_surface.o vmwgfx_prime.o vmwgfx_mob.o vmwgfx_shader.o \
vmwgfx_cmdbuf_res.o vmwgfx_cmdbuf.o \ vmwgfx_cmdbuf_res.o vmwgfx_cmdbuf.o vmwgfx_stdu.o \
obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o
...@@ -693,22 +693,28 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) ...@@ -693,22 +693,28 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM); SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM);
dev_priv->max_mob_size = dev_priv->max_mob_size =
vmw_read(dev_priv, SVGA_REG_MOB_MAX_SIZE); vmw_read(dev_priv, SVGA_REG_MOB_MAX_SIZE);
dev_priv->stdu_max_width =
vmw_read(dev_priv, SVGA_REG_SCREENTARGET_MAX_WIDTH);
dev_priv->stdu_max_height =
vmw_read(dev_priv, SVGA_REG_SCREENTARGET_MAX_HEIGHT);
vmw_write(dev_priv, SVGA_REG_DEV_CAP,
SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH);
dev_priv->texture_max_width = vmw_read(dev_priv,
SVGA_REG_DEV_CAP);
vmw_write(dev_priv, SVGA_REG_DEV_CAP,
SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT);
dev_priv->texture_max_height = vmw_read(dev_priv,
SVGA_REG_DEV_CAP);
} else } else
dev_priv->prim_bb_mem = dev_priv->vram_size; dev_priv->prim_bb_mem = dev_priv->vram_size;
vmw_print_capabilities(dev_priv->capabilities);
ret = vmw_dma_masks(dev_priv); ret = vmw_dma_masks(dev_priv);
if (unlikely(ret != 0)) if (unlikely(ret != 0))
goto out_err0; goto out_err0;
/*
* Limit back buffer size to VRAM size. Remove this once
* screen targets are implemented.
*/
if (dev_priv->prim_bb_mem > dev_priv->vram_size)
dev_priv->prim_bb_mem = dev_priv->vram_size;
vmw_print_capabilities(dev_priv->capabilities);
if (dev_priv->capabilities & SVGA_CAP_GMR2) { if (dev_priv->capabilities & SVGA_CAP_GMR2) {
DRM_INFO("Max GMR ids is %u\n", DRM_INFO("Max GMR ids is %u\n",
(unsigned)dev_priv->max_gmr_ids); (unsigned)dev_priv->max_gmr_ids);
......
...@@ -40,17 +40,17 @@ ...@@ -40,17 +40,17 @@
#include <drm/ttm/ttm_module.h> #include <drm/ttm/ttm_module.h>
#include "vmwgfx_fence.h" #include "vmwgfx_fence.h"
#define VMWGFX_DRIVER_DATE "20140704" #define VMWGFX_DRIVER_DATE "20150626"
#define VMWGFX_DRIVER_MAJOR 2 #define VMWGFX_DRIVER_MAJOR 2
#define VMWGFX_DRIVER_MINOR 6 #define VMWGFX_DRIVER_MINOR 7
#define VMWGFX_DRIVER_PATCHLEVEL 1 #define VMWGFX_DRIVER_PATCHLEVEL 0
#define VMWGFX_FILE_PAGE_OFFSET 0x00100000 #define VMWGFX_FILE_PAGE_OFFSET 0x00100000
#define VMWGFX_FIFO_STATIC_SIZE (1024*1024) #define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
#define VMWGFX_MAX_RELOCATIONS 2048 #define VMWGFX_MAX_RELOCATIONS 2048
#define VMWGFX_MAX_VALIDATIONS 2048 #define VMWGFX_MAX_VALIDATIONS 2048
#define VMWGFX_MAX_DISPLAYS 16 #define VMWGFX_MAX_DISPLAYS 16
#define VMWGFX_CMD_BOUNCE_INIT_SIZE 32768 #define VMWGFX_CMD_BOUNCE_INIT_SIZE 32768
#define VMWGFX_ENABLE_SCREEN_TARGET_OTABLE 0 #define VMWGFX_ENABLE_SCREEN_TARGET_OTABLE 1
/* /*
* Perhaps we should have sysfs entries for these. * Perhaps we should have sysfs entries for these.
...@@ -337,7 +337,8 @@ struct vmw_ctx_binding_state { ...@@ -337,7 +337,8 @@ struct vmw_ctx_binding_state {
enum vmw_display_unit_type { enum vmw_display_unit_type {
vmw_du_invalid = 0, vmw_du_invalid = 0,
vmw_du_legacy, vmw_du_legacy,
vmw_du_screen_object vmw_du_screen_object,
vmw_du_screen_target
}; };
...@@ -402,6 +403,10 @@ struct vmw_private { ...@@ -402,6 +403,10 @@ struct vmw_private {
uint32_t mmio_size; uint32_t mmio_size;
uint32_t fb_max_width; uint32_t fb_max_width;
uint32_t fb_max_height; uint32_t fb_max_height;
uint32_t texture_max_width;
uint32_t texture_max_height;
uint32_t stdu_max_width;
uint32_t stdu_max_height;
uint32_t initial_width; uint32_t initial_width;
uint32_t initial_height; uint32_t initial_height;
__le32 __iomem *mmio_virt; __le32 __iomem *mmio_virt;
......
...@@ -105,6 +105,10 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, ...@@ -105,6 +105,10 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data,
case DRM_VMW_PARAM_MAX_MOB_SIZE: case DRM_VMW_PARAM_MAX_MOB_SIZE:
param->value = dev_priv->max_mob_size; param->value = dev_priv->max_mob_size;
break; break;
case DRM_VMW_PARAM_SCREEN_TARGET:
param->value =
(dev_priv->active_display_unit == vmw_du_screen_target);
break;
default: default:
DRM_ERROR("Illegal vmwgfx get param request: %d\n", DRM_ERROR("Illegal vmwgfx get param request: %d\n",
param->param); param->param);
......
...@@ -463,6 +463,11 @@ static int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer, ...@@ -463,6 +463,11 @@ static int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer,
flags, color, flags, color,
clips, num_clips, clips, num_clips,
inc, NULL); inc, NULL);
else
ret = vmw_kms_stdu_do_surface_dirty(dev_priv, file_priv,
&vfbs->base,
clips, num_clips,
inc);
vmw_fifo_flush(dev_priv, false); vmw_fifo_flush(dev_priv, false);
ttm_read_unlock(&dev_priv->reservation_sem); ttm_read_unlock(&dev_priv->reservation_sem);
...@@ -636,6 +641,11 @@ static int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer, ...@@ -636,6 +641,11 @@ static int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer,
flags, color, flags, color,
clips, num_clips, increment, clips, num_clips, increment,
NULL); NULL);
} else {
ret = vmw_kms_stdu_do_surface_dirty(dev_priv, file_priv,
&vfbd->base,
clips, num_clips,
increment);
} }
vmw_fifo_flush(dev_priv, false); vmw_fifo_flush(dev_priv, false);
...@@ -999,8 +1009,6 @@ int vmw_kms_generic_present(struct vmw_private *dev_priv, ...@@ -999,8 +1009,6 @@ int vmw_kms_generic_present(struct vmw_private *dev_priv,
break; break;
} }
vmw_fifo_flush(dev_priv, false);
kfree(cmd); kfree(cmd);
out_free_tmp: out_free_tmp:
kfree(tmp); kfree(tmp);
...@@ -1017,8 +1025,21 @@ int vmw_kms_present(struct vmw_private *dev_priv, ...@@ -1017,8 +1025,21 @@ int vmw_kms_present(struct vmw_private *dev_priv,
struct drm_vmw_rect *clips, struct drm_vmw_rect *clips,
uint32_t num_clips) uint32_t num_clips)
{ {
return vmw_kms_generic_present(dev_priv, file_priv, vfb, surface, sid, int ret;
destX, destY, clips, num_clips);
if (dev_priv->active_display_unit == vmw_du_screen_target)
ret = vmw_kms_stdu_present(dev_priv, file_priv, vfb, sid,
destX, destY, clips, num_clips);
else
ret = vmw_kms_generic_present(dev_priv, file_priv, vfb,
surface, sid, destX, destY,
clips, num_clips);
if (ret)
return ret;
vmw_fifo_flush(dev_priv, false);
return 0;
} }
int vmw_kms_readback(struct vmw_private *dev_priv, int vmw_kms_readback(struct vmw_private *dev_priv,
...@@ -1141,9 +1162,12 @@ int vmw_kms_init(struct vmw_private *dev_priv) ...@@ -1141,9 +1162,12 @@ int vmw_kms_init(struct vmw_private *dev_priv)
dev->mode_config.max_width = 8192; dev->mode_config.max_width = 8192;
dev->mode_config.max_height = 8192; dev->mode_config.max_height = 8192;
ret = vmw_kms_sou_init_display(dev_priv); ret = vmw_kms_stdu_init_display(dev_priv);
if (ret) /* Fallback */ if (ret) {
ret = vmw_kms_ldu_init_display(dev_priv); ret = vmw_kms_sou_init_display(dev_priv);
if (ret) /* Fallback */
ret = vmw_kms_ldu_init_display(dev_priv);
}
return ret; return ret;
} }
...@@ -1160,6 +1184,8 @@ int vmw_kms_close(struct vmw_private *dev_priv) ...@@ -1160,6 +1184,8 @@ int vmw_kms_close(struct vmw_private *dev_priv)
drm_mode_config_cleanup(dev_priv->dev); drm_mode_config_cleanup(dev_priv->dev);
if (dev_priv->active_display_unit == vmw_du_screen_object) if (dev_priv->active_display_unit == vmw_du_screen_object)
ret = vmw_kms_sou_close_display(dev_priv); ret = vmw_kms_sou_close_display(dev_priv);
else if (dev_priv->active_display_unit == vmw_du_screen_target)
ret = vmw_kms_stdu_close_display(dev_priv);
else else
ret = vmw_kms_ldu_close_display(dev_priv); ret = vmw_kms_ldu_close_display(dev_priv);
...@@ -1311,7 +1337,9 @@ bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv, ...@@ -1311,7 +1337,9 @@ bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv,
uint32_t pitch, uint32_t pitch,
uint32_t height) uint32_t height)
{ {
return ((u64) pitch * (u64) height) < (u64) dev_priv->prim_bb_mem; return ((u64) pitch * (u64) height) < (u64)
((dev_priv->active_display_unit == vmw_du_screen_target) ?
dev_priv->prim_bb_mem : dev_priv->vram_size);
} }
...@@ -1558,6 +1586,11 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector, ...@@ -1558,6 +1586,11 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector,
if (dev_priv->active_display_unit == vmw_du_screen_object) if (dev_priv->active_display_unit == vmw_du_screen_object)
assumed_bpp = 4; assumed_bpp = 4;
if (dev_priv->active_display_unit == vmw_du_screen_target) {
max_width = min(max_width, dev_priv->stdu_max_width);
max_height = min(max_height, dev_priv->stdu_max_height);
}
/* Add preferred mode */ /* Add preferred mode */
mode = drm_mode_duplicate(dev, &prefmode); mode = drm_mode_duplicate(dev, &prefmode);
if (!mode) if (!mode)
...@@ -1674,6 +1707,19 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, ...@@ -1674,6 +1707,19 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
bounding_box.h = rects[i].y + rects[i].h; bounding_box.h = rects[i].y + rects[i].h;
} }
/*
* For Screen Target Display Unit, all the displays must fit
* inside of maximum texture size.
*/
if (dev_priv->active_display_unit == vmw_du_screen_target)
if (bounding_box.w > dev_priv->texture_max_width ||
bounding_box.h > dev_priv->texture_max_height) {
DRM_ERROR("Layout exceeds maximum texture size\n");
ret = -EINVAL;
goto out_free;
}
vmw_du_update_layout(dev_priv, arg->num_outputs, rects); vmw_du_update_layout(dev_priv, arg->num_outputs, rects);
out_free: out_free:
......
...@@ -204,4 +204,24 @@ int vmw_kms_sou_do_dmabuf_dirty(struct drm_file *file_priv, ...@@ -204,4 +204,24 @@ int vmw_kms_sou_do_dmabuf_dirty(struct drm_file *file_priv,
struct drm_clip_rect *clips, struct drm_clip_rect *clips,
unsigned num_clips, int increment, unsigned num_clips, int increment,
struct vmw_fence_obj **out_fence); struct vmw_fence_obj **out_fence);
/*
* Screen Target Display Unit functions - vmwgfx_stdu.c
*/
int vmw_kms_stdu_init_display(struct vmw_private *dev_priv);
int vmw_kms_stdu_close_display(struct vmw_private *dev_priv);
int vmw_kms_stdu_do_surface_dirty(struct vmw_private *dev_priv,
struct drm_file *file_priv,
struct vmw_framebuffer *framebuffer,
struct drm_clip_rect *clips,
unsigned num_clips, int increment);
int vmw_kms_stdu_present(struct vmw_private *dev_priv,
struct drm_file *file_priv,
struct vmw_framebuffer *vfb,
uint32_t user_handle,
int32_t dest_x, int32_t dest_y,
struct drm_vmw_rect *clips,
uint32_t num_clips);
#endif #endif
...@@ -31,7 +31,8 @@ ...@@ -31,7 +31,8 @@
* If we set up the screen target otable, screen objects stop working. * If we set up the screen target otable, screen objects stop working.
*/ */
#define VMW_OTABLE_SETUP_SUB ((VMWGFX_ENABLE_SCREEN_TARGET_OTABLE) ? 0 : 1) #define VMW_OTABLE_SETUP_SUB ((VMWGFX_ENABLE_SCREEN_TARGET_OTABLE && \
(dev_priv->capabilities & SVGA_CAP_3D)) ? 0 : 1)
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
#define VMW_PPN_SIZE 8 #define VMW_PPN_SIZE 8
......
This diff is collapsed.
...@@ -1486,6 +1486,10 @@ int vmw_surface_gb_priv_define(struct drm_device *dev, ...@@ -1486,6 +1486,10 @@ int vmw_surface_gb_priv_define(struct drm_device *dev,
srf->mip_levels[0], srf->mip_levels[0],
srf->flags & SVGA3D_SURFACE_CUBEMAP); srf->flags & SVGA3D_SURFACE_CUBEMAP);
if (dev_priv->active_display_unit == vmw_du_screen_target &&
for_scanout)
srf->flags |= SVGA3D_SURFACE_SCREENTARGET;
/* /*
* From this point, the generic resource management functions * From this point, the generic resource management functions
* destroy the object on failure. * destroy the object on failure.
......
...@@ -88,6 +88,7 @@ ...@@ -88,6 +88,7 @@
#define DRM_VMW_PARAM_3D_CAPS_SIZE 8 #define DRM_VMW_PARAM_3D_CAPS_SIZE 8
#define DRM_VMW_PARAM_MAX_MOB_MEMORY 9 #define DRM_VMW_PARAM_MAX_MOB_MEMORY 9
#define DRM_VMW_PARAM_MAX_MOB_SIZE 10 #define DRM_VMW_PARAM_MAX_MOB_SIZE 10
#define DRM_VMW_PARAM_SCREEN_TARGET 11
/** /**
* enum drm_vmw_handle_type - handle type for ref ioctls * enum drm_vmw_handle_type - handle type for ref ioctls
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment