Devicetree
 help / color / mirror / Atom feed
From: Fenglin Wu <fenglin.wu@oss.qualcomm.com>
To: Stephen Boyd <sboyd@kernel.org>, Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>,
	Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Cc: Subbaraman Narayanamurthy
	<subbaraman.narayanamurthy@oss.qualcomm.com>,
	David Collins <david.collins@oss.qualcomm.com>,
	linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org, kernel@oss.qualcomm.com,
	Fenglin Wu <fenglin.wu@oss.qualcomm.com>
Subject: [PATCH v3 2/2] spmi: spmi-pmic-arb: add support for PMIC arbiter v8.5
Date: Sun, 19 Apr 2026 19:25:53 -0700	[thread overview]
Message-ID: <20260419-hawi-spmi-v3-2-b04ee909cb87@oss.qualcomm.com> (raw)
In-Reply-To: <20260419-hawi-spmi-v3-0-b04ee909cb87@oss.qualcomm.com>

PMIC arbiter v8.5 is an extension of PMIC arbiter v8 that updated
the definition of the channel status register bit fields. Add support
to handle this difference.

Signed-off-by: Fenglin Wu <fenglin.wu@oss.qualcomm.com>
---
 drivers/spmi/spmi-pmic-arb.c | 142 ++++++++++++++++++++++++++++++++++---------
 1 file changed, 112 insertions(+), 30 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 69f8d456324a..2e2cb4774103 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -28,6 +28,7 @@
 #define PMIC_ARB_VERSION_V5_MIN		0x50000000
 #define PMIC_ARB_VERSION_V7_MIN		0x70000000
 #define PMIC_ARB_VERSION_V8_MIN		0x80000000
+#define PMIC_ARB_VERSION_V8P5_MIN	0x80050000
 #define PMIC_ARB_INT_EN			0x0004
 
 #define PMIC_ARB_FEATURES		0x0004
@@ -62,14 +63,6 @@
 /* Ownership Table */
 #define SPMI_OWNERSHIP_PERIPH2OWNER(X)	((X) & 0x7)
 
-/* Channel Status fields */
-enum pmic_arb_chnl_status {
-	PMIC_ARB_STATUS_DONE	= BIT(0),
-	PMIC_ARB_STATUS_FAILURE	= BIT(1),
-	PMIC_ARB_STATUS_DENIED	= BIT(2),
-	PMIC_ARB_STATUS_DROPPED	= BIT(3),
-};
-
 /* Command register fields */
 #define PMIC_ARB_CMD_MAX_BYTE_COUNT	8
 
