From: François Tigeot Date: Sat, 5 Jul 2014 15:24:25 +0000 (+0200) Subject: drm/i915: Sync intel_ringbuffer.h with Linux 3.8.13 X-Git-Url: https://gitweb.dragonflybsd.org/~nant/dragonfly.git/commitdiff_plain/15ac624938166e19db9a17ff4cf67bfa246ce505 drm/i915: Sync intel_ringbuffer.h with Linux 3.8.13 --- diff --git a/sys/dev/drm/i915/i915_drv.h b/sys/dev/drm/i915/i915_drv.h index 2e21fa6b9b..ffb51a6b6f 100644 --- a/sys/dev/drm/i915/i915_drv.h +++ b/sys/dev/drm/i915/i915_drv.h @@ -1456,6 +1456,7 @@ int i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj); int i915_gem_object_put_fence(struct drm_i915_gem_object *obj); int i915_gem_idle(struct drm_device *dev); int i915_gem_init_hw(struct drm_device *dev); +void i915_gem_l3_remap(struct drm_device *dev); void i915_gem_init_swizzling(struct drm_device *dev); void i915_gem_init_ppgtt(struct drm_device *dev); void i915_gem_cleanup_ringbuffer(struct drm_device *dev); diff --git a/sys/dev/drm/i915/i915_gem.c b/sys/dev/drm/i915/i915_gem.c index e5f01dde7c..2f04e39795 100644 --- a/sys/dev/drm/i915/i915_gem.c +++ b/sys/dev/drm/i915/i915_gem.c @@ -2705,6 +2705,38 @@ i915_gem_idle(struct drm_device *dev) return (ret); } +void i915_gem_l3_remap(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + u32 misccpctl; + int i; + + if (!HAS_L3_GPU_CACHE(dev)) + return; + + if (!dev_priv->l3_parity.remap_info) + return; + + misccpctl = I915_READ(GEN7_MISCCPCTL); + I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE); + POSTING_READ(GEN7_MISCCPCTL); + + for (i = 0; i < GEN7_L3LOG_SIZE; i += 4) { + u32 remap = I915_READ(GEN7_L3LOG_BASE + i); + if (remap && remap != dev_priv->l3_parity.remap_info[i/4]) + DRM_DEBUG("0x%x was already programmed to %x\n", + GEN7_L3LOG_BASE + i, remap); + if (remap && !dev_priv->l3_parity.remap_info[i/4]) + DRM_DEBUG_DRIVER("Clearing remapped register\n"); + I915_WRITE(GEN7_L3LOG_BASE + i, dev_priv->l3_parity.remap_info[i/4]); + } + + /* Make sure all the writes land before disabling dop clock gating */ + POSTING_READ(GEN7_L3LOG_BASE); + + I915_WRITE(GEN7_MISCCPCTL, misccpctl); +} + void i915_gem_init_swizzling(struct drm_device *dev) { @@ -2729,41 +2761,72 @@ i915_gem_init_swizzling(struct drm_device *dev) I915_WRITE(ARB_MODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_IVB)); } +static bool +intel_enable_blt(struct drm_device *dev) +{ + int revision; + + if (!HAS_BLT(dev)) + return false; + + /* The blitter was dysfunctional on early prototypes */ + revision = pci_read_config(dev->dev, PCIR_REVID, 1); + if (IS_GEN6(dev) && revision < 8) { + DRM_INFO("BLT not supported on this pre-production hardware;" + " graphics performance will be degraded.\n"); + return false; + } + + return true; +} + int i915_gem_init_hw(struct drm_device *dev) { - drm_i915_private_t *dev_priv; + drm_i915_private_t *dev_priv = dev->dev_private; int ret; - dev_priv = dev->dev_private; + if (IS_HASWELL(dev) && (I915_READ(0x120010) == 1)) + I915_WRITE(0x9008, I915_READ(0x9008) | 0xf0000); + + i915_gem_l3_remap(dev); i915_gem_init_swizzling(dev); ret = intel_init_render_ring_buffer(dev); - if (ret != 0) - return (ret); + if (ret) + return ret; if (HAS_BSD(dev)) { ret = intel_init_bsd_ring_buffer(dev); - if (ret != 0) + if (ret) goto cleanup_render_ring; } - if (HAS_BLT(dev)) { + if (intel_enable_blt(dev)) { ret = intel_init_blt_ring_buffer(dev); - if (ret != 0) + if (ret) goto cleanup_bsd_ring; } dev_priv->next_seqno = 1; + + /* + * XXX: There was some w/a described somewhere suggesting loading + * contexts before PPGTT. + */ +#if 0 /* XXX: HW context support */ + i915_gem_context_init(dev); +#endif i915_gem_init_ppgtt(dev); - return (0); + + return 0; cleanup_bsd_ring: intel_cleanup_ring_buffer(&dev_priv->ring[VCS]); cleanup_render_ring: intel_cleanup_ring_buffer(&dev_priv->ring[RCS]); - return (ret); + return ret; } void diff --git a/sys/dev/drm/i915/i915_gem_execbuffer.c b/sys/dev/drm/i915/i915_gem_execbuffer.c index 8be72f4b44..e23de23c16 100644 --- a/sys/dev/drm/i915/i915_gem_execbuffer.c +++ b/sys/dev/drm/i915/i915_gem_execbuffer.c @@ -1153,6 +1153,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, u32 exec_start, exec_len; u32 seqno; u32 mask; + u32 flags; int ret, mode, i; if (!i915_gem_check_execbuffer(args)) { @@ -1164,8 +1165,15 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, return (0); ret = validate_exec_list(exec, args->buffer_count, &relocs_ma); - if (ret != 0) - goto pre_struct_lock_err; + if (ret) + return ret; + + flags = 0; + if (args->flags & I915_EXEC_SECURE) { + flags |= I915_DISPATCH_SECURE; + } + if (args->flags & I915_EXEC_IS_PINNED) + flags |= I915_DISPATCH_PINNED; switch (args->flags & I915_EXEC_RING_MASK) { case I915_EXEC_DEFAULT: @@ -1322,6 +1330,13 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, } batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND; + /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure + * batch" bit. Hence we need to pin secure batches into the global gtt. + * hsw should have this fixed, but let's be paranoid and do it + * unconditionally for now. */ + if (flags & I915_DISPATCH_SECURE && !batch_obj->has_global_gtt_mapping) + i915_gem_gtt_bind_object(batch_obj, batch_obj->cache_level); + ret = i915_gem_execbuffer_move_to_gpu(ring, &objects); if (ret) goto err; @@ -1377,13 +1392,14 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, if (ret) goto err; - ret = ring->dispatch_execbuffer(ring, exec_start, - exec_len); + ret = ring->dispatch_execbuffer(ring, + exec_start, exec_len); if (ret) goto err; } } else { - ret = ring->dispatch_execbuffer(ring, exec_start, exec_len); + ret = ring->dispatch_execbuffer(ring, + exec_start, exec_len); if (ret) goto err; } diff --git a/sys/dev/drm/i915/intel_ringbuffer.h b/sys/dev/drm/i915/intel_ringbuffer.h index 537377eb9d..8a64a4c0f5 100644 --- a/sys/dev/drm/i915/intel_ringbuffer.h +++ b/sys/dev/drm/i915/intel_ringbuffer.h @@ -47,13 +47,13 @@ struct intel_ring_buffer { BCS, } id; #define I915_NUM_RINGS 3 - uint32_t mmio_base; - void *virtual_start; + u32 mmio_base; + void __iomem *virtual_start; struct drm_device *dev; struct drm_i915_gem_object *obj; - uint32_t head; - uint32_t tail; + u32 head; + u32 tail; int space; int size; int effective_size; @@ -70,20 +70,21 @@ struct intel_ring_buffer { u32 last_retired_head; struct lock irq_lock; - u32 irq_refcount; u32 irq_mask; + u32 irq_refcount; /* protected by dev_priv->irq_lock */ + u32 irq_enable_mask; /* bitmask to enable ring interrupt */ u32 trace_irq_seqno; u32 sync_seqno[I915_NUM_RINGS-1]; - bool (*irq_get)(struct intel_ring_buffer *ring); + bool __must_check (*irq_get)(struct intel_ring_buffer *ring); void (*irq_put)(struct intel_ring_buffer *ring); int (*init)(struct intel_ring_buffer *ring); void (*write_tail)(struct intel_ring_buffer *ring, - uint32_t value); - int (*flush)(struct intel_ring_buffer *ring, - uint32_t invalidate_domains, - uint32_t flush_domains); + u32 value); + int __must_check (*flush)(struct intel_ring_buffer *ring, + u32 invalidate_domains, + u32 flush_domains); int (*add_request)(struct intel_ring_buffer *ring, uint32_t *seqno); /* Some chipsets are not quite as coherent as advertised and need @@ -96,14 +97,15 @@ struct intel_ring_buffer { bool lazy_coherency); int (*dispatch_execbuffer)(struct intel_ring_buffer *ring, uint32_t offset, uint32_t length); +#define I915_DISPATCH_SECURE 0x1 +#define I915_DISPATCH_PINNED 0x2 void (*cleanup)(struct intel_ring_buffer *ring); int (*sync_to)(struct intel_ring_buffer *ring, struct intel_ring_buffer *to, u32 seqno); - + u32 semaphore_register[3]; /*our mbox written by others */ u32 signal_mbox[2]; /* mboxes this ring signals to */ - /** * List of objects currently involved in rendering from the * ringbuffer. @@ -122,25 +124,25 @@ struct intel_ring_buffer { */ struct list_head request_list; - /** - * List of objects currently pending a GPU write flush. - * - * All elements on this list will belong to either the - * active_list or flushing_list, last_rendering_seqno can - * be used to differentiate between the two elements. - */ struct list_head gpu_write_list; /** * Do we have some not yet emitted requests outstanding? */ - uint32_t outstanding_lazy_request; + u32 outstanding_lazy_request; bool gpu_caches_dirty; wait_queue_head_t irq_queue; drm_local_map_t map; + /** + * Do an explicit TLB flush before MI_SET_CONTEXT + */ + bool itlb_before_ctx_switch; + struct i915_hw_context *default_context; + struct drm_i915_gem_object *last_context_obj; + void *private; };