All of lore.kernel.org
 help / color / mirror / Atom feed
From: Adrian Hunter <adrian.hunter@intel.com>
To: alexandre.belloni@bootlin.com
Cc: Frank.Li@nxp.com, linux-i3c@lists.infradead.org
Subject: [PATCH V2 12/13] i3c: mipi-i3c-hci-pci: Add LTR support for Intel controllers
Date: Fri, 14 Nov 2025 20:13:55 +0200	[thread overview]
Message-ID: <20251114181356.66515-13-adrian.hunter@intel.com> (raw)
In-Reply-To: <20251114181356.66515-1-adrian.hunter@intel.com>

Add support for Latency Tolerance Reporting (LTR) for Intel controllers.

Implement PM ->set_latency_tolerance() callback to set LTR register values.
Also expose LTR register values via debugfs.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---


Changes in V2:

	Make use of FIELD_PREP()
	Improve handling of values that exceed the maximum


 .../master/mipi-i3c-hci/mipi-i3c-hci-pci.c    | 125 ++++++++++++++++++
 1 file changed, 125 insertions(+)

diff --git a/drivers/i3c/master/mipi-i3c-hci/mipi-i3c-hci-pci.c b/drivers/i3c/master/mipi-i3c-hci/mipi-i3c-hci-pci.c
index 3f391b0854ae..2c827e877d29 100644
--- a/drivers/i3c/master/mipi-i3c-hci/mipi-i3c-hci-pci.c
+++ b/drivers/i3c/master/mipi-i3c-hci/mipi-i3c-hci-pci.c
@@ -7,12 +7,15 @@
  * Author: Jarkko Nikula <jarkko.nikula@linux.intel.com>
  */
 #include <linux/acpi.h>
+#include <linux/bitfield.h>
+#include <linux/debugfs.h>
 #include <linux/idr.h>
 #include <linux/iopoll.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