@@ -239,6 +232,7 @@ struct spmi_pmic_arb {
  *			on v2 address of SPMI_PIC_IRQ_CLEARn.
  * @apid_map_offset:	offset of PMIC_ARB_REG_CHNLn
  * @apid_owner:		on v2 and later address of SPMI_PERIPHn_2OWNER_TABLE_REG
+ * @check_chnl_status:	checks channel status and returns error code if any
  */
 struct pmic_arb_ver_ops {
 	const char *ver_str;
@@ -261,6 +255,8 @@ struct pmic_arb_ver_ops {
 	void __iomem *(*irq_clear)(struct spmi_pmic_arb_bus *bus, u16 n);
 	u32 (*apid_map_offset)(u16 n);
 	void __iomem *(*apid_owner)(struct spmi_pmic_arb_bus *bus, u16 n);
+	int (*check_chnl_status)(struct spmi_controller *ctrl, u32 status,
+				 u8 sid, u16 addr, u32 offset);
 };
 
 static inline void pmic_arb_base_write(struct spmi_pmic_arb *pmic_arb,
@@ -306,6 +302,84 @@ static void pmic_arb_write_data(struct spmi_pmic_arb *pmic_arb, const u8 *buf,
 	__raw_writel(data, pmic_arb->wr_base + reg);
 }
 
+static int pmic_arb_check_chnl_status_v1(struct spmi_controller *ctrl,
+					 u32 status, u8 sid, u16 addr,
+					 u32 offset)
+{
+	/* Check if DONE bit is set */
+	if (!(status & BIT(0)))
+		return -EAGAIN;
+
+	if (status & BIT(1)) {
+		dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x) reg: 0x%x\n",
+			__func__, sid, addr, status, offset);
+		WARN_ON(1);
+		return -EIO;
+	}
+
+	if (status & BIT(2)) {
+		dev_err(&ctrl->dev, "%s: %#x %#x: transaction denied (%#x)\n",
+			__func__, sid, addr, status);
+		return -EPERM;
+	}
+
+	if (status & BIT(3)) {
+		dev_err(&ctrl->dev, "%s: %#x %#x: transaction dropped (%#x)\n",
+			__func__, sid, addr, status);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int pmic_arb_check_chnl_status_v8p5(struct spmi_controller *ctrl,
+					   u32 status, u8 sid, u16 addr,
+					   u32 offset)
+{
+	/* Check if DONE bit is set */
+	if (!(status & BIT(0)))
+		return -EAGAIN;
+
+	if (status & BIT(1)) {
+		dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x) reg: 0x%x\n",
+			__func__, sid, addr, status, offset);
+		WARN_ON(1);
+		return -EIO;
+	}
+
+	if (status & BIT(2)) {
+		dev_err(&ctrl->dev, "%s: %#x %#x: CRC error (%#x)\n",
+			__func__, sid, addr, status);
+		return -EIO;
+	}
+
+	if (status & BIT(3)) {
+		dev_err(&ctrl->dev, "%s: %#x %#x: parity error (%#x)\n",
+			__func__, sid, addr, status);
+		return -EIO;
+	}
+
+	if (status & BIT(4)) {
+		dev_err(&ctrl->dev, "%s: %#x %#x: NACK error (%#x)\n",
+			__func__, sid, addr, status);
+		return -EIO;
+	}
+
+	if (status & BIT(5)) {
+		dev_err(&ctrl->dev, "%s: %#x %#x: transaction denied (%#x)\n",
+			__func__, sid, addr, status);
+		return -EPERM;
+	}
+
+	if (status & BIT(6)) {
+		dev_err(&ctrl->dev, "%s: %#x %#x: transaction dropped (%#x)\n",
+			__func__, sid, addr, status);
+		return -EIO;
+	}
+
+	return 0;
+}
+
 static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 				  void __iomem *base, u8 sid, u16 addr,
 				  enum pmic_arb_channel ch_type)
@@ -327,28 +401,10 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 	while (timeout--) {
 		status = readl_relaxed(base + offset);
 
-		if (status & PMIC_ARB_STATUS_DONE) {
-			if (status & PMIC_ARB_STATUS_DENIED) {
-				dev_err(&ctrl->dev, "%s: %#x %#x: transaction denied (%#x)\n",
-					__func__, sid, addr, status);
-				return -EPERM;
-			}
+		rc = pmic_arb->ver_ops->check_chnl_status(ctrl, status, sid, addr, offset);
+		if (rc != -EAGAIN)
+			return rc;
 
-			if (status & PMIC_ARB_STATUS_FAILURE) {
-				dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x) reg: 0x%x\n",
-					__func__, sid, addr, status, offset);
-				WARN_ON(1);
-				return -EIO;
-			}
-
-			if (status & PMIC_ARB_STATUS_DROPPED) {
-				dev_err(&ctrl->dev, "%s: %#x %#x: transaction dropped (%#x)\n",
-					__func__, sid, addr, status);
-				return -EIO;
-			}
-
-			return 0;
-		}
 		udelay(1);
 	}
 
@@ -1768,6 +1824,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 	.irq_clear		= pmic_arb_irq_clear_v1,
 	.apid_map_offset	= pmic_arb_apid_map_offset_v2,
 	.apid_owner		= pmic_arb_apid_owner_v2,
