/*
 * Copyright © 2008-2010 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 * Authors:
 *    Eric Anholt <eric@anholt.net>
 *    Zou Nan hai <nanhai.zou@intel.com>
 *    Xiang Hai hao<haihao.xiang@intel.com>
 *
 */

#include "drmP.h"
#include "drm.h"
#include "i915_drv.h"
#include "i915_drm.h"
#include "i915_trace.h"
#include "intel_drv.h"

static u32 i915_gem_get_seqno(struct drm_device *dev)
{
	drm_i915_private_t *dev_priv = dev->dev_private;
	u32 seqno;

	seqno = dev_priv->next_seqno;

	/* reserve 0 for non-seqno */
	if (++dev_priv->next_seqno == 0)
		dev_priv->next_seqno = 1;

	return seqno;
}

static void
render_ring_flush(struct drm_device *dev,
		  struct intel_ring_buffer *ring,
		  u32	invalidate_domains,
		  u32	flush_domains)
{
	drm_i915_private_t *dev_priv = dev->dev_private;
	u32 cmd;

#if WATCH_EXEC
	DRM_INFO("%s: invalidate %08x flush %08x\n", __func__,
		  invalidate_domains, flush_domains);
#endif

	trace_i915_gem_request_flush(dev, dev_priv->next_seqno,
				     invalidate_domains, flush_domains);

	if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) {
		/*
		 * read/write caches:
		 *
		 * I915_GEM_DOMAIN_RENDER is always invalidated, but is
		 * only flushed if MI_NO_WRITE_FLUSH is unset.  On 965, it is
		 * also flushed at 2d versus 3d pipeline switches.
		 *
		 * read-only caches:
		 *
		 * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if
		 * MI_READ_FLUSH is set, and is always flushed on 965.
		 *
		 * I915_GEM_DOMAIN_COMMAND may not exist?
		 *
		 * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is
		 * invalidated when MI_EXE_FLUSH is set.
		 *
		 * I915_GEM_DOMAIN_VERTEX, which exists on 965, is
		 * invalidated with every MI_FLUSH.
		 *
		 * TLBs:
		 *
		 * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND
		 * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and
		 * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER
		 * are flushed at any MI_FLUSH.
		 */

		cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
		if ((invalidate_domains|flush_domains) &
		    I915_GEM_DOMAIN_RENDER)
			cmd &= ~MI_NO_WRITE_FLUSH;
		if (INTEL_INFO(dev)->gen < 4) {
			/*
			 * On the 965, the sampler cache always gets flushed
			 * and this bit is reserved.
			 */
			if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER)
				cmd |= MI_READ_FLUSH;
		}
		if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION)
			cmd |= MI_EXE_FLUSH;

#if WATCH_EXEC
		DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd);
#endif
		intel_ring_begin(dev, ring, 2);
		intel_ring_emit(dev, ring, cmd);
		intel_ring_emit(dev, ring, MI_NOOP);
		intel_ring_advance(dev, ring);
	}
}

static void ring_write_tail(struct drm_device *dev,
			    struct intel_ring_buffer *ring,
			    u32 value)
{
	drm_i915_private_t *dev_priv = dev->dev_private;
	I915_WRITE_TAIL(ring, value);
}

u32 intel_ring_get_active_head(struct drm_device *dev,
			       struct intel_ring_buffer *ring)
{
	drm_i915_private_t *dev_priv = dev->dev_private;
	u32 acthd_reg = INTEL_INFO(dev)->gen >= 4 ?
			RING_ACTHD(ring->mmio_base) : ACTHD;

	return I915_READ(acthd_reg);
}

static int init_ring_common(struct drm_device *dev,
			    struct intel_ring_buffer *ring)
{
	u32 head;
	drm_i915_private_t *dev_priv = dev->dev_private;
	struct drm_i915_gem_object *obj_priv;
	obj_priv = to_intel_bo(ring->gem_object);

