Skip to content

Commit 40dc5bb

Browse files
Jason-JH LinAngeloGioacchino Del Regno
authored andcommitted
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>
1 parent 4bf783d commit 40dc5bb

2 files changed

Lines changed: 144 additions & 0 deletions

File tree

drivers/soc/mediatek/mtk-cmdq-helper.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,16 @@ int cmdq_dev_get_client_reg(struct device *dev,
8585
/* make subsys invalid */
8686
client_reg->subsys = CMDQ_SUBSYS_INVALID;
8787

88+
/*
89+
* All GCEs support writing register PA with mask without subsys,
90+
* but this requires extra GCE instructions to convert the PA into
91+
* a format that GCE can handle, which is less performance than
92+
* directly using subsys. Therefore, when subsys is available,
93+
* we prefer to use subsys for writing register PA.
94+
*/
95+
client_reg->pkt_write = cmdq_pkt_write_pa;
96+
client_reg->pkt_write_mask = cmdq_pkt_write_mask_pa;
97+
8898
return 0;
8999
}
90100

@@ -93,6 +103,9 @@ int cmdq_dev_get_client_reg(struct device *dev,
93103
client_reg->size = (u16)spec.args[2];
94104
of_node_put(spec.np);
95105

106+
client_reg->pkt_write = cmdq_pkt_write_subsys;
107+
client_reg->pkt_write_mask = cmdq_pkt_write_mask_subsys;
108+
96109
return 0;
97110
}
98111
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)
214227
}
215228
EXPORT_SYMBOL(cmdq_pkt_write);
216229

230+
int cmdq_pkt_write_pa(struct cmdq_pkt *pkt, u8 subsys /*unused*/, u32 pa_base,
231+
u16 offset, u32 value)
232+
{
233+
int err;
234+
235+
err = cmdq_pkt_assign(pkt, CMDQ_THR_SPR_IDX0, CMDQ_ADDR_HIGH(pa_base));
236+
if (err < 0)
237+
return err;
238+
239+
return cmdq_pkt_write_s_value(pkt, CMDQ_THR_SPR_IDX0, CMDQ_ADDR_LOW(offset), value);
240+
}
241+
EXPORT_SYMBOL(cmdq_pkt_write_pa);
242+
243+
int cmdq_pkt_write_subsys(struct cmdq_pkt *pkt, u8 subsys, u32 pa_base /*unused*/,
244+
u16 offset, u32 value)
245+
{
246+
return cmdq_pkt_write(pkt, subsys, offset, value);
247+
}
248+
EXPORT_SYMBOL(cmdq_pkt_write_subsys);
249+
217250
int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
218251
u16 offset, u32 value, u32 mask)
219252
{
@@ -231,6 +264,27 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
231264
}
232265
EXPORT_SYMBOL(cmdq_pkt_write_mask);
233266

