Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 5353 → Rev 5354

/drivers/video/drm/i915/intel_ringbuffer.c
33,14 → 33,24
#include "i915_trace.h"
#include "intel_drv.h"
 
/* Early gen2 devices have a cacheline of just 32 bytes, using 64 is overkill,
* but keeps the logic simple. Indeed, the whole purpose of this macro is just
* to give some inclination as to some of the magic values used in the various
* workarounds!
*/
#define CACHELINE_BYTES 64
bool
intel_ring_initialized(struct intel_engine_cs *ring)
{
struct drm_device *dev = ring->dev;
 
static inline int __ring_space(int head, int tail, int size)
if (!dev)
return false;
 
if (i915.enable_execlists) {
struct intel_context *dctx = ring->default_context;
struct intel_ringbuffer *ringbuf = dctx->engine[ring->id].ringbuf;
 
return ringbuf->obj;
} else
return ring->buffer && ring->buffer->obj;
}
 
int __intel_ring_space(int head, int tail, int size)
{
int space = head - (tail + I915_RING_FREE_SPACE);
if (space < 0)
48,12 → 58,13
return space;
}
 
static inline int ring_space(struct intel_ringbuffer *ringbuf)
int intel_ring_space(struct intel_ringbuffer *ringbuf)
{
return __ring_space(ringbuf->head & HEAD_ADDR, ringbuf->tail, ringbuf->size);
return __intel_ring_space(ringbuf->head & HEAD_ADDR,
ringbuf->tail, ringbuf->size);
}
 
static bool intel_ring_stopped(struct intel_engine_cs *ring)
bool intel_ring_stopped(struct intel_engine_cs *ring)
{
struct drm_i915_private *dev_priv = ring->dev->dev_private;
return dev_priv->gpu_error.stop_rings & intel_ring_flag(ring);
351,6 → 362,7
flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
flags |= PIPE_CONTROL_MEDIA_STATE_CLEAR;
/*
* TLB invalidate requires a post-sync write.
*/
357,6 → 369,8
flags |= PIPE_CONTROL_QW_WRITE;
flags |= PIPE_CONTROL_GLOBAL_GTT_IVB;
 
flags |= PIPE_CONTROL_STALL_AT_SCOREBOARD;
 
/* Workaround: we must issue a pipe_control with CS-stall bit
* set before a pipe_control command that has the state cache
* invalidate bit set. */
433,7 → 447,14
return ret;
}
 
return gen8_emit_pipe_control(ring, flags, scratch_addr);
ret = gen8_emit_pipe_control(ring, flags, scratch_addr);
if (ret)
return ret;
 
if (!invalidate_domains && flush_domains)
return gen7_ring_fbc_flush(ring, FBC_REND_NUKE);
 
return 0;
}
 
