Commit 5c8b718c authored by Bibby Hsieh's avatar Bibby Hsieh Committed by Matthias Brugger
Browse files

soc: mediatek: cmdq: define the instruction struct



Define an instruction structure for gce driver to append command.
This structure can make the client's code more readability.

Signed-off-by: default avatarBibby Hsieh <bibby.hsieh@mediatek.com>
Reviewed-by: default avatarCK Hu <ck.hu@mediatek.com>
Signed-off-by: default avatarMatthias Brugger <matthias.bgg@gmail.com>
parent 01d1b408
Loading
Loading
Loading
Loading
+49 −24
Original line number Original line Diff line number Diff line
@@ -9,12 +9,24 @@
#include <linux/mailbox_controller.h>
#include <linux/mailbox_controller.h>
#include <linux/soc/mediatek/mtk-cmdq.h>
#include <linux/soc/mediatek/mtk-cmdq.h>


#define CMDQ_ARG_A_WRITE_MASK	0xffff
#define CMDQ_WRITE_ENABLE_MASK	BIT(0)
#define CMDQ_WRITE_ENABLE_MASK	BIT(0)
#define CMDQ_EOC_IRQ_EN		BIT(0)
#define CMDQ_EOC_IRQ_EN		BIT(0)
#define CMDQ_EOC_CMD		((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
#define CMDQ_EOC_CMD		((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
				<< 32 | CMDQ_EOC_IRQ_EN)
				<< 32 | CMDQ_EOC_IRQ_EN)


struct cmdq_instruction {
	union {
		u32 value;
		u32 mask;
	};
	union {
		u16 offset;
		u16 event;
	};
	u8 subsys;
	u8 op;
};

static void cmdq_client_timeout(struct timer_list *t)
static void cmdq_client_timeout(struct timer_list *t)
{
{
	struct cmdq_client *client = from_timer(client, t, timer);
	struct cmdq_client *client = from_timer(client, t, timer);
@@ -110,10 +122,10 @@ void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
}
}
EXPORT_SYMBOL(cmdq_pkt_destroy);
EXPORT_SYMBOL(cmdq_pkt_destroy);