267+
int cmdq_pkt_write_mask_pa(struct cmdq_pkt *pkt, u8 subsys /*unused*/, u32 pa_base,
268+
u16 offset, u32 value, u32 mask)
269+
{
270+
int err;
271+
272+
err = cmdq_pkt_assign(pkt, CMDQ_THR_SPR_IDX0, CMDQ_ADDR_HIGH(pa_base));
273+
if (err < 0)
274+
return err;
275+
276+
return cmdq_pkt_write_s_mask_value(pkt, CMDQ_THR_SPR_IDX0,
277+
CMDQ_ADDR_LOW(offset), value, mask);
278+
}
279+
EXPORT_SYMBOL(cmdq_pkt_write_mask_pa);
280+
281+
int cmdq_pkt_write_mask_subsys(struct cmdq_pkt *pkt, u8 subsys, u32 pa_base /*unused*/,
282+
u16 offset, u32 value, u32 mask)
283+
{
284+
return cmdq_pkt_write_mask(pkt, subsys, offset, value, mask);
285+
}
286+
EXPORT_SYMBOL(cmdq_pkt_write_mask_subsys);
287+
234288
int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, u16 addr_low,
235289
u16 reg_idx)
236290
{

include/linux/soc/mediatek/mtk-cmdq.h

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,17 @@ struct cmdq_client_reg {
5757
phys_addr_t pa_base;
5858
u16 offset;
5959
u16 size;
60+
61+
/*
62+
* Client only uses these functions for MMIO access,
63+
* so doesn't need to handle the mminfra_offset.
64+
* The mminfra_offset is used for DRAM access and
65+
* is handled internally by CMDQ APIs.
66+
*/
67+
int (*pkt_write)(struct cmdq_pkt *pkt, u8 subsys, u32 pa_base,
68+
u16 offset, u32 value);
69+
int (*pkt_write_mask)(struct cmdq_pkt *pkt, u8 subsys, u32 pa_base,
70+
u16 offset, u32 value, u32 mask);
6071
};
6172

6273
struct cmdq_client {
@@ -124,6 +135,32 @@ void cmdq_pkt_destroy(struct cmdq_client *client, struct cmdq_pkt *pkt);
124135
*/
125136
int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value);
126137

138+
/**
139+
* cmdq_pkt_write_pa() - append write command to the CMDQ packet with pa_base
140+
* @pkt: the CMDQ packet
141+
* @subsys: unused parameter
142+
* @pa_base: the physical address base of the hardware register
143+
* @offset: register offset from CMDQ sub system
144+
* @value: the specified target register value
145+
*
146+
* Return: 0 for success; else the error code is returned
147+
*/
148+
int cmdq_pkt_write_pa(struct cmdq_pkt *pkt, u8 subsys /*unused*/,
149+
u32 pa_base, u16 offset, u32 value);
150+
151+
/**
152+
* cmdq_pkt_write_subsys() - append write command to the CMDQ packet with subsys
153+
* @pkt: the CMDQ packet
154+
* @subsys: the CMDQ sub system code
155+
* @pa_base: unused parameter
156+
* @offset: register offset from CMDQ sub system
157+
* @value: the specified target register value
158+
*
159+
* Return: 0 for success; else the error code is returned
160+
*/
161+
int cmdq_pkt_write_subsys(struct cmdq_pkt *pkt, u8 subsys,
162+
u32 pa_base /*unused*/, u16 offset, u32 value);
163+
127164
/**
128165
* cmdq_pkt_write_mask() - append write command with mask to the CMDQ packet
129166
* @pkt: the CMDQ packet
@@ -137,6 +174,34 @@ int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value);
137174
int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
138175
u16 offset, u32 value, u32 mask);
139176

177+
/**
178+
* cmdq_pkt_write_mask_pa() - append write command with mask to the CMDQ packet with pa
179+
* @pkt: the CMDQ packet
180+
* @subsys: unused parameter
181+
* @pa_base: the physical address base of the hardware register
182+
* @offset: register offset from CMDQ sub system
183+
* @value: the specified target register value
184+
* @mask: the specified target register mask
185+
*
186+
* Return: 0 for success; else the error code is returned
187+
*/
188+
int cmdq_pkt_write_mask_pa(struct cmdq_pkt *pkt, u8 subsys /*unused*/,
189+
u32 pa_base, u16 offset, u32 value, u32 mask);
190+
191+
/**
192+
* cmdq_pkt_write_mask_subsys() - append write command with mask to the CMDQ packet with subsys
193+
* @pkt: the CMDQ packet
194+
* @subsys: the CMDQ sub system code
195+
* @pa_base: unused parameter
196+
* @offset: register offset from CMDQ sub system
197+
* @value: the specified target register value
198+
* @mask: the specified target register mask
199+
*
200+
* Return: 0 for success; else the error code is returned
201+
*/
202+
int cmdq_pkt_write_mask_subsys(struct cmdq_pkt *pkt, u8 subsys,
203+
u32 pa_base /*unused*/, u16 offset, u32 value, u32 mask);
204+
140205
/*
141206
* cmdq_pkt_read_s() - append read_s command to the CMDQ packet
142207
* @pkt: the CMDQ packet
@@ -421,12 +486,37 @@ static inline int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u3
421486
return -ENOENT;
422487
}
423488

489+
static inline int cmdq_pkt_write_pa(struct cmdq_pkt *pkt, u8 subsys /*unused*/,
490+
u32 pa_base, u16 offset, u32 value)
491+
{
492+
return -ENOENT;
493+
}
494+
495+
static inline int cmdq_pkt_write_subsys(struct cmdq_pkt *pkt, u8 subsys,
496+
u32 pa_base /*unused*/, u16 offset, u32 value)
497+
{
498+
return -ENOENT;
499+
}
500+
424501
static inline int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
425502
u16 offset, u32 value, u32 mask)
426503
{
427504
return -ENOENT;
428505
}
429506

507+
static inline int cmdq_pkt_write_mask_pa(struct cmdq_pkt *pkt, u8 subsys /*unused*/,
508+
u32 pa_base, u16 offset, u32 value, u32 mask)
509+
{
510+
return -ENOENT;
511+
}
512+
513+
static inline int cmdq_pkt_write_mask_subsys(struct cmdq_pkt *pkt, u8 subsys,
514+
u32 pa_base /*unused*/, u16 offset,
515+
u32 value, u32 mask)
516+
{
517+
return -ENOENT;
518+
}
519+
430520
static inline int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
431521
u16 addr_low, u16 reg_idx)
432522
{

0 commit comments

Comments
 (0)