	/* Stop the ring if it's running. */
	I915_WRITE_CTL(ring, 0);
	I915_WRITE_HEAD(ring, 0);
	ring->write_tail(dev, ring, 0);

	/* Initialize the ring. */
	I915_WRITE_START(ring, obj_priv->gtt_offset);
	head = I915_READ_HEAD(ring) & HEAD_ADDR;

	/* G45 ring initialization fails to reset head to zero */
	if (head != 0) {
		DRM_DEBUG_KMS("%s head not reset to zero "
			      "ctl %08x head %08x tail %08x start %08x\n",
			      ring->name,
			      I915_READ_CTL(ring),
			      I915_READ_HEAD(ring),
			      I915_READ_TAIL(ring),
			      I915_READ_START(ring));

		I915_WRITE_HEAD(ring, 0);

		if (I915_READ_HEAD(ring) & HEAD_ADDR) {
			DRM_ERROR("failed to set %s head to zero "
				  "ctl %08x head %08x tail %08x start %08x\n",
				  ring->name,
				  I915_READ_CTL(ring),
				  I915_READ_HEAD(ring),
				  I915_READ_TAIL(ring),
				  I915_READ_START(ring));
		}
	}

	I915_WRITE_CTL(ring,
			((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES)
			| RING_REPORT_64K | RING_VALID);

	head = I915_READ_HEAD(ring) & HEAD_ADDR;
	/* If the head is still not zero, the ring is dead */
	if (head != 0) {
		DRM_ERROR("%s initialization failed "
				"ctl %08x head %08x tail %08x start %08x\n",
				ring->name,
				I915_READ_CTL(ring),
				I915_READ_HEAD(ring),
				I915_READ_TAIL(ring),
				I915_READ_START(ring));
		return -EIO;
	}

	if (!drm_core_check_feature(dev, DRIVER_MODESET))
		i915_kernel_lost_context(dev);
	else {
		ring->head = I915_READ_HEAD(ring) & HEAD_ADDR;
		ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR;
		ring->space = ring->head - (ring->tail + 8);
		if (ring->space < 0)
			ring->space += ring->size;
	}
	return 0;
}

static int init_render_ring(struct drm_device *dev,
			    struct intel_ring_buffer *ring)
{
	drm_i915_private_t *dev_priv = dev->dev_private;
	int ret = init_ring_common(dev, ring);
	int mode;

	if (INTEL_INFO(dev)->gen > 3) {
		mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH;
		if (IS_GEN6(dev))
			mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE;
		I915_WRITE(MI_MODE, mode);
	}
	return ret;
}

#define PIPE_CONTROL_FLUSH(addr)					\
do {									\
	OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |		\
		 PIPE_CONTROL_DEPTH_STALL | 2);				\
	OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT);			\
	OUT_RING(0);							\
	OUT_RING(0);							\
} while (0)

/**
 * Creates a new sequence number, emitting a write of it to the status page
 * plus an interrupt, which will trigger i915_user_interrupt_handler.
 *
 * Must be called with struct_lock held.
 *
 * Returned sequence numbers are nonzero on success.
 */
