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

Commit 549f7365 authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915: Enable SandyBridge blitter ring



Based on an original patch by Zhenyu Wang, this initializes the BLT ring for
SandyBridge and enables support for user execbuffers.

Cc: Zhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent e36c1cd7
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -80,6 +80,8 @@ static int i915_capabilities(struct seq_file *m, void *data)
	B(has_overlay);
	B(has_overlay);
	B(overlay_needs_physical);
	B(overlay_needs_physical);
	B(supports_tv);
	B(supports_tv);
	B(has_bsd_ring);
	B(has_blt_ring);
#undef B
#undef B


	return 0;
	return 0;
+4 −0
Original line number Original line Diff line number Diff line
@@ -133,6 +133,7 @@ static int i915_dma_cleanup(struct drm_device * dev)
	mutex_lock(&dev->struct_mutex);
	mutex_lock(&dev->struct_mutex);
	intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
	intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
	intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring);
	intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring);
	intel_cleanup_ring_buffer(dev, &dev_priv->blt_ring);
	mutex_unlock(&dev->struct_mutex);
	mutex_unlock(&dev->struct_mutex);


	/* Clear the HWS virtual address at teardown */
	/* Clear the HWS virtual address at teardown */
@@ -763,6 +764,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
	case I915_PARAM_HAS_BSD:
	case I915_PARAM_HAS_BSD:
		value = HAS_BSD(dev);
		value = HAS_BSD(dev);
		break;
		break;
	case I915_PARAM_HAS_BLT:
		value = HAS_BLT(dev);
		break;
	default:
	default:
		DRM_DEBUG_DRIVER("Unknown parameter %d\n",
		DRM_DEBUG_DRIVER("Unknown parameter %d\n",
				 param->param);
				 param->param);
+2 −0
Original line number Original line Diff line number Diff line
@@ -158,12 +158,14 @@ static const struct intel_device_info intel_sandybridge_d_info = {
	.gen = 6,
	.gen = 6,
	.need_gfx_hws = 1, .has_hotplug = 1,
	.need_gfx_hws = 1, .has_hotplug = 1,
	.has_bsd_ring = 1,
	.has_bsd_ring = 1,
	.has_blt_ring = 1,
};
};


static const struct intel_device_info intel_sandybridge_m_info = {
static const struct intel_device_info intel_sandybridge_m_info = {
	.gen = 6, .is_mobile = 1,
	.gen = 6, .is_mobile = 1,
	.need_gfx_hws = 1, .has_hotplug = 1,
	.need_gfx_hws = 1, .has_hotplug = 1,
	.has_bsd_ring = 1,
	.has_bsd_ring = 1,
	.has_blt_ring = 1,
};
};