static void ring_write_tail(struct intel_engine_cs *ring,
476,8 → 497,13
 
if (!IS_GEN2(ring->dev)) {
I915_WRITE_MODE(ring, _MASKED_BIT_ENABLE(STOP_RING));
if (wait_for_atomic((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000)) {
if (wait_for((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000)) {
DRM_ERROR("%s :timed out trying to stop ring\n", ring->name);
/* Sometimes we observe that the idle flag is not
* set even though the ring is empty. So double
* check before giving up.
*/
if (I915_READ_HEAD(ring) != I915_READ_TAIL(ring))
return false;
}
}
540,6 → 566,14
* also enforces ordering), otherwise the hw might lose the new ring
* register values. */
I915_WRITE_START(ring, i915_gem_obj_ggtt_offset(obj));
 
/* WaClearRingBufHeadRegAtInit:ctg,elk */
if (I915_READ_HEAD(ring))
DRM_DEBUG("%s initialization failed [head=%08x], fudging\n",
ring->name, I915_READ_HEAD(ring));
I915_WRITE_HEAD(ring, 0);
(void)I915_READ_HEAD(ring);
 
I915_WRITE_CTL(ring,
((ringbuf->size - PAGE_SIZE) & RING_NR_PAGES)
| RING_VALID);
558,10 → 592,9
goto out;
}
 
 
ringbuf->head = I915_READ_HEAD(ring);
ringbuf->tail = I915_READ_TAIL(ring) & TAIL_ADDR;
ringbuf->space = ring_space(ringbuf);
ringbuf->space = intel_ring_space(ringbuf);
ringbuf->last_retired_head = -1;
 
memset(&ring->hangcheck, 0, sizeof(ring->hangcheck));
572,9 → 605,26
return ret;
}
 
static int
init_pipe_control(struct intel_engine_cs *ring)
void
intel_fini_pipe_control(struct intel_engine_cs *ring)
{
struct drm_device *dev = ring->dev;
 
if (ring->scratch.obj == NULL)
return;
 
if (INTEL_INFO(dev)->gen >= 5) {
kunmap(sg_page(ring->scratch.obj->pages->sgl));
i915_gem_object_ggtt_unpin(ring->scratch.obj);
}
 
drm_gem_object_unreference(&ring->scratch.obj->base);
ring->scratch.obj = NULL;
}
 
int
intel_init_pipe_control(struct intel_engine_cs *ring)
{
int ret;
 
if (ring->scratch.obj)
596,7 → 646,7
goto err_unref;
 
ring->scratch.gtt_offset = i915_gem_obj_ggtt_offset(ring->scratch.obj);
ring->scratch.cpu_page = (void*)MapIoMem((addr_t)sg_page(ring->scratch.obj->pages->sgl),4096, PG_SW|0x100);
ring->scratch.cpu_page = kmap(sg_page(ring->scratch.obj->pages->sgl));
if (ring->scratch.cpu_page == NULL) {
ret = -ENOMEM;
goto err_unpin;
614,6 → 664,170
return ret;
}
 
static int intel_ring_workarounds_emit(struct intel_engine_cs *ring,
struct intel_context *ctx)
{
int ret, i;
struct drm_device *dev = ring->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct i915_workarounds *w = &dev_priv->workarounds;
 
if (WARN_ON(w->count == 0))
return 0;
 
ring->gpu_caches_dirty = true;
ret = intel_ring_flush_all_caches(ring);
if (ret)
return ret;
 
ret = intel_ring_begin(ring, (w->count * 2 + 2));
if (ret)
return ret;
 
intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(w->count));
for (i = 0; i < w->count; i++) {
intel_ring_emit(ring, w->reg[i].addr);
intel_ring_emit(ring, w->reg[i].value);
}
intel_ring_emit(ring, MI_NOOP);
 
intel_ring_advance(ring);
 
ring->gpu_caches_dirty = true;
ret = intel_ring_flush_all_caches(ring);
if (ret)
return ret;
 
DRM_DEBUG_DRIVER("Number of Workarounds emitted: %d\n", w->count);
 
return 0;
}
 
static int wa_add(struct drm_i915_private *dev_priv,
const u32 addr, const u32 mask, const u32 val)
{
const u32 idx = dev_priv->workarounds.count;
 
if (WARN_ON(idx >= I915_MAX_WA_REGS))
return -ENOSPC;
 
dev_priv->workarounds.reg[idx].addr = addr;
dev_priv->workarounds.reg[idx].value = val;
dev_priv->workarounds.reg[idx].mask = mask;
 
dev_priv->workarounds.count++;
 
return 0;
}
 
#define WA_REG(addr, mask, val) { \
const int r = wa_add(dev_priv, (addr), (mask), (val)); \
if (r) \
return r; \
}
 
#define WA_SET_BIT_MASKED(addr, mask) \
WA_REG(addr, (mask), _MASKED_BIT_ENABLE(mask))
 
#define WA_CLR_BIT_MASKED(addr, mask) \
WA_REG(addr, (mask), _MASKED_BIT_DISABLE(mask))
 
#define WA_SET_FIELD_MASKED(addr, mask, value) \
WA_REG(addr, mask, _MASKED_FIELD(mask, value))
 
#define WA_SET_BIT(addr, mask) WA_REG(addr, mask, I915_READ(addr) | (mask))
#define WA_CLR_BIT(addr, mask) WA_REG(addr, mask, I915_READ(addr) & ~(mask))
 
#define WA_WRITE(addr, val) WA_REG(addr, 0xffffffff, val)
 
static int bdw_init_workarounds(struct intel_engine_cs *ring)
{
struct drm_device *dev = ring->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
 
/* WaDisablePartialInstShootdown:bdw */
/* WaDisableThreadStallDopClockGating:bdw (pre-production) */
WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE |
STALL_DOP_GATING_DISABLE);
 
/* WaDisableDopClockGating:bdw */
WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2,
DOP_CLOCK_GATING_DISABLE);
 
WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
GEN8_SAMPLER_POWER_BYPASS_DIS);
 