static u32
render_ring_add_request(struct drm_device *dev,
			struct intel_ring_buffer *ring,
			u32 flush_domains)
{
	drm_i915_private_t *dev_priv = dev->dev_private;
	u32 seqno;

	seqno = i915_gem_get_seqno(dev);

	if (IS_GEN6(dev)) {
		BEGIN_LP_RING(6);
		OUT_RING(GFX_OP_PIPE_CONTROL | 3);
		OUT_RING(PIPE_CONTROL_QW_WRITE |
			 PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH |
			 PIPE_CONTROL_NOTIFY);
		OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
		OUT_RING(seqno);
		OUT_RING(0);
		OUT_RING(0);
		ADVANCE_LP_RING();
	} else if (HAS_PIPE_CONTROL(dev)) {
		u32 scratch_addr = dev_priv->seqno_gfx_addr + 128;

		/*
		 * Workaround qword write incoherence by flushing the
		 * PIPE_NOTIFY buffers out to memory before requesting
		 * an interrupt.
		 */
		BEGIN_LP_RING(32);
		OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
			 PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH);
		OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
		OUT_RING(seqno);
		OUT_RING(0);
		PIPE_CONTROL_FLUSH(scratch_addr);
		scratch_addr += 128; /* write to separate cachelines */
		PIPE_CONTROL_FLUSH(scratch_addr);
		scratch_addr += 128;
		PIPE_CONTROL_FLUSH(scratch_addr);
		scratch_addr += 128;
		PIPE_CONTROL_FLUSH(scratch_addr);
		scratch_addr += 128;
		PIPE_CONTROL_FLUSH(scratch_addr);
		scratch_addr += 128;
		PIPE_CONTROL_FLUSH(scratch_addr);
		OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
			 PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
			 PIPE_CONTROL_NOTIFY);
		OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
		OUT_RING(seqno);
		OUT_RING(0);
		ADVANCE_LP_RING();
	} else {
		BEGIN_LP_RING(4);
		OUT_RING(MI_STORE_DWORD_INDEX);
		OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
		OUT_RING(seqno);

		OUT_RING(MI_USER_INTERRUPT);
		ADVANCE_LP_RING();
	}
	return seqno;
}

static u32
render_ring_get_seqno(struct drm_device *dev,
		      struct intel_ring_buffer *ring)
{
	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
	if (HAS_PIPE_CONTROL(dev))
		return ((volatile u32 *)(dev_priv->seqno_page))[0];
	else
		return intel_read_status_page(ring, I915_GEM_HWS_INDEX);
}

static void
render_ring_get_user_irq(struct drm_device *dev,
			 struct intel_ring_buffer *ring)
{
	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
	unsigned long irqflags;

	spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
	if (dev->irq_enabled && (++ring->user_irq_refcount == 1)) {
		if (HAS_PCH_SPLIT(dev))
			ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
		else
			i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
	}
	spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
}

static void
render_ring_put_user_irq(struct drm_device *dev,
			 struct intel_ring_buffer *ring)
{
	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
	unsigned long irqflags;

	spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
	BUG_ON(dev->irq_enabled && ring->user_irq_refcount <= 0);
	if (dev->irq_enabled && (--ring->user_irq_refcount == 0)) {
		if (HAS_PCH_SPLIT(dev))
			ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
		else
			i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
	}
	spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
}

void intel_ring_setup_status_page(struct drm_device *dev,
				  struct intel_ring_buffer *ring)
{
	drm_i915_private_t *dev_priv = dev->dev_private;
	if (IS_GEN6(dev)) {
		I915_WRITE(RING_HWS_PGA_GEN6(ring->mmio_base),
			   ring->status_page.gfx_addr);
		I915_READ(RING_HWS_PGA_GEN6(ring->mmio_base)); /* posting read */
	} else {
		I915_WRITE(RING_HWS_PGA(ring->mmio_base),
			   ring->status_page.gfx_addr);
		I915_READ(RING_HWS_PGA(ring->mmio_base)); /* posting read */
	}

}

static void
bsd_ring_flush(struct drm_device *dev,
		struct intel_ring_buffer *ring,
		u32     invalidate_domains,
		u32     flush_domains)
{
	intel_ring_begin(dev, ring, 2);
	intel_ring_emit(dev, ring, MI_FLUSH);
	intel_ring_emit(dev, ring, MI_NOOP);
	intel_ring_advance(dev, ring);
}

static int init_bsd_ring(struct drm_device *dev,
			 struct intel_ring_buffer *ring)
{
	return init_ring_common(dev, ring);
}

static u32
ring_add_request(struct drm_device *dev,
		 struct intel_ring_buffer *ring,
		 u32 flush_domains)
{
	u32 seqno;

	seqno = i915_gem_get_seqno(dev);

	intel_ring_begin(dev, ring, 4);
	intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX);
	intel_ring_emit(dev, ring,
			I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
	intel_ring_emit(dev, ring, seqno);
	intel_ring_emit(dev, ring, MI_USER_INTERRUPT);
	intel_ring_advance(dev, ring);

	DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno);

	return seqno;
}

