lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251017065028.1676930-11-jason-jh.lin@mediatek.com>
Date: Fri, 17 Oct 2025 14:44:35 +0800
From: Jason-JH Lin <jason-jh.lin@...iatek.com>
To: Rob Herring <robh@...nel.org>, Krzysztof Kozlowski <krzk+dt@...nel.org>,
	Conor Dooley <conor+dt@...nel.org>, Jassi Brar <jassisinghbrar@...il.com>,
	Chun-Kuang Hu <chunkuang.hu@...nel.org>, AngeloGioacchino Del Regno
	<angelogioacchino.delregno@...labora.com>, Mauro Carvalho Chehab
	<mchehab@...nel.org>
CC: Matthias Brugger <matthias.bgg@...il.com>, Nicolas Dufresne
	<nicolas@...fresne.ca>, Jason-JH Lin <jason-jh.lin@...iatek.com>, Nancy Lin
	<nancy.lin@...iatek.com>, Singo Chang <singo.chang@...iatek.com>, "Paul-PL
 Chen" <paul-pl.chen@...iatek.com>, Moudy Ho <moudy.ho@...iatek.com>,
	"Xiandong Wang" <xiandong.wang@...iatek.com>, Sirius Wang
	<sirius.wang@...iatek.com>, Fei Shao <fshao@...omium.org>, Chen-yu Tsai
	<wenst@...omium.org>, <Project_Global_Chrome_Upstream_Group@...iatek.com>,
	<devicetree@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
	<dri-devel@...ts.freedesktop.org>, <linux-mediatek@...ts.infradead.org>,
	<linux-arm-kernel@...ts.infradead.org>, <linux-media@...r.kernel.org>
Subject: [PATCH v8 10/20] soc: mediatek: mtk-cmdq: Extend cmdq_pkt_write API for SoCs without subsys ID

This patch extends the cmdq_pkt_write API to support SoCs that do not
have subsys ID mapping by introducing new register write APIs:
- cmdq_pkt_write_pa() and cmdq_pkt_write_subsys() replace
  cmdq_pkt_write()
- cmdq_pkt_write_mask_pa() and cmdq_pkt_write_mask_subsys() replace
  cmdq_pkt_write_mask()

To ensure consistent function pointer interfaces, both
cmdq_pkt_write_pa() and cmdq_pkt_write_subsys() provide subsys and
pa_base parameters. This unifies how register writes are invoked,
regardless of whether subsys ID is supported by the device.

All GCEs support writing registers by PA (with mask) without subsys,
but this requires extra GCE instructions to convert the PA into a GCE
readable format, reducing performance compared to using subsys directly.
Therefore, subsys is preferred for register writes when available.

API documentation and function pointer declarations in cmdq_client_reg
have been updated. The original write APIs will be removed after all
CMDQ users transition to the new interfaces.

Signed-off-by: Jason-JH Lin <jason-jh.lin@...iatek.com>
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 54 +++++++++++++++++
 include/linux/soc/mediatek/mtk-cmdq.h  | 83 ++++++++++++++++++++++++++
 2 files changed, 137 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 80806fbeba91..a884e481efa6 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -85,6 +85,16 @@ int cmdq_dev_get_client_reg(struct device *dev,
 		/* make subsys invalid */
 		client_reg->subsys = CMDQ_SUBSYS_INVALID;
 
+		/*
+		 * All GCEs support writing register PA with mask without subsys,
+		 * but this requires extra GCE instructions to convert the PA into
+		 * a format that GCE can handle, which is less performance than
+		 * directly using subsys. Therefore, when subsys is available,
+		 * we prefer to use subsys for writing register PA.
+		 */
+		client_reg->reg_write = cmdq_pkt_write_pa;
+		client_reg->reg_write_mask = cmdq_pkt_write_mask_pa;
+
 		return 0;
 	}
 
@@ -93,6 +103,9 @@ int cmdq_dev_get_client_reg(struct device *dev,
 	client_reg->size = (u16)spec.args[2];
 	of_node_put(spec.np);
 
+	client_reg->reg_write = cmdq_pkt_write_subsys;
+	client_reg->reg_write_mask = cmdq_pkt_write_mask_subsys;
+
 	return 0;
 }
 EXPORT_SYMBOL(cmdq_dev_get_client_reg);
@@ -214,6 +227,26 @@ int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value)
 }
 EXPORT_SYMBOL(cmdq_pkt_write);
 
+int cmdq_pkt_write_pa(struct cmdq_pkt *pkt, u8 subsys /*unused*/, u32 pa_base,
+		      u16 offset, u32 value)
+{
+	int err;
+
+	err = cmdq_pkt_assign(pkt, CMDQ_THR_SPR_IDX0, CMDQ_ADDR_HIGH(pa_base));
+	if (err < 0)
+		return err;
+
+	return cmdq_pkt_write_s_value(pkt, CMDQ_THR_SPR_IDX0, CMDQ_ADDR_LOW(offset), value);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_pa);
+
+int cmdq_pkt_write_subsys(struct cmdq_pkt *pkt, u8 subsys, u32 pa_base /*unused*/,
+			  u16 offset, u32 value)
+{
+	return cmdq_pkt_write(pkt, subsys, offset, value);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_subsys);
+
 int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
 			u16 offset, u32 value, u32 mask)
 {
@@ -231,6 +264,27 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_mask);
 