/* Use Force Non-Coherent whenever executing a 3D context. This is a
* workaround for for a possible hang in the unlikely event a TLB
* invalidation occurs during a PSD flush.
*/
/* WaDisableFenceDestinationToSLM:bdw (GT3 pre-production) */
WA_SET_BIT_MASKED(HDC_CHICKEN0,
HDC_FORCE_NON_COHERENT |
(IS_BDW_GT3(dev) ? HDC_FENCE_DEST_SLM_DISABLE : 0));
 
/* Wa4x4STCOptimizationDisable:bdw */
WA_SET_BIT_MASKED(CACHE_MODE_1,
GEN8_4x4_STC_OPTIMIZATION_DISABLE);
 
/*
* BSpec recommends 8x4 when MSAA is used,
* however in practice 16x4 seems fastest.
*
* Note that PS/WM thread counts depend on the WIZ hashing
* disable bit, which we don't touch here, but it's good
* to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
*/
WA_SET_FIELD_MASKED(GEN7_GT_MODE,
GEN6_WIZ_HASHING_MASK,
GEN6_WIZ_HASHING_16x4);
 
return 0;
}
 
static int chv_init_workarounds(struct intel_engine_cs *ring)
{
struct drm_device *dev = ring->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
 
/* WaDisablePartialInstShootdown:chv */
/* WaDisableThreadStallDopClockGating:chv */
WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE |
STALL_DOP_GATING_DISABLE);
 
/* Use Force Non-Coherent whenever executing a 3D context. This is a
* workaround for a possible hang in the unlikely event a TLB
* invalidation occurs during a PSD flush.
*/
/* WaForceEnableNonCoherent:chv */
/* WaHdcDisableFetchWhenMasked:chv */
WA_SET_BIT_MASKED(HDC_CHICKEN0,
HDC_FORCE_NON_COHERENT |
HDC_DONOT_FETCH_MEM_WHEN_MASKED);
 
return 0;
}
 
int init_workarounds_ring(struct intel_engine_cs *ring)
{
struct drm_device *dev = ring->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
 
WARN_ON(ring->id != RCS);
 
dev_priv->workarounds.count = 0;
 
if (IS_BROADWELL(dev))
return bdw_init_workarounds(ring);
 
if (IS_CHERRYVIEW(dev))
return chv_init_workarounds(ring);
 
return 0;
}
 
static int init_render_ring(struct intel_engine_cs *ring)
{
struct drm_device *dev = ring->dev;
632,7 → 846,7
*
* WaDisableAsyncFlipPerfMode:snb,ivb,hsw,vlv,bdw,chv
*/
if (INTEL_INFO(dev)->gen >= 6)
if (INTEL_INFO(dev)->gen >= 6 && INTEL_INFO(dev)->gen < 9)
I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(ASYNC_FLIP_PERF_DISABLE));
 
/* Required for the hardware to program scanline values for waiting */
648,7 → 862,7
_MASKED_BIT_ENABLE(GFX_REPLAY_MODE));
 
if (INTEL_INFO(dev)->gen >= 5) {
ret = init_pipe_control(ring);
ret = intel_init_pipe_control(ring);
if (ret)
return ret;
}
669,7 → 883,7
if (HAS_L3_DPF(dev))
I915_WRITE_IMR(ring, ~GT_PARITY_ERROR(dev));
 
return ret;
return init_workarounds_ring(ring);
}
 
static void render_ring_cleanup(struct intel_engine_cs *ring)
683,18 → 897,9
dev_priv->semaphore_obj = NULL;
}
 
if (ring->scratch.obj == NULL)
return;
 
if (INTEL_INFO(dev)->gen >= 5) {
// kunmap(sg_page(ring->scratch.obj->pages->sgl));
i915_gem_object_ggtt_unpin(ring->scratch.obj);
intel_fini_pipe_control(ring);
}
 
drm_gem_object_unreference(&ring->scratch.obj->base);
ring->scratch.obj = NULL;
}
 