static void
bsd_ring_get_user_irq(struct drm_device *dev,
		      struct intel_ring_buffer *ring)
{
	/* do nothing */
}
static void
bsd_ring_put_user_irq(struct drm_device *dev,
		      struct intel_ring_buffer *ring)
{
	/* do nothing */
}

static u32
ring_status_page_get_seqno(struct drm_device *dev,
			   struct intel_ring_buffer *ring)
{
	return intel_read_status_page(ring, I915_GEM_HWS_INDEX);
}

static int
ring_dispatch_gem_execbuffer(struct drm_device *dev,
			     struct intel_ring_buffer *ring,
			     struct drm_i915_gem_execbuffer2 *exec,
			     struct drm_clip_rect *cliprects,
			     uint64_t exec_offset)
{
	uint32_t exec_start;
	exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
	intel_ring_begin(dev, ring, 2);
	intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START |
			(2 << 6) | MI_BATCH_NON_SECURE_I965);
	intel_ring_emit(dev, ring, exec_start);
	intel_ring_advance(dev, ring);
	return 0;
}

static int
render_ring_dispatch_gem_execbuffer(struct drm_device *dev,
				    struct intel_ring_buffer *ring,
				    struct drm_i915_gem_execbuffer2 *exec,
				    struct drm_clip_rect *cliprects,
				    uint64_t exec_offset)
{
	drm_i915_private_t *dev_priv = dev->dev_private;
	int nbox = exec->num_cliprects;
	int i = 0, count;
	uint32_t exec_start, exec_len;
	exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
	exec_len = (uint32_t) exec->batch_len;

	trace_i915_gem_request_submit(dev, dev_priv->next_seqno + 1);

	count = nbox ? nbox : 1;

	for (i = 0; i < count; i++) {
		if (i < nbox) {
			int ret = i915_emit_box(dev, cliprects, i,
						exec->DR1, exec->DR4);
			if (ret)
				return ret;
		}

		if (IS_I830(dev) || IS_845G(dev)) {
			intel_ring_begin(dev, ring, 4);
			intel_ring_emit(dev, ring, MI_BATCH_BUFFER);
			intel_ring_emit(dev, ring,
					exec_start | MI_BATCH_NON_SECURE);
			intel_ring_emit(dev, ring, exec_start + exec_len - 4);
			intel_ring_emit(dev, ring, 0);
		} else {
			intel_ring_begin(dev, ring, 2);
			if (INTEL_INFO(dev)->gen >= 4) {
				intel_ring_emit(dev, ring,
						MI_BATCH_BUFFER_START | (2 << 6)
						| MI_BATCH_NON_SECURE_I965);
				intel_ring_emit(dev, ring, exec_start);
			} else {
				intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START
						| (2 << 6));
				intel_ring_emit(dev, ring, exec_start |
						MI_BATCH_NON_SECURE);
			}
		}
		intel_ring_advance(dev, ring);
	}

	if (IS_G4X(dev) || IS_GEN5(dev)) {
		intel_ring_begin(dev, ring, 2);
		intel_ring_emit(dev, ring, MI_FLUSH |
				MI_NO_WRITE_FLUSH |
				MI_INVALIDATE_ISP );
		intel_ring_emit(dev, ring, MI_NOOP);
		intel_ring_advance(dev, ring);
	}
	/* XXX breadcrumb */

	return 0;
}

static void cleanup_status_page(struct drm_device *dev,
				struct intel_ring_buffer *ring)
{
	drm_i915_private_t *dev_priv = dev->dev_private;
	struct drm_gem_object *obj;
	struct drm_i915_gem_object *obj_priv;

	obj = ring->status_page.obj;
	if (obj == NULL)
		return;
	obj_priv = to_intel_bo(obj);

