Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1f027f69 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'drm-fixes-for-v4.7-rc8-vmware' of git://people.freedesktop.org/~airlied/linux

Pull drm vmware fixes from Dave Airlie:
 "These are some fixes for the vmware graphics driver, that fix some
  black screen issues on at least Ubuntu 16.04, I think VMware would
  like to get these in so stable can pick them up ASAP"

* tag 'drm-fixes-for-v4.7-rc8-vmware' of git://people.freedesktop.org/~airlied/linux:
  drm/vmwgfx: Fix error paths when mapping framebuffer
  drm/vmwgfx: Fix corner case screen target management
  drm/vmwgfx: Delay pinning fbdev framebuffer until after mode set
  drm/vmwgfx: Check pin count before attempting to move a buffer
  drm/ttm: Make ttm_bo_mem_compat available
  drm/vmwgfx: Add an option to change assumed FB bpp
  drm/vmwgfx: Work around mode set failure in 2D VMs
  drm/vmwgfx: Add a check to handle host message failure
parents 24ee9a83 d2e1204f
Loading
Loading
Loading
Loading
+4 −3
Original line number Original line Diff line number Diff line
@@ -1034,7 +1034,7 @@ static int ttm_bo_move_buffer(struct ttm_buffer_object *bo,
	return ret;
	return ret;
}
}


