summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJason-JH Lin <jason-jh.lin@mediatek.com>2025-10-31 23:56:36 +0800
committerAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>2026-01-19 12:57:45 +0100
commit40dc5bbad63b5f60dd2e69a32def1a2673cba09e (patch)
tree23fd4c46a1d7c99c6feba126c560b8b18d97eb4f /drivers
parent4bf783d8415cc397334b375a05f0b2321fc6c319 (diff)
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@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Acked-by: Jassi Brar <jassisinghbrar@gmail.com> Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/soc/mediatek/mtk-cmdq-helper.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 80806fbeba91..b30715ef0d6f 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->pkt_write = cmdq_pkt_write_pa;
+ client_reg->pkt_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->pkt_write = cmdq_pkt_write_subsys;
+ client_reg->pkt_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)
{