	kunmap(obj_priv->pages[0]);
	i915_gem_object_unpin(obj);
	drm_gem_object_unreference(obj);
	ring->status_page.obj = NULL;

	memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
}

static int init_status_page(struct drm_device *dev,
			    struct intel_ring_buffer *ring)
{
	drm_i915_private_t *dev_priv = dev->dev_private;
	struct drm_gem_object *obj;
	struct drm_i915_gem_object *obj_priv;
	int ret;

	obj = i915_gem_alloc_object(dev, 4096);
	if (obj == NULL) {
		DRM_ERROR("Failed to allocate status page\n");
		ret = -ENOMEM;
		goto err;
	}
	obj_priv = to_intel_bo(obj);
	obj_priv->agp_type = AGP_USER_CACHED_MEMORY;

	ret = i915_gem_object_pin(obj, 4096);
	if (ret != 0) {
		goto err_unref;
	}

	ring->status_page.gfx_addr = obj_priv->gtt_offset;
	ring->status_page.page_addr = kmap(obj_priv->pages[0]);
	if (ring->status_page.page_addr == NULL) {
		memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
		goto err_unpin;
	}
	ring->status_page.obj = obj;
	memset(ring->status_page.page_addr, 0, PAGE_SIZE);

	intel_ring_setup_status_page(dev, ring);
	DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n",
			ring->name, ring->status_page.gfx_addr);

	return 0;

err_unpin:
	i915_gem_object_unpin(obj);
err_unref:
	drm_gem_object_unreference(obj);
err:
	return ret;
}

int intel_init_ring_buffer(struct drm_device *dev,
			   struct intel_ring_buffer *ring)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_i915_gem_object *obj_priv;
	struct drm_gem_object *obj;
	int ret;

	ring->dev = dev;
	INIT_LIST_HEAD(&ring->active_list);
	INIT_LIST_HEAD(&ring->request_list);
	INIT_LIST_HEAD(&ring->gpu_write_list);

	if (I915_NEED_GFX_HWS(dev)) {
		ret = init_status_page(dev, ring);
		if (ret)
			return ret;
	}

	obj = i915_gem_alloc_object(dev, ring->size);
	if (obj == NULL) {
		DRM_ERROR("Failed to allocate ringbuffer\n");
		ret = -ENOMEM;
		goto err_hws;
	}

	ring->gem_object = obj;

	ret = i915_gem_object_pin(obj, PAGE_SIZE);
	if (ret)
		goto err_unref;

	obj_priv = to_intel_bo(obj);
	ring->map.size = ring->size;
	ring->map.offset = dev->agp->base + obj_priv->gtt_offset;
	ring->map.type = 0;
	ring->map.flags = 0;
	ring->map.mtrr = 0;

	drm_core_ioremap_wc(&ring->map, dev);
	if (ring->map.handle == NULL) {
		DRM_ERROR("Failed to map ringbuffer.\n");
		ret = -EINVAL;
		goto err_unpin;
	}

	ring->virtual_start = ring->map.handle;
	ret = ring->init(dev, ring);
	if (ret)
		goto err_unmap;

	if (!drm_core_check_feature(dev, DRIVER_MODESET))
		i915_kernel_lost_context(dev);
	else {
		ring->head = I915_READ_HEAD(ring) & HEAD_ADDR;
		ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR;
		ring->space = ring->head - (ring->tail + 8);
		if (ring->space < 0)
			ring->space += ring->size;
	}
	return ret;

err_unmap:
	drm_core_ioremapfree(&ring->map, dev);
err_unpin:
	i915_gem_object_unpin(obj);
err_unref:
	drm_gem_object_unreference(obj);
	ring->gem_object = NULL;
err_hws:
	cleanup_status_page(dev, ring);
	return ret;
}

void intel_cleanup_ring_buffer(struct drm_device *dev,
			       struct intel_ring_buffer *ring)
{
	if (ring->gem_object == NULL)
		return;