static int gen8_rcs_signal(struct intel_engine_cs *signaller,
unsigned int num_dwords)
{
1015,7 → 1220,7
struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long flags;
 
if (!dev->irq_enabled)
if (WARN_ON(!intel_irqs_enabled(dev_priv)))
return false;
 
spin_lock_irqsave(&dev_priv->irq_lock, flags);
1046,7 → 1251,7
struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long flags;
 
if (!dev->irq_enabled)
if (!intel_irqs_enabled(dev_priv))
return false;
 
spin_lock_irqsave(&dev_priv->irq_lock, flags);
1083,7 → 1288,7
struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long flags;
 
if (!dev->irq_enabled)
if (!intel_irqs_enabled(dev_priv))
return false;
 
spin_lock_irqsave(&dev_priv->irq_lock, flags);
1217,7 → 1422,7
struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long flags;
 
if (!dev->irq_enabled)
if (WARN_ON(!intel_irqs_enabled(dev_priv)))
return false;
 
spin_lock_irqsave(&dev_priv->irq_lock, flags);
1260,7 → 1465,7
struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long flags;
 
if (!dev->irq_enabled)
if (WARN_ON(!intel_irqs_enabled(dev_priv)))
return false;
 
spin_lock_irqsave(&dev_priv->irq_lock, flags);
1280,9 → 1485,6
struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long flags;
 
if (!dev->irq_enabled)
return;
 
spin_lock_irqsave(&dev_priv->irq_lock, flags);
if (--ring->irq_refcount == 0) {
I915_WRITE_IMR(ring, ~0);
1298,7 → 1500,7
struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long flags;
 
if (!dev->irq_enabled)
if (WARN_ON(!intel_irqs_enabled(dev_priv)))
return false;
 
spin_lock_irqsave(&dev_priv->irq_lock, flags);
1449,7 → 1651,7
if (obj == NULL)
return;
 
// kunmap(sg_page(obj->pages->sgl));
kunmap(sg_page(obj->pages->sgl));
i915_gem_object_ggtt_unpin(obj);
drm_gem_object_unreference(&obj->base);
ring->status_page.obj = NULL;
1497,7 → 1699,7
}
 
ring->status_page.gfx_addr = i915_gem_obj_ggtt_offset(obj);
ring->status_page.page_addr = (void*)MapIoMem((addr_t)sg_page(obj->pages->sgl),4096,PG_SW|0x100);
ring->status_page.page_addr = kmap(sg_page(obj->pages->sgl));
memset(ring->status_page.page_addr, 0, PAGE_SIZE);
 
DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n",
1523,27 → 1725,51
return 0;
}
 
static void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf)
void intel_unpin_ringbuffer_obj(struct intel_ringbuffer *ringbuf)
{
if (!ringbuf->obj)
return;
 
iounmap(ringbuf->virtual_start);
ringbuf->virtual_start = NULL;
i915_gem_object_ggtt_unpin(ringbuf->obj);
drm_gem_object_unreference(&ringbuf->obj->base);
ringbuf->obj = NULL;
}
 
static int intel_alloc_ringbuffer_obj(struct drm_device *dev,
int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev,
struct intel_ringbuffer *ringbuf)
{
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_i915_gem_object *obj;
struct drm_i915_gem_object *obj = ringbuf->obj;
int ret;
 
if (ringbuf->obj)
ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, PIN_MAPPABLE);
if (ret)
return ret;
 
ret = i915_gem_object_set_to_gtt_domain(obj, true);
if (ret) {
i915_gem_object_ggtt_unpin(obj);
return ret;
}
 
ringbuf->virtual_start = ioremap_wc(dev_priv->gtt.mappable_base +
i915_gem_obj_ggtt_offset(obj), ringbuf->size);
if (ringbuf->virtual_start == NULL) {
i915_gem_object_ggtt_unpin(obj);
return -EINVAL;
}
 
return 0;
}
 
void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf)
{
drm_gem_object_unreference(&ringbuf->obj->base);
ringbuf->obj = NULL;
}
 
int intel_alloc_ringbuffer_obj(struct drm_device *dev,
struct intel_ringbuffer *ringbuf)
{
struct drm_i915_gem_object *obj;
 
obj = NULL;
if (!HAS_LLC(dev))
obj = i915_gem_object_create_stolen(dev, ringbuf->size);
1555,30 → 1781,9
/* mark ring buffers as read-only from GPU side by default */
obj->gt_ro = 1;
 
ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, PIN_MAPPABLE);
if (ret)
goto err_unref;
ringbuf->obj = obj;
 
ret = i915_gem_object_set_to_gtt_domain(obj, true);
if (ret)
goto err_unpin;
 
ringbuf->virtual_start =
ioremap_wc(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj),
ringbuf->size);
if (ringbuf->virtual_start == NULL) {
ret = -EINVAL;
goto err_unpin;
}
 
ringbuf->obj = obj;
return 0;
 
