return ce->lrc_desc;
 }
 
-static inline void elsp_write(u64 desc, u32 __iomem *elsp)
+static inline void write_desc(struct intel_engine_execlists *execlists, u64 desc, u32 port)
 {
-       writel(upper_32_bits(desc), elsp);
-       writel(lower_32_bits(desc), elsp);
+       if (execlists->ctrl_reg) {
+               writel(lower_32_bits(desc), execlists->submit_reg + port * 2);
+               writel(upper_32_bits(desc), execlists->submit_reg + port * 2 + 1);
+       } else {
+               writel(upper_32_bits(desc), execlists->submit_reg);
+               writel(lower_32_bits(desc), execlists->submit_reg);
+       }
 }
 
 static void execlists_submit_ports(struct intel_engine_cs *engine)
 {
-       struct execlist_port *port = engine->execlists.port;
+       struct intel_engine_execlists *execlists = &engine->execlists;
+       struct execlist_port *port = execlists->port;
        unsigned int n;
 
-       for (n = execlists_num_ports(&engine->execlists); n--; ) {
+       /*
+        * ELSQ note: the submit queue is not cleared after being submitted
+        * to the HW so we need to make sure we always clean it up. This is
+        * currently ensured by the fact that we always write the same number
+        * of elsq entries, keep this in mind before changing the loop below.
+        */
+       for (n = execlists_num_ports(execlists); n--; ) {
                struct i915_request *rq;
                unsigned int count;
                u64 desc;
                        desc = 0;
                }
 
-               elsp_write(desc, engine->execlists.elsp);
+               write_desc(execlists, desc, n);
        }
-       execlists_clear_active(&engine->execlists, EXECLISTS_ACTIVE_HWACK);
+
+       /* we need to manually load the submit queue */
+       if (execlists->ctrl_reg)
+               writel(EL_CTRL_LOAD, execlists->ctrl_reg);
+
+       execlists_clear_active(execlists, EXECLISTS_ACTIVE_HWACK);
 }
 
 static bool ctx_single_port_submission(const struct i915_gem_context *ctx)
 
 static void inject_preempt_context(struct intel_engine_cs *engine)
 {
+       struct intel_engine_execlists *execlists = &engine->execlists;
        struct intel_context *ce =
                &engine->i915->preempt_context->engine[engine->id];
        unsigned int n;
 
-       GEM_BUG_ON(engine->execlists.preempt_complete_status !=
+       GEM_BUG_ON(execlists->preempt_complete_status !=
                   upper_32_bits(ce->lrc_desc));
        GEM_BUG_ON((ce->lrc_reg_state[CTX_CONTEXT_CONTROL + 1] &
                    _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT |
         * the state of the GPU is known (idle).
         */
        GEM_TRACE("%s\n", engine->name);
-       for (n = execlists_num_ports(&engine->execlists); --n; )
-               elsp_write(0, engine->execlists.elsp);
+       for (n = execlists_num_ports(execlists); --n; )
+               write_desc(execlists, 0, n);
+
+       write_desc(execlists, ce->lrc_desc, n);
+
+       /* we need to manually load the submit queue */
+       if (execlists->ctrl_reg)
+               writel(EL_CTRL_LOAD, execlists->ctrl_reg);
 
-       elsp_write(ce->lrc_desc, engine->execlists.elsp);
        execlists_clear_active(&engine->execlists, EXECLISTS_ACTIVE_HWACK);
        execlists_set_active(&engine->execlists, EXECLISTS_ACTIVE_PREEMPT);
 }
        if (ret)
                goto error;
 
-       engine->execlists.elsp =
-               engine->i915->regs + i915_mmio_reg_offset(RING_ELSP(engine));
+       if (HAS_LOGICAL_RING_ELSQ(engine->i915)) {
+               engine->execlists.submit_reg = engine->i915->regs +
+                       i915_mmio_reg_offset(RING_EXECLIST_SQ_CONTENTS(engine));
+               engine->execlists.ctrl_reg = engine->i915->regs +
+                       i915_mmio_reg_offset(RING_EXECLIST_CONTROL(engine));
+       } else {
+               engine->execlists.submit_reg = engine->i915->regs +
+                       i915_mmio_reg_offset(RING_ELSP(engine));
+       }
 
        engine->execlists.preempt_complete_status = ~0u;
        if (engine->i915->preempt_context)
        if (!engine->default_state)
                regs[CTX_CONTEXT_CONTROL + 1] |=
                        _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT);
-       if (ctx == ctx->i915->preempt_context)
+       if (ctx == ctx->i915->preempt_context && INTEL_GEN(engine->i915) < 11)
                regs[CTX_CONTEXT_CONTROL + 1] |=
                        _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT |
                                           CTX_CTRL_ENGINE_CTX_SAVE_INHIBIT);