	drm_core_ioremapfree(&ring->map, dev);

	i915_gem_object_unpin(ring->gem_object);
	drm_gem_object_unreference(ring->gem_object);
	ring->gem_object = NULL;

	if (ring->cleanup)
		ring->cleanup(ring);

	cleanup_status_page(dev, ring);
}

static int intel_wrap_ring_buffer(struct drm_device *dev,
				  struct intel_ring_buffer *ring)
{
	unsigned int *virt;
	int rem;
	rem = ring->size - ring->tail;

	if (ring->space < rem) {
		int ret = intel_wait_ring_buffer(dev, ring, rem);
		if (ret)
			return ret;
	}

	virt = (unsigned int *)(ring->virtual_start + ring->tail);
	rem /= 8;
	while (rem--) {
		*virt++ = MI_NOOP;
		*virt++ = MI_NOOP;
	}

	ring->tail = 0;
	ring->space = ring->head - 8;

	return 0;
}

int intel_wait_ring_buffer(struct drm_device *dev,
			   struct intel_ring_buffer *ring, int n)
{
	unsigned long end;
	drm_i915_private_t *dev_priv = dev->dev_private;
	u32 head;

	trace_i915_ring_wait_begin (dev);
	end = jiffies + 3 * HZ;
	do {
		/* If the reported head position has wrapped or hasn't advanced,
		 * fallback to the slow and accurate path.
		 */
		head = intel_read_status_page(ring, 4);
		if (head < ring->actual_head)
			head = I915_READ_HEAD(ring);
		ring->actual_head = head;
		ring->head = head & HEAD_ADDR;
		ring->space = ring->head - (ring->tail + 8);
		if (ring->space < 0)
			ring->space += ring->size;
		if (ring->space >= n) {
			trace_i915_ring_wait_end (dev);
			return 0;
		}

		if (dev->primary->master) {
			struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
			if (master_priv->sarea_priv)
				master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
		}

		msleep(1);
	} while (!time_after(jiffies, end));
	trace_i915_ring_wait_end (dev);
	return -EBUSY;
}

void intel_ring_begin(struct drm_device *dev,
		      struct intel_ring_buffer *ring,
		      int num_dwords)
{
	int n = 4*num_dwords;
	if (unlikely(ring->tail + n > ring->size))
		intel_wrap_ring_buffer(dev, ring);
	if (unlikely(ring->space < n))
		intel_wait_ring_buffer(dev, ring, n);

	ring->space -= n;
}

void intel_ring_advance(struct drm_device *dev,
			struct intel_ring_buffer *ring)
{
	ring->tail &= ring->size - 1;
	ring->write_tail(dev, ring, ring->tail);
}

static const struct intel_ring_buffer render_ring = {
	.name			= "render ring",
	.id			= RING_RENDER,
	.mmio_base		= RENDER_RING_BASE,
	.size			= 32 * PAGE_SIZE,
	.init			= init_render_ring,
	.write_tail		= ring_write_tail,
	.flush			= render_ring_flush,
	.add_request		= render_ring_add_request,
	.get_seqno		= render_ring_get_seqno,
	.user_irq_get		= render_ring_get_user_irq,
	.user_irq_put		= render_ring_put_user_irq,
	.dispatch_gem_execbuffer = render_ring_dispatch_gem_execbuffer,
};

/* ring buffer for bit-stream decoder */

static const struct intel_ring_buffer bsd_ring = {
	.name                   = "bsd ring",
	.id			= RING_BSD,
	.mmio_base		= BSD_RING_BASE,
	.size			= 32 * PAGE_SIZE,
	.init			= init_bsd_ring,
	.write_tail		= ring_write_tail,
	.flush			= bsd_ring_flush,
	.add_request		= ring_add_request,
	.get_seqno		= ring_status_page_get_seqno,
	.user_irq_get		= bsd_ring_get_user_irq,
	.user_irq_put		= bsd_ring_put_user_irq,
	.dispatch_gem_execbuffer = ring_dispatch_gem_execbuffer,
};


