X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fgpu%2Fdrm%2Fi915%2Fintel_ringbuffer.c;h=487575f2340d3bd24f7464a9afa1394f9b50affe;hb=3d281d8cca1acb2483444e0d1519c8ab6dda3a47;hp=4b797e7dc95d073d507a5b2e5a86aad38c0b31af;hpb=870e86ddc2d110124812b277643ed0f2767148ee;p=pandora-kernel.git diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 4b797e7dc95d..487575f2340d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -50,9 +50,9 @@ static u32 i915_gem_get_seqno(struct drm_device *dev) static void render_ring_flush(struct drm_device *dev, - struct intel_ring_buffer *ring, - u32 invalidate_domains, - u32 flush_domains) + struct intel_ring_buffer *ring, + u32 invalidate_domains, + u32 flush_domains) { drm_i915_private_t *dev_priv = dev->dev_private; u32 cmd; @@ -119,13 +119,6 @@ render_ring_flush(struct drm_device *dev, } } -static unsigned int render_ring_get_head(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - return I915_READ(PRB0_HEAD) & HEAD_ADDR; -} - static void ring_set_tail(struct drm_device *dev, struct intel_ring_buffer *ring, u32 value) @@ -135,16 +128,17 @@ static void ring_set_tail(struct drm_device *dev, } static unsigned int render_ring_get_active_head(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; - u32 acthd_reg = INTEL_INFO(dev)->gen ? ACTHD_I965 : ACTHD; + 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) + struct intel_ring_buffer *ring) { u32 head; drm_i915_private_t *dev_priv = dev->dev_private; @@ -152,56 +146,56 @@ static int init_ring_common(struct drm_device *dev, obj_priv = to_intel_bo(ring->gem_object); /* Stop the ring if it's running. */ - I915_WRITE(ring->regs.ctl, 0); - I915_WRITE(ring->regs.head, 0); + I915_WRITE_CTL(ring, 0); + I915_WRITE_HEAD(ring, 0); ring->set_tail(dev, ring, 0); /* Initialize the ring. */ - I915_WRITE(ring->regs.start, obj_priv->gtt_offset); - head = ring->get_head(dev, 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_ERROR("%s head not reset to zero " "ctl %08x head %08x tail %08x start %08x\n", ring->name, - I915_READ(ring->regs.ctl), - I915_READ(ring->regs.head), + I915_READ_CTL(ring), + I915_READ_HEAD(ring), I915_READ_TAIL(ring), - I915_READ(ring->regs.start)); + I915_READ_START(ring)); - I915_WRITE(ring->regs.head, 0); + I915_WRITE_HEAD(ring, 0); DRM_ERROR("%s head forced to zero " "ctl %08x head %08x tail %08x start %08x\n", ring->name, - I915_READ(ring->regs.ctl), - I915_READ(ring->regs.head), + I915_READ_CTL(ring), + I915_READ_HEAD(ring), I915_READ_TAIL(ring), - I915_READ(ring->regs.start)); + I915_READ_START(ring)); } - I915_WRITE(ring->regs.ctl, + I915_WRITE_CTL(ring, ((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES) | RING_NO_REPORT | RING_VALID); - head = I915_READ(ring->regs.head) & HEAD_ADDR; + 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(ring->regs.ctl), - I915_READ(ring->regs.head), + I915_READ_CTL(ring), + I915_READ_HEAD(ring), I915_READ_TAIL(ring), - I915_READ(ring->regs.start)); + I915_READ_START(ring)); return -EIO; } if (!drm_core_check_feature(dev, DRIVER_MODESET)) i915_kernel_lost_context(dev); else { - ring->head = ring->get_head(dev, ring); + 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) @@ -211,7 +205,7 @@ static int init_ring_common(struct drm_device *dev, } static int init_render_ring(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; int ret = init_ring_common(dev, ring); @@ -245,9 +239,8 @@ do { \ */ static u32 render_ring_add_request(struct drm_device *dev, - struct intel_ring_buffer *ring, - struct drm_file *file_priv, - u32 flush_domains) + struct intel_ring_buffer *ring, + u32 flush_domains) { drm_i915_private_t *dev_priv = dev->dev_private; u32 seqno; @@ -310,8 +303,8 @@ render_ring_add_request(struct drm_device *dev, } static u32 -render_ring_get_gem_seqno(struct drm_device *dev, - struct intel_ring_buffer *ring) +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)) @@ -322,7 +315,7 @@ render_ring_get_gem_seqno(struct drm_device *dev, static void render_ring_get_user_irq(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; unsigned long irqflags; @@ -339,7 +332,7 @@ render_ring_get_user_irq(struct drm_device *dev, static void render_ring_put_user_irq(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; unsigned long irqflags; @@ -356,20 +349,22 @@ render_ring_put_user_irq(struct drm_device *dev, } static void render_setup_status_page(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; if (IS_GEN6(dev)) { - I915_WRITE(HWS_PGA_GEN6, ring->status_page.gfx_addr); - I915_READ(HWS_PGA_GEN6); /* posting read */ + 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(HWS_PGA, ring->status_page.gfx_addr); - I915_READ(HWS_PGA); /* posting read */ + I915_WRITE(RING_HWS_PGA(ring->mmio_base), + ring->status_page.gfx_addr); + I915_READ(RING_HWS_PGA(ring->mmio_base)); /* posting read */ } } -void +static void bsd_ring_flush(struct drm_device *dev, struct intel_ring_buffer *ring, u32 invalidate_domains, @@ -381,31 +376,23 @@ bsd_ring_flush(struct drm_device *dev, intel_ring_advance(dev, ring); } -static inline unsigned int bsd_ring_get_head(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - return I915_READ(BSD_RING_HEAD) & HEAD_ADDR; -} - -static inline unsigned int bsd_ring_get_active_head(struct drm_device *dev, - struct intel_ring_buffer *ring) +static unsigned int bsd_ring_get_active_head(struct drm_device *dev, + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; - return I915_READ(BSD_RING_ACTHD); + return I915_READ(RING_ACTHD(ring->mmio_base)); } static int init_bsd_ring(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { return init_ring_common(dev, ring); } static u32 bsd_ring_add_request(struct drm_device *dev, - struct intel_ring_buffer *ring, - struct drm_file *file_priv, - u32 flush_domains) + struct intel_ring_buffer *ring, + u32 flush_domains) { u32 seqno; @@ -425,39 +412,39 @@ bsd_ring_add_request(struct drm_device *dev, } static void bsd_setup_status_page(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; - I915_WRITE(BSD_HWS_PGA, ring->status_page.gfx_addr); - I915_READ(BSD_HWS_PGA); + I915_WRITE(RING_HWS_PGA(ring->mmio_base), ring->status_page.gfx_addr); + I915_READ(RING_HWS_PGA(ring->mmio_base)); } static void bsd_ring_get_user_irq(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { /* do nothing */ } static void bsd_ring_put_user_irq(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { /* do nothing */ } static u32 -bsd_ring_get_gem_seqno(struct drm_device *dev, - struct intel_ring_buffer *ring) +bsd_ring_get_seqno(struct drm_device *dev, + struct intel_ring_buffer *ring) { return intel_read_status_page(ring, I915_GEM_HWS_INDEX); } static int bsd_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) + 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; @@ -472,10 +459,10 @@ bsd_ring_dispatch_gem_execbuffer(struct drm_device *dev, 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) + 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; @@ -534,7 +521,7 @@ render_ring_dispatch_gem_execbuffer(struct drm_device *dev, } static void cleanup_status_page(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_gem_object *obj; @@ -554,7 +541,7 @@ static void cleanup_status_page(struct drm_device *dev, } static int init_status_page(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_gem_object *obj; @@ -598,9 +585,8 @@ err: return ret; } - int intel_init_ring_buffer(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv; @@ -624,7 +610,7 @@ int intel_init_ring_buffer(struct drm_device *dev, ring->gem_object = obj; - ret = i915_gem_object_pin(obj, ring->alignment); + ret = i915_gem_object_pin(obj, PAGE_SIZE); if (ret) goto err_unref; @@ -650,7 +636,7 @@ int intel_init_ring_buffer(struct drm_device *dev, if (!drm_core_check_feature(dev, DRIVER_MODESET)) i915_kernel_lost_context(dev); else { - ring->head = ring->get_head(dev, ring); + 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) @@ -673,7 +659,7 @@ err_hws: } void intel_cleanup_ring_buffer(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { if (ring->gem_object == NULL) return; @@ -686,8 +672,8 @@ void intel_cleanup_ring_buffer(struct drm_device *dev, cleanup_status_page(dev, ring); } -int intel_wrap_ring_buffer(struct drm_device *dev, - struct intel_ring_buffer *ring) +static int intel_wrap_ring_buffer(struct drm_device *dev, + struct intel_ring_buffer *ring) { unsigned int *virt; int rem; @@ -713,14 +699,15 @@ int intel_wrap_ring_buffer(struct drm_device *dev, } int intel_wait_ring_buffer(struct drm_device *dev, - struct intel_ring_buffer *ring, int n) + struct intel_ring_buffer *ring, int n) { unsigned long end; + drm_i915_private_t *dev_priv = dev->dev_private; trace_i915_ring_wait_begin (dev); end = jiffies + 3 * HZ; do { - ring->head = ring->get_head(dev, ring); + ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) ring->space += ring->size; @@ -742,7 +729,8 @@ int intel_wait_ring_buffer(struct drm_device *dev, } void intel_ring_begin(struct drm_device *dev, - struct intel_ring_buffer *ring, int num_dwords) + struct intel_ring_buffer *ring, + int num_dwords) { int n = 4*num_dwords; if (unlikely(ring->tail + n > ring->size)) @@ -754,16 +742,16 @@ void intel_ring_begin(struct drm_device *dev, } void intel_ring_advance(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { ring->tail &= ring->size - 1; ring->set_tail(dev, ring, ring->tail); } void intel_fill_struct(struct drm_device *dev, - struct intel_ring_buffer *ring, - void *data, - unsigned int len) + struct intel_ring_buffer *ring, + void *data, + unsigned int len) { unsigned int *virt = ring->virtual_start + ring->tail; BUG_ON((len&~(4-1)) != 0); @@ -778,36 +766,18 @@ void intel_fill_struct(struct drm_device *dev, static const struct intel_ring_buffer render_ring = { .name = "render ring", .id = RING_RENDER, - .regs = { - .ctl = PRB0_CTL, - .head = PRB0_HEAD, - .start = PRB0_START - }, .mmio_base = RENDER_RING_BASE, .size = 32 * PAGE_SIZE, - .alignment = PAGE_SIZE, - .virtual_start = NULL, - .dev = NULL, - .gem_object = NULL, - .head = 0, - .tail = 0, - .space = 0, - .user_irq_refcount = 0, - .irq_gem_seqno = 0, - .waiting_gem_seqno = 0, .setup_status_page = render_setup_status_page, .init = init_render_ring, - .get_head = render_ring_get_head, .set_tail = ring_set_tail, .get_active_head = render_ring_get_active_head, .flush = render_ring_flush, .add_request = render_ring_add_request, - .get_gem_seqno = render_ring_get_gem_seqno, + .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, - .status_page = {NULL, 0, NULL}, - .map = {0,} }; /* ring buffer for bit-stream decoder */ @@ -815,57 +785,32 @@ static const struct intel_ring_buffer render_ring = { static const struct intel_ring_buffer bsd_ring = { .name = "bsd ring", .id = RING_BSD, - .regs = { - .ctl = BSD_RING_CTL, - .head = BSD_RING_HEAD, - .start = BSD_RING_START - }, .mmio_base = BSD_RING_BASE, .size = 32 * PAGE_SIZE, - .alignment = PAGE_SIZE, - .virtual_start = NULL, - .dev = NULL, - .gem_object = NULL, - .head = 0, - .tail = 0, - .space = 0, - .user_irq_refcount = 0, - .irq_gem_seqno = 0, - .waiting_gem_seqno = 0, .setup_status_page = bsd_setup_status_page, .init = init_bsd_ring, - .get_head = bsd_ring_get_head, .set_tail = ring_set_tail, .get_active_head = bsd_ring_get_active_head, .flush = bsd_ring_flush, .add_request = bsd_ring_add_request, - .get_gem_seqno = bsd_ring_get_gem_seqno, + .get_seqno = bsd_ring_get_seqno, .user_irq_get = bsd_ring_get_user_irq, .user_irq_put = bsd_ring_put_user_irq, .dispatch_gem_execbuffer = bsd_ring_dispatch_gem_execbuffer, - .status_page = {NULL, 0, NULL}, - .map = {0,} }; static void gen6_bsd_setup_status_page(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - I915_WRITE(GEN6_BSD_HWS_PGA, ring->status_page.gfx_addr); - I915_READ(GEN6_BSD_HWS_PGA); -} - -static inline unsigned int gen6_bsd_ring_get_head(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; - return I915_READ(GEN6_BSD_RING_HEAD) & HEAD_ADDR; + I915_WRITE(RING_HWS_PGA_GEN6(ring->mmio_base), ring->status_page.gfx_addr); + I915_READ(RING_HWS_PGA_GEN6(ring->mmio_base)); } -static inline void gen6_bsd_ring_set_tail(struct drm_device *dev, - struct intel_ring_buffer *ring, - u32 value) +static void gen6_bsd_ring_set_tail(struct drm_device *dev, + struct intel_ring_buffer *ring, + u32 value) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -886,17 +831,17 @@ static inline void gen6_bsd_ring_set_tail(struct drm_device *dev, GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE); } -static inline unsigned int gen6_bsd_ring_get_active_head(struct drm_device *dev, - struct intel_ring_buffer *ring) +static unsigned int gen6_bsd_ring_get_active_head(struct drm_device *dev, + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; - return I915_READ(GEN6_BSD_RING_ACTHD); + return I915_READ(RING_ACTHD(ring->mmio_base)); } static void gen6_bsd_ring_flush(struct drm_device *dev, - struct intel_ring_buffer *ring, - u32 invalidate_domains, - u32 flush_domains) + 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); @@ -908,17 +853,22 @@ static void gen6_bsd_ring_flush(struct drm_device *dev, static int gen6_bsd_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) + 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, + 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; } @@ -926,36 +876,18 @@ gen6_bsd_ring_dispatch_gem_execbuffer(struct drm_device *dev, static const struct intel_ring_buffer gen6_bsd_ring = { .name = "gen6 bsd ring", .id = RING_BSD, - .regs = { - .ctl = GEN6_BSD_RING_CTL, - .head = GEN6_BSD_RING_HEAD, - .start = GEN6_BSD_RING_START - }, .mmio_base = GEN6_BSD_RING_BASE, .size = 32 * PAGE_SIZE, - .alignment = PAGE_SIZE, - .virtual_start = NULL, - .dev = NULL, - .gem_object = NULL, - .head = 0, - .tail = 0, - .space = 0, - .user_irq_refcount = 0, - .irq_gem_seqno = 0, - .waiting_gem_seqno = 0, .setup_status_page = gen6_bsd_setup_status_page, .init = init_bsd_ring, - .get_head = gen6_bsd_ring_get_head, .set_tail = gen6_bsd_ring_set_tail, .get_active_head = gen6_bsd_ring_get_active_head, .flush = gen6_bsd_ring_flush, .add_request = bsd_ring_add_request, - .get_gem_seqno = bsd_ring_get_gem_seqno, + .get_seqno = bsd_ring_get_seqno, .user_irq_get = bsd_ring_get_user_irq, .user_irq_put = bsd_ring_put_user_irq, .dispatch_gem_execbuffer = gen6_bsd_ring_dispatch_gem_execbuffer, - .status_page = {NULL, 0, NULL}, - .map = {0,} }; int intel_init_render_ring_buffer(struct drm_device *dev)