+	.check_chnl_status	= pmic_arb_check_chnl_status_v1,
 };
 
 static const struct pmic_arb_ver_ops pmic_arb_v2 = {
@@ -1784,6 +1841,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 	.irq_clear		= pmic_arb_irq_clear_v2,
 	.apid_map_offset	= pmic_arb_apid_map_offset_v2,
 	.apid_owner		= pmic_arb_apid_owner_v2,
+	.check_chnl_status	= pmic_arb_check_chnl_status_v1,
 };
 
 static const struct pmic_arb_ver_ops pmic_arb_v3 = {
@@ -1800,6 +1858,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 	.irq_clear		= pmic_arb_irq_clear_v2,
 	.apid_map_offset	= pmic_arb_apid_map_offset_v2,
 	.apid_owner		= pmic_arb_apid_owner_v2,
+	.check_chnl_status	= pmic_arb_check_chnl_status_v1,
 };
 
 static const struct pmic_arb_ver_ops pmic_arb_v5 = {
@@ -1816,6 +1875,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 	.irq_clear		= pmic_arb_irq_clear_v5,
 	.apid_map_offset	= pmic_arb_apid_map_offset_v5,
 	.apid_owner		= pmic_arb_apid_owner_v2,
+	.check_chnl_status	= pmic_arb_check_chnl_status_v1,
 };
 
 static const struct pmic_arb_ver_ops pmic_arb_v7 = {
@@ -1832,6 +1892,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v7 = {
 	.irq_clear		= pmic_arb_irq_clear_v7,
 	.apid_map_offset	= pmic_arb_apid_map_offset_v7,
 	.apid_owner		= pmic_arb_apid_owner_v7,
+	.check_chnl_status	= pmic_arb_check_chnl_status_v1,
 };
 
 static const struct pmic_arb_ver_ops pmic_arb_v8 = {
@@ -1849,6 +1910,25 @@ static const struct pmic_arb_ver_ops pmic_arb_v8 = {
 	.irq_clear		= pmic_arb_irq_clear_v8,
 	.apid_map_offset	= pmic_arb_apid_map_offset_v8,
 	.apid_owner		= pmic_arb_apid_owner_v8,
+	.check_chnl_status	= pmic_arb_check_chnl_status_v1,
+};
+
+static const struct pmic_arb_ver_ops pmic_arb_v8p5 = {
+	.ver_str		= "v8.5",
+	.get_core_resources	= pmic_arb_get_core_resources_v8,
+	.get_bus_resources	= pmic_arb_get_bus_resources_v8,
+	.init_apid		= pmic_arb_init_apid_v8,
+	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
+	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
+	.offset			= pmic_arb_offset_v8,
+	.fmt_cmd		= pmic_arb_fmt_cmd_v2,
+	.owner_acc_status	= pmic_arb_owner_acc_status_v7,
+	.acc_enable		= pmic_arb_acc_enable_v8,
+	.irq_status		= pmic_arb_irq_status_v8,
+	.irq_clear		= pmic_arb_irq_clear_v8,
+	.apid_map_offset	= pmic_arb_apid_map_offset_v8,
+	.apid_owner		= pmic_arb_apid_owner_v8,
+	.check_chnl_status	= pmic_arb_check_chnl_status_v8p5,
 };
 
 static const struct irq_domain_ops pmic_arb_irq_domain_ops = {
@@ -2030,8 +2110,10 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 		pmic_arb->ver_ops = &pmic_arb_v5;
 	else if (hw_ver < PMIC_ARB_VERSION_V8_MIN)
 		pmic_arb->ver_ops = &pmic_arb_v7;
-	else
+	else if (hw_ver < PMIC_ARB_VERSION_V8P5_MIN)
 		pmic_arb->ver_ops = &pmic_arb_v8;
+	else
+		pmic_arb->ver_ops = &pmic_arb_v8p5;
 
 	err = pmic_arb->ver_ops->get_core_resources(pdev, core);
 	if (err)

-- 
2.43.0


  parent reply	other threads:[~2026-04-20  2:26 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-20  2:25 [PATCH v3 0/2] spmi: pmic-arb: Add spmi-pmic-arb support for Qualcomm Hawi SoC Fenglin Wu
2026-04-20  2:25 ` [PATCH v3 1/2] dt-bindings: spmi: glymur-spmi-pmic-arb: Add compatible " Fenglin Wu
2026-04-20 14:14   ` Krzysztof Kozlowski
2026-04-20  2:25 ` Fenglin Wu [this message]
2026-04-20 20:51   ` [PATCH v3 2/2] spmi: spmi-pmic-arb: add support for PMIC arbiter v8.5 Dmitry Baryshkov

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=20260419-hawi-spmi-v3-2-b04ee909cb87@oss.qualcomm.com \
    --to=fenglin.wu@oss.qualcomm.com \
    --cc=conor+dt@kernel.org \
    --cc=david.collins@oss.qualcomm.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dmitry.baryshkov@oss.qualcomm.com \
    --cc=kernel@oss.qualcomm.com \
    --cc=konrad.dybcio@oss.qualcomm.com \
    --cc=krzk+dt@kernel.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=robh@kernel.org \
    --cc=sboyd@kernel.org \
    --cc=subbaraman.narayanamurthy@oss.qualcomm.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox