From patchwork Wed Jun 19 21:43:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniele Ceraolo Spurio X-Patchwork-Id: 11005389 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C43E01580 for ; Wed, 19 Jun 2019 21:44:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B0C96286C6 for ; Wed, 19 Jun 2019 21:44:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A50602876B; Wed, 19 Jun 2019 21:44:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3A897286C6 for ; Wed, 19 Jun 2019 21:44:16 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D1F2D6E47F; Wed, 19 Jun 2019 21:44:15 +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 ESMTPS id D06186E47F for ; Wed, 19 Jun 2019 21:44:13 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 19 Jun 2019 14:44:13 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.63,394,1557212400"; d="scan'208";a="153925267" Received: from dceraolo-linux.fm.intel.com ([10.1.27.145]) by orsmga008.jf.intel.com with ESMTP; 19 Jun 2019 14:44:13 -0700 From: Daniele Ceraolo Spurio To: intel-gfx@lists.freedesktop.org Date: Wed, 19 Jun 2019 14:43:51 -0700 Message-Id: <20190619214351.12000-3-daniele.ceraolospurio@intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190619214351.12000-1-daniele.ceraolospurio@intel.com> References: <20190619214351.12000-1-daniele.ceraolospurio@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH 2/2] drm/i915/guc: handle GuC messages received with CTB disabled X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP There is a very small chance of triggering a log flush event when enabling or disabling CT buffers. Events triggered while CT buffers are disabled are logged in the SCRATCH_15 register using the same bits used in the CT message payload. Since our communication channel with GuC is turned off, we can save the message and handle it after we turn it back on. GuC should be idle and not generate more events in the meantime because we're not talking to it. Signed-off-by: Daniele Ceraolo Spurio Cc: Michal Wajdeczko Cc: Chris Wilson --- drivers/gpu/drm/i915/intel_guc.h | 5 +++ drivers/gpu/drm/i915/intel_uc.c | 73 ++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h index 08c906abdfa2..d6a75bc3d7f4 100644 --- a/drivers/gpu/drm/i915/intel_guc.h +++ b/drivers/gpu/drm/i915/intel_guc.h @@ -88,6 +88,9 @@ struct intel_guc { enum forcewake_domains fw_domains; } send_regs; + /* Store msg (e.g. log flush) that we see while CTBs are disabled */ + u32 mmio_msg; + /* To serialize the intel_guc_send actions */ struct mutex send_mutex; @@ -181,6 +184,8 @@ static inline bool intel_guc_is_loaded(struct intel_guc *guc) static inline int intel_guc_sanitize(struct intel_guc *guc) { intel_uc_fw_sanitize(&guc->fw); + guc->mmio_msg = 0; + return 0; } diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index c7f82c944dd6..38c87885aae3 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -218,6 +218,54 @@ static void guc_free_load_err_log(struct intel_guc *guc) i915_gem_object_put(guc->load_err_log); } +/* + * Events triggered while CT buffers are disabled are logged in the SCRATCH_15 + * register using the same bits used in the CT message payload. Since our + * communication channel with guc is turned off at this point, we can save the + * message and handle it after we turn it back on. + */ +static void guc_clear_mmio_msg(struct intel_guc *guc) +{ + intel_uncore_write(&guc_to_i915(guc)->uncore, SOFT_SCRATCH(15), 0); +} + +static void guc_get_mmio_msg(struct intel_guc *guc) +{ + u32 val; + + spin_lock_irq(&guc->irq_lock); + + val = intel_uncore_read(&guc_to_i915(guc)->uncore, SOFT_SCRATCH(15)); + guc->mmio_msg |= val & guc->msg_enabled_mask; + + /* + * clear all events, including the ones we're not currently servicing, + * to make sure we don't try to process a stale message if we enable + * handling of more events later. + */ + guc_clear_mmio_msg(guc); + + spin_unlock_irq(&guc->irq_lock); +} + +static void guc_handle_mmio_msg(struct intel_guc *guc) +{ + struct drm_i915_private *i915 = guc_to_i915(guc); + + /* we need communication to be enabled to reply to GuC */ + GEM_BUG_ON(guc->handler == intel_guc_to_host_event_handler_nop); + + if (!guc->mmio_msg) + return; + + spin_lock_irq(&i915->irq_lock); + intel_guc_to_host_process_recv_msg(guc, &guc->mmio_msg, 1); + spin_unlock_irq(&i915->irq_lock); + + guc->mmio_msg = 0; +} + + static void guc_reset_interrupts(struct intel_guc *guc) { guc->interrupts.reset(guc_to_i915(guc)); @@ -235,6 +283,7 @@ static void guc_disable_interrupts(struct intel_guc *guc) static int guc_enable_communication(struct intel_guc *guc) { + struct drm_i915_private *i915 = guc_to_i915(guc); int ret; ret = intel_guc_ct_enable(&guc->ct); @@ -244,8 +293,17 @@ static int guc_enable_communication(struct intel_guc *guc) guc->send = intel_guc_send_ct; guc->handler = intel_guc_to_host_event_handler_ct; + /* check for mmio messages received before/during the CT enable */ + guc_get_mmio_msg(guc); + guc_handle_mmio_msg(guc); + guc_enable_interrupts(guc); + /* check for CT messages received before we enabled interrupts */ + spin_lock_irq(&i915->irq_lock); + intel_guc_to_host_event_handler_ct(guc); + spin_unlock_irq(&i915->irq_lock); + DRM_INFO("GuC communication enabled\n"); return 0; @@ -261,6 +319,13 @@ static void guc_stop_communication(struct intel_guc *guc) static void guc_disable_communication(struct intel_guc *guc) { + /* + * Events generated during or after CT disable are logged by guc in + * via mmio. Make sure the register is clear before disabling CT since + * all events we cared about have already been processed via CT. + */ + guc_clear_mmio_msg(guc); + guc_disable_interrupts(guc); guc->send = intel_guc_send_nop; @@ -268,6 +333,14 @@ static void guc_disable_communication(struct intel_guc *guc) intel_guc_ct_disable(&guc->ct); + /* + * Check for messages received during/after the CT disable. We do not + * expect any messages to have arrived via CT between the interrupt + * disable and the CT disable because GuC should've been idle until we + * triggered the CT disable protocol. + */ + guc_get_mmio_msg(guc); + DRM_INFO("GuC communication disabled\n"); }