static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
static int cmdq_pkt_append_command(struct cmdq_pkt *pkt,
				   u32 arg_a, u32 arg_b)
				   struct cmdq_instruction inst)
{
{
	u64 *cmd_ptr;
	struct cmdq_instruction *cmd_ptr;


	if (unlikely(pkt->cmd_buf_size + CMDQ_INST_SIZE > pkt->buf_size)) {
	if (unlikely(pkt->cmd_buf_size + CMDQ_INST_SIZE > pkt->buf_size)) {
		/*
		/*
@@ -129,8 +141,9 @@ static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
			__func__, (u32)pkt->buf_size);
			__func__, (u32)pkt->buf_size);
		return -ENOMEM;
		return -ENOMEM;
	}
	}

	cmd_ptr = pkt->va_base + pkt->cmd_buf_size;
	cmd_ptr = pkt->va_base + pkt->cmd_buf_size;
	(*cmd_ptr) = (u64)((code << CMDQ_OP_CODE_SHIFT) | arg_a) << 32 | arg_b;
	*cmd_ptr = inst;
	pkt->cmd_buf_size += CMDQ_INST_SIZE;
	pkt->cmd_buf_size += CMDQ_INST_SIZE;


	return 0;
	return 0;
@@ -138,21 +151,28 @@ static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,


int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value)
int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value)
{
{
	u32 arg_a = (offset & CMDQ_ARG_A_WRITE_MASK) |
	struct cmdq_instruction inst;
		    (subsys << CMDQ_SUBSYS_SHIFT);


	return cmdq_pkt_append_command(pkt, CMDQ_CODE_WRITE, arg_a, value);
	inst.op = CMDQ_CODE_WRITE;
	inst.value = value;
	inst.offset = offset;
	inst.subsys = subsys;

	return cmdq_pkt_append_command(pkt, inst);
}
}
EXPORT_SYMBOL(cmdq_pkt_write);
EXPORT_SYMBOL(cmdq_pkt_write);


int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
			u16 offset, u32 value, u32 mask)
			u16 offset, u32 value, u32 mask)
{
{
	u32 offset_mask = offset;
	struct cmdq_instruction inst = { {0} };
	u16 offset_mask = offset;
	int err;
	int err;


	if (mask != 0xffffffff) {
	if (mask != 0xffffffff) {
		err = cmdq_pkt_append_command(pkt, CMDQ_CODE_MASK, 0, ~mask);
		inst.op = CMDQ_CODE_MASK;
		inst.mask = ~mask;
		err = cmdq_pkt_append_command(pkt, inst);
		if (err < 0)
		if (err < 0)
			return err;
			return err;


@@ -166,45 +186,50 @@ EXPORT_SYMBOL(cmdq_pkt_write_mask);


int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
{
{
	u32 arg_b;
	struct cmdq_instruction inst = { {0} };


	if (event >= CMDQ_MAX_EVENT)
	if (event >= CMDQ_MAX_EVENT)
		return -EINVAL;
		return -EINVAL;


	/*
	inst.op = CMDQ_CODE_WFE;
	 * WFE arg_b
	inst.value = CMDQ_WFE_OPTION;
	 * bit 0-11: wait value
	inst.event = event;
	 * bit 15: 1 - wait, 0 - no wait
	 * bit 16-27: update value
	 * bit 31: 1 - update, 0 - no update
	 */
	arg_b = CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | CMDQ_WFE_WAIT_VALUE;


	return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event, arg_b);
	return cmdq_pkt_append_command(pkt, inst);
}
}
EXPORT_SYMBOL(cmdq_pkt_wfe);
EXPORT_SYMBOL(cmdq_pkt_wfe);


int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event)
int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event)
{
{
	struct cmdq_instruction inst = { {0} };

	if (event >= CMDQ_MAX_EVENT)
	if (event >= CMDQ_MAX_EVENT)
		return -EINVAL;
		return -EINVAL;


	return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event,
	inst.op = CMDQ_CODE_WFE;
				       CMDQ_WFE_UPDATE);
	inst.value = CMDQ_WFE_UPDATE;
	inst.event = event;

	return cmdq_pkt_append_command(pkt, inst);
}
}
EXPORT_SYMBOL(cmdq_pkt_clear_event);
EXPORT_SYMBOL(cmdq_pkt_clear_event);


static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
{
{
	struct cmdq_instruction inst = { {0} };
	int err;
	int err;


	/* insert EOC and generate IRQ for each command iteration */
	/* insert EOC and generate IRQ for each command iteration */
	err = cmdq_pkt_append_command(pkt, CMDQ_CODE_EOC, 0, CMDQ_EOC_IRQ_EN);
	inst.op = CMDQ_CODE_EOC;
	inst.value = CMDQ_EOC_IRQ_EN;
	err = cmdq_pkt_append_command(pkt, inst);
	if (err < 0)
	if (err < 0)
		return err;
		return err;


	/* JUMP to end */
	/* JUMP to end */
	err = cmdq_pkt_append_command(pkt, CMDQ_CODE_JUMP, 0, CMDQ_JUMP_PASS);
	inst.op = CMDQ_CODE_JUMP;
	inst.value = CMDQ_JUMP_PASS;
	err = cmdq_pkt_append_command(pkt, inst);


	return err;
	return err;
}
}
+10 −0
Original line number Original line Diff line number Diff line
@@ -20,6 +20,16 @@
#define CMDQ_WFE_WAIT			BIT(15)
#define CMDQ_WFE_WAIT			BIT(15)
#define CMDQ_WFE_WAIT_VALUE		0x1
#define CMDQ_WFE_WAIT_VALUE		0x1


/*
 * WFE arg_b
 * bit 0-11: wait value
 * bit 15: 1 - wait, 0 - no wait
 * bit 16-27: update value
 * bit 31: 1 - update, 0 - no update
 */
#define CMDQ_WFE_OPTION			(CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | \
					CMDQ_WFE_WAIT_VALUE)

/** cmdq event maximum */
/** cmdq event maximum */
#define CMDQ_MAX_EVENT			0x3ff
#define CMDQ_MAX_EVENT			0x3ff