27,6 → 27,7 |
* |
*/ |
|
#include <linux/log2.h> |
#include <drm/drmP.h> |
#include "i915_drv.h" |
#include <drm/i915_drm.h> |
33,23 → 34,6 |
#include "i915_trace.h" |
#include "intel_drv.h" |
|
bool |
intel_ring_initialized(struct intel_engine_cs *ring) |
{ |
struct drm_device *dev = ring->dev; |
|
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; |
483,7 → 467,7 |
{ |
struct drm_device *dev = ring->dev; |
struct drm_i915_private *dev_priv = ring->dev->dev_private; |
u32 mmio = 0; |
i915_reg_t mmio; |
|
/* The ring status page addresses are no longer next to the rest of |
* the ring registers as of gen7. |
526,7 → 510,7 |
* invalidating the TLB? |
*/ |
if (INTEL_INFO(dev)->gen >= 6 && INTEL_INFO(dev)->gen < 8) { |
u32 reg = RING_INSTPM(ring->mmio_base); |
i915_reg_t reg = RING_INSTPM(ring->mmio_base); |
|
/* ring should be idle before issuing a sync flush*/ |
WARN_ON((I915_READ_MODE(ring) & MODE_IDLE) == 0); |
735,7 → 719,7 |
|
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_reg(ring, w->reg[i].addr); |
intel_ring_emit(ring, w->reg[i].value); |
} |
intel_ring_emit(ring, MI_NOOP); |
768,7 → 752,8 |
} |
|
static int wa_add(struct drm_i915_private *dev_priv, |
const u32 addr, const u32 mask, const u32 val) |
i915_reg_t addr, |
const u32 mask, const u32 val) |
{ |
const u32 idx = dev_priv->workarounds.count; |
|
926,17 → 911,15 |
WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, |
GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC); |
|
if ((IS_SKYLAKE(dev) && (INTEL_REVID(dev) == SKL_REVID_A0 || |
INTEL_REVID(dev) == SKL_REVID_B0)) || |
(IS_BROXTON(dev) && INTEL_REVID(dev) < BXT_REVID_B0)) { |
/* WaDisableDgMirrorFixInHalfSliceChicken5:skl,bxt */ |
if (IS_SKL_REVID(dev, 0, SKL_REVID_B0) || |
IS_BXT_REVID(dev, 0, BXT_REVID_A1)) |
WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5, |
GEN9_DG_MIRROR_FIX_ENABLE); |
} |
|
if ((IS_SKYLAKE(dev) && INTEL_REVID(dev) <= SKL_REVID_B0) || |
(IS_BROXTON(dev) && INTEL_REVID(dev) < BXT_REVID_B0)) { |
/* WaSetDisablePixMaskCammingAndRhwoInCommonSliceChicken:skl,bxt */ |
if (IS_SKL_REVID(dev, 0, SKL_REVID_B0) || |
IS_BXT_REVID(dev, 0, BXT_REVID_A1)) { |
WA_SET_BIT_MASKED(GEN7_COMMON_SLICE_CHICKEN1, |
GEN9_RHWO_OPTIMIZATION_DISABLE); |
/* |
946,12 → 929,10 |
*/ |
} |
|
if ((IS_SKYLAKE(dev) && INTEL_REVID(dev) >= SKL_REVID_C0) || |
IS_BROXTON(dev)) { |
/* WaEnableYV12BugFixInHalfSliceChicken7:skl,bxt */ |
if (IS_SKL_REVID(dev, SKL_REVID_C0, REVID_FOREVER) || IS_BROXTON(dev)) |
WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7, |
GEN9_ENABLE_YV12_BUGFIX); |
} |
|
/* Wa4x4STCOptimizationDisable:skl,bxt */ |
/* WaDisablePartialResolveInVc:skl,bxt */ |
963,24 → 944,22 |
GEN9_CCS_TLB_PREFETCH_ENABLE); |
|
/* WaDisableMaskBasedCammingInRCC:skl,bxt */ |
if ((IS_SKYLAKE(dev) && INTEL_REVID(dev) == SKL_REVID_C0) || |
(IS_BROXTON(dev) && INTEL_REVID(dev) < BXT_REVID_B0)) |
if (IS_SKL_REVID(dev, SKL_REVID_C0, SKL_REVID_C0) || |
IS_BXT_REVID(dev, 0, BXT_REVID_A1)) |
WA_SET_BIT_MASKED(SLICE_ECO_CHICKEN0, |
PIXEL_MASK_CAMMING_DISABLE); |
|
/* WaForceContextSaveRestoreNonCoherent:skl,bxt */ |
tmp = HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT; |
if ((IS_SKYLAKE(dev) && INTEL_REVID(dev) == SKL_REVID_F0) || |
(IS_BROXTON(dev) && INTEL_REVID(dev) >= BXT_REVID_B0)) |
if (IS_SKL_REVID(dev, SKL_REVID_F0, REVID_FOREVER) || |
IS_BXT_REVID(dev, BXT_REVID_B0, REVID_FOREVER)) |
tmp |= HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE; |
WA_SET_BIT_MASKED(HDC_CHICKEN0, tmp); |
|
/* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt */ |
if (IS_SKYLAKE(dev) || |
(IS_BROXTON(dev) && INTEL_REVID(dev) <= BXT_REVID_B0)) { |
if (IS_SKYLAKE(dev) || IS_BXT_REVID(dev, 0, BXT_REVID_B0)) |
WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, |
GEN8_SAMPLER_POWER_BYPASS_DIS); |
} |
|
/* WaDisableSTUnitPowerOptimization:skl,bxt */ |
WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN2, GEN8_ST_PO_DISABLE); |
1002,7 → 981,7 |
* Only consider slices where one, and only one, subslice has 7 |
* EUs |
*/ |
if (hweight8(dev_priv->info.subslice_7eu[i]) != 1) |
if (!is_power_of_2(dev_priv->info.subslice_7eu[i])) |
continue; |
|
/* |
1040,11 → 1019,7 |
if (ret) |
return ret; |
|
if (INTEL_REVID(dev) <= SKL_REVID_D0) { |
/* WaDisableHDCInvalidation:skl */ |
I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | |
BDW_DISABLE_HDC_INVALIDATION); |
|
if (IS_SKL_REVID(dev, 0, SKL_REVID_D0)) { |
/* WaDisableChickenBitTSGBarrierAckForFFSliceCS:skl */ |
I915_WRITE(FF_SLICE_CS_CHICKEN2, |
_MASKED_BIT_ENABLE(GEN9_TSG_BARRIER_ACK_DISABLE)); |
1053,23 → 1028,24 |
/* GEN8_L3SQCREG4 has a dependency with WA batch so any new changes |
* involving this register should also be added to WA batch as required. |
*/ |
if (INTEL_REVID(dev) <= SKL_REVID_E0) |
if (IS_SKL_REVID(dev, 0, SKL_REVID_E0)) |
/* WaDisableLSQCROPERFforOCL:skl */ |
I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) | |
GEN8_LQSC_RO_PERF_DIS); |
|
/* WaEnableGapsTsvCreditFix:skl */ |
if (IS_SKYLAKE(dev) && (INTEL_REVID(dev) >= SKL_REVID_C0)) { |
if (IS_SKL_REVID(dev, SKL_REVID_C0, REVID_FOREVER)) { |
I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) | |
GEN9_GAPS_TSV_CREDIT_DISABLE)); |
} |
|
/* WaDisablePowerCompilerClockGating:skl */ |
if (INTEL_REVID(dev) == SKL_REVID_B0) |
if (IS_SKL_REVID(dev, SKL_REVID_B0, SKL_REVID_B0)) |
WA_SET_BIT_MASKED(HIZ_CHICKEN, |
BDW_HIZ_POWER_COMPILER_CLOCK_GATING_DISABLE); |
|
if (INTEL_REVID(dev) <= SKL_REVID_D0) { |
/* This is tied to WaForceContextSaveRestoreNonCoherent */ |
if (IS_SKL_REVID(dev, 0, REVID_FOREVER)) { |
/* |
*Use Force Non-Coherent whenever executing a 3D context. This |
* is a workaround for a possible hang in the unlikely event |
1078,21 → 1054,23 |
/* WaForceEnableNonCoherent:skl */ |
WA_SET_BIT_MASKED(HDC_CHICKEN0, |
HDC_FORCE_NON_COHERENT); |
|
/* WaDisableHDCInvalidation:skl */ |
I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | |
BDW_DISABLE_HDC_INVALIDATION); |
} |
|
if (INTEL_REVID(dev) == SKL_REVID_C0 || |
INTEL_REVID(dev) == SKL_REVID_D0) |
/* WaBarrierPerformanceFixDisable:skl */ |
if (IS_SKL_REVID(dev, SKL_REVID_C0, SKL_REVID_D0)) |
WA_SET_BIT_MASKED(HDC_CHICKEN0, |
HDC_FENCE_DEST_SLM_DISABLE | |
HDC_BARRIER_PERFORMANCE_DISABLE); |
|
/* WaDisableSbeCacheDispatchPortSharing:skl */ |
if (INTEL_REVID(dev) <= SKL_REVID_F0) { |
if (IS_SKL_REVID(dev, 0, SKL_REVID_F0)) |
WA_SET_BIT_MASKED( |
GEN7_HALF_SLICE_CHICKEN1, |
GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE); |
} |
|
return skl_tune_iz_hashing(ring); |
} |
1109,11 → 1087,11 |
|
/* WaStoreMultiplePTEenable:bxt */ |
/* This is a requirement according to Hardware specification */ |
if (INTEL_REVID(dev) == BXT_REVID_A0) |
if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) |
I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF); |
|
/* WaSetClckGatingDisableMedia:bxt */ |
if (INTEL_REVID(dev) == BXT_REVID_A0) { |
if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) { |
I915_WRITE(GEN7_MISCCPCTL, (I915_READ(GEN7_MISCCPCTL) & |
~GEN8_DOP_CLOCK_GATE_MEDIA_ENABLE)); |
} |
1123,7 → 1101,7 |
STALL_DOP_GATING_DISABLE); |
|
/* WaDisableSbeCacheDispatchPortSharing:bxt */ |
if (INTEL_REVID(dev) <= BXT_REVID_B0) { |
if (IS_BXT_REVID(dev, 0, BXT_REVID_B0)) { |
WA_SET_BIT_MASKED( |
GEN7_HALF_SLICE_CHICKEN1, |
GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE); |
1321,11 → 1299,13 |
return ret; |
|
for_each_ring(useless, dev_priv, i) { |
u32 mbox_reg = signaller->semaphore.mbox.signal[i]; |
if (mbox_reg != GEN6_NOSYNC) { |
i915_reg_t mbox_reg = signaller->semaphore.mbox.signal[i]; |
|
if (i915_mmio_reg_valid(mbox_reg)) { |
u32 seqno = i915_gem_request_get_seqno(signaller_req); |
|
intel_ring_emit(signaller, MI_LOAD_REGISTER_IMM(1)); |
intel_ring_emit(signaller, mbox_reg); |
intel_ring_emit_reg(signaller, mbox_reg); |
intel_ring_emit(signaller, seqno); |
} |
} |
2027,6 → 2007,8 |
{ |
struct drm_i915_private *dev_priv = to_i915(dev); |
struct drm_i915_gem_object *obj = ringbuf->obj; |
/* Ring wraparound at offset 0 sometimes hangs. No idea why. */ |
unsigned flags = PIN_OFFSET_BIAS | 4096; |
int ret; |
|
ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, PIN_MAPPABLE); |
2083,10 → 2065,14 |
int ret; |
|
ring = kzalloc(sizeof(*ring), GFP_KERNEL); |
if (ring == NULL) |
if (ring == NULL) { |
DRM_DEBUG_DRIVER("Failed to allocate ringbuffer %s\n", |
engine->name); |
return ERR_PTR(-ENOMEM); |
} |
|
ring->ring = engine; |
list_add(&ring->link, &engine->buffers); |
|
ring->size = size; |
/* Workaround an erratum on the i830 which causes a hang if |
2102,8 → 2088,9 |
|
ret = intel_alloc_ringbuffer_obj(engine->dev, ring); |
if (ret) { |
DRM_ERROR("Failed to allocate ringbuffer %s: %d\n", |
DRM_DEBUG_DRIVER("Failed to allocate ringbuffer %s: %d\n", |
engine->name, ret); |
list_del(&ring->link); |
kfree(ring); |
return ERR_PTR(ret); |
} |
2115,6 → 2102,7 |
intel_ringbuffer_free(struct intel_ringbuffer *ring) |
{ |
intel_destroy_ringbuffer_obj(ring); |
list_del(&ring->link); |
kfree(ring); |
} |
|
2130,6 → 2118,7 |
INIT_LIST_HEAD(&ring->active_list); |
INIT_LIST_HEAD(&ring->request_list); |
INIT_LIST_HEAD(&ring->execlist_queue); |
INIT_LIST_HEAD(&ring->buffers); |
i915_gem_batch_pool_init(dev, &ring->batch_pool); |
memset(ring->semaphore.sync_seqno, 0, sizeof(ring->semaphore.sync_seqno)); |
|
2136,8 → 2125,10 |
init_waitqueue_head(&ring->irq_queue); |
|
ringbuf = intel_engine_create_ringbuffer(ring, 32 * PAGE_SIZE); |
if (IS_ERR(ringbuf)) |
return PTR_ERR(ringbuf); |
if (IS_ERR(ringbuf)) { |
ret = PTR_ERR(ringbuf); |
goto error; |
} |
ring->buffer = ringbuf; |
|
if (I915_NEED_GFX_HWS(dev)) { |
2166,8 → 2157,7 |
return 0; |
|
error: |
intel_ringbuffer_free(ringbuf); |
ring->buffer = NULL; |
intel_cleanup_ring_buffer(ring); |
return ret; |
} |
|
2180,6 → 2170,7 |
|
dev_priv = to_i915(ring->dev); |
|
if (ring->buffer) { |
intel_stop_ring_buffer(ring); |
WARN_ON(!IS_GEN2(ring->dev) && (I915_READ_MODE(ring) & MODE_IDLE) == 0); |
|
2186,6 → 2177,7 |
intel_unpin_ringbuffer_obj(ring->buffer); |
intel_ringbuffer_free(ring->buffer); |
ring->buffer = NULL; |
} |
|
if (ring->cleanup) |
ring->cleanup(ring); |
2199,6 → 2191,7 |
|
i915_cmd_parser_fini_ring(ring); |
i915_gem_batch_pool_fini(&ring->batch_pool); |
ring->dev = NULL; |
} |
|
static int ring_wait_for_space(struct intel_engine_cs *ring, int n) |