static bool ttm_bo_mem_compat(struct ttm_placement *placement,
bool ttm_bo_mem_compat(struct ttm_placement *placement,
		       struct ttm_mem_reg *mem,
		       struct ttm_mem_reg *mem,
		       uint32_t *new_flags)
		       uint32_t *new_flags)
{
{
@@ -1068,6 +1068,7 @@ static bool ttm_bo_mem_compat(struct ttm_placement *placement,


	return false;
	return false;
}
}
EXPORT_SYMBOL(ttm_bo_mem_compat);


int ttm_bo_validate(struct ttm_buffer_object *bo,
int ttm_bo_validate(struct ttm_buffer_object *bo,
			struct ttm_placement *placement,
			struct ttm_placement *placement,
+22 −3
Original line number Original line Diff line number Diff line
@@ -49,6 +49,7 @@ int vmw_dmabuf_pin_in_placement(struct vmw_private *dev_priv,
{
{
	struct ttm_buffer_object *bo = &buf->base;
	struct ttm_buffer_object *bo = &buf->base;
	int ret;
	int ret;
	uint32_t new_flags;


	ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible);
	ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible);
	if (unlikely(ret != 0))
	if (unlikely(ret != 0))
@@ -60,7 +61,12 @@ int vmw_dmabuf_pin_in_placement(struct vmw_private *dev_priv,
	if (unlikely(ret != 0))
	if (unlikely(ret != 0))
		goto err;
		goto err;


	if (buf->pin_count > 0)
		ret = ttm_bo_mem_compat(placement, &bo->mem,
					&new_flags) == true ? 0 : -EINVAL;
	else
		ret = ttm_bo_validate(bo, placement, interruptible, false);
		ret = ttm_bo_validate(bo, placement, interruptible, false);

	if (!ret)
	if (!ret)
		vmw_bo_pin_reserved(buf, true);
		vmw_bo_pin_reserved(buf, true);


@@ -91,6 +97,7 @@ int vmw_dmabuf_pin_in_vram_or_gmr(struct vmw_private *dev_priv,
{
{
	struct ttm_buffer_object *bo = &buf->base;
	struct ttm_buffer_object *bo = &buf->base;
	int ret;
	int ret;
	uint32_t new_flags;


	ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible);
	ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible);
	if (unlikely(ret != 0))
	if (unlikely(ret != 0))
@@ -102,6 +109,12 @@ int vmw_dmabuf_pin_in_vram_or_gmr(struct vmw_private *dev_priv,
	if (unlikely(ret != 0))
	if (unlikely(ret != 0))
		goto err;
		goto err;


	if (buf->pin_count > 0) {
		ret = ttm_bo_mem_compat(&vmw_vram_gmr_placement, &bo->mem,
					&new_flags) == true ? 0 : -EINVAL;
		goto out_unreserve;
	}

	ret = ttm_bo_validate(bo, &vmw_vram_gmr_placement, interruptible,
	ret = ttm_bo_validate(bo, &vmw_vram_gmr_placement, interruptible,
			      false);
			      false);
	if (likely(ret == 0) || ret == -ERESTARTSYS)
	if (likely(ret == 0) || ret == -ERESTARTSYS)
@@ -161,6 +174,7 @@ int vmw_dmabuf_pin_in_start_of_vram(struct vmw_private *dev_priv,
	struct ttm_placement placement;
	struct ttm_placement placement;
	struct ttm_place place;
	struct ttm_place place;
	int ret = 0;
	int ret = 0;
	uint32_t new_flags;


	place = vmw_vram_placement.placement[0];
	place = vmw_vram_placement.placement[0];
	place.lpfn = bo->num_pages;
	place.lpfn = bo->num_pages;
@@ -185,9 +199,14 @@ int vmw_dmabuf_pin_in_start_of_vram(struct vmw_private *dev_priv,
	 */
	 */
	if (bo->mem.mem_type == TTM_PL_VRAM &&
	if (bo->mem.mem_type == TTM_PL_VRAM &&
	    bo->mem.start < bo->num_pages &&
	    bo->mem.start < bo->num_pages &&
	    bo->mem.start > 0)
	    bo->mem.start > 0 &&
	    buf->pin_count == 0)
		(void) ttm_bo_validate(bo, &vmw_sys_placement, false, false);
		(void) ttm_bo_validate(bo, &vmw_sys_placement, false, false);


	if (buf->pin_count > 0)
		ret = ttm_bo_mem_compat(&placement, &bo->mem,
					&new_flags) == true ? 0 : -EINVAL;
	else
		ret = ttm_bo_validate(bo, &placement, interruptible, false);
		ret = ttm_bo_validate(bo, &placement, interruptible, false);


	/* For some reason we didn't end up at the start of vram */
	/* For some reason we didn't end up at the start of vram */
+12 −0
Original line number Original line Diff line number Diff line
@@ -233,6 +233,7 @@ static int vmw_force_iommu;
static int vmw_restrict_iommu;
static int vmw_restrict_iommu;
static int vmw_force_coherent;
static int vmw_force_coherent;
static int vmw_restrict_dma_mask;
static int vmw_restrict_dma_mask;
static int vmw_assume_16bpp;


static int vmw_probe(struct pci_dev *, const struct pci_device_id *);
static int vmw_probe(struct pci_dev *, const struct pci_device_id *);
static void vmw_master_init(struct vmw_master *);
static void vmw_master_init(struct vmw_master *);
@@ -249,6 +250,8 @@ MODULE_PARM_DESC(force_coherent, "Force coherent TTM pages");
module_param_named(force_coherent, vmw_force_coherent, int, 0600);
module_param_named(force_coherent, vmw_force_coherent, int, 0600);
MODULE_PARM_DESC(restrict_dma_mask, "Restrict DMA mask to 44 bits with IOMMU");
MODULE_PARM_DESC(restrict_dma_mask, "Restrict DMA mask to 44 bits with IOMMU");
module_param_named(restrict_dma_mask, vmw_restrict_dma_mask, int, 0600);
module_param_named(restrict_dma_mask, vmw_restrict_dma_mask, int, 0600);
MODULE_PARM_DESC(assume_16bpp, "Assume 16-bpp when filtering modes");
module_param_named(assume_16bpp, vmw_assume_16bpp, int, 0600);




static void vmw_print_capabilities(uint32_t capabilities)
static void vmw_print_capabilities(uint32_t capabilities)
@@ -660,6 +663,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
	dev_priv->vram_start = pci_resource_start(dev->pdev, 1);
	dev_priv->vram_start = pci_resource_start(dev->pdev, 1);
	dev_priv->mmio_start = pci_resource_start(dev->pdev, 2);
	dev_priv->mmio_start = pci_resource_start(dev->pdev, 2);


	dev_priv->assume_16bpp = !!vmw_assume_16bpp;

	dev_priv->enable_fb = enable_fbdev;
	dev_priv->enable_fb = enable_fbdev;


	vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2);
	vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2);
@@ -706,6 +711,13 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
			vmw_read(dev_priv,
			vmw_read(dev_priv,
				 SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB);
				 SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB);


		/*
		 * Workaround for low memory 2D VMs to compensate for the
		 * allocation taken by fbdev
		 */
		if (!(dev_priv->capabilities & SVGA_CAP_3D))
			mem_size *= 2;

		dev_priv->max_mob_pages = mem_size * 1024 / PAGE_SIZE;
		dev_priv->max_mob_pages = mem_size * 1024 / PAGE_SIZE;
		dev_priv->prim_bb_mem =
		dev_priv->prim_bb_mem =
			vmw_read(dev_priv,
			vmw_read(dev_priv,
+1 −0
Original line number Original line Diff line number Diff line
@@ -386,6 +386,7 @@ struct vmw_private {
	spinlock_t hw_lock;
	spinlock_t hw_lock;
	spinlock_t cap_lock;
	spinlock_t cap_lock;
	bool has_dx;
	bool has_dx;
	bool assume_16bpp;


	/*
	/*
	 * VGA registers.
	 * VGA registers.
+25 −22
Original line number Original line Diff line number Diff line
@@ -517,28 +517,6 @@ static int vmw_fb_kms_framebuffer(struct fb_info *info)


	par->set_fb = &vfb->base;
	par->set_fb = &vfb->base;


	if (!par->bo_ptr) {
		/*
		 * Pin before mapping. Since we don't know in what placement
		 * to pin, call into KMS to do it for us.
		 */
		ret = vfb->pin(vfb);
		if (ret) {
			DRM_ERROR("Could not pin the fbdev framebuffer.\n");
			return ret;
		}

		ret = ttm_bo_kmap(&par->vmw_bo->base, 0,
				  par->vmw_bo->base.num_pages, &par->map);
		if (ret) {
			vfb->unpin(vfb);
			DRM_ERROR("Could not map the fbdev framebuffer.\n");
			return ret;
		}

		par->bo_ptr = ttm_kmap_obj_virtual(&par->map, &par->bo_iowrite);
	}

	return 0;
	return 0;
}
}


@@ -601,6 +579,31 @@ static int vmw_fb_set_par(struct fb_info *info)
	if (ret)
	if (ret)
		goto out_unlock;
		goto out_unlock;


	if (!par->bo_ptr) {
		struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(set.fb);

		/*
		 * Pin before mapping. Since we don't know in what placement
		 * to pin, call into KMS to do it for us.
		 */
		ret = vfb->pin(vfb);
		if (ret) {
			DRM_ERROR("Could not pin the fbdev framebuffer.\n");
			goto out_unlock;
		}

		ret = ttm_bo_kmap(&par->vmw_bo->base, 0,
				  par->vmw_bo->base.num_pages, &par->map);
		if (ret) {
			vfb->unpin(vfb);
			DRM_ERROR("Could not map the fbdev framebuffer.\n");
			goto out_unlock;
		}

		par->bo_ptr = ttm_kmap_obj_virtual(&par->map, &par->bo_iowrite);
	}


	vmw_fb_dirty_mark(par, par->fb_x, par->fb_y,
	vmw_fb_dirty_mark(par, par->fb_x, par->fb_y,
			  par->set_fb->width, par->set_fb->height);
			  par->set_fb->width, par->set_fb->height);


Loading