drm/i915: introduce intel_ring_buffer structure (V2)

Introduces a more complete intel_ring_buffer structure with callbacks
for setup and management of a particular ringbuffer, and converts the
render ring buffer consumers to use it.

Signed-off-by: Zou Nan hai <nanhai.zou@intel.com>
Signed-off-by: Xiang Hai hao <haihao.xiang@intel.com>
[anholt: Fixed up whitespace fail and rebased against prep patches]
Signed-off-by: Eric Anholt <eric@anholt.net>
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 95dbe56..58b6e81 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1590,6 +1590,7 @@
 		}
 	}
 }
+
 uint32_t
 i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
 		 uint32_t flush_domains)
@@ -1607,7 +1608,8 @@
 	if (request == NULL)
 		return 0;
 
-	seqno = i915_ring_add_request(dev);
+	seqno = dev_priv->render_ring.add_request(dev, &dev_priv->render_ring,
+						  file_priv, flush_domains);
 
 	DRM_DEBUG_DRIVER("%d\n", seqno);
 
@@ -1645,10 +1647,8 @@
 static uint32_t
 i915_retire_commands(struct drm_device *dev)
 {
-	drm_i915_private_t *dev_priv = dev->dev_private;
 	uint32_t cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
 	uint32_t flush_domains = 0;
-	RING_LOCALS;
 
 	/* The sampler always gets flushed on i965 (sigh) */
 	if (IS_I965G(dev))
@@ -1746,7 +1746,9 @@
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	uint32_t seqno;
 
-	if (!dev_priv->hw_status_page || list_empty(&dev_priv->mm.request_list))
+	struct intel_ring_buffer *ring = &(dev_priv->render_ring);
+	if (!ring->status_page.page_addr
+			|| list_empty(&dev_priv->mm.request_list))
 		return;
 
 	seqno = i915_get_gem_seqno(dev);
@@ -1773,7 +1775,8 @@
 
 	if (unlikely (dev_priv->trace_irq_seqno &&
 		      i915_seqno_passed(dev_priv->trace_irq_seqno, seqno))) {
-		i915_user_irq_put(dev);
+
+		ring->user_irq_put(dev, ring);
 		dev_priv->trace_irq_seqno = 0;
 	}
 }
@@ -1803,6 +1806,7 @@
 	u32 ier;
 	int ret = 0;
 
+	struct intel_ring_buffer *ring = &dev_priv->render_ring;
 	BUG_ON(seqno == 0);
 
 	if (atomic_read(&dev_priv->mm.wedged))
@@ -1823,7 +1827,7 @@
 		trace_i915_gem_request_wait_begin(dev, seqno);
 
 		dev_priv->mm.waiting_gem_seqno = seqno;
-		i915_user_irq_get(dev);
+		ring->user_irq_get(dev, ring);
 		if (interruptible)
 			ret = wait_event_interruptible(dev_priv->irq_queue,
 				i915_seqno_passed(i915_get_gem_seqno(dev), seqno) ||
@@ -1833,7 +1837,7 @@
 				i915_seqno_passed(i915_get_gem_seqno(dev), seqno) ||
 				atomic_read(&dev_priv->mm.wedged));
 
-		i915_user_irq_put(dev);
+		ring->user_irq_put(dev, ring);
 		dev_priv->mm.waiting_gem_seqno = 0;
 
 		trace_i915_gem_request_wait_end(dev, seqno);
@@ -1867,6 +1871,19 @@
 }
 
 
+static void
+i915_gem_flush(struct drm_device *dev,
+	       uint32_t invalidate_domains,
+	       uint32_t flush_domains)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	if (flush_domains & I915_GEM_DOMAIN_CPU)
+		drm_agp_chipset_flush(dev);
+	dev_priv->render_ring.flush(dev, &dev_priv->render_ring,
+			invalidate_domains,
+			flush_domains);
+}
+
 /**
  * Ensures that all rendering to the object has completed and the object is
  * safe to unbind from the GTT or access from the CPU.
@@ -3820,7 +3837,11 @@
 #endif
 
 	/* Exec the batchbuffer */
-	ret = i915_dispatch_gem_execbuffer(dev, args, cliprects, exec_offset);
+	ret = dev_priv->render_ring.dispatch_gem_execbuffer(dev,
+							    &dev_priv->render_ring,
+							    args,
+							    cliprects,
+							    exec_offset);
 	if (ret) {
 		DRM_ERROR("dispatch failed %d\n", ret);
 		goto err;
@@ -4378,7 +4399,8 @@
 
 	mutex_lock(&dev->struct_mutex);
 
-	if (dev_priv->mm.suspended || dev_priv->render_ring.ring_obj == NULL) {
+	if (dev_priv->mm.suspended ||
+			dev_priv->render_ring.gem_object == NULL) {
 		mutex_unlock(&dev->struct_mutex);
 		return 0;
 	}
@@ -4420,7 +4442,7 @@
  * 965+ support PIPE_CONTROL commands, which provide finer grained control
  * over cache flushing.
  */
-int
+static int
 i915_gem_init_pipe_control(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -4459,7 +4481,8 @@
 	return ret;
 }
 
-void
+
+static void
 i915_gem_cleanup_pipe_control(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -4477,6 +4500,37 @@
 }
 
 int
+i915_gem_init_ringbuffer(struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	int ret;
+	dev_priv->render_ring = render_ring;
+	if (!I915_NEED_GFX_HWS(dev)) {
+		dev_priv->render_ring.status_page.page_addr
+			= dev_priv->status_page_dmah->vaddr;
+		memset(dev_priv->render_ring.status_page.page_addr,
+				0, PAGE_SIZE);
+	}
+	if (HAS_PIPE_CONTROL(dev)) {
+		ret = i915_gem_init_pipe_control(dev);
+		if (ret)
+			return ret;
+	}
+	ret = intel_init_ring_buffer(dev, &dev_priv->render_ring);
+	return ret;
+}
+
+void
+i915_gem_cleanup_ringbuffer(struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+
+	intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
+	if (HAS_PIPE_CONTROL(dev))
+		i915_gem_cleanup_pipe_control(dev);
+}
+
+int
 i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
 		       struct drm_file *file_priv)
 {