@@ -519,6 +519,89 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine)
engine->context_unpin(engine, engine->i915->kernel_context);
}
+static void setup_phys_status_page(struct intel_engine_cs *engine)
+{
+ struct drm_i915_private *dev_priv = engine->i915;
+ u32 addr;
+
+ addr = dev_priv->status_page_dmah->busaddr;
+ if (INTEL_GEN(dev_priv) >= 4)
+ addr |= (dev_priv->status_page_dmah->busaddr >> 28) & 0xf0;
+ I915_WRITE(HWS_PGA, addr);
+}
+
+static void setup_status_page(struct intel_engine_cs *engine)
+{
+ struct drm_i915_private *dev_priv = engine->i915;
+ i915_reg_t mmio;
+
+ /* The ring status page addresses are no longer next to the rest of
+ * the ring registers as of gen7.
+ */
+ if (IS_GEN7(dev_priv)) {
+ switch (engine->id) {
+ case RCS:
+ mmio = RENDER_HWS_PGA_GEN7;
+ break;
+ case BCS:
+ mmio = BLT_HWS_PGA_GEN7;
+ break;
+ /*
+ * VCS2 actually doesn't exist on Gen7. Only shut up
+ * gcc switch check warning
+ */
+ case VCS2:
+ case VCS:
+ mmio = BSD_HWS_PGA_GEN7;
+ break;
+ case VECS:
+ mmio = VEBOX_HWS_PGA_GEN7;
+ break;
+ }
+ } else if (IS_GEN6(dev_priv)) {
+ mmio = RING_HWS_PGA_GEN6(engine->mmio_base);
+ } else {
+ /* XXX: gen8 returns to sanity */
+ mmio = RING_HWS_PGA(engine->mmio_base);
+ }
+
+ I915_WRITE(mmio, engine->status_page.ggtt_offset);
+ POSTING_READ(mmio);
+
+ /*
+ * Flush the TLB for this page
+ *
+ * FIXME: These two bits have disappeared on gen8, so a question
+ * arises: do we still need this and if so how should we go about
+ * invalidating the TLB?
+ */
+ if (IS_GEN(dev_priv, 6, 7)) {
+ i915_reg_t reg = RING_INSTPM(engine->mmio_base);
+
+ /* ring should be idle before issuing a sync flush*/
+ WARN_ON((I915_READ_MODE(engine) & MODE_IDLE) == 0);
+
+ I915_WRITE(reg,
+ _MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE |
+ INSTPM_SYNC_FLUSH));
+ if (intel_wait_for_register(dev_priv,
+ reg, INSTPM_SYNC_FLUSH, 0,
+ 1000))
+ DRM_ERROR("%s: wait for SyncFlush to complete for TLB invalidation timed out\n",
+ engine->name);
+ }
+}
+
+void intel_engine_setup_hws(struct intel_engine_cs *engine)
+{
+ struct drm_i915_private *dev_priv = engine->i915;
+
+ if (HWS_NEEDS_PHYSICAL(dev_priv))
+ setup_phys_status_page(engine);
+ else
+ setup_status_page(engine);
+}
+
u64 intel_engine_get_active_head(struct intel_engine_cs *engine)
{
struct drm_i915_private *dev_priv = engine->i915;
@@ -1220,9 +1220,25 @@ static int intel_init_workaround_bb(struct intel_engine_cs *engine)
return ret;
}
-static int gen8_init_common_ring(struct intel_engine_cs *engine)
+static void intel_engine_mask_hws(struct intel_engine_cs *engine)
{
struct drm_i915_private *dev_priv = engine->i915;
+
+ I915_WRITE(RING_HWSTAM(engine->mmio_base), 0xffffffff);
+}
+
+static void gen8_execlist_enable(struct intel_engine_cs *engine)
+{
+ struct drm_i915_private *dev_priv = engine->i915;
+
+ I915_WRITE(RING_MODE_GEN7(engine),
+ _MASKED_BIT_ENABLE(GFX_RUN_LIST_ENABLE));
+
+ DRM_DEBUG_DRIVER("Execlists enabled for %s\n", engine->name);
+}
+
+static int gen8_init_common_ring(struct intel_engine_cs *engine)
+{
struct execlist_port *port = engine->execlist_port;
unsigned int n;
bool submit;
@@ -1234,15 +1250,9 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine)
intel_engine_reset_breadcrumbs(engine);
intel_engine_init_hangcheck(engine);
-
- I915_WRITE(RING_HWSTAM(engine->mmio_base), 0xffffffff);
- I915_WRITE(RING_MODE_GEN7(engine),
- _MASKED_BIT_ENABLE(GFX_RUN_LIST_ENABLE));
- I915_WRITE(RING_HWS_PGA(engine->mmio_base),
- engine->status_page.ggtt_offset);
- POSTING_READ(RING_HWS_PGA(engine->mmio_base));
-
- DRM_DEBUG_DRIVER("Execlists enabled for %s\n", engine->name);
+ intel_engine_mask_hws(engine);
+ intel_engine_setup_hws(engine);
+ gen8_execlist_enable(engine);
/* After a GPU reset, we may have requests to replay */
clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
@@ -381,79 +381,6 @@ gen8_render_ring_flush(struct drm_i915_gem_request *req, u32 mode)
return 0;
}
-static void ring_setup_phys_status_page(struct intel_engine_cs *engine)
-{
- struct drm_i915_private *dev_priv = engine->i915;
- u32 addr;
-
- addr = dev_priv->status_page_dmah->busaddr;
- if (INTEL_GEN(dev_priv) >= 4)
- addr |= (dev_priv->status_page_dmah->busaddr >> 28) & 0xf0;
- I915_WRITE(HWS_PGA, addr);
-}
-
-static void intel_ring_setup_status_page(struct intel_engine_cs *engine)
-{
- struct drm_i915_private *dev_priv = engine->i915;
- i915_reg_t mmio;
-
- /* The ring status page addresses are no longer next to the rest of
- * the ring registers as of gen7.
- */
- if (IS_GEN7(dev_priv)) {
- switch (engine->id) {
- case RCS:
- mmio = RENDER_HWS_PGA_GEN7;
- break;
- case BCS:
- mmio = BLT_HWS_PGA_GEN7;
- break;
- /*
- * VCS2 actually doesn't exist on Gen7. Only shut up
- * gcc switch check warning
- */
- case VCS2:
- case VCS:
- mmio = BSD_HWS_PGA_GEN7;
- break;
- case VECS:
- mmio = VEBOX_HWS_PGA_GEN7;
- break;
- }
- } else if (IS_GEN6(dev_priv)) {
- mmio = RING_HWS_PGA_GEN6(engine->mmio_base);
- } else {
- /* XXX: gen8 returns to sanity */
- mmio = RING_HWS_PGA(engine->mmio_base);
- }
-
- I915_WRITE(mmio, engine->status_page.ggtt_offset);
- POSTING_READ(mmio);
-
- /*
- * Flush the TLB for this page
- *
- * FIXME: These two bits have disappeared on gen8, so a question
- * arises: do we still need this and if so how should we go about
- * invalidating the TLB?
- */
- if (IS_GEN(dev_priv, 6, 7)) {
- i915_reg_t reg = RING_INSTPM(engine->mmio_base);
-
- /* ring should be idle before issuing a sync flush*/
- WARN_ON((I915_READ_MODE(engine) & MODE_IDLE) == 0);
-
- I915_WRITE(reg,
- _MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE |
- INSTPM_SYNC_FLUSH));
- if (intel_wait_for_register(dev_priv,
- reg, INSTPM_SYNC_FLUSH, 0,
- 1000))
- DRM_ERROR("%s: wait for SyncFlush to complete for TLB invalidation timed out\n",
- engine->name);
- }
-}
-
static bool stop_ring(struct intel_engine_cs *engine)
{
struct drm_i915_private *dev_priv = engine->i915;
@@ -519,11 +446,7 @@ static int init_ring_common(struct intel_engine_cs *engine)
}
}
- if (HWS_NEEDS_PHYSICAL(dev_priv))
- ring_setup_phys_status_page(engine);
- else
- intel_ring_setup_status_page(engine);
-
+ intel_engine_setup_hws(engine);
intel_engine_reset_breadcrumbs(engine);
/* Enforce ordering by reading HEAD register back */
@@ -594,6 +594,7 @@ void intel_engine_setup_common(struct intel_engine_cs *engine);
int intel_engine_init_common(struct intel_engine_cs *engine);
int intel_engine_create_scratch(struct intel_engine_cs *engine, int size);
void intel_engine_cleanup_common(struct intel_engine_cs *engine);
+void intel_engine_setup_hws(struct intel_engine_cs *engine);
int intel_init_render_ring_buffer(struct intel_engine_cs *engine);
int intel_init_bsd_ring_buffer(struct intel_engine_cs *engine);
Similar code was duplicated in ringbuffer.c and lrc.c Lets share the code and move it to engine_cs.c While around, move execlist enabling into separate inline function, as this will make future patches simpler. Suggested-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Oscar Mateo <oscar.mateo@intel.com> --- drivers/gpu/drm/i915/intel_engine_cs.c | 83 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_lrc.c | 30 ++++++++---- drivers/gpu/drm/i915/intel_ringbuffer.c | 79 +------------------------------ drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + 4 files changed, 105 insertions(+), 88 deletions(-)