forked from Minki/linux
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: Sinclair Yeh <syeh@vmware.com> Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
This commit is contained in:
parent
c9146cd918
commit
35c051258e
@ -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_fence.o vmwgfx_dmabuf.o vmwgfx_scrn.o vmwgfx_context.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
|
||||
|
@ -693,22 +693,28 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
|
||||
SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM);
|
||||
dev_priv->max_mob_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
|
||||
dev_priv->prim_bb_mem = dev_priv->vram_size;
|
||||
|
||||
vmw_print_capabilities(dev_priv->capabilities);
|
||||
|
||||
ret = vmw_dma_masks(dev_priv);
|
||||
if (unlikely(ret != 0))
|
||||
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) {
|
||||
DRM_INFO("Max GMR ids is %u\n",
|
||||
(unsigned)dev_priv->max_gmr_ids);
|
||||
|
@ -40,17 +40,17 @@
|
||||
#include <drm/ttm/ttm_module.h>
|
||||
#include "vmwgfx_fence.h"
|
||||
|
||||
#define VMWGFX_DRIVER_DATE "20140704"
|
||||
#define VMWGFX_DRIVER_DATE "20150626"
|
||||
#define VMWGFX_DRIVER_MAJOR 2
|
||||
#define VMWGFX_DRIVER_MINOR 6
|
||||
#define VMWGFX_DRIVER_PATCHLEVEL 1
|
||||
#define VMWGFX_DRIVER_MINOR 7
|
||||
#define VMWGFX_DRIVER_PATCHLEVEL 0
|
||||
#define VMWGFX_FILE_PAGE_OFFSET 0x00100000
|
||||
#define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
|
||||
#define VMWGFX_MAX_RELOCATIONS 2048
|
||||
#define VMWGFX_MAX_VALIDATIONS 2048
|
||||
#define VMWGFX_MAX_DISPLAYS 16
|
||||
#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.
|
||||
@ -337,7 +337,8 @@ struct vmw_ctx_binding_state {
|
||||
enum vmw_display_unit_type {
|
||||
vmw_du_invalid = 0,
|
||||
vmw_du_legacy,
|
||||
vmw_du_screen_object
|
||||
vmw_du_screen_object,
|
||||
vmw_du_screen_target
|
||||
};
|
||||
|
||||
|
||||
@ -402,6 +403,10 @@ struct vmw_private {
|
||||
uint32_t mmio_size;
|
||||
uint32_t fb_max_width;
|
||||
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_height;
|
||||
__le32 __iomem *mmio_virt;
|
||||
|
@ -105,6 +105,10 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data,
|
||||
case DRM_VMW_PARAM_MAX_MOB_SIZE:
|
||||
param->value = dev_priv->max_mob_size;
|
||||
break;
|
||||
case DRM_VMW_PARAM_SCREEN_TARGET:
|
||||
param->value =
|
||||
(dev_priv->active_display_unit == vmw_du_screen_target);
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Illegal vmwgfx get param request: %d\n",
|
||||
param->param);
|
||||
|
@ -463,6 +463,11 @@ static int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer,
|
||||
flags, color,
|
||||
clips, num_clips,
|
||||
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);
|
||||
ttm_read_unlock(&dev_priv->reservation_sem);
|
||||
@ -636,6 +641,11 @@ static int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer,
|
||||
flags, color,
|
||||
clips, num_clips, increment,
|
||||
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);
|
||||
@ -999,8 +1009,6 @@ int vmw_kms_generic_present(struct vmw_private *dev_priv,
|
||||
break;
|
||||
}
|
||||
|
||||
vmw_fifo_flush(dev_priv, false);
|
||||
|
||||
kfree(cmd);
|
||||
out_free_tmp:
|
||||
kfree(tmp);
|
||||
@ -1017,8 +1025,21 @@ int vmw_kms_present(struct vmw_private *dev_priv,
|
||||
struct drm_vmw_rect *clips,
|
||||
uint32_t num_clips)
|
||||
{
|
||||
return vmw_kms_generic_present(dev_priv, file_priv, vfb, surface, sid,
|
||||
destX, destY, clips, num_clips);
|
||||
int ret;
|
||||
|
||||
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,
|
||||
@ -1141,9 +1162,12 @@ int vmw_kms_init(struct vmw_private *dev_priv)
|
||||
dev->mode_config.max_width = 8192;
|
||||
dev->mode_config.max_height = 8192;
|
||||
|
||||
ret = vmw_kms_sou_init_display(dev_priv);
|
||||
if (ret) /* Fallback */
|
||||
ret = vmw_kms_ldu_init_display(dev_priv);
|
||||
ret = vmw_kms_stdu_init_display(dev_priv);
|
||||
if (ret) {
|
||||
ret = vmw_kms_sou_init_display(dev_priv);
|
||||
if (ret) /* Fallback */
|
||||
ret = vmw_kms_ldu_init_display(dev_priv);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1160,6 +1184,8 @@ int vmw_kms_close(struct vmw_private *dev_priv)
|
||||
drm_mode_config_cleanup(dev_priv->dev);
|
||||
if (dev_priv->active_display_unit == vmw_du_screen_object)
|
||||
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
|
||||
ret = vmw_kms_ldu_close_display(dev_priv);
|
||||
|
||||
@ -1311,7 +1337,9 @@ bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv,
|
||||
uint32_t pitch,
|
||||
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,
|
||||
if (dev_priv->active_display_unit == vmw_du_screen_object)
|
||||
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 */
|
||||
mode = drm_mode_duplicate(dev, &prefmode);
|
||||
if (!mode)
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
out_free:
|
||||
|
@ -204,4 +204,24 @@ int vmw_kms_sou_do_dmabuf_dirty(struct drm_file *file_priv,
|
||||
struct drm_clip_rect *clips,
|
||||
unsigned num_clips, int increment,
|
||||
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
|
||||
|
@ -31,7 +31,8 @@
|
||||
* 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
|
||||
#define VMW_PPN_SIZE 8
|
||||
|
1364
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
Normal file
1364
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -1486,6 +1486,10 @@ int vmw_surface_gb_priv_define(struct drm_device *dev,
|
||||
srf->mip_levels[0],
|
||||
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
|
||||
* destroy the object on failure.
|
||||
|
@ -88,6 +88,7 @@
|
||||
#define DRM_VMW_PARAM_3D_CAPS_SIZE 8
|
||||
#define DRM_VMW_PARAM_MAX_MOB_MEMORY 9
|
||||
#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
|
||||
|
Loading…
Reference in New Issue
Block a user