From patchwork Thu Apr 4 11:41:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Coelho X-Patchwork-Id: 13617602 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 F04C9CD1292 for ; Thu, 4 Apr 2024 11:42:08 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2B25D11B49B; Thu, 4 Apr 2024 11:42:08 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="SkqSmP8o"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) by gabe.freedesktop.org (Postfix) with ESMTPS id 01A1011B493; Thu, 4 Apr 2024 11:42:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712230924; x=1743766924; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=4e5zPWCIWTCaZi5uN/suOuUsErfyDaeUdT8GutDudv0=; b=SkqSmP8oKO2Wk9HGabjzI3NkDuG0y5yJrRAz3ItbySrGGG1qs9ugdyxK TRur62iWQP0Mj9dpV9qoANTvCqe+JJMALE5AnJ9VGWfI9NFMrlQCXDuHk Oxs3LzLEm1SvuohGD7/4FztY3iG+w3yZHDL9y7XyueU3zw0Ud6CmrUVBE qqqtFQz/u22+9oGBnPO0cGTvdzURTee7A7UuLvD7YBG8IDmWavQTJ2d7/ 9+32C/+gi7gO30A0nNr9v7XvlNf13xW2KSt83T7PhBfoRRxefkyLqXCFN Eo9EWeeZfWkYz4EyTzrP1p09RbA71Eb47EHEHtDDCZoMX6DNkQTUEjeBp Q==; X-CSE-ConnectionGUID: Kr6macnXRpqNxANrbntSXg== X-CSE-MsgGUID: 0zS6mp6CRJKas7gWPXanFA== X-IronPort-AV: E=McAfee;i="6600,9927,11033"; a="11279840" X-IronPort-AV: E=Sophos;i="6.07,179,1708416000"; d="scan'208";a="11279840" Received: from orviesa007.jf.intel.com ([10.64.159.147]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Apr 2024 04:42:04 -0700 X-CSE-ConnectionGUID: pISDMa1EQcOVKj8znCJafg== X-CSE-MsgGUID: TV+Kc7gISnaVxbPkrTt51g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,178,1708416000"; d="scan'208";a="19199772" Received: from tsonono-mobl.ger.corp.intel.com (HELO hazy.ger.corp.intel.com) ([10.252.41.97]) by orviesa007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Apr 2024 04:42:02 -0700 From: Luca Coelho To: intel-gfx@lists.freedesktop.org Cc: intel-xe@lists.freedesktop.org, uma.shankar@intel.com, ville.syrjala@linux.intel.com, jani.nikula@intel.com Subject: [PATCH v4 1/4] drm/i915/display: add support for DMC wakelocks Date: Thu, 4 Apr 2024 14:41:44 +0300 Message-Id: <20240404114147.236316-2-luciano.coelho@intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240404114147.236316-1-luciano.coelho@intel.com> References: <20240404114147.236316-1-luciano.coelho@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" In order to reduce the DC5->DC2 restore time, wakelocks have been introduced in DMC so the driver can tell it when registers and other memory areas are going to be accessed and keep their respective blocks awake. Implement this in the driver by adding the concept of DMC wakelocks. When the driver needs to access memory which lies inside pre-defined ranges, it will tell DMC to set the wakelock, access the memory, then wait for a while and clear the wakelock. The wakelock state is protected in the driver with spinlocks to prevent concurrency issues. BSpec: 71583 Signed-off-by: Luca Coelho --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/display/intel_de.h | 97 ++++++- .../gpu/drm/i915/display/intel_display_core.h | 2 + drivers/gpu/drm/i915/display/intel_dmc_regs.h | 6 + drivers/gpu/drm/i915/display/intel_dmc_wl.c | 238 ++++++++++++++++++ drivers/gpu/drm/i915/display/intel_dmc_wl.h | 31 +++ drivers/gpu/drm/xe/Makefile | 1 + 7 files changed, 368 insertions(+), 8 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/intel_dmc_wl.c create mode 100644 drivers/gpu/drm/i915/display/intel_dmc_wl.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index af9e871daf1d..7cad944b825c 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -266,6 +266,7 @@ i915-y += \ display/intel_display_rps.o \ display/intel_display_wa.o \ display/intel_dmc.o \ + display/intel_dmc_wl.o \ display/intel_dpio_phy.o \ display/intel_dpll.o \ display/intel_dpll_mgr.o \ diff --git a/drivers/gpu/drm/i915/display/intel_de.h b/drivers/gpu/drm/i915/display/intel_de.h index ba7a1c6ebc2a..0a0fba81e7af 100644 --- a/drivers/gpu/drm/i915/display/intel_de.h +++ b/drivers/gpu/drm/i915/display/intel_de.h @@ -13,52 +13,125 @@ static inline u32 intel_de_read(struct drm_i915_private *i915, i915_reg_t reg) { - return intel_uncore_read(&i915->uncore, reg); + u32 val; + + intel_dmc_wl_get(i915, reg); + + val = intel_uncore_read(&i915->uncore, reg); + + intel_dmc_wl_put(i915, reg); + + return val; } static inline u8 intel_de_read8(struct drm_i915_private *i915, i915_reg_t reg) { - return intel_uncore_read8(&i915->uncore, reg); + u8 val; + + intel_dmc_wl_get(i915, reg); + + val = intel_uncore_read8(&i915->uncore, reg); + + intel_dmc_wl_put(i915, reg); + + return val; } static inline u64 intel_de_read64_2x32(struct drm_i915_private *i915, i915_reg_t lower_reg, i915_reg_t upper_reg) { - return intel_uncore_read64_2x32(&i915->uncore, lower_reg, upper_reg); + u64 val; + + intel_dmc_wl_get(i915, lower_reg); + intel_dmc_wl_get(i915, upper_reg); + + val = intel_uncore_read64_2x32(&i915->uncore, lower_reg, upper_reg); + + intel_dmc_wl_put(i915, upper_reg); + intel_dmc_wl_put(i915, lower_reg); + + return val; } static inline void intel_de_posting_read(struct drm_i915_private *i915, i915_reg_t reg) { + intel_dmc_wl_get(i915, reg); + intel_uncore_posting_read(&i915->uncore, reg); + + intel_dmc_wl_put(i915, reg); } static inline void intel_de_write(struct drm_i915_private *i915, i915_reg_t reg, u32 val) { + intel_dmc_wl_get(i915, reg); + intel_uncore_write(&i915->uncore, reg, val); + + intel_dmc_wl_put(i915, reg); } static inline u32 -intel_de_rmw(struct drm_i915_private *i915, i915_reg_t reg, u32 clear, u32 set) +__intel_de_rmw_nowl(struct drm_i915_private *i915, i915_reg_t reg, + u32 clear, u32 set) { return intel_uncore_rmw(&i915->uncore, reg, clear, set); } +static inline u32 +intel_de_rmw(struct drm_i915_private *i915, i915_reg_t reg, u32 clear, u32 set) +{ + u32 val; + + intel_dmc_wl_get(i915, reg); + + val = __intel_de_rmw_nowl(i915, reg, clear, set); + + intel_dmc_wl_put(i915, reg); + + return val; +} + +static inline int +__intel_wait_for_register_nowl(struct drm_i915_private *i915, i915_reg_t reg, + u32 mask, u32 value, unsigned int timeout) +{ + return intel_wait_for_register(&i915->uncore, reg, mask, + value, timeout); +} + static inline int intel_de_wait(struct drm_i915_private *i915, i915_reg_t reg, u32 mask, u32 value, unsigned int timeout) { - return intel_wait_for_register(&i915->uncore, reg, mask, value, timeout); + int ret; + + intel_dmc_wl_get(i915, reg); + + ret = __intel_wait_for_register_nowl(i915, reg, mask, value, timeout); + + intel_dmc_wl_put(i915, reg); + + return ret; } static inline int intel_de_wait_fw(struct drm_i915_private *i915, i915_reg_t reg, u32 mask, u32 value, unsigned int timeout) { - return intel_wait_for_register_fw(&i915->uncore, reg, mask, value, timeout); + int ret; + + intel_dmc_wl_get(i915, reg); + + ret = intel_wait_for_register_fw(&i915->uncore, reg, mask, value, timeout); + + intel_dmc_wl_put(i915, reg); + + return ret; } static inline int @@ -67,8 +140,16 @@ intel_de_wait_custom(struct drm_i915_private *i915, i915_reg_t reg, unsigned int fast_timeout_us, unsigned int slow_timeout_ms, u32 *out_value) { - return __intel_wait_for_register(&i915->uncore, reg, mask, value, - fast_timeout_us, slow_timeout_ms, out_value); + int ret; + + intel_dmc_wl_get(i915, reg); + + ret = __intel_wait_for_register(&i915->uncore, reg, mask, value, + fast_timeout_us, slow_timeout_ms, out_value); + + intel_dmc_wl_put(i915, reg); + + return ret; } static inline int diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h index 2167dbee5eea..c40719073510 100644 --- a/drivers/gpu/drm/i915/display/intel_display_core.h +++ b/drivers/gpu/drm/i915/display/intel_display_core.h @@ -26,6 +26,7 @@ #include "intel_global_state.h" #include "intel_gmbus.h" #include "intel_opregion.h" +#include "intel_dmc_wl.h" #include "intel_wm_types.h" struct task_struct; @@ -534,6 +535,7 @@ struct intel_display { struct intel_overlay *overlay; struct intel_display_params params; struct intel_vbt_data vbt; + struct intel_dmc_wl wl; struct intel_wm wm; }; diff --git a/drivers/gpu/drm/i915/display/intel_dmc_regs.h b/drivers/gpu/drm/i915/display/intel_dmc_regs.h index 90d0dbb41cfe..1bf446f96a10 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_regs.h +++ b/drivers/gpu/drm/i915/display/intel_dmc_regs.h @@ -97,4 +97,10 @@ #define TGL_DMC_DEBUG3 _MMIO(0x101090) #define DG1_DMC_DEBUG3 _MMIO(0x13415c) +#define DMC_WAKELOCK_CFG _MMIO(0x8F1B0) +#define DMC_WAKELOCK_CFG_ENABLE REG_BIT(31) +#define DMC_WAKELOCK1_CTL _MMIO(0x8F140) +#define DMC_WAKELOCK_CTL_REQ REG_BIT(31) +#define DMC_WAKELOCK_CTL_ACK REG_BIT(15) + #endif /* __INTEL_DMC_REGS_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c b/drivers/gpu/drm/i915/display/intel_dmc_wl.c new file mode 100644 index 000000000000..3d7cf47321c2 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c @@ -0,0 +1,238 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright (C) 2024 Intel Corporation + */ + +#include + +#include "intel_de.h" +#include "intel_dmc_regs.h" +#include "intel_dmc_wl.h" + +/** + * DOC: DMC wakelock support + * + * Wake lock is the mechanism to cause display engine to exit DC + * states to allow programming to registers that are powered down in + * those states. Previous projects exited DC states automatically when + * detecting programming. Now software controls the exit by + * programming the wake lock. This improves system performance and + * system interactions and better fits the flip queue style of + * programming. Wake lock is only required when DC5, DC6, or DC6v have + * been enabled in DC_STATE_EN and the wake lock mode of operation has + * been enabled. + * + * The wakelock mechanism in DMC allows the display engine to exit DC + * states explicitly before programming registers that may be powered + * down. In earlier hardware, this was done automatically and + * implicitly when the display engine accessed a register. With the + * wakelock implementation, the driver asserts a wakelock in DMC, + * which forces it to exit the DC state until the wakelock is + * deasserted. + * + * This improves system performance and system interactions and better + * fits the flip queue style of programming. Wakelock is only + * required when DC5, DC6, or DC6v have been enabled in DC_STATE_EN + * and the wakelock feature enabled in the driver. + * + * The mechanism can be enabled and disabled by writing to the + * DMC_WAKELOCK_CFG register. There are also 13 control registers + * that can be used to hold and release different wakelocks. In the + * current implementation, we only need one wakelock, so only + * DMC_WAKELOCK1_CTL is used. The other definitions are here for + * potential future use. + */ + +#define DMC_WAKELOCK_CTL_TIMEOUT 5 +#define DMC_WAKELOCK_HOLD_TIME 50 + +struct intel_dmc_wl_range { + u32 start; + u32 end; +}; + +static struct intel_dmc_wl_range lnl_wl_range[] = { + { .start = 0x60000, .end = 0x7ffff }, +}; + +static void __intel_dmc_wl_release(struct drm_i915_private *i915) +{ + struct intel_dmc_wl *wl = &i915->display.wl; + + WARN_ON(refcount_read(&wl->refcount)); + + queue_delayed_work(i915->unordered_wq, &wl->work, + msecs_to_jiffies(DMC_WAKELOCK_HOLD_TIME)); +} + +static void intel_dmc_wl_work(struct work_struct *work) +{ + struct intel_dmc_wl *wl = + container_of(work, struct intel_dmc_wl, work.work); + struct drm_i915_private *i915 = + container_of(wl, struct drm_i915_private, display.wl); + unsigned long flags; + + spin_lock_irqsave(&wl->lock, flags); + + /* Bail out if refcount reached zero while waiting for the spinlock */ + if (!refcount_read(&wl->refcount)) + goto out_unlock; + + __intel_de_rmw_nowl(i915, DMC_WAKELOCK1_CTL, DMC_WAKELOCK_CTL_REQ, 0); + + if (__intel_wait_for_register_nowl(i915, DMC_WAKELOCK1_CTL, + DMC_WAKELOCK_CTL_ACK, 0, + DMC_WAKELOCK_CTL_TIMEOUT)) { + WARN_RATELIMIT(1, "DMC wakelock release timed out"); + goto out_unlock; + } + + wl->taken = false; + +out_unlock: + spin_unlock_irqrestore(&wl->lock, flags); +} + +static bool intel_dmc_wl_check_range(u32 address) +{ + int i; + bool wl_needed = false; + + for (i = 0; i < ARRAY_SIZE(lnl_wl_range); i++) { + if (address >= lnl_wl_range[i].start && + address <= lnl_wl_range[i].end) { + wl_needed = true; + break; + } + } + + return wl_needed; +} + +void intel_dmc_wl_init(struct drm_i915_private *i915) +{ + struct intel_dmc_wl *wl = &i915->display.wl; + + INIT_DELAYED_WORK(&wl->work, intel_dmc_wl_work); + spin_lock_init(&wl->lock); + refcount_set(&wl->refcount, 0); +} + +void intel_dmc_wl_enable(struct drm_i915_private *i915) +{ + struct intel_dmc_wl *wl = &i915->display.wl; + unsigned long flags; + + spin_lock_irqsave(&wl->lock, flags); + + if (wl->enabled) + goto out_unlock; + + /* + * Enable wakelock in DMC. We shouldn't try to take the + * wakelock, because we're just enabling it, so call the + * non-locking version directly here. + */ + __intel_de_rmw_nowl(i915, DMC_WAKELOCK_CFG, 0, DMC_WAKELOCK_CFG_ENABLE); + + wl->enabled = true; + wl->taken = false; + +out_unlock: + spin_unlock_irqrestore(&wl->lock, flags); +} + +void intel_dmc_wl_disable(struct drm_i915_private *i915) +{ + struct intel_dmc_wl *wl = &i915->display.wl; + unsigned long flags; + + flush_delayed_work(&wl->work); + + spin_lock_irqsave(&wl->lock, flags); + + if (!wl->enabled) + goto out_unlock; + + /* Disable wakelock in DMC */ + __intel_de_rmw_nowl(i915, DMC_WAKELOCK_CFG, DMC_WAKELOCK_CFG_ENABLE, 0); + + refcount_set(&wl->refcount, 0); + wl->enabled = false; + wl->taken = false; + +out_unlock: + spin_unlock_irqrestore(&wl->lock, flags); +} + +void intel_dmc_wl_get(struct drm_i915_private *i915, i915_reg_t reg) +{ + struct intel_dmc_wl *wl = &i915->display.wl; + unsigned long flags; + + if (!intel_dmc_wl_check_range(reg.reg)) + return; + + spin_lock_irqsave(&wl->lock, flags); + + if (!wl->enabled) + goto out_unlock; + + cancel_delayed_work(&wl->work); + + if (refcount_inc_not_zero(&wl->refcount)) + goto out_unlock; + + refcount_set(&wl->refcount, 1); + + /* Only try to take the wakelock if it's not marked as taken + * yet. It may be already taken at this point if we have + * already released the last reference, but the work has not + * run yet. + */ + if (!wl->taken) { + __intel_de_rmw_nowl(i915, DMC_WAKELOCK1_CTL, 0, + DMC_WAKELOCK_CTL_REQ); + + if (__intel_wait_for_register_nowl(i915, DMC_WAKELOCK1_CTL, + DMC_WAKELOCK_CTL_ACK, + DMC_WAKELOCK_CTL_ACK, + DMC_WAKELOCK_CTL_TIMEOUT)) { + WARN_RATELIMIT(1, "DMC wakelock ack timed out"); + goto out_unlock; + } + + wl->taken = true; + } + +out_unlock: + spin_unlock_irqrestore(&wl->lock, flags); +} + +void intel_dmc_wl_put(struct drm_i915_private *i915, i915_reg_t reg) +{ + struct intel_dmc_wl *wl = &i915->display.wl; + unsigned long flags; + + if (!intel_dmc_wl_check_range(reg.reg)) + return; + + spin_lock_irqsave(&wl->lock, flags); + + if (!wl->enabled) + goto out_unlock; + + if (WARN_RATELIMIT(!refcount_read(&wl->refcount), + "Tried to put wakelock with refcount zero\n")) + goto out_unlock; + + if (refcount_dec_and_test(&wl->refcount)) { + __intel_dmc_wl_release(i915); + + goto out_unlock; + } + +out_unlock: + spin_unlock_irqrestore(&wl->lock, flags); +} diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.h b/drivers/gpu/drm/i915/display/intel_dmc_wl.h new file mode 100644 index 000000000000..6fb86b05b437 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright (C) 2024 Intel Corporation + */ + +#ifndef __INTEL_WAKELOCK_H__ +#define __INTEL_WAKELOCK_H__ + +#include +#include +#include + +#include "i915_reg_defs.h" + +struct drm_i915_private; + +struct intel_dmc_wl { + spinlock_t lock; /* protects enabled, taken and refcount */ + bool enabled; + bool taken; + refcount_t refcount; + struct delayed_work work; +}; + +void intel_dmc_wl_init(struct drm_i915_private *i915); +void intel_dmc_wl_enable(struct drm_i915_private *i915); +void intel_dmc_wl_disable(struct drm_i915_private *i915); +void intel_dmc_wl_get(struct drm_i915_private *i915, i915_reg_t reg); +void intel_dmc_wl_put(struct drm_i915_private *i915, i915_reg_t reg); + +#endif /* __INTEL_WAKELOCK_H__ */ diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index e5b1715f721e..7e2b418a6f16 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -278,6 +278,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ i915-display/intel_vdsc.o \ i915-display/intel_vga.o \ i915-display/intel_vrr.o \ + i915-display/intel_dmc_wl.o \ i915-display/intel_wm.o \ i915-display/skl_scaler.o \ i915-display/skl_universal_plane.o \ From patchwork Thu Apr 4 11:41:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Coelho X-Patchwork-Id: 13617603 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 BCFCBCD129A for ; Thu, 4 Apr 2024 11:42:10 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B665211B49E; Thu, 4 Apr 2024 11:42:09 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="FPfO8+Gj"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) by gabe.freedesktop.org (Postfix) with ESMTPS id EACD011B499; Thu, 4 Apr 2024 11:42:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712230926; x=1743766926; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Mto8iMng7b75iTfFUPjPJ4Yjy1yqHNe4W+riUL47sEM=; b=FPfO8+Gjyt3d2J9TadngtqaoojW0QIci8E24i3uGUL/rJoLGWYyNiI9Z hyBsDNs0V9IaYSLXCPgCFy4BBBQJD5+Q3Lc0ifMgarBJcqTtQU2Buln8C MIUh7PBE8qGUjsm1wEx/Y17dUxLCzfL3xtVQvA8mipMzBUt18Ej67rwOF KZBs9Xj3u49NmGP8Gs4b+M+rPpX1GkuuXgXoJ1+KRA2jnMnQTjJv/YnsJ qU02yHqomzTMsAY58gDDx8UhxvRc7ZukXXGHDXLiuWQgjYQ3glHOG9kRD mv/MaW4Ddr9S+fIsMdsyFpDiTcggBlZtu5f87XsM4gJw5+UBB8jwbBjiB A==; X-CSE-ConnectionGUID: uG4GsNvxSSmP07UHeT4kxQ== X-CSE-MsgGUID: pHaeuQ1TSnm0fb6SKSz55g== X-IronPort-AV: E=McAfee;i="6600,9927,11033"; a="11279852" X-IronPort-AV: E=Sophos;i="6.07,179,1708416000"; d="scan'208";a="11279852" Received: from orviesa007.jf.intel.com ([10.64.159.147]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Apr 2024 04:42:06 -0700 X-CSE-ConnectionGUID: 8fa+cu46RdqKp3yI6RF9TQ== X-CSE-MsgGUID: EAXwPPqfScO3sqZ8/kLorg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,178,1708416000"; d="scan'208";a="19199784" Received: from tsonono-mobl.ger.corp.intel.com (HELO hazy.ger.corp.intel.com) ([10.252.41.97]) by orviesa007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Apr 2024 04:42:04 -0700 From: Luca Coelho To: intel-gfx@lists.freedesktop.org Cc: intel-xe@lists.freedesktop.org, uma.shankar@intel.com, ville.syrjala@linux.intel.com, jani.nikula@intel.com Subject: [PATCH v4 2/4] drm/i915/display: don't allow DMC wakelock on older hardware Date: Thu, 4 Apr 2024 14:41:45 +0300 Message-Id: <20240404114147.236316-3-luciano.coelho@intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240404114147.236316-1-luciano.coelho@intel.com> References: <20240404114147.236316-1-luciano.coelho@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" Only allow running DMC wakelock code if the display version is 20 or greater. Also check if DMC is loaded before enabling. Signed-off-by: Luca Coelho Reviewed-by: Uma Shankar --- .../drm/i915/display/intel_display_driver.c | 1 + drivers/gpu/drm/i915/display/intel_dmc_wl.c | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index 87dd07e0d138..e4015557af6a 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -198,6 +198,7 @@ void intel_display_driver_early_probe(struct drm_i915_private *i915) intel_dpll_init_clock_hook(i915); intel_init_display_hooks(i915); intel_fdi_init_hook(i915); + intel_dmc_wl_init(i915); } /* part #1: call before irq install */ diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c b/drivers/gpu/drm/i915/display/intel_dmc_wl.c index 3d7cf47321c2..065652fc475c 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_wl.c +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c @@ -6,6 +6,7 @@ #include #include "intel_de.h" +#include "intel_dmc.h" #include "intel_dmc_regs.h" #include "intel_dmc_wl.h" @@ -110,10 +111,23 @@ static bool intel_dmc_wl_check_range(u32 address) return wl_needed; } +static bool __intel_dmc_wl_supported(struct drm_i915_private *i915) +{ + if (DISPLAY_VER(i915) < 20 || + !intel_dmc_has_payload(i915)) + return false; + + return true; +} + void intel_dmc_wl_init(struct drm_i915_private *i915) { struct intel_dmc_wl *wl = &i915->display.wl; + /* don't call __intel_dmc_wl_supported(), DMC is not loaded yet */ + if (DISPLAY_VER(i915) < 20) + return; + INIT_DELAYED_WORK(&wl->work, intel_dmc_wl_work); spin_lock_init(&wl->lock); refcount_set(&wl->refcount, 0); @@ -124,6 +138,9 @@ void intel_dmc_wl_enable(struct drm_i915_private *i915) struct intel_dmc_wl *wl = &i915->display.wl; unsigned long flags; + if (!__intel_dmc_wl_supported(i915)) + return; + spin_lock_irqsave(&wl->lock, flags); if (wl->enabled) @@ -148,6 +165,9 @@ void intel_dmc_wl_disable(struct drm_i915_private *i915) struct intel_dmc_wl *wl = &i915->display.wl; unsigned long flags; + if (!__intel_dmc_wl_supported(i915)) + return; + flush_delayed_work(&wl->work); spin_lock_irqsave(&wl->lock, flags); @@ -171,6 +191,9 @@ void intel_dmc_wl_get(struct drm_i915_private *i915, i915_reg_t reg) struct intel_dmc_wl *wl = &i915->display.wl; unsigned long flags; + if (!__intel_dmc_wl_supported(i915)) + return; + if (!intel_dmc_wl_check_range(reg.reg)) return; @@ -215,6 +238,9 @@ void intel_dmc_wl_put(struct drm_i915_private *i915, i915_reg_t reg) struct intel_dmc_wl *wl = &i915->display.wl; unsigned long flags; + if (!__intel_dmc_wl_supported(i915)) + return; + if (!intel_dmc_wl_check_range(reg.reg)) return; From patchwork Thu Apr 4 11:41:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Coelho X-Patchwork-Id: 13617604 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 A38CFCD1292 for ; Thu, 4 Apr 2024 11:42:12 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 469EE11B49F; Thu, 4 Apr 2024 11:42:11 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="FloeEHLl"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) by gabe.freedesktop.org (Postfix) with ESMTPS id 093AC11B499; Thu, 4 Apr 2024 11:42:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712230928; x=1743766928; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=aL0N3kBr9I0C43P0zsaPAISV6iJ4pl4pYLiv29wbb68=; b=FloeEHLl7h+v1G5qLCIOvfCYsSVWm1rkdraQ47GY4nHXewnt/tAnQBZd hNzuuJtn9R0A0k/Er0YumuBeXFRlrhVVAUjMqe0fcvQIrCeyro222vLtT yawc9Xm+kFWLxG81c74MINeQgFNP4n3PDnUsKfU4tGurA+1b0VgLlNc3D ghKUropEgfZnYKpbct0+72tJjyaPKppfGySgOAaQJcvA7KNnL9OFIsR0s lFV7NjEyhC+P/DTagByv0tKvKYQAgXg9FtzNYRxfyW7oeeLFRb34kQ/gz VivUif6nZYhotKiFmyyZrOJgDhvBlj9IcN4+Pxs6vaVIjZ32+uHd1cbN5 A==; X-CSE-ConnectionGUID: 1x38029dTpao4C1RlGJz5A== X-CSE-MsgGUID: JgZ9SBKkSyqDzU3WFX5PGA== X-IronPort-AV: E=McAfee;i="6600,9927,11033"; a="11279860" X-IronPort-AV: E=Sophos;i="6.07,179,1708416000"; d="scan'208";a="11279860" Received: from orviesa007.jf.intel.com ([10.64.159.147]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Apr 2024 04:42:08 -0700 X-CSE-ConnectionGUID: us1AQAxgQkiDwZKYZWP2/g== X-CSE-MsgGUID: qL+tefdpSK6YLe5P9dD3Zg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,178,1708416000"; d="scan'208";a="19199794" Received: from tsonono-mobl.ger.corp.intel.com (HELO hazy.ger.corp.intel.com) ([10.252.41.97]) by orviesa007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Apr 2024 04:42:06 -0700 From: Luca Coelho To: intel-gfx@lists.freedesktop.org Cc: intel-xe@lists.freedesktop.org, uma.shankar@intel.com, ville.syrjala@linux.intel.com, jani.nikula@intel.com Subject: [PATCH v4 3/4] drm/i915/display: add module parameter to enable DMC wakelock Date: Thu, 4 Apr 2024 14:41:46 +0300 Message-Id: <20240404114147.236316-4-luciano.coelho@intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240404114147.236316-1-luciano.coelho@intel.com> References: <20240404114147.236316-1-luciano.coelho@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" This feature should be disabled by default until properly tested and mature. Add a module parameter to enable the feature for testing, while keeping it disabled by default for now. Reviewed-by: Uma Shankar Signed-off-by: Luca Coelho --- drivers/gpu/drm/i915/display/intel_display_params.c | 5 +++++ drivers/gpu/drm/i915/display/intel_display_params.h | 1 + drivers/gpu/drm/i915/display/intel_dmc_wl.c | 6 ++++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_params.c b/drivers/gpu/drm/i915/display/intel_display_params.c index 11e03cfb774d..f40b223cc8a1 100644 --- a/drivers/gpu/drm/i915/display/intel_display_params.c +++ b/drivers/gpu/drm/i915/display/intel_display_params.c @@ -116,6 +116,11 @@ intel_display_param_named_unsafe(enable_psr2_sel_fetch, bool, 0400, "(0=disabled, 1=enabled) " "Default: 1"); +intel_display_param_named_unsafe(enable_dmc_wl, bool, 0400, + "Enable DMC wakelock " + "(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 6206cc51df04..bf8dbbdb20a1 100644 --- a/drivers/gpu/drm/i915/display/intel_display_params.h +++ b/drivers/gpu/drm/i915/display/intel_display_params.h @@ -46,6 +46,7 @@ struct drm_i915_private; param(int, enable_psr, -1, 0600) \ param(bool, psr_safest_params, false, 0400) \ param(bool, enable_psr2_sel_fetch, true, 0400) \ + param(bool, enable_dmc_wl, false, 0400) \ #define MEMBER(T, member, ...) T member; struct intel_display_params { diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c b/drivers/gpu/drm/i915/display/intel_dmc_wl.c index 065652fc475c..6f05e377b8b6 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_wl.c +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c @@ -114,7 +114,8 @@ static bool intel_dmc_wl_check_range(u32 address) static bool __intel_dmc_wl_supported(struct drm_i915_private *i915) { if (DISPLAY_VER(i915) < 20 || - !intel_dmc_has_payload(i915)) + !intel_dmc_has_payload(i915) || + !i915->display.params.enable_dmc_wl) return false; return true; @@ -125,7 +126,8 @@ void intel_dmc_wl_init(struct drm_i915_private *i915) struct intel_dmc_wl *wl = &i915->display.wl; /* don't call __intel_dmc_wl_supported(), DMC is not loaded yet */ - if (DISPLAY_VER(i915) < 20) + if (DISPLAY_VER(i915) < 20 || + !i915->display.params.enable_dmc_wl) return; INIT_DELAYED_WORK(&wl->work, intel_dmc_wl_work); From patchwork Thu Apr 4 11:41:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Coelho X-Patchwork-Id: 13617605 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 7FD71CD1284 for ; Thu, 4 Apr 2024 11:42:19 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B5D9211B48C; Thu, 4 Apr 2024 11:42:18 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="J9j3zwLv"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) by gabe.freedesktop.org (Postfix) with ESMTPS id 006FD11B49F; Thu, 4 Apr 2024 11:42: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=1712230930; x=1743766930; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=VeAeOazBPG/uY4rYjle7h1TD5T0a1xc7D+OZL8tGLHQ=; b=J9j3zwLvJmhT58UKSmmo8RuILOyioU28dRFqZWjXmpg1Jt+XetzypqPs yKfjCTWb3KG5n9EBwbFnXuOQ4v0wR6kFTB4VI5IL59LXJuIsoySwmbIBp tlO3NbHnL4C6/J2Fko2AmDZG7DAkDiMyxsD1mfDCUH3GIXcyKNp2UA4Ps LOySbZt1LZ7NBIl/YCFOqORbWwYTkFQv6M1Jm5kAHhCI3xcLQGOsQvNFT dMeqzUcLZbk8EpLUYWHX8/lZVVGgKicHhMP2uml18UqhBHhg8PmrHo6hF w/5QsCF+uX/ZOTPivAMQROpXlzKUxyRIZt8boq80WROjemWpSPyePJ/cE g==; X-CSE-ConnectionGUID: iIknjaYBSieBQaI7Rnx5IQ== X-CSE-MsgGUID: lhmx+pR/Qo+at6y68ojrow== X-IronPort-AV: E=McAfee;i="6600,9927,11033"; a="11279864" X-IronPort-AV: E=Sophos;i="6.07,179,1708416000"; d="scan'208";a="11279864" Received: from orviesa007.jf.intel.com ([10.64.159.147]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Apr 2024 04:42:10 -0700 X-CSE-ConnectionGUID: 8QIvntxEQYKiapwrz8s1SQ== X-CSE-MsgGUID: 3Li2mDxyQH23O44hMX8wIw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,178,1708416000"; d="scan'208";a="19199798" Received: from tsonono-mobl.ger.corp.intel.com (HELO hazy.ger.corp.intel.com) ([10.252.41.97]) by orviesa007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Apr 2024 04:42:08 -0700 From: Luca Coelho To: intel-gfx@lists.freedesktop.org Cc: intel-xe@lists.freedesktop.org, uma.shankar@intel.com, ville.syrjala@linux.intel.com, jani.nikula@intel.com Subject: [PATCH v4 4/4] drm/i915/display: tie DMC wakelock to DC5/6 state transitions Date: Thu, 4 Apr 2024 14:41:47 +0300 Message-Id: <20240404114147.236316-5-luciano.coelho@intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240404114147.236316-1-luciano.coelho@intel.com> References: <20240404114147.236316-1-luciano.coelho@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 only need DMC wakelocks when we allow DC5 and DC6 states. Add the calls to enable and disable DMC wakelock accordingly. Signed-off-by: Luca Coelho Reviewed-by: Uma Shankar --- drivers/gpu/drm/i915/display/intel_display_power_well.c | 7 +++++++ drivers/gpu/drm/i915/display/intel_dmc.c | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c index e4de40228997..7f4b7602cf02 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -17,6 +17,7 @@ #include "intel_dkl_phy.h" #include "intel_dkl_phy_regs.h" #include "intel_dmc.h" +#include "intel_dmc_wl.h" #include "intel_dp_aux_regs.h" #include "intel_dpio_phy.h" #include "intel_dpll.h" @@ -821,6 +822,8 @@ void gen9_enable_dc5(struct drm_i915_private *dev_priv) intel_de_rmw(dev_priv, GEN8_CHICKEN_DCPR_1, 0, SKL_SELECT_ALTERNATE_DC_EXIT); + intel_dmc_wl_enable(dev_priv); + gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC5); } @@ -850,6 +853,8 @@ void skl_enable_dc6(struct drm_i915_private *dev_priv) intel_de_rmw(dev_priv, GEN8_CHICKEN_DCPR_1, 0, SKL_SELECT_ALTERNATE_DC_EXIT); + intel_dmc_wl_enable(dev_priv); + gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6); } @@ -970,6 +975,8 @@ void gen9_disable_dc_states(struct drm_i915_private *dev_priv) if (!HAS_DISPLAY(dev_priv)) return; + intel_dmc_wl_disable(dev_priv); + intel_cdclk_get_cdclk(dev_priv, &cdclk_config); /* Can't read out voltage_level so can't use intel_cdclk_changed() */ drm_WARN_ON(&dev_priv->drm, diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 3fa851b5c7a6..b20cc018b9a8 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -550,6 +550,8 @@ void intel_dmc_disable_program(struct drm_i915_private *i915) pipedmc_clock_gating_wa(i915, true); disable_all_event_handlers(i915); pipedmc_clock_gating_wa(i915, false); + + intel_dmc_wl_disable(i915); } void assert_dmc_loaded(struct drm_i915_private *i915) @@ -1079,6 +1081,8 @@ void intel_dmc_suspend(struct drm_i915_private *i915) if (dmc) flush_work(&dmc->work); + intel_dmc_wl_disable(i915); + /* Drop the reference held in case DMC isn't loaded. */ if (!intel_dmc_has_payload(i915)) intel_dmc_runtime_pm_put(i915);