From patchwork Fri Jan 17 22:06:52 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gustavo Sousa X-Patchwork-Id: 13944011 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D2E09C02188 for ; Fri, 17 Jan 2025 22:08:10 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5099910E31D; Fri, 17 Jan 2025 22:08:10 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="dl/BA9Mm"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.11]) by gabe.freedesktop.org (Postfix) with ESMTPS id 79B4310E31D; Fri, 17 Jan 2025 22:08:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1737151689; x=1768687689; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=05saPPw5MyAtlTDel2BwiHsZYaMPSVeCokPHjGaKNyU=; b=dl/BA9Mmw0zJfvJtD2fCVrarS6ngbmg7tvkpD0lLarts1TFylgTcY+sH eRwcMia0bwl0qW+WP5u7v2xICSaRl7uOCEQOBz1ZJuHRufwTXxvpXtXpj Y7yWraMyyR8vVU/SM9RF7SKs5vjOL6KXRiIgWlWp96bzga/yQK7KkjeI+ niUFKvimTtgXAlCBzrSfUpKoL2qa6tPn5R7/kk6TDI165po3ACUWwTjV8 reHHolMVNCSJKMahtspo2bDyQVZLVwGHxcs42QKhwo4/HVyoRWVa7yLbj Lac0fLPjX1TKvdziqVZnCjwv8iWMdlQ/HEAhMJ0uf9TVRGut2jake2wYy w==; X-CSE-ConnectionGUID: COF2MFKZTiilhHTZzfVntQ== X-CSE-MsgGUID: L/iMs0nEQSu2yBn9/KtamA== X-IronPort-AV: E=McAfee;i="6700,10204,11318"; a="48188783" X-IronPort-AV: E=Sophos;i="6.13,213,1732608000"; d="scan'208";a="48188783" Received: from orviesa003.jf.intel.com ([10.64.159.143]) by fmvoesa105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jan 2025 14:08:09 -0800 X-CSE-ConnectionGUID: fBfkRex3TCOIUcUd8AgUHQ== X-CSE-MsgGUID: 6Zu9tTSDRWea//dJR1ARsA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,199,1725346800"; d="scan'208";a="110915381" Received: from inaky-mobl1.amr.corp.intel.com (HELO gjsousa-mobl2.corp.amr.intel.com) ([10.125.109.126]) by ORVIESA003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jan 2025 14:08:09 -0800 From: Gustavo Sousa To: intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org Subject: [PATCH 1/4] drm/i915/dmc_wl: Pass offset instead of reg to range table iterator Date: Fri, 17 Jan 2025 19:06:52 -0300 Message-ID: <20250117220747.87927-2-gustavo.sousa@intel.com> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250117220747.87927-1-gustavo.sousa@intel.com> References: <20250117220747.87927-1-gustavo.sousa@intel.com> MIME-Version: 1.0 X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 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" We will add another function that checks the offset in an upcoming change. Instead of passing the reg variable to only extract the offset later, let's extract the offset before so that we do not need to repeat ourselves. Signed-off-by: Gustavo Sousa --- drivers/gpu/drm/i915/display/intel_dmc_wl.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c b/drivers/gpu/drm/i915/display/intel_dmc_wl.c index 43884740f8ea..330b43a72e08 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_wl.c +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c @@ -227,11 +227,9 @@ static void __intel_dmc_wl_take(struct intel_display *display) wl->taken = true; } -static bool intel_dmc_wl_reg_in_range(i915_reg_t reg, - const struct intel_dmc_wl_range ranges[]) +static bool intel_dmc_wl_offset_in_ranges(u32 offset, + const struct intel_dmc_wl_range ranges[]) { - u32 offset = i915_mmio_reg_offset(reg); - for (int i = 0; ranges[i].start; i++) { u32 end = ranges[i].end ?: ranges[i].start; @@ -247,6 +245,7 @@ static bool intel_dmc_wl_check_range(struct intel_display *display, u32 dc_state) { const struct intel_dmc_wl_range *ranges; + u32 offset = i915_mmio_reg_offset(reg); if (display->params.enable_dmc_wl == ENABLE_DMC_WL_ANY_REGISTER) return true; @@ -255,7 +254,7 @@ static bool intel_dmc_wl_check_range(struct intel_display *display, * Check that the offset is in one of the ranges for which * registers are powered off during DC states. */ - if (intel_dmc_wl_reg_in_range(reg, powered_off_ranges)) + if (intel_dmc_wl_offset_in_ranges(offset, powered_off_ranges)) return true; /* @@ -274,7 +273,7 @@ static bool intel_dmc_wl_check_range(struct intel_display *display, ranges = NULL; } - if (ranges && intel_dmc_wl_reg_in_range(reg, ranges)) + if (ranges && intel_dmc_wl_offset_in_ranges(offset, ranges)) return true; return false; From patchwork Fri Jan 17 22:06:53 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gustavo Sousa X-Patchwork-Id: 13944014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 283D8C0218B for ; Fri, 17 Jan 2025 22:08:14 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 99D4210EB80; Fri, 17 Jan 2025 22:08:13 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="TwnrOoZx"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.11]) by gabe.freedesktop.org (Postfix) with ESMTPS id C397D10E345; Fri, 17 Jan 2025 22:08:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1737151690; x=1768687690; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=wTNFuz1/VOk3L+aI9JJfg7jJuLxOf8eiQj4il5TQtRM=; b=TwnrOoZxRrrsnK6WRAPjWHbvIlLmHT/4U8CQEn+/4QgAeK8/TDdBS0mT zXfQIGRtoB5cUGt0YHhYEg6f/S8f+zI5GbIeoitDT+SLddjVlVwC2eSG7 v3aTxhiuvUAmMZ9LUWMY/EPsErCcXqr8sf0J6O2BzvUtyIs87mCdeuty+ Z/DYMWnP1nPAgtqM+wRug4mVsmVlj8xD/chYHbvyEbXj2xQZSsgnumHIQ T3GfzFdi3Fv27Iwzrv0iFa9kz4GhBjC943r+AQlNTdXkr2qGl35+Sb5Ux sn+B24HDdPk6QTmSAuC/uPqHMPaUc6DDFdY1G1KFzFMR+rUSOxDHmu8rs w==; X-CSE-ConnectionGUID: JJiOimHHQK2Uq+vlM6BlmA== X-CSE-MsgGUID: BBVsccgnRBSJvOP18lv7+A== X-IronPort-AV: E=McAfee;i="6700,10204,11318"; a="48188789" X-IronPort-AV: E=Sophos;i="6.13,213,1732608000"; d="scan'208";a="48188789" Received: from orviesa003.jf.intel.com ([10.64.159.143]) by fmvoesa105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jan 2025 14:08:10 -0800 X-CSE-ConnectionGUID: 3SXmVJXCRdGMCQBhzskyMw== X-CSE-MsgGUID: g6ZeH0qXR4CpUrfaW30L/Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,199,1725346800"; d="scan'208";a="110915383" Received: from inaky-mobl1.amr.corp.intel.com (HELO gjsousa-mobl2.corp.amr.intel.com) ([10.125.109.126]) by ORVIESA003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jan 2025 14:08:10 -0800 From: Gustavo Sousa To: intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org Subject: [PATCH 2/4] drm/i915/dmc_wl: Add debugfs for untracked offsets Date: Fri, 17 Jan 2025 19:06:53 -0300 Message-ID: <20250117220747.87927-3-gustavo.sousa@intel.com> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250117220747.87927-1-gustavo.sousa@intel.com> References: <20250117220747.87927-1-gustavo.sousa@intel.com> MIME-Version: 1.0 X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 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" The DMC wakelock code needs to keep track of register offsets that need the wakelock for proper access. If one of the necessary offsets are missed, then the failure in asserting the wakelock is very likely to cause problems down the road. A miss could happen for at least two different reasons: - We might have forgotten to add the offset (or range) to the relevant tables tracked by the driver in the first place. - Or updates to either the DMC firmware or the display IP that require new offsets to be tracked and we fail to realize that. To help capture these cases, let's introduce a debugfs interface for the DMC wakelock. In this part, we export a buffer containing offsets of registers that were considered not needing the wakelock by our driver. In an upcoming change we will also allow defining an extra set of offset ranges to be tracked by our driver. Signed-off-by: Gustavo Sousa --- drivers/gpu/drm/i915/Makefile | 1 + .../drm/i915/display/intel_display_debugfs.c | 2 + drivers/gpu/drm/i915/display/intel_dmc_wl.c | 5 +- drivers/gpu/drm/i915/display/intel_dmc_wl.h | 2 + .../drm/i915/display/intel_dmc_wl_debugfs.c | 251 ++++++++++++++++++ .../drm/i915/display/intel_dmc_wl_debugfs.h | 29 ++ drivers/gpu/drm/xe/Makefile | 1 + 7 files changed, 290 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/i915/display/intel_dmc_wl_debugfs.c create mode 100644 drivers/gpu/drm/i915/display/intel_dmc_wl_debugfs.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 3dda9f0eda82..ac1ab79de9c8 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -251,6 +251,7 @@ i915-y += \ display/intel_display_wa.o \ display/intel_dmc.o \ display/intel_dmc_wl.o \ + display/intel_dmc_wl_debugfs.o \ display/intel_dpio_phy.o \ display/intel_dpll.o \ display/intel_dpll_mgr.o \ diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index f1d76484025a..b032535f4830 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -26,6 +26,7 @@ #include "intel_display_power_well.h" #include "intel_display_types.h" #include "intel_dmc.h" +#include "intel_dmc_wl_debugfs.h" #include "intel_dp.h" #include "intel_dp_link_training.h" #include "intel_dp_mst.h" @@ -883,6 +884,7 @@ void intel_display_debugfs_register(struct drm_i915_private *i915) intel_bios_debugfs_register(display); intel_cdclk_debugfs_register(display); + intel_dmc_wl_debugfs_register(display); intel_dmc_debugfs_register(display); intel_dp_test_debugfs_register(display); intel_fbc_debugfs_register(display); diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c b/drivers/gpu/drm/i915/display/intel_dmc_wl.c index 330b43a72e08..3686d4e90167 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_wl.c +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c @@ -338,6 +338,7 @@ void intel_dmc_wl_init(struct intel_display *display) spin_lock_init(&wl->lock); refcount_set(&wl->refcount, display->params.enable_dmc_wl == ENABLE_DMC_WL_ALWAYS_LOCKED ? 1 : 0); + intel_dmc_wl_debugfs_init(display); } /* Must only be called as part of enabling dynamic DC states. */ @@ -444,8 +445,10 @@ void intel_dmc_wl_get(struct intel_display *display, i915_reg_t reg) spin_lock_irqsave(&wl->lock, flags); if (i915_mmio_reg_valid(reg) && - !intel_dmc_wl_check_range(display, reg, wl->dc_state)) + !intel_dmc_wl_check_range(display, reg, wl->dc_state)) { + intel_dmc_wl_debugfs_log_untracked(display, i915_mmio_reg_offset(reg)); goto out_unlock; + } if (!wl->enabled) { if (!refcount_inc_not_zero(&wl->refcount)) diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.h b/drivers/gpu/drm/i915/display/intel_dmc_wl.h index 5488fbdf29b8..d11b0ab50b3c 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_wl.h +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.h @@ -11,6 +11,7 @@ #include #include "i915_reg_defs.h" +#include "intel_dmc_wl_debugfs.h" struct intel_display; @@ -27,6 +28,7 @@ struct intel_dmc_wl { */ u32 dc_state; struct delayed_work work; + struct intel_dmc_wl_dbg dbg; }; void intel_dmc_wl_init(struct intel_display *display); diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl_debugfs.c b/drivers/gpu/drm/i915/display/intel_dmc_wl_debugfs.c new file mode 100644 index 000000000000..41e59d775fe5 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl_debugfs.c @@ -0,0 +1,251 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright (C) 2025 Intel Corporation + */ + +#include + +#include +#include +#include + +#include "intel_display_core.h" +#include "intel_dmc_wl_debugfs.h" + +#define DEBUGFS_UNTRACKED_BUFFER_SIZE_MAX 65536 + +/* + * DOC: DMC wakelock debugfs + * + * The DMC wakelock code needs to keep track of register offsets that need the + * wakelock for proper access. If one of the necessary offsets are missed, then + * the failure in asserting the wakelock is very likely to cause problems down + * the road. + * + * A miss could happen for at least two different reasons: + * + * - We might have forgotten to add the offset (or range) to the relevant + * tables tracked by the driver in the first place. + * + * - Or updates to either the DMC firmware or the display IP that require new + * offsets to be tracked and we fail to realize that. + * + * To help capture these cases, we provide the intel_dmc_wl/ debugfs directory, + * which exports a buffer of untracked register offsets. + * + * Untracked offsets + * ----------------- + * + * This is a buffer that records every register offset that went through the + * DMC wakelock check and was deemed not needing the wakelock for MMIO access. + * + * To activate the logging of offsets into such a buffer, one can do:: + * + * # echo -1 > /sys/kernel/debug/dri/(...)/intel_dmc_wl/untracked_size + * + * This will create a buffer with the maximum number of entries allowed + * (DEBUGFS_UNTRACKED_BUFFER_SIZE_MAX). A positive value can be used instead to + * define a different size: + * + * # echo 1024 > /sys/kernel/debug/dri/(...)/intel_dmc_wl/untracked_size + * + * Every write to untracked_size will cause the buffer to be reset. + * + * It is also possible to read untracked_size in order to get the current + * value. + * + * After enabled, the buffer starts getting filled with offsets as MMIOs are + * performed by the driver. + * + * In order to view the content of the buffer, one can do:: + * + * # cat /sys/kernel/debug/dri/(...)/intel_dmc_wl/untracked + * 0x000c4000 + * 0x0016fe50 + * 0x000c7200 + * 0x000c7204 + * 0x00045230 + * 0x00046440 + * 0x00045234 + * 0x0016fa48 + * 0x0016fa40 + * 0x0016fa5c + * (...) + * + * The order of those offsets does not reflect the order the checks were done + * (some recently seen offsets are skipped to save space). + * + * Once done with it, the logging can be disabled with:: + * + * # echo 0 > /sys/kernel/debug/dri/(...)/intel_dmc_wl/untracked_size + */ + +static int untracked_size_get(void *data, u64 *val) +{ + struct intel_display *display = data; + struct intel_dmc_wl_dbg *dbg = &display->wl.dbg; + unsigned long flags; + + spin_lock_irqsave(&dbg->lock, flags); + *val = dbg->untracked.size; + spin_unlock_irqrestore(&dbg->lock, flags); + + return 0; +} + +static int untracked_size_set(void *data, u64 val) +{ + struct intel_display *display = data; + struct intel_dmc_wl_dbg *dbg = &display->wl.dbg; + s64 new_size; + u32 *old_offsets; + u32 *new_offsets; + unsigned long flags; + + new_size = (s64)val; + + if (new_size == -1) { + new_size = DEBUGFS_UNTRACKED_BUFFER_SIZE_MAX; + } else if (new_size < 0) { + drm_err(display->drm, + "%lld is invalid for untracked_size, the only negative value allowed is -1\n", + new_size); + return -EINVAL; + } else if (new_size > DEBUGFS_UNTRACKED_BUFFER_SIZE_MAX) { + drm_err(display->drm, + "%lld too big for untracked_size, maximum allowed value is %d\n", + new_size, + DEBUGFS_UNTRACKED_BUFFER_SIZE_MAX); + return -EINVAL; + } + + if (new_size == 0) { + new_offsets = NULL; + } else { + new_offsets = drmm_kmalloc_array(display->drm, new_size, sizeof(*new_offsets), + GFP_KERNEL); + + if (!new_offsets) + return -ENOMEM; + } + + spin_lock_irqsave(&dbg->lock, flags); + old_offsets = dbg->untracked.offsets; + dbg->untracked.offsets = new_offsets; + dbg->untracked.size = new_size; + dbg->untracked.head = 0; + dbg->untracked.len = 0; + dbg->untracked.overflow = false; + spin_unlock_irqrestore(&dbg->lock, flags); + + if (old_offsets) + drmm_kfree(display->drm, old_offsets); + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE_SIGNED(untracked_size_fops, + untracked_size_get, + untracked_size_set, + "%lld\n"); + +static int untracked_show(struct seq_file *m, void *data) +{ + struct intel_display *display = m->private; + struct intel_dmc_wl_dbg *dbg = &display->wl.dbg; + unsigned long flags; + size_t remaining; + size_t i; + + spin_lock_irqsave(&dbg->lock, flags); + + remaining = dbg->untracked.len; + i = dbg->untracked.head; + + while (remaining--) { + if (i == 0) + i = dbg->untracked.size; + + seq_printf(m, "0x%08x\n", dbg->untracked.offsets[--i]); + } + + spin_unlock_irqrestore(&dbg->lock, flags); + + return 0; +} + +DEFINE_SHOW_ATTRIBUTE(untracked); + +void intel_dmc_wl_debugfs_init(struct intel_display *display) +{ + struct intel_dmc_wl_dbg *dbg = &display->wl.dbg; + + spin_lock_init(&dbg->lock); +} + +void intel_dmc_wl_debugfs_register(struct intel_display *display) +{ + struct dentry *dir; + + if (!HAS_DMC_WAKELOCK(display)) + return; + + dir = debugfs_create_dir("intel_dmc_wl", display->drm->debugfs_root); + if (IS_ERR(dir)) + return; + + debugfs_create_file("untracked_size", 0644, dir, display, + &untracked_size_fops); + debugfs_create_file("untracked", 0644, dir, display, + &untracked_fops); +} + +static bool untracked_has_recent_offset(struct intel_display *display, u32 offset) +{ + struct intel_dmc_wl_dbg *dbg = &display->wl.dbg; + int look_back = 32; + size_t i; + + if (look_back > dbg->untracked.len) + look_back = dbg->untracked.len; + + i = dbg->untracked.head; + + while (look_back--) { + if (i == 0) + i = dbg->untracked.size; + + if (dbg->untracked.offsets[--i] == offset) + return true; + } + + return false; +} + +void intel_dmc_wl_debugfs_log_untracked(struct intel_display *display, u32 offset) +{ + struct intel_dmc_wl_dbg *dbg = &display->wl.dbg; + unsigned long flags; + + spin_lock_irqsave(&dbg->lock, flags); + + if (!dbg->untracked.size) + goto out_unlock; + + /* Save some space by not repeating recent offsets. */ + if (untracked_has_recent_offset(display, offset)) + goto out_unlock; + + dbg->untracked.offsets[dbg->untracked.head] = offset; + dbg->untracked.head = (dbg->untracked.head + 1) % dbg->untracked.size; + if (dbg->untracked.len < dbg->untracked.size) + dbg->untracked.len++; + + if (dbg->untracked.len == dbg->untracked.size && !dbg->untracked.overflow) { + dbg->untracked.overflow = true; + drm_warn(display->drm, "Overflow detected in DMC wakelock debugfs untracked offsets\n"); + } + +out_unlock: + spin_unlock_irqrestore(&dbg->lock, flags); +} diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl_debugfs.h b/drivers/gpu/drm/i915/display/intel_dmc_wl_debugfs.h new file mode 100644 index 000000000000..9437c324966f --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl_debugfs.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright (C) 2025 Intel Corporation + */ + +#ifndef __INTEL_DMC_WL_DEBUGFS_H__ +#define __INTEL_DMC_WL_DEBUGFS_H__ + +#include +#include + +struct intel_display; + +struct intel_dmc_wl_dbg { + spinlock_t lock; /* protects everything below */ + struct { + u32 *offsets; + size_t head; + size_t len; + size_t size; + bool overflow; + } untracked; +}; + +void intel_dmc_wl_debugfs_init(struct intel_display *display); +void intel_dmc_wl_debugfs_register(struct intel_display *display); +void intel_dmc_wl_debugfs_log_untracked(struct intel_display *display, u32 offset); + +#endif /* __INTEL_DMC_WL_DEBUGFS_H__ */ diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index 81f63258a7e1..f03fbdbcb1a4 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -221,6 +221,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ i915-display/intel_display_wa.o \ i915-display/intel_dkl_phy.o \ i915-display/intel_dmc.o \ + i915-display/intel_dmc_wl_debugfs.o \ i915-display/intel_dp.o \ i915-display/intel_dp_aux.o \ i915-display/intel_dp_aux_backlight.o \ From patchwork Fri Jan 17 22:06:54 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gustavo Sousa X-Patchwork-Id: 13944013 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D8F59C02188 for ; Fri, 17 Jan 2025 22:08:13 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 50C7D10E345; Fri, 17 Jan 2025 22:08:13 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="WhYmYvx/"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.11]) by gabe.freedesktop.org (Postfix) with ESMTPS id 18A6010E345; Fri, 17 Jan 2025 22:08:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1737151692; x=1768687692; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=ocG/ufTAuhKODS2avxqcULXuC65MfzY2O2gYpXa1kMc=; b=WhYmYvx//PPJNSSxZba2ujmYQtYdtDnmbnd5uVL66BT6vnmGF2N/PnAv PwPwDcqhSQflkH3xf3L8x5653S6KN78g4U7+ZL2mYbFhztfkrl5391myc WcAFyM833jCO/Lq26qZl9FOwyN8Pf4dpeDRmLnus+79z2x0awRKyRRao+ NJoHdKhsr8NhkElqShDTtsWtNZ5ZweaYeaJoo3A5WMLOssnczyN8nWLG4 eb56CLN7U5A8FhKfQ2bJtNjSlS/oIKevWvSObEOqfOMOKD4gKYg6VVAgf 3PAQ8oNSFiE/oo4RJW4qf5dPtVhqrcffN69kG29V5n+7ghoGgfTypzRP+ A==; X-CSE-ConnectionGUID: /2z75omvSquEym9z6Ur+eg== X-CSE-MsgGUID: wxasIXUuTcSrLI/ao6BMGA== X-IronPort-AV: E=McAfee;i="6700,10204,11318"; a="48188794" X-IronPort-AV: E=Sophos;i="6.13,213,1732608000"; d="scan'208";a="48188794" Received: from orviesa003.jf.intel.com ([10.64.159.143]) by fmvoesa105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jan 2025 14:08:11 -0800 X-CSE-ConnectionGUID: DpZXdk+fThKEbdTTyyg19Q== X-CSE-MsgGUID: 4GYf8FFeT1asTKwF73KwoQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,199,1725346800"; d="scan'208";a="110915387" Received: from inaky-mobl1.amr.corp.intel.com (HELO gjsousa-mobl2.corp.amr.intel.com) ([10.125.109.126]) by ORVIESA003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jan 2025 14:08:11 -0800 From: Gustavo Sousa To: intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org Subject: [PATCH 3/4] drm/i915/dmc_wl: Add extra_ranges debugfs Date: Fri, 17 Jan 2025 19:06:54 -0300 Message-ID: <20250117220747.87927-4-gustavo.sousa@intel.com> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250117220747.87927-1-gustavo.sousa@intel.com> References: <20250117220747.87927-1-gustavo.sousa@intel.com> MIME-Version: 1.0 X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 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" We already have a way of finding the set of untracked offsets for which there has been one or more MMIO operations via the "intel_dmc_wl/untracked" debugfs interface. However, in order to try adding one or more of those registers to the set of tracked offsets, one would need to manually change the source code and re-compile the driver. To make debugging easier, also add a "intel_dmc_wl/extra_ranges" debugfs interface so that extra offsets to be tracked can be defined during runtime, removing the need of re-compilation or even module reloading. With "intel_dmc_wl/untracked" and "intel_dmc_wl/extra_ranges", one could even come up with a search algorithm to find missing offsets when debugging a failing test case in a similar fashion to git-bisect. Such an algorithm is subject for a future tool, probably implemented in another repository (e.g. IGT). Signed-off-by: Gustavo Sousa --- drivers/gpu/drm/i915/display/intel_dmc_wl.c | 7 + .../drm/i915/display/intel_dmc_wl_debugfs.c | 254 +++++++++++++++++- .../drm/i915/display/intel_dmc_wl_debugfs.h | 7 + 3 files changed, 267 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c b/drivers/gpu/drm/i915/display/intel_dmc_wl.c index 3686d4e90167..c9740250be73 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_wl.c +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c @@ -276,6 +276,13 @@ static bool intel_dmc_wl_check_range(struct intel_display *display, if (ranges && intel_dmc_wl_offset_in_ranges(offset, ranges)) return true; + /* + * Call to check extra ranges from debugfs only as last resort to avoid + * taking intel_dmc_wl_dbg's spinlock. + */ + if (intel_dmc_wl_debugfs_offset_in_extra_ranges(display, offset)) + return true; + return false; } diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl_debugfs.c b/drivers/gpu/drm/i915/display/intel_dmc_wl_debugfs.c index 41e59d775fe5..1493d296ac98 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_wl_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl_debugfs.c @@ -3,6 +3,8 @@ * Copyright (C) 2025 Intel Corporation */ +#include +#include #include #include @@ -13,6 +15,7 @@ #include "intel_dmc_wl_debugfs.h" #define DEBUGFS_UNTRACKED_BUFFER_SIZE_MAX 65536 +#define DEBUGFS_EXTRA_RANGES_MAX 255 /* * DOC: DMC wakelock debugfs @@ -31,7 +34,8 @@ * offsets to be tracked and we fail to realize that. * * To help capture these cases, we provide the intel_dmc_wl/ debugfs directory, - * which exports a buffer of untracked register offsets. + * which exports a buffer of untracked register offsets and also allows extra + * register offsets to be tracked by the driver. * * Untracked offsets * ----------------- @@ -78,6 +82,43 @@ * Once done with it, the logging can be disabled with:: * * # echo 0 > /sys/kernel/debug/dri/(...)/intel_dmc_wl/untracked_size + * + * Tracking extra ranges + * --------------------- + * + * After looking at a list of untracked offsets via intel_dmc_wl/untracked, it + * is likely that one would want to check whether tracking a suspicious + * set of register offsets (i.e. asserting the DMC wakelock for them) would + * solve a bug. + * + * Instead of adding the offsets manually in the source code (which would + * require re-compiling and reloading the module) the intel_dmc_wl/extra_ranges + * debugfs interface allow defining extra ranges during runtime, which can + * significantly speed up debugging time. + * + * Every write to intel_dmc_wl/untracked defines a new set of ranges to be + * tracked. The input format is a whitespace-separated list of ranges and each + * range is in the format .., with .. + * being optional. Note that is inclusive. + * + * Examples:: + * + * # echo 0x44400..0x4440c \ # Track a single range of 4 registers + * > /sys/kernel/debug/dri/(...)/intel_dmc_wl/untracked_size + * + * # echo 0x44400..0x4440c 0x44410..0x4441c \ # Track 2 ranges + * > /sys/kernel/debug/dri/(...)/intel_dmc_wl/untracked_size + * + * # echo 0x44400 0x44410..0x4441c \ # Track a single register and 1 range + * > /sys/kernel/debug/dri/(...)/intel_dmc_wl/untracked_size + * + * # echo \ # Do not track extra ranges anymore + * > /sys/kernel/debug/dri/(...)/intel_dmc_wl/untracked_size + * + * The new set of extra ranges take effect after the write operation, meaning + * that the next MMIOs made by the driver for registers that match those + * offsets will assert the wakelock (besides the offsets already hardcoded in + * the driver). */ static int untracked_size_get(void *data, u64 *val) @@ -176,6 +217,189 @@ static int untracked_show(struct seq_file *m, void *data) DEFINE_SHOW_ATTRIBUTE(untracked); +static int extra_ranges_show(struct seq_file *m, void *data) +{ + struct intel_display *display = m->private; + struct intel_dmc_wl_dbg *dbg = &display->wl.dbg; + unsigned long flags; + + spin_lock_irqsave(&dbg->lock, flags); + + if (!dbg->extra_ranges) + goto out_unlock; + + for (int i = 0; dbg->extra_ranges[i].start; i++) { + if (dbg->extra_ranges[i].end) + seq_printf(m, "0x%08x..0x%08x\n", + dbg->extra_ranges[i].start, + dbg->extra_ranges[i].end); + else + seq_printf(m, "0x%08x\n", dbg->extra_ranges[i].start); + } + +out_unlock: + spin_unlock_irqrestore(&dbg->lock, flags); + + return 0; +} + +/* + * Parse *p to match the pattern .. and store the + * offsets into *dest, if dest is not NULL. + * + * Leading whitespaces are ignored and .. is optional. Both offsets + * are expected to be expressed in hexadecimal. + * + * The pointer *p is updated to point at the next character in the string for + * parsing a new range. + * + * On success, 1 is returned if a valid range was found and 0 is returned if + * there is no range left to parse. On error, a negative error number is + * returned. + */ +static int parse_single_extra_range(struct intel_display *display, + char **p, + struct intel_dmc_wl_dbg_extra_range *dest) +{ + char c; + char *s; + char *range_substr; + int err; + u32 val; + + while (isspace(**p)) + ++*p; + + if (**p == '\0') + return 0; + + range_substr = *p; + + /* s is the substr */ + s = *p; + while (!isspace(**p) && **p != '.' && **p != '\0') + ++*p; + c = **p; + **p = '\0'; + err = kstrtou32(s, 16, &val); + **p = c; + if (err) + goto out_err; + + if (dest) + dest->start = val; + + if (**p != '.') { + /* only the "start offset" was passed */ + if (dest) + dest->end = 0; + return 1; + } + + if (*(++*p) != '.') { + err = -EINVAL; + goto out_err; + } + + /* s is the substr */ + s = ++*p; + while (!isspace(**p) && **p != '\0') + ++*p; + c = **p; + **p = '\0'; + err = kstrtou32(s, 16, &val); + **p = c; + if (err) + goto out_err; + + if (dest) + dest->end = val; + + return 1; + +out_err: + while (!isspace(**p) && **p != '\0') + ++*p; + c = **p; + **p = '\0'; + drm_err(display->drm, "invalid DMC Wakelock extra range: %s\n", range_substr); + **p = c; + + return err; +} + +static struct intel_dmc_wl_dbg_extra_range * +parse_extra_ranges(struct intel_display *display, char *s) +{ + struct intel_dmc_wl_dbg_extra_range *ranges; + char *p; + int num_ranges; + int err; + + /* Do a first pass and validate everything. */ + p = s; + num_ranges = 0; + while ((err = parse_single_extra_range(display, &p, NULL)) > 0) { + num_ranges++; + if (num_ranges > DEBUGFS_EXTRA_RANGES_MAX) { + drm_err(display->drm, "Too many DMC wakelock extra ranges, maximum is %d\n", + DEBUGFS_EXTRA_RANGES_MAX); + return ERR_PTR(-EINVAL); + } + } + + if (err < 0) + return ERR_PTR(err); + + /* Now allocate and do a second pass storing the parsed ranges. */ + ranges = drmm_kmalloc_array(display->drm, num_ranges + 1, sizeof(*ranges), GFP_KERNEL); + if (!ranges) + return ERR_PTR(-ENOMEM); + + p = s; + num_ranges = 0; + while (parse_single_extra_range(display, &p, &ranges[num_ranges]) > 0) + num_ranges++; + + ranges[num_ranges].start = 0; /* Sentinel value. */ + + return ranges; +} + +static ssize_t extra_ranges_write(struct file *file, + const char __user *ubuf, + size_t len, loff_t *offp) +{ + struct seq_file *m = file->private_data; + struct intel_display *display = m->private; + struct intel_dmc_wl_dbg *dbg = &display->wl.dbg; + struct intel_dmc_wl_dbg_extra_range *old_extra_ranges; + struct intel_dmc_wl_dbg_extra_range *new_extra_ranges; + unsigned long flags; + char *kbuf; + + kbuf = memdup_user_nul(ubuf, len); + if (IS_ERR(kbuf)) + return PTR_ERR(kbuf); + + new_extra_ranges = parse_extra_ranges(display, kbuf); + kfree(kbuf); + if (IS_ERR(new_extra_ranges)) + return PTR_ERR(new_extra_ranges); + + spin_lock_irqsave(&dbg->lock, flags); + old_extra_ranges = dbg->extra_ranges; + dbg->extra_ranges = new_extra_ranges; + spin_unlock_irqrestore(&dbg->lock, flags); + + if (old_extra_ranges) + drmm_kfree(display->drm, old_extra_ranges); + + return len; +} + +DEFINE_SHOW_STORE_ATTRIBUTE(extra_ranges); + void intel_dmc_wl_debugfs_init(struct intel_display *display) { struct intel_dmc_wl_dbg *dbg = &display->wl.dbg; @@ -198,6 +422,8 @@ void intel_dmc_wl_debugfs_register(struct intel_display *display) &untracked_size_fops); debugfs_create_file("untracked", 0644, dir, display, &untracked_fops); + debugfs_create_file("extra_ranges", 0644, dir, display, + &extra_ranges_fops); } static bool untracked_has_recent_offset(struct intel_display *display, u32 offset) @@ -249,3 +475,29 @@ void intel_dmc_wl_debugfs_log_untracked(struct intel_display *display, u32 offse out_unlock: spin_unlock_irqrestore(&dbg->lock, flags); } + +bool intel_dmc_wl_debugfs_offset_in_extra_ranges(struct intel_display *display, u32 offset) +{ + struct intel_dmc_wl_dbg *dbg = &display->wl.dbg; + bool ret = false; + unsigned long flags; + + spin_lock_irqsave(&dbg->lock, flags); + + if (!dbg->extra_ranges) + goto out_unlock; + + for (int i = 0; dbg->extra_ranges[i].start; i++) { + u32 end = dbg->extra_ranges[i].end ?: dbg->extra_ranges[i].start; + + if (dbg->extra_ranges[i].start <= offset && offset <= end) { + ret = true; + goto out_unlock; + } + } + +out_unlock: + spin_unlock_irqrestore(&dbg->lock, flags); + + return ret; +} diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl_debugfs.h b/drivers/gpu/drm/i915/display/intel_dmc_wl_debugfs.h index 9437c324966f..ae61217a2789 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_wl_debugfs.h +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl_debugfs.h @@ -11,6 +11,11 @@ struct intel_display; +struct intel_dmc_wl_dbg_extra_range { + u32 start; + u32 end; +}; + struct intel_dmc_wl_dbg { spinlock_t lock; /* protects everything below */ struct { @@ -20,10 +25,12 @@ struct intel_dmc_wl_dbg { size_t size; bool overflow; } untracked; + struct intel_dmc_wl_dbg_extra_range *extra_ranges; }; void intel_dmc_wl_debugfs_init(struct intel_display *display); void intel_dmc_wl_debugfs_register(struct intel_display *display); void intel_dmc_wl_debugfs_log_untracked(struct intel_display *display, u32 offset); +bool intel_dmc_wl_debugfs_offset_in_extra_ranges(struct intel_display *display, u32 offset); #endif /* __INTEL_DMC_WL_DEBUGFS_H__ */ From patchwork Fri Jan 17 22:06:55 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gustavo Sousa X-Patchwork-Id: 13944015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1BA38C0218C for ; Fri, 17 Jan 2025 22:08:15 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 54EF910EB82; Fri, 17 Jan 2025 22:08:14 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="XdXdILFR"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.11]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5A2E910E3DF; Fri, 17 Jan 2025 22:08:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1737151693; x=1768687693; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=+XitAGzD7ZfHvHECGdmDO3EAnaQDKDrN5N55vx5WVxM=; b=XdXdILFR45vnTSqYZEOPcfhYSYzSy2ilR7+oJwMPaZs0orRmsyFdCKo7 56FduFSl7On7xW8YjDVqdJtP3Ojor4ebhwyqlVLSTh/5zSTzC1QRfd+ID BJ1IbXzJX8xi6tXjUs0W/wb6dDbubHDlV8G6X5RzTqjqcbYkcmjpwuDG8 XJAJwFBdAdiIosAU+U9TGHLchN1hVmlLWxgx7KMR5iOhki6OLPBpmZRWw AwueZ1N1cKipKtpwDAEsxeso4zEImF8wF5G2To3qkg7YqrSBdYM2LK4pF JodTmafZ69RUK2XAle3gEeKd3m6IAFPPBxHcMAZcPrtY98/Epm2JapHMN Q==; X-CSE-ConnectionGUID: xPb5sM3+ShKEMf8ZuLVd3g== X-CSE-MsgGUID: EBTasK0hQOKpiN0rmsLreQ== X-IronPort-AV: E=McAfee;i="6700,10204,11318"; a="48188800" X-IronPort-AV: E=Sophos;i="6.13,213,1732608000"; d="scan'208";a="48188800" Received: from orviesa003.jf.intel.com ([10.64.159.143]) by fmvoesa105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jan 2025 14:08:13 -0800 X-CSE-ConnectionGUID: xDea00VSSymh6bhoxLQBBA== X-CSE-MsgGUID: r2G/+NnKTh6qBFzfk5CBOA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,199,1725346800"; d="scan'208";a="110915388" Received: from inaky-mobl1.amr.corp.intel.com (HELO gjsousa-mobl2.corp.amr.intel.com) ([10.125.109.126]) by ORVIESA003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jan 2025 14:08:13 -0800 From: Gustavo Sousa To: intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org Subject: [PATCH 4/4] drm/i915/dmc_wl: Enable the debugfs only with enable_dmc_wl_debugfs=1 Date: Fri, 17 Jan 2025 19:06:55 -0300 Message-ID: <20250117220747.87927-5-gustavo.sousa@intel.com> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250117220747.87927-1-gustavo.sousa@intel.com> References: <20250117220747.87927-1-gustavo.sousa@intel.com> MIME-Version: 1.0 X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 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" We use a spinlock to protect DMC wakelock debugfs data, since it is also accessed by the core DMC wakelock logic. Taking the spinlock when the debugfs is not in use introduces a small but unnecessary penalty. Since the debugfs functionality is only expected to be used for, uh, debugging sessions, let's protect it behind a module parameter enable_dmc_wl_debugfs. That way, we only take the lock if the feature was enabled in the first place. Signed-off-by: Gustavo Sousa --- .../gpu/drm/i915/display/intel_display_params.c | 5 +++++ .../gpu/drm/i915/display/intel_display_params.h | 1 + .../gpu/drm/i915/display/intel_dmc_wl_debugfs.c | 16 +++++++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_params.c b/drivers/gpu/drm/i915/display/intel_display_params.c index c4f1ab43fc0c..bc36d1b0ef87 100644 --- a/drivers/gpu/drm/i915/display/intel_display_params.c +++ b/drivers/gpu/drm/i915/display/intel_display_params.c @@ -133,6 +133,11 @@ intel_display_param_named_unsafe(enable_dmc_wl, int, 0400, "(-1=use per-chip default, 0=disabled, 1=enabled, 2=match any register, 3=always locked) " "Default: -1"); +intel_display_param_named_unsafe(enable_dmc_wl_debugfs, bool, 0400, + "Enable DMC wakelock debugfs" + "(0=disabled, 1=enabled) " + "Default: 0"); + __maybe_unused static void _param_print_bool(struct drm_printer *p, const char *driver_name, const char *name, bool val) diff --git a/drivers/gpu/drm/i915/display/intel_display_params.h b/drivers/gpu/drm/i915/display/intel_display_params.h index 5317138e6044..cb7dc1bc6846 100644 --- a/drivers/gpu/drm/i915/display/intel_display_params.h +++ b/drivers/gpu/drm/i915/display/intel_display_params.h @@ -48,6 +48,7 @@ struct drm_printer; param(bool, psr_safest_params, false, 0400) \ param(bool, enable_psr2_sel_fetch, true, 0400) \ param(int, enable_dmc_wl, -1, 0400) \ + param(bool, enable_dmc_wl_debugfs, false, 0400) \ #define MEMBER(T, member, ...) T member; struct intel_display_params { diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl_debugfs.c b/drivers/gpu/drm/i915/display/intel_dmc_wl_debugfs.c index 1493d296ac98..f4e4c7a5a730 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_wl_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl_debugfs.c @@ -37,6 +37,9 @@ * which exports a buffer of untracked register offsets and also allows extra * register offsets to be tracked by the driver. * + * The debugfs directory is only exported if the module parameter + * enable_dmc_wl_debugfs=1 is passed. + * * Untracked offsets * ----------------- * @@ -411,6 +414,9 @@ void intel_dmc_wl_debugfs_register(struct intel_display *display) { struct dentry *dir; + if (!display->params.enable_dmc_wl_debugfs) + return; + if (!HAS_DMC_WAKELOCK(display)) return; @@ -453,6 +459,9 @@ void intel_dmc_wl_debugfs_log_untracked(struct intel_display *display, u32 offse struct intel_dmc_wl_dbg *dbg = &display->wl.dbg; unsigned long flags; + if (!display->params.enable_dmc_wl_debugfs) + return; + spin_lock_irqsave(&dbg->lock, flags); if (!dbg->untracked.size) @@ -479,9 +488,14 @@ void intel_dmc_wl_debugfs_log_untracked(struct intel_display *display, u32 offse bool intel_dmc_wl_debugfs_offset_in_extra_ranges(struct intel_display *display, u32 offset) { struct intel_dmc_wl_dbg *dbg = &display->wl.dbg; - bool ret = false; + bool ret; unsigned long flags; + if (!display->params.enable_dmc_wl_debugfs) + return false; + + ret = false; + spin_lock_irqsave(&dbg->lock, flags); if (!dbg->extra_ranges)