+int cmdq_pkt_write_mask_pa(struct cmdq_pkt *pkt, u8 subsys /*unused*/, u32 pa_base,
+			   u16 offset, u32 value, u32 mask)
+{
+	int err;
+
+	err = cmdq_pkt_assign(pkt, CMDQ_THR_SPR_IDX0, CMDQ_ADDR_HIGH(pa_base));
+	if (err < 0)
+		return err;
+
+	return cmdq_pkt_write_s_mask_value(pkt, CMDQ_THR_SPR_IDX0,
+					   CMDQ_ADDR_LOW(offset), value, mask);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_mask_pa);
+
+int cmdq_pkt_write_mask_subsys(struct cmdq_pkt *pkt, u8 subsys, u32 pa_base /*unused*/,
+			       u16 offset, u32 value, u32 mask)
+{
+	return cmdq_pkt_write_mask(pkt, subsys, offset, value, mask);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_mask_subsys);
+
 int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, u16 addr_low,
 		    u16 reg_idx)
 {
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index 154d0511a0ad..f6dc43c036bd 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -57,6 +57,10 @@ struct cmdq_client_reg {
 	phys_addr_t pa_base;
 	u16 offset;
 	u16 size;
+	int (*reg_write)(struct cmdq_pkt *pkt, u8 subsys, u32 pa_base,
+			 u16 offset, u32 value);
+	int (*reg_write_mask)(struct cmdq_pkt *pkt, u8 subsys, u32 pa_base,
+			      u16 offset, u32 value, u32 mask);
 };
 
 struct cmdq_client {
@@ -124,6 +128,32 @@ void cmdq_pkt_destroy(struct cmdq_client *client, struct cmdq_pkt *pkt);
  */
 int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value);
 
+/**
+ * cmdq_pkt_write_pa() - append write command to the CMDQ packet with pa_base
+ * @pkt:	the CMDQ packet
+ * @subsys:	unused parameter
+ * @pa_base:	the physical address base of the hardware register
+ * @offset:	register offset from CMDQ sub system
+ * @value:	the specified target register value
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write_pa(struct cmdq_pkt *pkt, u8 subsys /*unused*/,
+		      u32 pa_base, u16 offset, u32 value);
+
+/**
+ * cmdq_pkt_write_subsys() - append write command to the CMDQ packet with subsys
+ * @pkt:	the CMDQ packet
+ * @subsys:	the CMDQ sub system code
+ * @pa_base:	unused parameter
+ * @offset:	register offset from CMDQ sub system
+ * @value:	the specified target register value
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write_subsys(struct cmdq_pkt *pkt, u8 subsys,
+			  u32 pa_base /*unused*/, u16 offset, u32 value);
+
 /**
  * cmdq_pkt_write_mask() - append write command with mask to the CMDQ packet
  * @pkt:	the CMDQ packet
@@ -137,6 +167,34 @@ int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value);
 int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
 			u16 offset, u32 value, u32 mask);
 
+/**
+ * cmdq_pkt_write_mask_pa() - append write command with mask to the CMDQ packet with pa
+ * @pkt:	the CMDQ packet
+ * @subsys:	unused parameter
+ * @pa_base:	the physical address base of the hardware register
+ * @offset:	register offset from CMDQ sub system
+ * @value:	the specified target register value
+ * @mask:	the specified target register mask
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write_mask_pa(struct cmdq_pkt *pkt, u8 subsys /*unused*/,
+			   u32 pa_base, u16 offset, u32 value, u32 mask);
+
+/**
+ * cmdq_pkt_write_mask_subsys() - append write command with mask to the CMDQ packet with subsys
+ * @pkt:	the CMDQ packet
+ * @subsys:	the CMDQ sub system code
+ * @pa_base:	unused parameter
+ * @offset:	register offset from CMDQ sub system
+ * @value:	the specified target register value
+ * @mask:	the specified target register mask
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write_mask_subsys(struct cmdq_pkt *pkt, u8 subsys,
+			       u32 pa_base /*unused*/, u16 offset, u32 value, u32 mask);
+
 /*
  * cmdq_pkt_read_s() - append read_s command to the CMDQ packet
  * @pkt:	the CMDQ packet
@@ -439,12 +497,37 @@ static inline int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u3
 	return -ENOENT;
 }
 
+static inline int cmdq_pkt_write_pa(struct cmdq_pkt *pkt, u8 subsys /*unused*/,
+				    u32 pa_base, u16 offset, u32 value)
+{
+	return -ENOENT;
+}
+
+static inline int cmdq_pkt_write_subsys(struct cmdq_pkt *pkt, u8 subsys,
+					u32 pa_base /*unused*/, u16 offset, u32 value)
+{
+	return -ENOENT;
+}
+
 static inline int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
 				      u16 offset, u32 value, u32 mask)
 {
 	return -ENOENT;
 }
 
+static inline int cmdq_pkt_write_mask_pa(struct cmdq_pkt *pkt, u8 subsys /*unused*/,
+					 u32 pa_base, u16 offset, u32 value, u32 mask)
+{
+	return -ENOENT;
+}
+
+static inline int cmdq_pkt_write_mask_subsys(struct cmdq_pkt *pkt, u8 subsys,
+					     u32 pa_base /*unused*/, u16 offset,
+					     u32 value, u32 mask)
+{
+	return -ENOENT;
+}
+
 static inline int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
 				  u16 addr_low, u16 reg_idx)
 {
-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