static const struct pci_device_id pciidlist[] = {		/* aka */
static const struct pci_device_id pciidlist[] = {		/* aka */
+3 −0
Original line number Original line Diff line number Diff line
@@ -216,6 +216,7 @@ struct intel_device_info {
	u8 overlay_needs_physical : 1;
	u8 overlay_needs_physical : 1;
	u8 supports_tv : 1;
	u8 supports_tv : 1;
	u8 has_bsd_ring : 1;
	u8 has_bsd_ring : 1;
	u8 has_blt_ring : 1;
};
};


enum no_fbc_reason {
enum no_fbc_reason {
@@ -255,6 +256,7 @@ typedef struct drm_i915_private {
	struct pci_dev *bridge_dev;
	struct pci_dev *bridge_dev;
	struct intel_ring_buffer render_ring;
	struct intel_ring_buffer render_ring;
	struct intel_ring_buffer bsd_ring;
	struct intel_ring_buffer bsd_ring;
	struct intel_ring_buffer blt_ring;
	uint32_t next_seqno;
	uint32_t next_seqno;


	drm_dma_handle_t *status_page_dmah;
	drm_dma_handle_t *status_page_dmah;
@@ -1300,6 +1302,7 @@ static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg,
#define IS_GEN6(dev)	(INTEL_INFO(dev)->gen == 6)
#define IS_GEN6(dev)	(INTEL_INFO(dev)->gen == 6)


#define HAS_BSD(dev)            (INTEL_INFO(dev)->has_bsd_ring)
#define HAS_BSD(dev)            (INTEL_INFO(dev)->has_bsd_ring)
#define HAS_BLT(dev)            (INTEL_INFO(dev)->has_blt_ring)
#define I915_NEED_GFX_HWS(dev)	(INTEL_INFO(dev)->need_gfx_hws)
#define I915_NEED_GFX_HWS(dev)	(INTEL_INFO(dev)->need_gfx_hws)


#define HAS_OVERLAY(dev) 		(INTEL_INFO(dev)->has_overlay)
#define HAS_OVERLAY(dev) 		(INTEL_INFO(dev)->has_overlay)
+48 −7
Original line number Original line Diff line number Diff line
@@ -1800,6 +1800,7 @@ void i915_gem_reset(struct drm_device *dev)


	i915_gem_reset_ring_lists(dev_priv, &dev_priv->render_ring);
	i915_gem_reset_ring_lists(dev_priv, &dev_priv->render_ring);
	i915_gem_reset_ring_lists(dev_priv, &dev_priv->bsd_ring);
	i915_gem_reset_ring_lists(dev_priv, &dev_priv->bsd_ring);
	i915_gem_reset_ring_lists(dev_priv, &dev_priv->blt_ring);


	/* Remove anything from the flushing lists. The GPU cache is likely
	/* Remove anything from the flushing lists. The GPU cache is likely
	 * to be lost on reset along with the data, so simply move the
	 * to be lost on reset along with the data, so simply move the
@@ -1922,6 +1923,7 @@ i915_gem_retire_requests(struct drm_device *dev)


	i915_gem_retire_requests_ring(dev, &dev_priv->render_ring);
	i915_gem_retire_requests_ring(dev, &dev_priv->render_ring);
	i915_gem_retire_requests_ring(dev, &dev_priv->bsd_ring);
	i915_gem_retire_requests_ring(dev, &dev_priv->bsd_ring);
	i915_gem_retire_requests_ring(dev, &dev_priv->blt_ring);
}
}


static void
static void
@@ -1944,7 +1946,8 @@ i915_gem_retire_work_handler(struct work_struct *work)


	if (!dev_priv->mm.suspended &&
	if (!dev_priv->mm.suspended &&
		(!list_empty(&dev_priv->render_ring.request_list) ||
		(!list_empty(&dev_priv->render_ring.request_list) ||
		 !list_empty(&dev_priv->bsd_ring.request_list)))
		 !list_empty(&dev_priv->bsd_ring.request_list) ||
		 !list_empty(&dev_priv->blt_ring.request_list)))
		queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ);
		queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ);
	mutex_unlock(&dev->struct_mutex);
	mutex_unlock(&dev->struct_mutex);
}
}
@@ -2063,6 +2066,10 @@ i915_gem_flush(struct drm_device *dev,
			i915_gem_flush_ring(dev, file_priv,
			i915_gem_flush_ring(dev, file_priv,
					    &dev_priv->bsd_ring,
					    &dev_priv->bsd_ring,
					    invalidate_domains, flush_domains);
					    invalidate_domains, flush_domains);
		if (flush_rings & RING_BLT)
			i915_gem_flush_ring(dev, file_priv,
					    &dev_priv->blt_ring,
					    invalidate_domains, flush_domains);
	}
	}
}
}


@@ -2182,7 +2189,8 @@ i915_gpu_idle(struct drm_device *dev)


	lists_empty = (list_empty(&dev_priv->mm.flushing_list) &&
	lists_empty = (list_empty(&dev_priv->mm.flushing_list) &&
		       list_empty(&dev_priv->render_ring.active_list) &&
		       list_empty(&dev_priv->render_ring.active_list) &&
		       list_empty(&dev_priv->bsd_ring.active_list));
		       list_empty(&dev_priv->bsd_ring.active_list) &&
		       list_empty(&dev_priv->blt_ring.active_list));
	if (lists_empty)
	if (lists_empty)
		return 0;
		return 0;


@@ -2195,6 +2203,10 @@ i915_gpu_idle(struct drm_device *dev)
	if (ret)
	if (ret)
		return ret;
		return ret;


	ret = i915_ring_idle(dev, &dev_priv->blt_ring);
	if (ret)
		return ret;

	return 0;
	return 0;
}
}


@@ -3609,14 +3621,29 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
	DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
	DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
		  (int) args->buffers_ptr, args->buffer_count, args->batch_len);
		  (int) args->buffers_ptr, args->buffer_count, args->batch_len);
#endif
#endif
	if (args->flags & I915_EXEC_BSD) {
	switch (args->flags & I915_EXEC_RING_MASK) {
	case I915_EXEC_DEFAULT:
	case I915_EXEC_RENDER:
		ring = &dev_priv->render_ring;
		break;
	case I915_EXEC_BSD:
		if (!HAS_BSD(dev)) {
		if (!HAS_BSD(dev)) {
			DRM_ERROR("execbuf with wrong flag\n");
			DRM_ERROR("execbuf with invalid ring (BSD)\n");
			return -EINVAL;
			return -EINVAL;
		}
		}
		ring = &dev_priv->bsd_ring;
		ring = &dev_priv->bsd_ring;
	} else {
		break;
		ring = &dev_priv->render_ring;
	case I915_EXEC_BLT:
		if (!HAS_BLT(dev)) {
			DRM_ERROR("execbuf with invalid ring (BLT)\n");
			return -EINVAL;
		}
		ring = &dev_priv->blt_ring;
		break;
	default:
		DRM_ERROR("execbuf with unknown ring: %d\n",
			  (int)(args->flags & I915_EXEC_RING_MASK));
		return -EINVAL;
	}
	}


	if (args->buffer_count < 1) {
	if (args->buffer_count < 1) {
@@ -4482,10 +4509,18 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
			goto cleanup_render_ring;
			goto cleanup_render_ring;
	}
	}


	if (HAS_BLT(dev)) {
		ret = intel_init_blt_ring_buffer(dev);
		if (ret)
			goto cleanup_bsd_ring;
	}

	dev_priv->next_seqno = 1;
	dev_priv->next_seqno = 1;


	return 0;
	return 0;


cleanup_bsd_ring:
	intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring);
cleanup_render_ring:
cleanup_render_ring:
	intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
	intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
cleanup_pipe_control:
cleanup_pipe_control:
@@ -4501,6 +4536,7 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev)


	intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
	intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
	intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring);
	intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring);
	intel_cleanup_ring_buffer(dev, &dev_priv->blt_ring);
	if (HAS_PIPE_CONTROL(dev))
	if (HAS_PIPE_CONTROL(dev))
		i915_gem_cleanup_pipe_control(dev);
		i915_gem_cleanup_pipe_control(dev);
}
}
@@ -4532,10 +4568,12 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
	BUG_ON(!list_empty(&dev_priv->mm.active_list));
	BUG_ON(!list_empty(&dev_priv->mm.active_list));
	BUG_ON(!list_empty(&dev_priv->render_ring.active_list));
	BUG_ON(!list_empty(&dev_priv->render_ring.active_list));
	BUG_ON(!list_empty(&dev_priv->bsd_ring.active_list));
	BUG_ON(!list_empty(&dev_priv->bsd_ring.active_list));
	BUG_ON(!list_empty(&dev_priv->blt_ring.active_list));
	BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
	BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
	BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
	BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
	BUG_ON(!list_empty(&dev_priv->render_ring.request_list));
	BUG_ON(!list_empty(&dev_priv->render_ring.request_list));
	BUG_ON(!list_empty(&dev_priv->bsd_ring.request_list));
	BUG_ON(!list_empty(&dev_priv->bsd_ring.request_list));
	BUG_ON(!list_empty(&dev_priv->blt_ring.request_list));
	mutex_unlock(&dev->struct_mutex);
	mutex_unlock(&dev->struct_mutex);


	ret = drm_irq_install(dev);
	ret = drm_irq_install(dev);
@@ -4594,6 +4632,8 @@ i915_gem_load(struct drm_device *dev)
	INIT_LIST_HEAD(&dev_priv->render_ring.request_list);
	INIT_LIST_HEAD(&dev_priv->render_ring.request_list);
	INIT_LIST_HEAD(&dev_priv->bsd_ring.active_list);
	INIT_LIST_HEAD(&dev_priv->bsd_ring.active_list);
	INIT_LIST_HEAD(&dev_priv->bsd_ring.request_list);
	INIT_LIST_HEAD(&dev_priv->bsd_ring.request_list);
	INIT_LIST_HEAD(&dev_priv->blt_ring.active_list);
	INIT_LIST_HEAD(&dev_priv->blt_ring.request_list);
	for (i = 0; i < 16; i++)
	for (i = 0; i < 16; i++)
		INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list);
		INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list);
	INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
	INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
@@ -4857,7 +4897,8 @@ i915_gpu_is_active(struct drm_device *dev)


	lists_empty = list_empty(&dev_priv->mm.flushing_list) &&
	lists_empty = list_empty(&dev_priv->mm.flushing_list) &&
		      list_empty(&dev_priv->render_ring.active_list) &&
		      list_empty(&dev_priv->render_ring.active_list) &&
		      list_empty(&dev_priv->bsd_ring.active_list);
		      list_empty(&dev_priv->bsd_ring.active_list) &&
		      list_empty(&dev_priv->blt_ring.active_list);


	return !lists_empty;
	return !lists_empty;
}
}
Loading