In order to avoid some complexity in trying to reconstruct the workqueues across reset, remember them instead. Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- drivers/gpu/drm/i915/i915_guc_submission.c | 79 ++++++++++++++---------------- drivers/gpu/drm/i915/intel_guc.h | 2 +- 3 files changed, 40 insertions(+), 43 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index b7f42c448a44..a10f43e3fd3c 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2430,7 +2430,7 @@ static void i915_guc_client_info(struct seq_file *m, seq_printf(m, "\tPriority %d, GuC ctx index: %u, PD offset 0x%x\n", client->priority, client->ctx_index, client->proc_desc_offset); seq_printf(m, "\tDoorbell id %d, offset: 0x%x, cookie 0x%x\n", - client->doorbell_id, client->doorbell_offset, client->cookie); + client->doorbell_id, client->doorbell_offset, client->doorbell_cookie); seq_printf(m, "\tWQ size %d, offset: 0x%x, tail %d\n", client->wq_size, client->wq_offset, client->wq_tail); diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 4462112725ef..a42c27ec4bb1 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -247,18 +247,11 @@ static int guc_update_doorbell_id(struct intel_guc *guc, /* Activate the new doorbell */ __set_bit(new_id, doorbell_bitmap); - doorbell->cookie = 0; doorbell->db_status = GUC_DOORBELL_ENABLED; + doorbell->cookie = client->doorbell_cookie; return host2guc_allocate_doorbell(guc, client); } -static int guc_init_doorbell(struct intel_guc *guc, - struct i915_guc_client *client, - uint16_t db_id) -{ - return guc_update_doorbell_id(guc, client, db_id); -} - static void guc_disable_doorbell(struct intel_guc *guc, struct i915_guc_client *client) { @@ -567,11 +560,11 @@ static int guc_ring_doorbell(struct i915_guc_client *gc) /* current cookie */ db_cmp.db_status = GUC_DOORBELL_ENABLED; - db_cmp.cookie = gc->cookie; + db_cmp.cookie = gc->doorbell_cookie; /* cookie to be updated */ db_exc.db_status = GUC_DOORBELL_ENABLED; - db_exc.cookie = gc->cookie + 1; + db_exc.cookie = gc->doorbell_cookie + 1; if (db_exc.cookie == 0) db_exc.cookie = 1; @@ -586,7 +579,7 @@ static int guc_ring_doorbell(struct i915_guc_client *gc) /* if the exchange was successfully executed */ if (db_ret.value_qw == db_cmp.value_qw) { /* db was successfully rung */ - gc->cookie = db_exc.cookie; + gc->doorbell_cookie = db_exc.cookie; ret = 0; break; } @@ -779,8 +772,7 @@ static void guc_init_doorbell_hw(struct intel_guc *guc) uint16_t db_id; int i, err; - /* Save client's original doorbell selection */ - db_id = client->doorbell_id; + guc_disable_doorbell(guc, client); for (i = 0; i < GUC_MAX_DOORBELLS; ++i) { /* Skip if doorbell is OK */ @@ -793,7 +785,9 @@ static void guc_init_doorbell_hw(struct intel_guc *guc) i, err); } - /* Restore to original value */ + db_id = select_doorbell_register(guc, client->priority); + WARN_ON(db_id == GUC_INVALID_DOORBELL_ID); + err = guc_update_doorbell_id(guc, client, db_id); if (err) DRM_WARN("Failed to restore doorbell to %d, err %d\n", @@ -883,8 +877,13 @@ guc_client_alloc(struct drm_i915_private *dev_priv, guc_proc_desc_init(guc, client); guc_ctx_desc_init(guc, client); - if (guc_init_doorbell(guc, client, db_id)) - goto err; + + /* For runtime client allocation we need to enable the doorbell. Not + * required yet for the static execbuf_client as this special kernel + * client is enabled from i915_guc_submission_enable(). + * + * guc_update_doorbell_id(guc, client, db_id); + */ DRM_DEBUG_DRIVER("new priority %u client %p for engine(s) 0x%x: ctx_index %u\n", priority, client, client->engines, client->ctx_index); @@ -1504,42 +1503,43 @@ int i915_guc_submission_init(struct drm_i915_private *dev_priv) guc_log_create(guc); guc_addon_create(guc); + guc->execbuf_client = guc_client_alloc(dev_priv, + INTEL_INFO(dev_priv)->ring_mask, + GUC_CTX_PRIORITY_KMD_NORMAL, + dev_priv->kernel_context); + if (!guc->execbuf_client) { + DRM_ERROR("Failed to create GuC client for execbuf!\n"); + goto err; + } + return 0; + +err: + i915_guc_submission_fini(dev_priv); + return -ENOMEM; } int i915_guc_submission_enable(struct drm_i915_private *dev_priv) { struct intel_guc *guc = &dev_priv->guc; - struct drm_i915_gem_request *request; - struct i915_guc_client *client; + struct i915_guc_client *client = guc->execbuf_client; struct intel_engine_cs *engine; enum intel_engine_id id; - /* client for execbuf submission */ - client = guc_client_alloc(dev_priv, - INTEL_INFO(dev_priv)->ring_mask, - GUC_CTX_PRIORITY_KMD_NORMAL, - dev_priv->kernel_context); - if (!client) { - DRM_ERROR("Failed to create normal GuC client!\n"); - return -ENOMEM; - } - - guc->execbuf_client = client; host2guc_sample_forcewake(guc, client); guc_init_doorbell_hw(guc); /* Take over from manual control of ELSP (execlists) */ for_each_engine(engine, dev_priv, id) { + struct drm_i915_gem_request *rq; + engine->submit_request = i915_guc_submit; engine->schedule = NULL; /* Replay the current set of previously submitted requests */ - list_for_each_entry(request, - &engine->timeline->requests, link) { + list_for_each_entry(rq, &engine->timeline->requests, link) { client->wq_rsvd += sizeof(struct guc_wq_item); - if (i915_sw_fence_done(&request->submit)) - i915_guc_submit(request); + i915_guc_submit(rq); } } @@ -1548,21 +1548,18 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv) void i915_guc_submission_disable(struct drm_i915_private *dev_priv) { - struct intel_guc *guc = &dev_priv->guc; - - if (!guc->execbuf_client) - return; - /* Revert back to manual ELSP submission */ intel_execlists_enable_submission(dev_priv); - - guc_client_free(dev_priv, guc->execbuf_client); - guc->execbuf_client = NULL; } void i915_guc_submission_fini(struct drm_i915_private *dev_priv) { struct intel_guc *guc = &dev_priv->guc; + struct i915_guc_client *gc; + + gc = fetch_and_zero(&guc->execbuf_client); + if (gc) + guc_client_free(dev_priv, gc); i915_vma_unpin_and_release(&guc->ads_vma); i915_vma_unpin_and_release(&guc->log.vma); diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h index 0053258e03d3..dc570a6d612e 100644 --- a/drivers/gpu/drm/i915/intel_guc.h +++ b/drivers/gpu/drm/i915/intel_guc.h @@ -74,7 +74,7 @@ struct i915_guc_client { uint32_t proc_desc_offset; uint32_t doorbell_offset; - uint32_t cookie; + uint32_t doorbell_cookie; uint16_t doorbell_id; uint16_t padding[3]; /* Maintain alignment */ -- 2.10.2 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx