From patchwork Mon Mar 21 10:16:39 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Gordon X-Patchwork-Id: 8631361 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 381C8C0553 for ; Mon, 21 Mar 2016 10:17:54 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4303F20220 for ; Mon, 21 Mar 2016 10:17:53 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 4318D2021B for ; Mon, 21 Mar 2016 10:17:52 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7EFB86E293; Mon, 21 Mar 2016 10:17:45 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTP id B41E36E290 for ; Mon, 21 Mar 2016 10:16:57 +0000 (UTC) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga101.jf.intel.com with ESMTP; 21 Mar 2016 03:16:59 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,371,1455004800"; d="scan'208";a="768140193" Received: from dsgordon-linux2.isw.intel.com ([10.102.226.88]) by orsmga003.jf.intel.com with ESMTP; 21 Mar 2016 03:16:56 -0700 From: Dave Gordon To: intel-gfx@lists.freedesktop.org Date: Mon, 21 Mar 2016 10:16:39 +0000 Message-Id: <1458555400-22859-7-git-send-email-david.s.gordon@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1458555400-22859-1-git-send-email-david.s.gordon@intel.com> References: <1458555400-22859-1-git-send-email-david.s.gordon@intel.com> Organization: Intel Corporation (UK) Ltd. - Co. Reg. #1134945 - Pipers Way, Swindon SN3 1RJ Subject: [Intel-gfx] [PATCH 6/7] drm/i915/guc: (re)initialise doorbell h/w when enabling GuC submission X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP During a hibernate/resume cycle, the whole system is reset, including the GuC and the doorbell hardware. Then the system is booted up, drivers are loaded, etc -- the GuC firmware may be loaded and set running at this point. But then, the booted kernel is replaced by the hibernated image, and this resumed kernel will also try to reload the GuC firmware (which will fail). To recover, we reset the GuC and try again (which should work). But this GuC reset doesn't also reset the doorbell hardware, so it can be left in a state inconsistent with that assumed by the driver and the GuC. It would be better if the GuC reset also cleared all doorbell state, but that's not how the hardware currently works; also, the driver cannot directly reprogram the doorbell hardware (only the GuC can do that). So this patch cycles through all doorbells, assigning and releasing each in turn, so that all the doorbell hardware is left in a consistent state, no matter how it was programmed by the previously-running kernel and/or GuC firmware. Signed-off-by: Dave Gordon Cc: Arun Siluvery Cc: Alex Dai --- drivers/gpu/drm/i915/i915_guc_submission.c | 46 +++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 6b30207..ea8b8cb 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -707,6 +707,50 @@ static void guc_client_free(struct drm_device *dev, kfree(client); } +/* + * Borrow the first client to set up & tear down every doorbell + * in turn, to ensure that all doorbell h/w is (re)initialised. + */ +static void guc_init_doorbell_hw(struct intel_guc *guc) +{ + struct drm_i915_private *dev_priv = guc_to_i915(guc); + struct i915_guc_client *client = guc->execbuf_client; + struct guc_doorbell_info *doorbell; + uint16_t db_id, i; + void *base; + int ret; + + base = kmap_atomic(i915_gem_object_get_page(client->client_obj, 0)); + doorbell = base + client->doorbell_offset; + db_id = client->doorbell_id; + + for (i = 0; i < GUC_MAX_DOORBELLS; ++i) { + i915_reg_t drbreg = GEN8_DRBREGL(i); + u32 value = I915_READ(drbreg); + + ret = guc_update_doorbell_id(client, doorbell, i); + + if (((value & GUC_DOORBELL_ENABLED) && (i != db_id)) || ret) + DRM_DEBUG_DRIVER("Doorbell reg 0x%x was 0x%x, ret %d\n", + drbreg.reg, value, ret); + } + + /* Restore to original value */ + guc_update_doorbell_id(client, doorbell, db_id); + + for (i = 0; i < GUC_MAX_DOORBELLS; ++i) { + i915_reg_t drbreg = GEN8_DRBREGL(i); + u32 value = I915_READ(drbreg); + + if ((value & GUC_DOORBELL_ENABLED) && (i != db_id)) + DRM_DEBUG_DRIVER("Doorbell reg 0x%x finally 0x%x\n", + drbreg.reg, value); + + } + + kunmap_atomic(base); +} + /** * guc_client_alloc() - Allocate an i915_guc_client * @dev: drm device @@ -971,8 +1015,8 @@ int i915_guc_submission_enable(struct drm_device *dev) } guc->execbuf_client = client; - host2guc_sample_forcewake(guc, client); + guc_init_doorbell_hw(guc); return 0; }