drm/i915: Define an engine class enum for the uABI
[sfrench/cifs-2.6.git] / drivers / gpu / drm / i915 / intel_engine_cs.c
index fedb839dff6111768dd14dfd0a917191db1dfee4..bded9c40dbd53313024d629e23d37f16a87cf757 100644 (file)
@@ -50,6 +50,8 @@ struct engine_class_info {
        const char *name;
        int (*init_legacy)(struct intel_engine_cs *engine);
        int (*init_execlists)(struct intel_engine_cs *engine);
+
+       u8 uabi_class;
 };
 
 static const struct engine_class_info intel_engine_classes[] = {
@@ -57,21 +59,25 @@ static const struct engine_class_info intel_engine_classes[] = {
                .name = "rcs",
                .init_execlists = logical_render_ring_init,
                .init_legacy = intel_init_render_ring_buffer,
+               .uabi_class = I915_ENGINE_CLASS_RENDER,
        },
        [COPY_ENGINE_CLASS] = {
                .name = "bcs",
                .init_execlists = logical_xcs_ring_init,
                .init_legacy = intel_init_blt_ring_buffer,
+               .uabi_class = I915_ENGINE_CLASS_COPY,
        },
        [VIDEO_DECODE_CLASS] = {
                .name = "vcs",
                .init_execlists = logical_xcs_ring_init,
                .init_legacy = intel_init_bsd_ring_buffer,
+               .uabi_class = I915_ENGINE_CLASS_VIDEO,
        },
        [VIDEO_ENHANCEMENT_CLASS] = {
                .name = "vecs",
                .init_execlists = logical_xcs_ring_init,
                .init_legacy = intel_init_vebox_ring_buffer,
+               .uabi_class = I915_ENGINE_CLASS_VIDEO_ENHANCE,
        },
 };
 
@@ -213,13 +219,15 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
        WARN_ON(snprintf(engine->name, sizeof(engine->name), "%s%u",
                         class_info->name, info->instance) >=
                sizeof(engine->name));
-       engine->uabi_id = info->uabi_id;
        engine->hw_id = engine->guc_id = info->hw_id;
        engine->mmio_base = info->mmio_base;
        engine->irq_shift = info->irq_shift;
        engine->class = info->class;
        engine->instance = info->instance;
 
+       engine->uabi_id = info->uabi_id;
+       engine->uabi_class = class_info->uabi_class;
+
        engine->context_size = __intel_engine_context_size(dev_priv,
                                                           engine->class);
        if (WARN_ON(engine->context_size > BIT(20)))
@@ -620,7 +628,7 @@ int intel_engine_init_common(struct intel_engine_cs *engine)
         * Similarly the preempt context must always be available so that
         * we can interrupt the engine at any time.
         */
-       if (INTEL_INFO(engine->i915)->has_logical_ring_preemption) {
+       if (HAS_LOGICAL_RING_PREEMPTION(engine->i915)) {
                ring = engine->context_pin(engine,
                                           engine->i915->preempt_context);
                if (IS_ERR(ring)) {
@@ -651,7 +659,7 @@ err_rs_fini:
 err_breadcrumbs:
        intel_engine_fini_breadcrumbs(engine);
 err_unpin_preempt:
-       if (INTEL_INFO(engine->i915)->has_logical_ring_preemption)
+       if (HAS_LOGICAL_RING_PREEMPTION(engine->i915))
                engine->context_unpin(engine, engine->i915->preempt_context);
 err_unpin_kernel:
        engine->context_unpin(engine, engine->i915->kernel_context);
@@ -679,7 +687,7 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine)
        intel_engine_cleanup_cmd_parser(engine);
        i915_gem_batch_pool_fini(&engine->batch_pool);
 
-       if (INTEL_INFO(engine->i915)->has_logical_ring_preemption)
+       if (HAS_LOGICAL_RING_PREEMPTION(engine->i915))
                engine->context_unpin(engine, engine->i915->preempt_context);
        engine->context_unpin(engine, engine->i915->kernel_context);
 }
@@ -1320,6 +1328,9 @@ static int cnl_init_workarounds(struct intel_engine_cs *engine)
        WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1, GEN9_PREEMPT_GPGPU_LEVEL_MASK,
                            GEN9_PREEMPT_GPGPU_COMMAND_LEVEL);
 
+       /* ReadHitWriteOnlyDisable: cnl */
+       WA_SET_BIT_MASKED(SLICE_UNIT_LEVEL_CLKGATE, RCCUNIT_CLKGATE_DIS);
+
        /* WaEnablePreemptionGranularityControlByUMD:cnl */
        I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
                   _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
@@ -1614,12 +1625,27 @@ void intel_engines_park(struct drm_i915_private *i915)
        enum intel_engine_id id;
 
        for_each_engine(engine, i915, id) {
-               if (engine->park)
-                       engine->park(engine);
-
+               /* Flush the residual irq tasklets first. */
                intel_engine_disarm_breadcrumbs(engine);
                tasklet_kill(&engine->execlists.irq_tasklet);
 
+               /*
+                * We are committed now to parking the engines, make sure there
+                * will be no more interrupts arriving later and the engines
+                * are truly idle.
+                */
+               if (wait_for(intel_engine_is_idle(engine), 10)) {
+                       struct drm_printer p = drm_debug_printer(__func__);
+
+                       dev_err(i915->drm.dev,
+                               "%s is not idle before parking\n",
+                               engine->name);
+                       intel_engine_dump(engine, &p);
+               }
+
+               if (engine->park)
+                       engine->park(engine);
+
                i915_gem_batch_pool_fini(&engine->batch_pool);
                engine->execlists.no_priolist = false;
        }
@@ -1723,9 +1749,14 @@ void intel_engine_dump(struct intel_engine_cs *engine, struct drm_printer *m)
        drm_printf(m, "\tRING_TAIL:  0x%08x [0x%08x]\n",
                   I915_READ(RING_TAIL(engine->mmio_base)) & TAIL_ADDR,
                   rq ? rq->ring->tail : 0);
-       drm_printf(m, "\tRING_CTL:   0x%08x [%s]\n",
+       drm_printf(m, "\tRING_CTL:   0x%08x%s\n",
                   I915_READ(RING_CTL(engine->mmio_base)),
-                  I915_READ(RING_CTL(engine->mmio_base)) & (RING_WAIT | RING_WAIT_SEMAPHORE) ? "waiting" : "");
+                  I915_READ(RING_CTL(engine->mmio_base)) & (RING_WAIT | RING_WAIT_SEMAPHORE) ? " [waiting]" : "");
+       if (INTEL_GEN(engine->i915) > 2) {
+               drm_printf(m, "\tRING_MODE:  0x%08x%s\n",
+                          I915_READ(RING_MI_MODE(engine->mmio_base)),
+                          I915_READ(RING_MI_MODE(engine->mmio_base)) & (MODE_IDLE) ? " [idle]" : "");
+       }
 
        rcu_read_unlock();
 
@@ -1816,6 +1847,7 @@ void intel_engine_dump(struct intel_engine_cs *engine, struct drm_printer *m)
        }
        spin_unlock_irq(&b->rb_lock);
 
+       drm_printf(m, "Idle? %s\n", yesno(intel_engine_is_idle(engine)));
        drm_printf(m, "\n");
 }