diff options
Diffstat (limited to 'sys/dev/drm2/i915/intel_ringbuffer.h')
-rw-r--r-- | sys/dev/drm2/i915/intel_ringbuffer.h | 95 |
1 files changed, 58 insertions, 37 deletions
diff --git a/sys/dev/drm2/i915/intel_ringbuffer.h b/sys/dev/drm2/i915/intel_ringbuffer.h index e5e52aec7178..fb6707fd8d81 100644 --- a/sys/dev/drm2/i915/intel_ringbuffer.h +++ b/sys/dev/drm2/i915/intel_ringbuffer.h @@ -1,10 +1,9 @@ -/* - * $FreeBSD$ - */ - #ifndef _INTEL_RINGBUFFER_H_ #define _INTEL_RINGBUFFER_H_ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + /* * Gen2 BSpec "1. Programming Environment" / 1.4.4.6 "Ring Buffer Use" * Gen3 BSpec "vol1c Memory Interface Functions" / 2.3.4.5 "Ring Buffer Use" @@ -50,7 +49,7 @@ struct intel_ring_buffer { } id; #define I915_NUM_RINGS 3 u32 mmio_base; - void *virtual_start; + void __iomem *virtual_start; struct drm_device *dev; struct drm_i915_gem_object *obj; @@ -75,21 +74,28 @@ struct intel_ring_buffer { 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, u32 value); - int (*flush)(struct intel_ring_buffer *ring, + 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); - uint32_t (*get_seqno)(struct intel_ring_buffer *ring); + int (*add_request)(struct intel_ring_buffer *ring); + /* Some chipsets are not quite as coherent as advertised and need + * an expensive kick to force a true read of the up-to-date seqno. + * However, the up-to-date seqno is not always required and the last + * seen value is good enough. Note that the seqno will always be + * monotonic, even if not coherent. + */ + u32 (*get_seqno)(struct intel_ring_buffer *ring, + bool lazy_coherency); int (*dispatch_execbuffer)(struct intel_ring_buffer *ring, - u32 offset, u32 length); + u32 offset, u32 length, + unsigned flags); #define I915_DISPATCH_SECURE 0x1 #define I915_DISPATCH_PINNED 0x2 void (*cleanup)(struct intel_ring_buffer *ring); @@ -118,18 +124,12 @@ 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? */ u32 outstanding_lazy_request; + bool gpu_caches_dirty; + + wait_queue_head_t irq_queue; /** * Do an explicit TLB flush before MI_SET_CONTEXT @@ -138,8 +138,6 @@ struct intel_ring_buffer { struct i915_hw_context *default_context; struct drm_i915_gem_object *last_context_obj; - drm_local_map_t map; - void *private; }; @@ -179,32 +177,43 @@ intel_read_status_page(struct intel_ring_buffer *ring, int reg) { /* Ensure that the compiler doesn't optimize away the load. */ - __compiler_membar(); + barrier(); return atomic_load_acq_32(ring->status_page.page_addr + reg); } -void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring); - -int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n); -static inline int intel_wait_ring_idle(struct intel_ring_buffer *ring) -{ - - return (intel_wait_ring_buffer(ring, ring->size - 8)); -} +/** + * Reads a dword out of the status page, which is written to from the command + * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or + * MI_STORE_DATA_IMM. + * + * The following dwords have a reserved meaning: + * 0x00: ISR copy, updated when an ISR bit not set in the HWSTAM changes. + * 0x04: ring 0 head pointer + * 0x05: ring 1 head pointer (915-class) + * 0x06: ring 2 head pointer (915-class) + * 0x10-0x1b: Context status DWords (GM45) + * 0x1f: Last written status offset. (GM45) + * + * The area from dword 0x20 to 0x3ff is available for driver usage. + */ +#define I915_GEM_HWS_INDEX 0x20 +#define I915_GEM_HWS_SCRATCH_INDEX 0x30 +#define I915_GEM_HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT) -int intel_ring_begin(struct intel_ring_buffer *ring, int n); +void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring); +int __must_check intel_ring_begin(struct intel_ring_buffer *ring, int n); static inline void intel_ring_emit(struct intel_ring_buffer *ring, u32 data) { - *(volatile uint32_t *)((char *)ring->virtual_start + - ring->tail) = data; + iowrite32(data, ring->virtual_start + ring->tail); ring->tail += 4; } - void intel_ring_advance(struct intel_ring_buffer *ring); +int __must_check intel_ring_idle(struct intel_ring_buffer *ring); -uint32_t intel_ring_get_seqno(struct intel_ring_buffer *ring); +int intel_ring_flush_all_caches(struct intel_ring_buffer *ring); +int intel_ring_invalidate_all_caches(struct intel_ring_buffer *ring); int intel_init_render_ring_buffer(struct drm_device *dev); int intel_init_bsd_ring_buffer(struct drm_device *dev); @@ -218,7 +227,19 @@ static inline u32 intel_ring_get_tail(struct intel_ring_buffer *ring) return ring->tail; } -void i915_trace_irq_get(struct intel_ring_buffer *ring, uint32_t seqno); +static inline u32 intel_ring_get_seqno(struct intel_ring_buffer *ring) +{ + BUG_ON(ring->outstanding_lazy_request == 0); + return ring->outstanding_lazy_request; +} + +#ifdef __linux__ +static inline void i915_trace_irq_get(struct intel_ring_buffer *ring, u32 seqno) +{ + if (ring->trace_irq_seqno == 0 && ring->irq_get(ring)) + ring->trace_irq_seqno = seqno; +} +#endif /* DRI warts */ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size); |