static void gen6_bsd_ring_write_tail(struct drm_device *dev,
				     struct intel_ring_buffer *ring,
				     u32 value)
{
       drm_i915_private_t *dev_priv = dev->dev_private;

       /* Every tail move must follow the sequence below */
       I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL,
	       GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK |
	       GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_DISABLE);
       I915_WRITE(GEN6_BSD_RNCID, 0x0);

       if (wait_for((I915_READ(GEN6_BSD_SLEEP_PSMI_CONTROL) &
                               GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR) == 0,
                       50))
               DRM_ERROR("timed out waiting for IDLE Indicator\n");

       I915_WRITE_TAIL(ring, value);
       I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL,
	       GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK |
	       GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE);
}

static void gen6_ring_flush(struct drm_device *dev,
			    struct intel_ring_buffer *ring,
			    u32 invalidate_domains,
			    u32 flush_domains)
{
       intel_ring_begin(dev, ring, 4);
       intel_ring_emit(dev, ring, MI_FLUSH_DW);
       intel_ring_emit(dev, ring, 0);
       intel_ring_emit(dev, ring, 0);
       intel_ring_emit(dev, ring, 0);
       intel_ring_advance(dev, ring);
}

static int
gen6_ring_dispatch_gem_execbuffer(struct drm_device *dev,
				  struct intel_ring_buffer *ring,
				  struct drm_i915_gem_execbuffer2 *exec,
				  struct drm_clip_rect *cliprects,
				  uint64_t exec_offset)
{
       uint32_t exec_start;

       exec_start = (uint32_t) exec_offset + exec->batch_start_offset;

       intel_ring_begin(dev, ring, 2);
       intel_ring_emit(dev, ring,
		       MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965);
       /* bit0-7 is the length on GEN6+ */
       intel_ring_emit(dev, ring, exec_start);
       intel_ring_advance(dev, ring);

       return 0;
}

/* ring buffer for Video Codec for Gen6+ */
static const struct intel_ring_buffer gen6_bsd_ring = {
       .name			= "gen6 bsd ring",
       .id			= RING_BSD,
       .mmio_base		= GEN6_BSD_RING_BASE,
       .size			= 32 * PAGE_SIZE,
       .init			= init_bsd_ring,
       .write_tail		= gen6_bsd_ring_write_tail,
       .flush			= gen6_ring_flush,
       .add_request		= ring_add_request,
       .get_seqno		= ring_status_page_get_seqno,
       .user_irq_get		= bsd_ring_get_user_irq,
       .user_irq_put		= bsd_ring_put_user_irq,
       .dispatch_gem_execbuffer	= gen6_ring_dispatch_gem_execbuffer,
};

/* Blitter support (SandyBridge+) */

static void
blt_ring_get_user_irq(struct drm_device *dev,
		      struct intel_ring_buffer *ring)
{
	/* do nothing */
}
static void
blt_ring_put_user_irq(struct drm_device *dev,
		      struct intel_ring_buffer *ring)
{
	/* do nothing */
}


/* Workaround for some stepping of SNB,
 * each time when BLT engine ring tail moved,
 * the first command in the ring to be parsed
 * should be MI_BATCH_BUFFER_START
 */
#define NEED_BLT_WORKAROUND(dev) \
	(IS_GEN6(dev) && (dev->pdev->revision < 8))

static inline struct drm_i915_gem_object *
to_blt_workaround(struct intel_ring_buffer *ring)
{
	return ring->private;
}

