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

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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
+15 −9
Original line number Diff line number Diff line
@@ -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);
+10 −5
Original line number Diff line number Diff line
@@ -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;
+4 −0
Original line number Diff line number Diff line
@@ -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);
+54 −8
Original line number Diff line number Diff line
@@ -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,
	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_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:
Loading