+#include <linux/pm_qos.h>
 
 struct mipi_i3c_hci_pci {
 	struct pci_dev *pci;
@@ -35,10 +38,122 @@ static DEFINE_IDA(mipi_i3c_hci_pci_ida);
 #define INTEL_RESETS_RESET_DONE		BIT(1)
 #define INTEL_RESETS_TIMEOUT_US		(10 * USEC_PER_MSEC)
 
+#define INTEL_ACTIVELTR			0x0c
+#define INTEL_IDLELTR			0x10
+
+#define INTEL_LTR_REQ			BIT(15)
+#define INTEL_LTR_SCALE_MASK		GENMASK(11, 10)
+#define INTEL_LTR_SCALE_1US		FIELD_PREP(INTEL_LTR_SCALE_MASK, 2)
+#define INTEL_LTR_SCALE_32US		FIELD_PREP(INTEL_LTR_SCALE_MASK, 3)
+#define INTEL_LTR_VALUE_MASK		GENMASK(9, 0)
+
 struct intel_host {
 	void __iomem	*priv;
+	u32		active_ltr;
+	u32		idle_ltr;
+	struct dentry	*debugfs_root;
 };
 
+static void intel_cache_ltr(struct intel_host *host)
+{
+	host->active_ltr = readl(host->priv + INTEL_ACTIVELTR);
+	host->idle_ltr = readl(host->priv + INTEL_IDLELTR);
+}
+
+static void intel_ltr_set(struct device *dev, s32 val)
+{
+	struct mipi_i3c_hci_pci *hci = dev_get_drvdata(dev);
+	struct intel_host *host = hci->private;
+	u32 ltr;
+
+	/*
+	 * Program latency tolerance (LTR) accordingly what has been asked
+	 * by the PM QoS layer or disable it in case we were passed
+	 * negative value or PM_QOS_LATENCY_ANY.
+	 */
+	ltr = readl(host->priv + INTEL_ACTIVELTR);
+
+	if (val == PM_QOS_LATENCY_ANY || val < 0) {
+		ltr &= ~INTEL_LTR_REQ;
+	} else {
+		ltr |= INTEL_LTR_REQ;
+		ltr &= ~INTEL_LTR_SCALE_MASK;
+		ltr &= ~INTEL_LTR_VALUE_MASK;
+
+		if (val > INTEL_LTR_VALUE_MASK) {
+			val >>= 5;
+			if (val > INTEL_LTR_VALUE_MASK)
+				val = INTEL_LTR_VALUE_MASK;
+			ltr |= INTEL_LTR_SCALE_32US | val;
+		} else {
+			ltr |= INTEL_LTR_SCALE_1US | val;
+		}
+	}
+
+	if (ltr == host->active_ltr)
+		return;
+
+	writel(ltr, host->priv + INTEL_ACTIVELTR);
+	writel(ltr, host->priv + INTEL_IDLELTR);
+
+	/* Cache the values into intel_host structure */
+	intel_cache_ltr(host);
+}
+
+static void intel_ltr_expose(struct device *dev)
+{
+	dev->power.set_latency_tolerance = intel_ltr_set;
+	dev_pm_qos_expose_latency_tolerance(dev);
+}
+
+static void intel_ltr_hide(struct device *dev)
+{
+	dev_pm_qos_hide_latency_tolerance(dev);
+	dev->power.set_latency_tolerance = NULL;
+}
+
+static struct dentry *intel_actualize_debugfs_root(bool add)
+{
+	static struct dentry *debugfs_root;
+	static DEFINE_MUTEX(lock);
+	static int ref_cnt;
+
+	guard(mutex)(&lock);
+
+	ref_cnt += add ? 1 : -1;
+
+	if (ref_cnt) {
+		if (IS_ERR_OR_NULL(debugfs_root))
+			debugfs_root = debugfs_create_dir("intel_i3c", NULL);
+	} else {
+		debugfs_remove(debugfs_root);
+		debugfs_root = NULL;
+	}
+
+	return debugfs_root;
+}
+
+static void intel_add_debugfs(struct mipi_i3c_hci_pci *hci)
+{
+	struct dentry *debugfs_root = intel_actualize_debugfs_root(true);
+	struct dentry *dir = debugfs_create_dir(dev_name(&hci->pci->dev), debugfs_root);
+	struct intel_host *host = hci->private;
+
+	intel_cache_ltr(host);
+
+	host->debugfs_root = dir;
+	debugfs_create_x32("active_ltr", 0444, dir, &host->active_ltr);
+	debugfs_create_x32("idle_ltr", 0444, dir, &host->idle_ltr);
+}
+
+static void intel_remove_debugfs(struct mipi_i3c_hci_pci *hci)
+{
+	struct intel_host *host = hci->private;
+
+	debugfs_remove_recursive(host->debugfs_root);
+	intel_actualize_debugfs_root(false);
+}
+
 static void intel_reset(void __iomem *priv)
 {
 	u32 reg;
@@ -73,11 +188,21 @@ static int intel_i3c_init(struct mipi_i3c_hci_pci *hci)
 
 	intel_reset(priv);
 
+	intel_ltr_expose(&hci->pci->dev);
+	intel_add_debugfs(hci);
+
 	return 0;
 }
 
+static void intel_exit(struct mipi_i3c_hci_pci *hci)
+{
+	intel_remove_debugfs(hci);
+	intel_ltr_hide(&hci->pci->dev);
+}
+
 static const struct mipi_i3c_hci_pci_info intel_info = {
 	.init = intel_i3c_init,
+	.exit = intel_exit,
 };
 
 static int mipi_i3c_hci_pci_probe(struct pci_dev *pci,
-- 
2.51.0


-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

  parent reply	other threads:[~2025-11-14 18:14 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-14 18:13 [PATCH V2 00/13] i3c: mipi-i3c-hci-pci: Add LTR support for Intel controllers Adrian Hunter
2025-11-14 18:13 ` [PATCH V2 01/13] i3c: mipi-i3c-hci-pci: Set 64-bit DMA mask " Adrian Hunter
2025-11-14 19:43   ` Frank Li
2025-11-14 18:13 ` [PATCH V2 02/13] i3c: mipi-i3c-hci-pci: Move all Intel-related definitions together Adrian Hunter
2025-11-14 18:13 ` [PATCH V2 03/13] i3c: mipi-i3c-hci-pci: Rename some Intel-related identifiers Adrian Hunter
2025-11-14 19:44   ` Frank Li
2025-11-14 18:13 ` [PATCH V2 04/13] i3c: mipi-i3c-hci-pci: Use readl_poll_timeout() Adrian Hunter
2025-11-14 19:44   ` Frank Li
2025-11-14 18:13 ` [PATCH V2 05/13] i3c: mipi-i3c-hci-pci: Constify driver data Adrian Hunter
2025-11-14 18:13 ` [PATCH V2 06/13] i3c: mipi-i3c-hci-pci: Factor out private registers ioremapping Adrian Hunter
2025-11-14 18:13 ` [PATCH V2 07/13] i3c: mipi-i3c-hci-pci: Factor out intel_reset() Adrian Hunter
2025-11-14 19:46   ` Frank Li
2025-11-14 18:13 ` [PATCH V2 08/13] i3c: mipi-i3c-hci-pci: Allocate a structure for mipi_i3c_hci_pci device information Adrian Hunter
2025-11-14 18:13 ` [PATCH V2 09/13] i3c: mipi-i3c-hci-pci: Change callback parameter Adrian Hunter
2025-11-14 19:49   ` Frank Li
2025-11-14 18:13 ` [PATCH V2 10/13] i3c: mipi-i3c-hci-pci: Add exit callback Adrian Hunter
2025-11-14 19:52   ` Frank Li
2025-11-14 19:59     ` Adrian Hunter
2025-11-17 15:33       ` Frank Li
2025-11-14 18:13 ` [PATCH V2 11/13] i3c: mipi-i3c-hci-pci: Allocate a structure for Intel controller information Adrian Hunter
2025-11-14 20:11   ` Frank Li
2025-11-14 18:13 ` Adrian Hunter [this message]
2025-11-14 20:09   ` [PATCH V2 12/13] i3c: mipi-i3c-hci-pci: Add LTR support for Intel controllers Frank Li
2025-11-17 11:36     ` Adrian Hunter
2025-11-17 15:59       ` Frank Li
2025-11-17 17:47         ` Adrian Hunter
2025-11-17 17:54           ` Frank Li
2025-11-17 18:09             ` Adrian Hunter
2025-11-17 18:56               ` Frank Li
2025-11-17 19:07                 ` Adrian Hunter
2025-11-17 19:35                   ` Frank Li
2025-11-14 18:13 ` [PATCH V2 13/13] i3c: mipi-i3c-hci-pci: Set d3cold_delay to 0 " Adrian Hunter
2025-11-14 20:10   ` Frank Li

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251114181356.66515-13-adrian.hunter@intel.com \
    --to=adrian.hunter@intel.com \
    --cc=Frank.Li@nxp.com \
    --cc=alexandre.belloni@bootlin.com \
    --cc=linux-i3c@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.