Skip to content

Commit 400e2fa

Browse files
Jason-JH.LinAngeloGioacchino Del Regno
authored andcommitted
soc: mediatek: mtk-cmdq: Add cmdq_pkt_poll_addr() function
Add cmdq_pkt_poll_addr function to support CMDQ user making an instruction for polling a specific address of hardware rigster to check the value with or without mask. POLL is a legacy operation in GCE, so it does not support SPR and CMDQ_CODE_LOGIC. To support polling the register address which doesn't have the subsys id, CMDQ users need to make an instruction with GPR and CMDQ_CODE_MASK operation to move the register address to be poll into GPR. Then users can make an POLL instruction with GPR to poll the register address assigned in previous instruction. Signed-off-by: Jason-JH.Lin <jason-jh.lin@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Link: https://lore.kernel.org/r/20240307013458.23550-4-jason-jh.lin@mediatek.com Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
1 parent 263801f commit 400e2fa

2 files changed

Lines changed: 70 additions & 0 deletions

File tree

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

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
#define CMDQ_WRITE_ENABLE_MASK BIT(0)
1414
#define CMDQ_POLL_ENABLE_MASK BIT(0)
15+
/* dedicate the last GPR_R15 to assign the register address to be poll */
16+
#define CMDQ_POLL_ADDR_GPR (15)
1517
#define CMDQ_EOC_IRQ_EN BIT(0)
1618
#define CMDQ_REG_TYPE 1
1719
#define CMDQ_JUMP_RELATIVE 0
@@ -397,6 +399,53 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
397399
}
398400
EXPORT_SYMBOL(cmdq_pkt_poll_mask);
399401

402+
int cmdq_pkt_poll_addr(struct cmdq_pkt *pkt, dma_addr_t addr, u32 value, u32 mask)
403+
{
404+
struct cmdq_instruction inst = { {0} };
405+
u8 use_mask = 0;
406+
int ret;
407+
408+
/*
409+
* Append an MASK instruction to set the mask for following POLL instruction
410+
* which enables use_mask bit.
411+
*/
412+
if (mask != GENMASK(31, 0)) {
413+
inst.op = CMDQ_CODE_MASK;
414+
inst.mask = ~mask;
415+
ret = cmdq_pkt_append_command(pkt, inst);
416+
if (ret < 0)
417+
return ret;
418+
use_mask = CMDQ_POLL_ENABLE_MASK;
419+
}
420+
421+
/*
422+
* POLL is an legacy operation in GCE and it does not support SPR and CMDQ_CODE_LOGIC,
423+
* so it can not use cmdq_pkt_assign to keep polling register address to SPR.
424+
* If user wants to poll a register address which doesn't have a subsys id,
425+
* user needs to use GPR and CMDQ_CODE_MASK to move polling register address to GPR.
426+
*/
427+
inst.op = CMDQ_CODE_MASK;
428+
inst.dst_t = CMDQ_REG_TYPE;
429+
inst.sop = CMDQ_POLL_ADDR_GPR;
430+
inst.value = addr;
431+
ret = cmdq_pkt_append_command(pkt, inst);
432+
if (ret < 0)
433+
return ret;
434+
435+
/* Append POLL instruction to poll the register address assign to GPR previously. */
436+
inst.op = CMDQ_CODE_POLL;
437+
inst.dst_t = CMDQ_REG_TYPE;
438+
inst.sop = CMDQ_POLL_ADDR_GPR;
439+
inst.offset = use_mask;
440+
inst.value = value;
441+
ret = cmdq_pkt_append_command(pkt, inst);
442+
if (ret < 0)
443+
return ret;
444+
445+
return 0;
446+
}
447+
EXPORT_SYMBOL(cmdq_pkt_poll_addr);
448+
400449
int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
401450
{
402451
struct cmdq_instruction inst = {};

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,22 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
270270
*/
271271
int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
272272

273+
/**
274+
* cmdq_pkt_poll_addr() - Append blocking POLL command to CMDQ packet
275+
* @pkt: the CMDQ packet
276+
* @addr: the hardware register address
277+
* @value: the specified target register value
278+
* @mask: the specified target register mask
279+
*
280+
* Appends a polling (POLL) command to the CMDQ packet and asks the GCE
281+
* to execute an instruction that checks for the specified `value` (with
282+
* or without `mask`) to appear in the specified hardware register `addr`.
283+
* All GCE threads will be blocked by this instruction.
284+
*
285+
* Return: 0 for success or negative error code
286+
*/
287+
int cmdq_pkt_poll_addr(struct cmdq_pkt *pkt, dma_addr_t addr, u32 value, u32 mask);
288+
273289
/**
274290
* cmdq_pkt_jump_abs() - Append jump command to the CMDQ packet, ask GCE
275291
* to execute an instruction that change current thread
@@ -421,6 +437,11 @@ static inline int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
421437
return -EINVAL;
422438
}
423439

440+
static inline int cmdq_pkt_poll_addr(struct cmdq_pkt *pkt, dma_addr_t addr, u32 value, u32 mask)
441+
{
442+
return -EINVAL;
443+
}
444+
424445
static inline int cmdq_pkt_jump_abs(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
425446
{
426447
return -EINVAL;

0 commit comments

Comments
 (0)