static int blt_ring_init(struct drm_device *dev,
			 struct intel_ring_buffer *ring)
{
	if (NEED_BLT_WORKAROUND(dev)) {
		struct drm_i915_gem_object *obj;
		u32 __iomem *ptr;
		int ret;

		obj = to_intel_bo(i915_gem_alloc_object(dev, 4096));
		if (obj == NULL)
			return -ENOMEM;

		ret = i915_gem_object_pin(&obj->base, 4096);
		if (ret) {
			drm_gem_object_unreference(&obj->base);
			return ret;
		}

		ptr = kmap(obj->pages[0]);
		iowrite32(MI_BATCH_BUFFER_END, ptr);
		iowrite32(MI_NOOP, ptr+1);
		kunmap(obj->pages[0]);

		ret = i915_gem_object_set_to_gtt_domain(&obj->base, false);
		if (ret) {
			i915_gem_object_unpin(&obj->base);
			drm_gem_object_unreference(&obj->base);
			return ret;
		}

		ring->private = obj;
	}

	return init_ring_common(dev, ring);
}

static void blt_ring_begin(struct drm_device *dev,
			   struct intel_ring_buffer *ring,
			  int num_dwords)
{
	if (ring->private) {
		intel_ring_begin(dev, ring, num_dwords+2);
		intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START);
		intel_ring_emit(dev, ring, to_blt_workaround(ring)->gtt_offset);
	} else
		intel_ring_begin(dev, ring, 4);
}

static void blt_ring_flush(struct drm_device *dev,
			   struct intel_ring_buffer *ring,
			   u32 invalidate_domains,
			   u32 flush_domains)
{
	blt_ring_begin(dev, ring, 4);
	intel_ring_emit(dev, ring, MI_FLUSH_DW);
	intel_ring_emit(dev, ring, 0);
	intel_ring_emit(dev, ring, 0);
	intel_ring_emit(dev, ring, 0);
	intel_ring_advance(dev, ring);
}

static u32
blt_ring_add_request(struct drm_device *dev,
		     struct intel_ring_buffer *ring,
		     u32 flush_domains)
{
	u32 seqno = i915_gem_get_seqno(dev);

	blt_ring_begin(dev, ring, 4);
	intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX);
	intel_ring_emit(dev, ring,
			I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
	intel_ring_emit(dev, ring, seqno);
	intel_ring_emit(dev, ring, MI_USER_INTERRUPT);
	intel_ring_advance(dev, ring);

	DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno);
	return seqno;
}

static void blt_ring_cleanup(struct intel_ring_buffer *ring)
{
	if (!ring->private)
		return;

	i915_gem_object_unpin(ring->private);
	drm_gem_object_unreference(ring->private);
	ring->private = NULL;
}

static const struct intel_ring_buffer gen6_blt_ring = {
       .name			= "blt ring",
       .id			= RING_BLT,
       .mmio_base		= BLT_RING_BASE,
       .size			= 32 * PAGE_SIZE,
       .init			= blt_ring_init,
       .write_tail		= ring_write_tail,
       .flush			= blt_ring_flush,
       .add_request		= blt_ring_add_request,
       .get_seqno		= ring_status_page_get_seqno,
       .user_irq_get		= blt_ring_get_user_irq,
       .user_irq_put		= blt_ring_put_user_irq,
       .dispatch_gem_execbuffer	= gen6_ring_dispatch_gem_execbuffer,
       .cleanup			= blt_ring_cleanup,
};

int intel_init_render_ring_buffer(struct drm_device *dev)
{
	drm_i915_private_t *dev_priv = dev->dev_private;

	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);
	}

	return intel_init_ring_buffer(dev, &dev_priv->render_ring);
}

int intel_init_bsd_ring_buffer(struct drm_device *dev)
{
	drm_i915_private_t *dev_priv = dev->dev_private;

	if (IS_GEN6(dev))
		dev_priv->bsd_ring = gen6_bsd_ring;
	else
		dev_priv->bsd_ring = bsd_ring;

	return intel_init_ring_buffer(dev, &dev_priv->bsd_ring);
}

int intel_init_blt_ring_buffer(struct drm_device *dev)
{
	drm_i915_private_t *dev_priv = dev->dev_private;

	dev_priv->blt_ring = gen6_blt_ring;

	return intel_init_ring_buffer(dev, &dev_priv->blt_ring);
}