err_unpin:
i915_gem_object_ggtt_unpin(obj);
err_unref:
drm_gem_object_unreference(&obj->base);
return ret;
}
 
static int intel_init_ring_buffer(struct drm_device *dev,
1597,7 → 1802,9
ring->dev = dev;
INIT_LIST_HEAD(&ring->active_list);
INIT_LIST_HEAD(&ring->request_list);
INIT_LIST_HEAD(&ring->execlist_queue);
ringbuf->size = 32 * PAGE_SIZE;
ringbuf->ring = ring;
memset(ring->semaphore.sync_seqno, 0, sizeof(ring->semaphore.sync_seqno));
 
init_waitqueue_head(&ring->irq_queue);
1613,12 → 1820,23
goto error;
}
 
if (ringbuf->obj == NULL) {
ret = intel_alloc_ringbuffer_obj(dev, ringbuf);
if (ret) {
DRM_ERROR("Failed to allocate ringbuffer %s: %d\n", ring->name, ret);
DRM_ERROR("Failed to allocate ringbuffer %s: %d\n",
ring->name, ret);
goto error;
}
 
ret = intel_pin_and_map_ringbuffer_obj(dev, ringbuf);
if (ret) {
DRM_ERROR("Failed to pin and map ringbuffer %s: %d\n",
ring->name, ret);
intel_destroy_ringbuffer_obj(ringbuf);
goto error;
}
}
 
/* Workaround an erratum on the i830 which causes a hang if
* the TAIL pointer points to within the last 2 cachelines
* of the buffer.
1645,15 → 1863,19
 
void intel_cleanup_ring_buffer(struct intel_engine_cs *ring)
{
struct drm_i915_private *dev_priv = to_i915(ring->dev);
struct intel_ringbuffer *ringbuf = ring->buffer;
struct drm_i915_private *dev_priv;
struct intel_ringbuffer *ringbuf;
 
if (!intel_ring_initialized(ring))
return;
 
dev_priv = to_i915(ring->dev);
ringbuf = ring->buffer;
 
intel_stop_ring_buffer(ring);
WARN_ON(!IS_GEN2(ring->dev) && (I915_READ_MODE(ring) & MODE_IDLE) == 0);
 
intel_unpin_ringbuffer_obj(ringbuf);
intel_destroy_ringbuffer_obj(ringbuf);
ring->preallocated_lazy_request = NULL;
ring->outstanding_lazy_seqno = 0;
1680,13 → 1902,14
ringbuf->head = ringbuf->last_retired_head;
ringbuf->last_retired_head = -1;
 
ringbuf->space = ring_space(ringbuf);
ringbuf->space = intel_ring_space(ringbuf);
if (ringbuf->space >= n)
return 0;
}
 
list_for_each_entry(request, &ring->request_list, list) {
if (__ring_space(request->tail, ringbuf->tail, ringbuf->size) >= n) {
if (__intel_ring_space(request->tail, ringbuf->tail,
ringbuf->size) >= n) {
seqno = request->seqno;
break;
}
1703,7 → 1926,7
ringbuf->head = ringbuf->last_retired_head;
ringbuf->last_retired_head = -1;
 
ringbuf->space = ring_space(ringbuf);
ringbuf->space = intel_ring_space(ringbuf);
return 0;
}
 
1732,13 → 1955,12
trace_i915_ring_wait_begin(ring);
do {
ringbuf->head = I915_READ_HEAD(ring);
ringbuf->space = ring_space(ringbuf);
ringbuf->space = intel_ring_space(ringbuf);
if (ringbuf->space >= n) {
ret = 0;
break;
}
 
 
msleep(1);
 
ret = i915_gem_check_wedge(&dev_priv->gpu_error,
1773,7 → 1995,7
iowrite32(MI_NOOP, virt++);
 
ringbuf->tail = 0;
ringbuf->space = ring_space(ringbuf);
ringbuf->space = intel_ring_space(ringbuf);
 
return 0;
}
1978,9 → 2200,7
u64 offset, u32 len,
unsigned flags)
{
struct drm_i915_private *dev_priv = ring->dev->dev_private;
bool ppgtt = dev_priv->mm.aliasing_ppgtt != NULL &&
!(flags & I915_DISPATCH_SECURE);
bool ppgtt = USES_PPGTT(ring->dev) && !(flags & I915_DISPATCH_SECURE);
int ret;
 
ret = intel_ring_begin(ring, 4);
2009,8 → 2229,9
return ret;
 
intel_ring_emit(ring,
MI_BATCH_BUFFER_START | MI_BATCH_PPGTT_HSW |
(flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE_HSW));
MI_BATCH_BUFFER_START |
(flags & I915_DISPATCH_SECURE ?
0 : MI_BATCH_PPGTT_HSW | MI_BATCH_NON_SECURE_HSW));
/* bit0-7 is the length on GEN6+ */
intel_ring_emit(ring, offset);
intel_ring_advance(ring);
2045,6 → 2266,7
u32 invalidate, u32 flush)
{
struct drm_device *dev = ring->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t cmd;
int ret;
 
2075,8 → 2297,12
}
intel_ring_advance(ring);
 
if (IS_GEN7(dev) && !invalidate && flush)
if (!invalidate && flush) {
if (IS_GEN7(dev))
return gen7_ring_fbc_flush(ring, FBC_REND_CACHE_CLEAN);
else if (IS_BROADWELL(dev))
dev_priv->fbc.need_sw_cache_clean = true;
}
 
return 0;
}
2109,6 → 2335,8
dev_priv->semaphore_obj = obj;
}
}
 
ring->init_context = intel_ring_workarounds_emit;
ring->add_request = gen6_add_request;
ring->flush = gen8_render_ring_flush;
ring->irq_get = gen8_ring_get_irq;
2218,93 → 2446,6
return intel_init_ring_buffer(dev, ring);
}
 
#if 0
int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_engine_cs *ring = &dev_priv->ring[RCS];
struct intel_ringbuffer *ringbuf = ring->buffer;
int ret;
 
if (ringbuf == NULL) {
ringbuf = kzalloc(sizeof(*ringbuf), GFP_KERNEL);
if (!ringbuf)
return -ENOMEM;
ring->buffer = ringbuf;
}
 
ring->name = "render ring";
ring->id = RCS;
ring->mmio_base = RENDER_RING_BASE;
 
if (INTEL_INFO(dev)->gen >= 6) {
/* non-kms not supported on gen6+ */
ret = -ENODEV;
goto err_ringbuf;
}
 
/* Note: gem is not supported on gen5/ilk without kms (the corresponding
* gem_init ioctl returns with -ENODEV). Hence we do not need to set up
* the special gen5 functions. */
ring->add_request = i9xx_add_request;
if (INTEL_INFO(dev)->gen < 4)
ring->flush = gen2_render_ring_flush;
else
ring->flush = gen4_render_ring_flush;
ring->get_seqno = ring_get_seqno;
ring->set_seqno = ring_set_seqno;
if (IS_GEN2(dev)) {
ring->irq_get = i8xx_ring_get_irq;
ring->irq_put = i8xx_ring_put_irq;
} else {
ring->irq_get = i9xx_ring_get_irq;
ring->irq_put = i9xx_ring_put_irq;
}
ring->irq_enable_mask = I915_USER_INTERRUPT;
ring->write_tail = ring_write_tail;
if (INTEL_INFO(dev)->gen >= 4)
ring->dispatch_execbuffer = i965_dispatch_execbuffer;
else if (IS_I830(dev) || IS_845G(dev))
ring->dispatch_execbuffer = i830_dispatch_execbuffer;
else
ring->dispatch_execbuffer = i915_dispatch_execbuffer;
ring->init = init_render_ring;
ring->cleanup = render_ring_cleanup;
 
ring->dev = dev;
INIT_LIST_HEAD(&ring->active_list);
INIT_LIST_HEAD(&ring->request_list);
 
ringbuf->size = size;
ringbuf->effective_size = ringbuf->size;
if (IS_I830(ring->dev) || IS_845G(ring->dev))
ringbuf->effective_size -= 2 * CACHELINE_BYTES;
 
ringbuf->virtual_start = ioremap_wc(start, size);
if (ringbuf->virtual_start == NULL) {
DRM_ERROR("can not ioremap virtual address for"
" ring buffer\n");
ret = -ENOMEM;
goto err_ringbuf;
}
 
if (!I915_NEED_GFX_HWS(dev)) {
ret = init_phys_status_page(ring);
if (ret)
goto err_vstart;
}
 
return 0;
 
err_vstart:
iounmap(ringbuf->virtual_start);
err_ringbuf:
kfree(ringbuf);
ring->buffer = NULL;
return ret;
}
#endif
 
int intel_init_bsd_ring_buffer(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;