2019-08-20 08:52:50

by Bibby Hsieh

[permalink] [raw]
Subject: [RESEND, PATCH v13 00/12] support gce on mt8183 platform

Changes since v12:
- clear the value of command ptr address.
- fixup some typo and remove unused define.

Changes since v11:
- correct some data type to avoid type conversion.

Changes since v10:
- remove subsys-cell from gce device node
- use of_parse_phandle_with_fixed_args instead of
of_parse_phandle_with_args

Changes since v8 and v9:
- change the error return code in cmdq_dev_get_client_reg()

Changes since v7:
- remove the memory allocation out of cmdq_dev_get_client_reg()
- rebase onto 5.2-rc1

Changes since v6:
- remove cmdq_dev_get_event function and gce event property
- separate some changes to indepentent patch
- change the binding document related to gce-client-reg property

Changes since v5:
- fix typo
- remove gce-event-name form the dt-binding
- add reasons in commit message

Changes since v4:
- refine the architecture of the packet encoder function
- refine the gce enevt property
- change the patch's title

Changes since v3:
- fix a typo in dt-binding and dtsi
- cast the return value to right format

Changes since v2:
- according to CK's review comment, change the property name and
refine the parameter
- change the patch's title
- remove unused property from dt-binding and dts

Changes since v1:
- add prefix "cmdq" in the commit subject
- add dt-binding document for get event and subsys function
- add fix up tag in fixup patch
- fix up some coding style (alignment)

MTK will support gce function on mt8183 platform.
dt-binding: gce: add gce header file for mt8183
mailbox: mediatek: cmdq: support mt8183 gce function
arm64: dts: add gce node for mt8183

Besides above patches, we refine gce driver on those patches.
soc: mediatek: cmdq: reorder the parameter
soc: mediatek: cmdq: change the type of input parameter
mailbox: mediatek: cmdq: move the CMDQ_IRQ_MASK into cmdq driver data
soc: mediatek: cmdq: clear the event in cmdq initial flow

In order to enhance the convenience of gce usage, we add new
helper functions and refine the method of instruction combining.
dt-binding: gce: remove thread-num property
dt-binding: gce: add binding for gce client reg property
soc: mediatek: cmdq: define the instruction struct
soc: mediatek: cmdq: add polling function
soc: mediatek: cmdq: add cmdq_dev_get_client_reg function

Bibby Hsieh (12):
dt-binding: gce: remove thread-num property
dt-binding: gce: add gce header file for mt8183
dt-binding: gce: add binding for gce client reg property
mailbox: mediatek: cmdq: move the CMDQ_IRQ_MASK into cmdq driver data
mailbox: mediatek: cmdq: support mt8183 gce function
soc: mediatek: cmdq: clear the event in cmdq initial flow
soc: mediatek: cmdq: reorder the parameter
soc: mediatek: cmdq: change the type of input parameter
soc: mediatek: cmdq: define the instruction struct
soc: mediatek: cmdq: add polling function
soc: mediatek: cmdq: add cmdq_dev_get_client_reg function
arm64: dts: add gce node for mt8183

.../devicetree/bindings/mailbox/mtk-gce.txt | 23 ++-
arch/arm64/boot/dts/mediatek/mt8183.dtsi | 10 +
drivers/mailbox/mtk-cmdq-mailbox.c | 18 +-
drivers/soc/mediatek/mtk-cmdq-helper.c | 173 +++++++++++++----
include/dt-bindings/gce/mt8183-gce.h | 175 ++++++++++++++++++
include/linux/mailbox/mtk-cmdq-mailbox.h | 5 +
include/linux/soc/mediatek/mtk-cmdq.h | 53 +++++-
7 files changed, 395 insertions(+), 62 deletions(-)
create mode 100644 include/dt-bindings/gce/mt8183-gce.h

--
2.18.0


2019-08-20 08:52:53

by Bibby Hsieh

[permalink] [raw]
Subject: [RESEND, PATCH v13 07/12] soc: mediatek: cmdq: reorder the parameter

The order of gce instructions is [subsys offset value]
so reorder the parameter of cmdq_pkt_write_mask
and cmdq_pkt_write function.

Signed-off-by: Bibby Hsieh <[email protected]>
Reviewed-by: CK Hu <[email protected]>
---
drivers/soc/mediatek/mtk-cmdq-helper.c | 6 +++---
include/linux/soc/mediatek/mtk-cmdq.h | 10 +++++-----
2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index ff9fef5a032b..082b8978651e 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -136,7 +136,7 @@ static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
return 0;
}

-int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 value, u32 subsys, u32 offset)
+int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 subsys, u32 offset, u32 value)
{
u32 arg_a = (offset & CMDQ_ARG_A_WRITE_MASK) |
(subsys << CMDQ_SUBSYS_SHIFT);
@@ -145,8 +145,8 @@ int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 value, u32 subsys, u32 offset)
}
EXPORT_SYMBOL(cmdq_pkt_write);

-int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 value,
- u32 subsys, u32 offset, u32 mask)
+int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 subsys,
+ u32 offset, u32 value, u32 mask)
{
u32 offset_mask = offset;
int err = 0;
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index 4e8899972db4..39d813dde4b4 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -60,26 +60,26 @@ void cmdq_pkt_destroy(struct cmdq_pkt *pkt);
/**
* cmdq_pkt_write() - append write command to the CMDQ packet
* @pkt: the CMDQ packet
- * @value: the specified target register value
* @subsys: the CMDQ sub system code
* @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(struct cmdq_pkt *pkt, u32 value, u32 subsys, u32 offset);
+int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 subsys, u32 offset, u32 value);

/**
* cmdq_pkt_write_mask() - append write command with mask to the CMDQ packet
* @pkt: the CMDQ packet
- * @value: the specified target register value
* @subsys: the CMDQ sub system code
* @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(struct cmdq_pkt *pkt, u32 value,
- u32 subsys, u32 offset, u32 mask);
+int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 subsys,
+ u32 offset, u32 value, u32 mask);

/**
* cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
--
2.18.0

2019-08-20 08:52:55

by Bibby Hsieh

[permalink] [raw]
Subject: [RESEND, PATCH v13 09/12] 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: Bibby Hsieh <[email protected]>
Reviewed-by: CK Hu <[email protected]>
---
drivers/soc/mediatek/mtk-cmdq-helper.c | 106 +++++++++++++++--------
include/linux/mailbox/mtk-cmdq-mailbox.h | 2 +
2 files changed, 74 insertions(+), 34 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 7aa0517ff2f3..e3d5b0be8e79 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -9,12 +9,24 @@
#include <linux/mailbox_controller.h>
#include <linux/soc/mediatek/mtk-cmdq.h>

-#define CMDQ_ARG_A_WRITE_MASK 0xffff
#define CMDQ_WRITE_ENABLE_MASK BIT(0)
#define CMDQ_EOC_IRQ_EN BIT(0)
#define CMDQ_EOC_CMD ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
<< 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)
{
struct cmdq_client *client = from_timer(client, t, timer);
@@ -110,10 +122,8 @@ void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
}
EXPORT_SYMBOL(cmdq_pkt_destroy);

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

if (unlikely(pkt->cmd_buf_size + CMDQ_INST_SIZE > pkt->buf_size)) {
/*
@@ -127,81 +137,109 @@ static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
pkt->cmd_buf_size += CMDQ_INST_SIZE;
WARN_ONCE(1, "%s: buffer size %u is too small !\n",
__func__, (u32)pkt->buf_size);
- return -ENOMEM;
+ return NULL;
}
- cmd_ptr = pkt->va_base + pkt->cmd_buf_size;
- (*cmd_ptr) = (u64)((code << CMDQ_OP_CODE_SHIFT) | arg_a) << 32 | arg_b;
+
+ *(u64 *)(pkt->va_base + pkt->cmd_buf_size) = 0;
pkt->cmd_buf_size += CMDQ_INST_SIZE;

- return 0;
+ return pkt->va_base + pkt->cmd_buf_size - CMDQ_INST_SIZE;
}

int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value)
{
- u32 arg_a = (offset & CMDQ_ARG_A_WRITE_MASK) |
- (subsys << CMDQ_SUBSYS_SHIFT);
+ struct cmdq_instruction *inst;
+
+ inst = cmdq_pkt_append_command(pkt);
+ if (!inst)
+ return -ENOMEM;
+
+ inst->op = CMDQ_CODE_WRITE;
+ inst->value = value;
+ inst->offset = offset;
+ inst->subsys = subsys;

- return cmdq_pkt_append_command(pkt, CMDQ_CODE_WRITE, arg_a, value);
+ return 0;
}
EXPORT_SYMBOL(cmdq_pkt_write);

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

if (mask != 0xffffffff) {
- err = cmdq_pkt_append_command(pkt, CMDQ_CODE_MASK, 0, ~mask);
+ inst = cmdq_pkt_append_command(pkt);
+ if (!inst)
+ return -ENOMEM;
+
+ inst->op = CMDQ_CODE_MASK;
+ inst->mask = ~mask;
offset_mask |= CMDQ_WRITE_ENABLE_MASK;
}
- err |= cmdq_pkt_write(pkt, value, subsys, offset_mask);

- return err;
+ return cmdq_pkt_write(pkt, subsys, offset_mask, value);
}
EXPORT_SYMBOL(cmdq_pkt_write_mask);

int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
{
- u32 arg_b;
+ struct cmdq_instruction *inst;

if (event >= CMDQ_MAX_EVENT)
return -EINVAL;

- /*
- * 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
- */
- arg_b = CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | CMDQ_WFE_WAIT_VALUE;
+ inst = cmdq_pkt_append_command(pkt);
+ if (!inst)
+ return -ENOMEM;
+
+ inst->op = CMDQ_CODE_WFE;
+ inst->value = CMDQ_WFE_OPTION;
+ inst->event = event;

- return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event, arg_b);
+ return 0;
}
EXPORT_SYMBOL(cmdq_pkt_wfe);

int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event)
{
+ struct cmdq_instruction *inst;
+
if (event >= CMDQ_MAX_EVENT)
return -EINVAL;

- return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event,
- CMDQ_WFE_UPDATE);
+ inst = cmdq_pkt_append_command(pkt);
+ if (!inst)
+ return -ENOMEM;
+
+ inst->op = CMDQ_CODE_WFE;
+ inst->value = CMDQ_WFE_UPDATE;
+ inst->event = event;
+
+ return 0;
}
EXPORT_SYMBOL(cmdq_pkt_clear_event);

static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
{
- int err;
+ struct cmdq_instruction *inst;
+
+ inst = cmdq_pkt_append_command(pkt);
+ if (!inst)
+ return -ENOMEM;

- /* 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;

- /* JUMP to end */
- err |= cmdq_pkt_append_command(pkt, CMDQ_CODE_JUMP, 0, CMDQ_JUMP_PASS);
+ inst = cmdq_pkt_append_command(pkt);
+ if (!inst)
+ return -ENOMEM;
+
+ inst->op = CMDQ_CODE_JUMP;
+ inst->value = CMDQ_JUMP_PASS;

- return err;
+ return 0;
}

static void cmdq_pkt_flush_async_cb(struct cmdq_cb_data data)
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 911475da7a53..c8adedefaf42 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -19,6 +19,8 @@
#define CMDQ_WFE_UPDATE BIT(31)
#define CMDQ_WFE_WAIT BIT(15)
#define CMDQ_WFE_WAIT_VALUE 0x1
+#define CMDQ_WFE_OPTION (CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | \
+ CMDQ_WFE_WAIT_VALUE)
/** cmdq event maximum */
#define CMDQ_MAX_EVENT 0x3ff

--
2.18.0

2019-08-20 08:53:02

by Bibby Hsieh

[permalink] [raw]
Subject: [RESEND, PATCH v13 11/12] soc: mediatek: cmdq: add cmdq_dev_get_client_reg function

GCE cannot know the register base address, this function
can help cmdq client to get the cmdq_client_reg structure.

Signed-off-by: Bibby Hsieh <[email protected]>
Reviewed-by: CK Hu <[email protected]>
---
drivers/soc/mediatek/mtk-cmdq-helper.c | 29 ++++++++++++++++++++++++++
include/linux/soc/mediatek/mtk-cmdq.h | 21 +++++++++++++++++++
2 files changed, 50 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index c53f8476c68d..80f75a1075b4 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -27,6 +27,35 @@ struct cmdq_instruction {
u8 op;
};

+int cmdq_dev_get_client_reg(struct device *dev,
+ struct cmdq_client_reg *client_reg, int idx)
+{
+ struct of_phandle_args spec;
+ int err;
+
+ if (!client_reg)
+ return -ENOENT;
+
+ err = of_parse_phandle_with_fixed_args(dev->of_node,
+ "mediatek,gce-client-reg",
+ 3, idx, &spec);
+ if (err < 0) {
+ dev_err(dev,
+ "error %d can't parse gce-client-reg property (%d)",
+ err, idx);
+
+ return err;
+ }
+
+ client_reg->subsys = (u8)spec.args[0];
+ client_reg->offset = (u16)spec.args[1];
+ client_reg->size = (u16)spec.args[2];
+ of_node_put(spec.np);
+
+ return 0;
+}
+EXPORT_SYMBOL(cmdq_dev_get_client_reg);
+
static void cmdq_client_timeout(struct timer_list *t)
{
struct cmdq_client *client = from_timer(client, t, timer);
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index a345870a6d10..02ddd60b212f 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -15,6 +15,12 @@

struct cmdq_pkt;

+struct cmdq_client_reg {
+ u8 subsys;
+ u16 offset;
+ u16 size;
+};
+
struct cmdq_client {
spinlock_t lock;
u32 pkt_cnt;
@@ -24,6 +30,21 @@ struct cmdq_client {
u32 timeout_ms; /* in unit of microsecond */
};

+/**
+ * cmdq_dev_get_client_reg() - parse cmdq client reg from the device
+ * node of CMDQ client
+ * @dev: device of CMDQ mailbox client
+ * @client_reg: CMDQ client reg pointer
+ * @idx: the index of desired reg
+ *
+ * Return: 0 for success; else the error code is returned
+ *
+ * Help CMDQ client parsing the cmdq client reg
+ * from the device node of CMDQ client.
+ */
+int cmdq_dev_get_client_reg(struct device *dev,
+ struct cmdq_client_reg *client_reg, int idx);
+
/**
* cmdq_mbox_create() - create CMDQ mailbox client and channel
* @dev: device of CMDQ mailbox client
--
2.18.0

2019-08-20 08:53:04

by Bibby Hsieh

[permalink] [raw]
Subject: [RESEND, PATCH v13 05/12] mailbox: mediatek: cmdq: support mt8183 gce function

add mt8183 compatible name for supporting gce function

Signed-off-by: Bibby Hsieh <[email protected]>
Reviewed-by: CK Hu <[email protected]>
---
drivers/mailbox/mtk-cmdq-mailbox.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index 8fddd26288e8..69daaadc3a5f 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -539,6 +539,7 @@ static const struct dev_pm_ops cmdq_pm_ops = {

static const struct of_device_id cmdq_of_ids[] = {
{.compatible = "mediatek,mt8173-gce", .data = (void *)16},
+ {.compatible = "mediatek,mt8183-gce", .data = (void *)24},
{}
};

--
2.18.0

2019-08-20 09:41:00

by houlong wei

[permalink] [raw]
Subject: Re: [RESEND, PATCH v13 09/12] soc: mediatek: cmdq: define the instruction struct

Reviewed-by: Houlong Wei <[email protected]>

On Tue, 2019-08-20 at 16:49 +0800, Bibby Hsieh wrote:
> Define an instruction structure for gce driver to append command.
> This structure can make the client's code more readability.
>
> Signed-off-by: Bibby Hsieh <[email protected]>
> Reviewed-by: CK Hu <[email protected]>
> ---
> drivers/soc/mediatek/mtk-cmdq-helper.c | 106 +++++++++++++++--------
> include/linux/mailbox/mtk-cmdq-mailbox.h | 2 +
> 2 files changed, 74 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
> index 7aa0517ff2f3..e3d5b0be8e79 100644
> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -9,12 +9,24 @@
> #include <linux/mailbox_controller.h>
> #include <linux/soc/mediatek/mtk-cmdq.h>
>
> -#define CMDQ_ARG_A_WRITE_MASK 0xffff
> #define CMDQ_WRITE_ENABLE_MASK BIT(0)
> #define CMDQ_EOC_IRQ_EN BIT(0)
> #define CMDQ_EOC_CMD ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
> << 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)
> {
> struct cmdq_client *client = from_timer(client, t, timer);
> @@ -110,10 +122,8 @@ void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
> }
> EXPORT_SYMBOL(cmdq_pkt_destroy);
>
> -static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
> - u32 arg_a, u32 arg_b)
> +static struct cmdq_instruction *cmdq_pkt_append_command(struct cmdq_pkt *pkt)
> {
> - u64 *cmd_ptr;
>
> if (unlikely(pkt->cmd_buf_size + CMDQ_INST_SIZE > pkt->buf_size)) {
> /*
> @@ -127,81 +137,109 @@ static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
> pkt->cmd_buf_size += CMDQ_INST_SIZE;
> WARN_ONCE(1, "%s: buffer size %u is too small !\n",
> __func__, (u32)pkt->buf_size);
> - return -ENOMEM;
> + return NULL;
> }
> - cmd_ptr = pkt->va_base + pkt->cmd_buf_size;
> - (*cmd_ptr) = (u64)((code << CMDQ_OP_CODE_SHIFT) | arg_a) << 32 | arg_b;
> +
> + *(u64 *)(pkt->va_base + pkt->cmd_buf_size) = 0;
> pkt->cmd_buf_size += CMDQ_INST_SIZE;
>
> - return 0;
> + return pkt->va_base + pkt->cmd_buf_size - CMDQ_INST_SIZE;
> }
>
> int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value)
> {
> - u32 arg_a = (offset & CMDQ_ARG_A_WRITE_MASK) |
> - (subsys << CMDQ_SUBSYS_SHIFT);
> + struct cmdq_instruction *inst;
> +
> + inst = cmdq_pkt_append_command(pkt);
> + if (!inst)
> + return -ENOMEM;
> +
> + inst->op = CMDQ_CODE_WRITE;
> + inst->value = value;
> + inst->offset = offset;
> + inst->subsys = subsys;
>
> - return cmdq_pkt_append_command(pkt, CMDQ_CODE_WRITE, arg_a, value);
> + return 0;
> }
> EXPORT_SYMBOL(cmdq_pkt_write);
>
> int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
> u16 offset, u32 value, u32 mask)
> {
> - u32 offset_mask = offset;
> - int err = 0;
> + struct cmdq_instruction *inst;
> + u16 offset_mask = offset;
>
> if (mask != 0xffffffff) {
> - err = cmdq_pkt_append_command(pkt, CMDQ_CODE_MASK, 0, ~mask);
> + inst = cmdq_pkt_append_command(pkt);
> + if (!inst)
> + return -ENOMEM;
> +
> + inst->op = CMDQ_CODE_MASK;
> + inst->mask = ~mask;
> offset_mask |= CMDQ_WRITE_ENABLE_MASK;
> }
> - err |= cmdq_pkt_write(pkt, value, subsys, offset_mask);
>
> - return err;
> + return cmdq_pkt_write(pkt, subsys, offset_mask, value);
> }
> EXPORT_SYMBOL(cmdq_pkt_write_mask);
>
> int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
> {
> - u32 arg_b;
> + struct cmdq_instruction *inst;
>
> if (event >= CMDQ_MAX_EVENT)
> return -EINVAL;
>
> - /*
> - * 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
> - */
> - arg_b = CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | CMDQ_WFE_WAIT_VALUE;
> + inst = cmdq_pkt_append_command(pkt);
> + if (!inst)
> + return -ENOMEM;
> +
> + inst->op = CMDQ_CODE_WFE;
> + inst->value = CMDQ_WFE_OPTION;
> + inst->event = event;
>
> - return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event, arg_b);
> + return 0;
> }
> EXPORT_SYMBOL(cmdq_pkt_wfe);
>
> int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event)
> {
> + struct cmdq_instruction *inst;
> +
> if (event >= CMDQ_MAX_EVENT)
> return -EINVAL;
>
> - return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event,
> - CMDQ_WFE_UPDATE);
> + inst = cmdq_pkt_append_command(pkt);
> + if (!inst)
> + return -ENOMEM;
> +
> + inst->op = CMDQ_CODE_WFE;
> + inst->value = CMDQ_WFE_UPDATE;
> + inst->event = event;
> +
> + return 0;
> }
> EXPORT_SYMBOL(cmdq_pkt_clear_event);
>
> static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
> {
> - int err;
> + struct cmdq_instruction *inst;
> +
> + inst = cmdq_pkt_append_command(pkt);
> + if (!inst)
> + return -ENOMEM;
>
> - /* 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;
>
> - /* JUMP to end */
> - err |= cmdq_pkt_append_command(pkt, CMDQ_CODE_JUMP, 0, CMDQ_JUMP_PASS);
> + inst = cmdq_pkt_append_command(pkt);
> + if (!inst)
> + return -ENOMEM;
> +
> + inst->op = CMDQ_CODE_JUMP;
> + inst->value = CMDQ_JUMP_PASS;
>
> - return err;
> + return 0;
> }
>
> static void cmdq_pkt_flush_async_cb(struct cmdq_cb_data data)
> diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h
> index 911475da7a53..c8adedefaf42 100644
> --- a/include/linux/mailbox/mtk-cmdq-mailbox.h
> +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
> @@ -19,6 +19,8 @@
> #define CMDQ_WFE_UPDATE BIT(31)
> #define CMDQ_WFE_WAIT BIT(15)
> #define CMDQ_WFE_WAIT_VALUE 0x1
> +#define CMDQ_WFE_OPTION (CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | \
> + CMDQ_WFE_WAIT_VALUE)
> /** cmdq event maximum */
> #define CMDQ_MAX_EVENT 0x3ff
>


2019-08-20 09:48:50

by houlong wei

[permalink] [raw]
Subject: Re: [RESEND, PATCH v13 11/12] soc: mediatek: cmdq: add cmdq_dev_get_client_reg function

On Tue, 2019-08-20 at 16:49 +0800, Bibby Hsieh wrote:
> GCE cannot know the register base address, this function
> can help cmdq client to get the cmdq_client_reg structure.
>
> Signed-off-by: Bibby Hsieh <[email protected]>
> Reviewed-by: CK Hu <[email protected]>
> ---
> drivers/soc/mediatek/mtk-cmdq-helper.c | 29 ++++++++++++++++++++++++++
> include/linux/soc/mediatek/mtk-cmdq.h | 21 +++++++++++++++++++
> 2 files changed, 50 insertions(+)
>
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
> index c53f8476c68d..80f75a1075b4 100644
> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -27,6 +27,35 @@ struct cmdq_instruction {
> u8 op;
> };
>
> +int cmdq_dev_get_client_reg(struct device *dev,
> + struct cmdq_client_reg *client_reg, int idx)
> +{
> + struct of_phandle_args spec;
> + int err;
> +
> + if (!client_reg)
> + return -ENOENT;
> +
> + err = of_parse_phandle_with_fixed_args(dev->of_node,
> + "mediatek,gce-client-reg",
> + 3, idx, &spec);
> + if (err < 0) {
> + dev_err(dev,
> + "error %d can't parse gce-client-reg property (%d)",
> + err, idx);
> +
> + return err;
> + }
> +
> + client_reg->subsys = (u8)spec.args[0];
> + client_reg->offset = (u16)spec.args[1];
> + client_reg->size = (u16)spec.args[2];
> + of_node_put(spec.np);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(cmdq_dev_get_client_reg);
> +
> static void cmdq_client_timeout(struct timer_list *t)
> {
> struct cmdq_client *client = from_timer(client, t, timer);
> diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
> index a345870a6d10..02ddd60b212f 100644
> --- a/include/linux/soc/mediatek/mtk-cmdq.h
> +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> @@ -15,6 +15,12 @@
>
> struct cmdq_pkt;
>
> +struct cmdq_client_reg {
> + u8 subsys;
> + u16 offset;
> + u16 size;
> +};
> +
> struct cmdq_client {
> spinlock_t lock;
> u32 pkt_cnt;
> @@ -24,6 +30,21 @@ struct cmdq_client {
> u32 timeout_ms; /* in unit of microsecond */
> };
>
> +/**
> + * cmdq_dev_get_client_reg() - parse cmdq client reg from the device
> + * node of CMDQ client
> + * @dev: device of CMDQ mailbox client
> + * @client_reg: CMDQ client reg pointer
> + * @idx: the index of desired reg
> + *
> + * Return: 0 for success; else the error code is returned
> + *
> + * Help CMDQ client parsing the cmdq client reg
> + * from the device node of CMDQ client.
> + */
> +int cmdq_dev_get_client_reg(struct device *dev,
> + struct cmdq_client_reg *client_reg, int idx);
> +
> /**
> * cmdq_mbox_create() - create CMDQ mailbox client and channel
> * @dev: device of CMDQ mailbox client

Reviewed-by: Houlong Wei <[email protected]>

2019-08-23 23:11:06

by Matthias Brugger

[permalink] [raw]
Subject: Re: [RESEND, PATCH v13 07/12] soc: mediatek: cmdq: reorder the parameter



On 20/08/2019 10:49, Bibby Hsieh wrote:
> The order of gce instructions is [subsys offset value]
> so reorder the parameter of cmdq_pkt_write_mask
> and cmdq_pkt_write function.
>
> Signed-off-by: Bibby Hsieh <[email protected]>
> Reviewed-by: CK Hu <[email protected]>

applied to v5.3-next/soc

Thanks!

> ---
> drivers/soc/mediatek/mtk-cmdq-helper.c | 6 +++---
> include/linux/soc/mediatek/mtk-cmdq.h | 10 +++++-----
> 2 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
> index ff9fef5a032b..082b8978651e 100644
> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -136,7 +136,7 @@ static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
> return 0;
> }
>
> -int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 value, u32 subsys, u32 offset)
> +int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 subsys, u32 offset, u32 value)
> {
> u32 arg_a = (offset & CMDQ_ARG_A_WRITE_MASK) |
> (subsys << CMDQ_SUBSYS_SHIFT);
> @@ -145,8 +145,8 @@ int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 value, u32 subsys, u32 offset)
> }
> EXPORT_SYMBOL(cmdq_pkt_write);
>
> -int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 value,
> - u32 subsys, u32 offset, u32 mask)
> +int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 subsys,
> + u32 offset, u32 value, u32 mask)
> {
> u32 offset_mask = offset;
> int err = 0;
> diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
> index 4e8899972db4..39d813dde4b4 100644
> --- a/include/linux/soc/mediatek/mtk-cmdq.h
> +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> @@ -60,26 +60,26 @@ void cmdq_pkt_destroy(struct cmdq_pkt *pkt);
> /**
> * cmdq_pkt_write() - append write command to the CMDQ packet
> * @pkt: the CMDQ packet
> - * @value: the specified target register value
> * @subsys: the CMDQ sub system code
> * @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(struct cmdq_pkt *pkt, u32 value, u32 subsys, u32 offset);
> +int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 subsys, u32 offset, u32 value);
>
> /**
> * cmdq_pkt_write_mask() - append write command with mask to the CMDQ packet
> * @pkt: the CMDQ packet
> - * @value: the specified target register value
> * @subsys: the CMDQ sub system code
> * @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(struct cmdq_pkt *pkt, u32 value,
> - u32 subsys, u32 offset, u32 mask);
> +int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 subsys,
> + u32 offset, u32 value, u32 mask);
>
> /**
> * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
>

2019-08-23 23:24:43

by Matthias Brugger

[permalink] [raw]
Subject: Re: [RESEND, PATCH v13 09/12] soc: mediatek: cmdq: define the instruction struct



On 20/08/2019 10:49, Bibby Hsieh wrote:
> Define an instruction structure for gce driver to append command.
> This structure can make the client's code more readability.
>
> Signed-off-by: Bibby Hsieh <[email protected]>
> Reviewed-by: CK Hu <[email protected]>
> ---
> drivers/soc/mediatek/mtk-cmdq-helper.c | 106 +++++++++++++++--------
> include/linux/mailbox/mtk-cmdq-mailbox.h | 2 +
> 2 files changed, 74 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
> index 7aa0517ff2f3..e3d5b0be8e79 100644
> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -9,12 +9,24 @@
> #include <linux/mailbox_controller.h>
> #include <linux/soc/mediatek/mtk-cmdq.h>
>
> -#define CMDQ_ARG_A_WRITE_MASK 0xffff
> #define CMDQ_WRITE_ENABLE_MASK BIT(0)
> #define CMDQ_EOC_IRQ_EN BIT(0)
> #define CMDQ_EOC_CMD ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
> << 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)
> {
> struct cmdq_client *client = from_timer(client, t, timer);
> @@ -110,10 +122,8 @@ void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
> }
> EXPORT_SYMBOL(cmdq_pkt_destroy);
>
> -static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
> - u32 arg_a, u32 arg_b)
> +static struct cmdq_instruction *cmdq_pkt_append_command(struct cmdq_pkt *pkt)
> {
> - u64 *cmd_ptr;
>
> if (unlikely(pkt->cmd_buf_size + CMDQ_INST_SIZE > pkt->buf_size)) {
> /*
> @@ -127,81 +137,109 @@ static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
> pkt->cmd_buf_size += CMDQ_INST_SIZE;
> WARN_ONCE(1, "%s: buffer size %u is too small !\n",
> __func__, (u32)pkt->buf_size);
> - return -ENOMEM;
> + return NULL;
> }
> - cmd_ptr = pkt->va_base + pkt->cmd_buf_size;
> - (*cmd_ptr) = (u64)((code << CMDQ_OP_CODE_SHIFT) | arg_a) << 32 | arg_b;
> +
> + *(u64 *)(pkt->va_base + pkt->cmd_buf_size) = 0;> pkt->cmd_buf_size += CMDQ_INST_SIZE;
>
> - return 0;
> + return pkt->va_base + pkt->cmd_buf_size - CMDQ_INST_SIZE;
> }
>
> int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value)
> {
> - u32 arg_a = (offset & CMDQ_ARG_A_WRITE_MASK) |
> - (subsys << CMDQ_SUBSYS_SHIFT);
> + struct cmdq_instruction *inst;
> +
> + inst = cmdq_pkt_append_command(pkt);
> + if (!inst)
> + return -ENOMEM;
> +
> + inst->op = CMDQ_CODE_WRITE;
> + inst->value = value;
> + inst->offset = offset;
> + inst->subsys = subsys;
>

I can see that using cmdq_instruction will make the code more readable, but I
dislike the approach that cmdq_pkt_append_command returns a pointer where we
write the instruction to. Better we pass inst to cmdq_pkt_append_command() and
write it there to cmd_ptr.

I think this way we can get rid of explicitly setting the memory to zero:
*(u64 *)(pkt->va_base + pkt->cmd_buf_size) = 0;

And if we pass the inst to the append_command we don't have to change the return
value handling of cmdq_pkt_append_command(), which makes the patch easier to
understand.

> - return cmdq_pkt_append_command(pkt, CMDQ_CODE_WRITE, arg_a, value);
> + return 0;
> }
> EXPORT_SYMBOL(cmdq_pkt_write);
>
> int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
> u16 offset, u32 value, u32 mask)
> {
> - u32 offset_mask = offset;
> - int err = 0;
> + struct cmdq_instruction *inst;
> + u16 offset_mask = offset;
>
> if (mask != 0xffffffff) {
> - err = cmdq_pkt_append_command(pkt, CMDQ_CODE_MASK, 0, ~mask);
> + inst = cmdq_pkt_append_command(pkt);
> + if (!inst)
> + return -ENOMEM;
> +
> + inst->op = CMDQ_CODE_MASK;
> + inst->mask = ~mask;
> offset_mask |= CMDQ_WRITE_ENABLE_MASK;
> }
> - err |= cmdq_pkt_write(pkt, value, subsys, offset_mask);
>
> - return err;
> + return cmdq_pkt_write(pkt, subsys, offset_mask, value);
> }
> EXPORT_SYMBOL(cmdq_pkt_write_mask);
>
> int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
> {
> - u32 arg_b;
> + struct cmdq_instruction *inst;
>
> if (event >= CMDQ_MAX_EVENT)
> return -EINVAL;
>
> - /*
> - * 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
> - */

I have no strong opinion of CMDQ_WFE_OPTION but if you want to introduce it,
then please copy the comment over to include/linux/mailbox/mtk-cmdq-mailbox.h

Just one question, why did you call it _OPTION? It's not really expressive for me.

> - arg_b = CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | CMDQ_WFE_WAIT_VALUE;
> + inst = cmdq_pkt_append_command(pkt);
> + if (!inst)
> + return -ENOMEM;
> +
> + inst->op = CMDQ_CODE_WFE;
> + inst->value = CMDQ_WFE_OPTION;
> + inst->event = event;
>
> - return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event, arg_b);
> + return 0;
> }
> EXPORT_SYMBOL(cmdq_pkt_wfe);
>
> int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event)
> {
> + struct cmdq_instruction *inst;
> +
> if (event >= CMDQ_MAX_EVENT)
> return -EINVAL;
>
> - return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event,
> - CMDQ_WFE_UPDATE);
> + inst = cmdq_pkt_append_command(pkt);
> + if (!inst)
> + return -ENOMEM;
> +
> + inst->op = CMDQ_CODE_WFE;
> + inst->value = CMDQ_WFE_UPDATE;
> + inst->event = event;
> +
> + return 0;
> }
> EXPORT_SYMBOL(cmdq_pkt_clear_event);
>
> static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
> {
> - int err;
> + struct cmdq_instruction *inst;
> +
> + inst = cmdq_pkt_append_command(pkt);
> + if (!inst)
> + return -ENOMEM;
>
> - /* insert EOC and generate IRQ for each command iteration */

Please don't delete the comment.

> - 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;
>
> - /* JUMP to end */

Same here.

Regards,
Matthias

> - err |= cmdq_pkt_append_command(pkt, CMDQ_CODE_JUMP, 0, CMDQ_JUMP_PASS);
> + inst = cmdq_pkt_append_command(pkt);
> + if (!inst)
> + return -ENOMEM;
> +
> + inst->op = CMDQ_CODE_JUMP;
> + inst->value = CMDQ_JUMP_PASS;
>
> - return err;
> + return 0;
> }
>
> static void cmdq_pkt_flush_async_cb(struct cmdq_cb_data data)
> diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h
> index 911475da7a53..c8adedefaf42 100644
> --- a/include/linux/mailbox/mtk-cmdq-mailbox.h
> +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
> @@ -19,6 +19,8 @@
> #define CMDQ_WFE_UPDATE BIT(31)
> #define CMDQ_WFE_WAIT BIT(15)
> #define CMDQ_WFE_WAIT_VALUE 0x1
> +#define CMDQ_WFE_OPTION (CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | \
> + CMDQ_WFE_WAIT_VALUE)
> /** cmdq event maximum */
> #define CMDQ_MAX_EVENT 0x3ff
>
>

2019-08-23 23:26:02

by Matthias Brugger

[permalink] [raw]
Subject: Re: [RESEND, PATCH v13 11/12] soc: mediatek: cmdq: add cmdq_dev_get_client_reg function



On 20/08/2019 10:49, Bibby Hsieh wrote:
> GCE cannot know the register base address, this function
> can help cmdq client to get the cmdq_client_reg structure.
>
> Signed-off-by: Bibby Hsieh <[email protected]>
> Reviewed-by: CK Hu <[email protected]>
> ---
> drivers/soc/mediatek/mtk-cmdq-helper.c | 29 ++++++++++++++++++++++++++
> include/linux/soc/mediatek/mtk-cmdq.h | 21 +++++++++++++++++++
> 2 files changed, 50 insertions(+)
>
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
> index c53f8476c68d..80f75a1075b4 100644
> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -27,6 +27,35 @@ struct cmdq_instruction {
> u8 op;
> };
>
> +int cmdq_dev_get_client_reg(struct device *dev,
> + struct cmdq_client_reg *client_reg, int idx)
> +{

Can't we do/call this in cmdq_mbox_create parsing the number of gce-client-reg
properties we have and allocating these using a pointer to cmdq_client_reg in
cmdq_client?
We will have to free the pointer then in cmdq_mbox_destroy.

Regards,
Matthias

> + struct of_phandle_args spec;
> + int err;
> +
> + if (!client_reg)
> + return -ENOENT;
> +
> + err = of_parse_phandle_with_fixed_args(dev->of_node,
> + "mediatek,gce-client-reg",
> + 3, idx, &spec);
> + if (err < 0) {
> + dev_err(dev,
> + "error %d can't parse gce-client-reg property (%d)",
> + err, idx);
> +
> + return err;
> + }
> +
> + client_reg->subsys = (u8)spec.args[0];
> + client_reg->offset = (u16)spec.args[1];
> + client_reg->size = (u16)spec.args[2];
> + of_node_put(spec.np);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(cmdq_dev_get_client_reg);
> +
> static void cmdq_client_timeout(struct timer_list *t)
> {
> struct cmdq_client *client = from_timer(client, t, timer);
> diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
> index a345870a6d10..02ddd60b212f 100644
> --- a/include/linux/soc/mediatek/mtk-cmdq.h
> +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> @@ -15,6 +15,12 @@
>
> struct cmdq_pkt;
>
> +struct cmdq_client_reg {
> + u8 subsys;
> + u16 offset;
> + u16 size;
> +};
> +
> struct cmdq_client {
> spinlock_t lock;
> u32 pkt_cnt;
> @@ -24,6 +30,21 @@ struct cmdq_client {
> u32 timeout_ms; /* in unit of microsecond */
> };
>
> +/**
> + * cmdq_dev_get_client_reg() - parse cmdq client reg from the device
> + * node of CMDQ client
> + * @dev: device of CMDQ mailbox client
> + * @client_reg: CMDQ client reg pointer
> + * @idx: the index of desired reg
> + *
> + * Return: 0 for success; else the error code is returned
> + *
> + * Help CMDQ client parsing the cmdq client reg
> + * from the device node of CMDQ client.
> + */
> +int cmdq_dev_get_client_reg(struct device *dev,
> + struct cmdq_client_reg *client_reg, int idx);
> +
> /**
> * cmdq_mbox_create() - create CMDQ mailbox client and channel
> * @dev: device of CMDQ mailbox client
>

2019-08-27 04:01:14

by Bibby Hsieh

[permalink] [raw]
Subject: Re: [RESEND, PATCH v13 11/12] soc: mediatek: cmdq: add cmdq_dev_get_client_reg function

On Fri, 2019-08-23 at 16:21 +0200, Matthias Brugger wrote:
>
> On 20/08/2019 10:49, Bibby Hsieh wrote:
> > GCE cannot know the register base address, this function
> > can help cmdq client to get the cmdq_client_reg structure.
> >
> > Signed-off-by: Bibby Hsieh <[email protected]>
> > Reviewed-by: CK Hu <[email protected]>
> > ---
> > drivers/soc/mediatek/mtk-cmdq-helper.c | 29 ++++++++++++++++++++++++++
> > include/linux/soc/mediatek/mtk-cmdq.h | 21 +++++++++++++++++++
> > 2 files changed, 50 insertions(+)
> >
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index c53f8476c68d..80f75a1075b4 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -27,6 +27,35 @@ struct cmdq_instruction {
> > u8 op;
> > };
> >
> > +int cmdq_dev_get_client_reg(struct device *dev,
> > + struct cmdq_client_reg *client_reg, int idx)
> > +{
>
> Can't we do/call this in cmdq_mbox_create parsing the number of gce-client-reg
> properties we have and allocating these using a pointer to cmdq_client_reg in
> cmdq_client?
> We will have to free the pointer then in cmdq_mbox_destroy.
>
> Regards,
> Matthias

I don't think we need to keep the cmdq_client_reg in cmdq_client
structure.
Because our client will have own data structure, they will copy the
client_reg information into their own structure.

In the design now, we do not allocate the cmdq_client_reg, client pass
the cmdq_client_reg pointer into this API.
Client will destroy the pointer after they get the information they
want.

Thanks for the comments so much.

Bibby

>
> > + struct of_phandle_args spec;
> > + int err;
> > +
> > + if (!client_reg)
> > + return -ENOENT;
> > +
> > + err = of_parse_phandle_with_fixed_args(dev->of_node,
> > + "mediatek,gce-client-reg",
> > + 3, idx, &spec);
> > + if (err < 0) {
> > + dev_err(dev,
> > + "error %d can't parse gce-client-reg property (%d)",
> > + err, idx);
> > +
> > + return err;
> > + }
> > +
> > + client_reg->subsys = (u8)spec.args[0];
> > + client_reg->offset = (u16)spec.args[1];
> > + client_reg->size = (u16)spec.args[2];
> > + of_node_put(spec.np);
> > +
> > + return 0;
> > +}
> > +EXPORT_SYMBOL(cmdq_dev_get_client_reg);
> > +
> > static void cmdq_client_timeout(struct timer_list *t)
> > {
> > struct cmdq_client *client = from_timer(client, t, timer);
> > diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
> > index a345870a6d10..02ddd60b212f 100644
> > --- a/include/linux/soc/mediatek/mtk-cmdq.h
> > +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> > @@ -15,6 +15,12 @@
> >
> > struct cmdq_pkt;
> >
> > +struct cmdq_client_reg {
> > + u8 subsys;
> > + u16 offset;
> > + u16 size;
> > +};
> > +
> > struct cmdq_client {
> > spinlock_t lock;
> > u32 pkt_cnt;
> > @@ -24,6 +30,21 @@ struct cmdq_client {
> > u32 timeout_ms; /* in unit of microsecond */
> > };
> >
> > +/**
> > + * cmdq_dev_get_client_reg() - parse cmdq client reg from the device
> > + * node of CMDQ client
> > + * @dev: device of CMDQ mailbox client
> > + * @client_reg: CMDQ client reg pointer
> > + * @idx: the index of desired reg
> > + *
> > + * Return: 0 for success; else the error code is returned
> > + *
> > + * Help CMDQ client parsing the cmdq client reg
> > + * from the device node of CMDQ client.
> > + */
> > +int cmdq_dev_get_client_reg(struct device *dev,
> > + struct cmdq_client_reg *client_reg, int idx);
> > +
> > /**
> > * cmdq_mbox_create() - create CMDQ mailbox client and channel
> > * @dev: device of CMDQ mailbox client
> >


2019-08-27 04:13:24

by Bibby Hsieh

[permalink] [raw]
Subject: Re: [RESEND, PATCH v13 09/12] soc: mediatek: cmdq: define the instruction struct

On Fri, 2019-08-23 at 15:50 +0200, Matthias Brugger wrote:
>
> On 20/08/2019 10:49, Bibby Hsieh wrote:
> > Define an instruction structure for gce driver to append command.
> > This structure can make the client's code more readability.
> >
> > Signed-off-by: Bibby Hsieh <[email protected]>
> > Reviewed-by: CK Hu <[email protected]>
> > ---
> > drivers/soc/mediatek/mtk-cmdq-helper.c | 106 +++++++++++++++--------
> > include/linux/mailbox/mtk-cmdq-mailbox.h | 2 +
> > 2 files changed, 74 insertions(+), 34 deletions(-)
> >
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index 7aa0517ff2f3..e3d5b0be8e79 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -9,12 +9,24 @@
> > #include <linux/mailbox_controller.h>
> > #include <linux/soc/mediatek/mtk-cmdq.h>
> >
> > -#define CMDQ_ARG_A_WRITE_MASK 0xffff
> > #define CMDQ_WRITE_ENABLE_MASK BIT(0)
> > #define CMDQ_EOC_IRQ_EN BIT(0)
> > #define CMDQ_EOC_CMD ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
> > << 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)
> > {
> > struct cmdq_client *client = from_timer(client, t, timer);
> > @@ -110,10 +122,8 @@ void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
> > }
> > EXPORT_SYMBOL(cmdq_pkt_destroy);
> >
> > -static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
> > - u32 arg_a, u32 arg_b)
> > +static struct cmdq_instruction *cmdq_pkt_append_command(struct cmdq_pkt *pkt)
> > {
> > - u64 *cmd_ptr;
> >
> > if (unlikely(pkt->cmd_buf_size + CMDQ_INST_SIZE > pkt->buf_size)) {
> > /*
> > @@ -127,81 +137,109 @@ static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
> > pkt->cmd_buf_size += CMDQ_INST_SIZE;
> > WARN_ONCE(1, "%s: buffer size %u is too small !\n",
> > __func__, (u32)pkt->buf_size);
> > - return -ENOMEM;
> > + return NULL;
> > }
> > - cmd_ptr = pkt->va_base + pkt->cmd_buf_size;
> > - (*cmd_ptr) = (u64)((code << CMDQ_OP_CODE_SHIFT) | arg_a) << 32 | arg_b;
> > +
> > + *(u64 *)(pkt->va_base + pkt->cmd_buf_size) = 0;> pkt->cmd_buf_size += CMDQ_INST_SIZE;
> >
> > - return 0;
> > + return pkt->va_base + pkt->cmd_buf_size - CMDQ_INST_SIZE;
> > }
> >
> > int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value)
> > {
> > - u32 arg_a = (offset & CMDQ_ARG_A_WRITE_MASK) |
> > - (subsys << CMDQ_SUBSYS_SHIFT);
> > + struct cmdq_instruction *inst;
> > +
> > + inst = cmdq_pkt_append_command(pkt);
> > + if (!inst)
> > + return -ENOMEM;
> > +
> > + inst->op = CMDQ_CODE_WRITE;
> > + inst->value = value;
> > + inst->offset = offset;
> > + inst->subsys = subsys;
> >
>
> I can see that using cmdq_instruction will make the code more readable, but I
> dislike the approach that cmdq_pkt_append_command returns a pointer where we
> write the instruction to. Better we pass inst to cmdq_pkt_append_command() and
> write it there to cmd_ptr.
>
> I think this way we can get rid of explicitly setting the memory to zero:
> *(u64 *)(pkt->va_base + pkt->cmd_buf_size) = 0;
>
> And if we pass the inst to the append_command we don't have to change the return
> value handling of cmdq_pkt_append_command(), which makes the patch easier to
> understand.

Ok, I will change and resend it.

>
> > - return cmdq_pkt_append_command(pkt, CMDQ_CODE_WRITE, arg_a, value);
> > + return 0;
> > }
> > EXPORT_SYMBOL(cmdq_pkt_write);
> >
> > int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
> > u16 offset, u32 value, u32 mask)
> > {
> > - u32 offset_mask = offset;
> > - int err = 0;
> > + struct cmdq_instruction *inst;
> > + u16 offset_mask = offset;
> >
> > if (mask != 0xffffffff) {
> > - err = cmdq_pkt_append_command(pkt, CMDQ_CODE_MASK, 0, ~mask);
> > + inst = cmdq_pkt_append_command(pkt);
> > + if (!inst)
> > + return -ENOMEM;
> > +
> > + inst->op = CMDQ_CODE_MASK;
> > + inst->mask = ~mask;
> > offset_mask |= CMDQ_WRITE_ENABLE_MASK;
> > }
> > - err |= cmdq_pkt_write(pkt, value, subsys, offset_mask);
> >
> > - return err;
> > + return cmdq_pkt_write(pkt, subsys, offset_mask, value);
> > }
> > EXPORT_SYMBOL(cmdq_pkt_write_mask);
> >
> > int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
> > {
> > - u32 arg_b;
> > + struct cmdq_instruction *inst;
> >
> > if (event >= CMDQ_MAX_EVENT)
> > return -EINVAL;
> >
> > - /*
> > - * 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
> > - */
>
> I have no strong opinion of CMDQ_WFE_OPTION but if you want to introduce it,
> then please copy the comment over to include/linux/mailbox/mtk-cmdq-mailbox.h

Ok. let's move the descriptions to header.
>
> Just one question, why did you call it _OPTION? It's not really expressive for me.

Actually, _OPTION is come from our hardware design name...

>
> > - arg_b = CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | CMDQ_WFE_WAIT_VALUE;
> > + inst = cmdq_pkt_append_command(pkt);
> > + if (!inst)
> > + return -ENOMEM;
> > +
> > + inst->op = CMDQ_CODE_WFE;
> > + inst->value = CMDQ_WFE_OPTION;
> > + inst->event = event;
> >
> > - return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event, arg_b);
> > + return 0;
> > }
> > EXPORT_SYMBOL(cmdq_pkt_wfe);
> >
> > int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event)
> > {
> > + struct cmdq_instruction *inst;
> > +
> > if (event >= CMDQ_MAX_EVENT)
> > return -EINVAL;
> >
> > - return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event,
> > - CMDQ_WFE_UPDATE);
> > + inst = cmdq_pkt_append_command(pkt);
> > + if (!inst)
> > + return -ENOMEM;
> > +
> > + inst->op = CMDQ_CODE_WFE;
> > + inst->value = CMDQ_WFE_UPDATE;
> > + inst->event = event;
> > +
> > + return 0;
> > }
> > EXPORT_SYMBOL(cmdq_pkt_clear_event);
> >
> > static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
> > {
> > - int err;
> > + struct cmdq_instruction *inst;
> > +
> > + inst = cmdq_pkt_append_command(pkt);
> > + if (!inst)
> > + return -ENOMEM;
> >
> > - /* insert EOC and generate IRQ for each command iteration */
>
> Please don't delete the comment.
>
> > - 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;
> >
> > - /* JUMP to end */
>
> Same here.
>
> Regards,
> Matthias
>
> > - err |= cmdq_pkt_append_command(pkt, CMDQ_CODE_JUMP, 0, CMDQ_JUMP_PASS);
> > + inst = cmdq_pkt_append_command(pkt);
> > + if (!inst)
> > + return -ENOMEM;
> > +
> > + inst->op = CMDQ_CODE_JUMP;
> > + inst->value = CMDQ_JUMP_PASS;
> >
> > - return err;
> > + return 0;
> > }
> >
> > static void cmdq_pkt_flush_async_cb(struct cmdq_cb_data data)
> > diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > index 911475da7a53..c8adedefaf42 100644
> > --- a/include/linux/mailbox/mtk-cmdq-mailbox.h
> > +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > @@ -19,6 +19,8 @@
> > #define CMDQ_WFE_UPDATE BIT(31)
> > #define CMDQ_WFE_WAIT BIT(15)
> > #define CMDQ_WFE_WAIT_VALUE 0x1
> > +#define CMDQ_WFE_OPTION (CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | \
> > + CMDQ_WFE_WAIT_VALUE)
> > /** cmdq event maximum */
> > #define CMDQ_MAX_EVENT 0x3ff
> >
> >

--
Bibby

2019-08-27 10:05:38

by Matthias Brugger

[permalink] [raw]
Subject: Re: [RESEND, PATCH v13 09/12] soc: mediatek: cmdq: define the instruction struct



On 27/08/2019 06:12, Bibby Hsieh wrote:

>>>
>>> int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
>>> {
>>> - u32 arg_b;
>>> + struct cmdq_instruction *inst;
>>>
>>> if (event >= CMDQ_MAX_EVENT)
>>> return -EINVAL;
>>>
>>> - /*
>>> - * 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
>>> - */
>>
>> I have no strong opinion of CMDQ_WFE_OPTION but if you want to introduce it,
>> then please copy the comment over to include/linux/mailbox/mtk-cmdq-mailbox.h
>
> Ok. let's move the descriptions to header.
>>
>> Just one question, why did you call it _OPTION? It's not really expressive for me.
>
> Actually, _OPTION is come from our hardware design name...
>

Ok, then I'll stop bike-shedding. I leave it up to you to rename it or not.

Regards,
Matthias

2019-08-27 10:16:25

by Matthias Brugger

[permalink] [raw]
Subject: Re: [RESEND, PATCH v13 11/12] soc: mediatek: cmdq: add cmdq_dev_get_client_reg function



On 27/08/2019 05:59, Bibby Hsieh wrote:
> On Fri, 2019-08-23 at 16:21 +0200, Matthias Brugger wrote:
>>
>> On 20/08/2019 10:49, Bibby Hsieh wrote:
>>> GCE cannot know the register base address, this function
>>> can help cmdq client to get the cmdq_client_reg structure.
>>>
>>> Signed-off-by: Bibby Hsieh <[email protected]>
>>> Reviewed-by: CK Hu <[email protected]>
>>> ---
>>> drivers/soc/mediatek/mtk-cmdq-helper.c | 29 ++++++++++++++++++++++++++
>>> include/linux/soc/mediatek/mtk-cmdq.h | 21 +++++++++++++++++++
>>> 2 files changed, 50 insertions(+)
>>>
>>> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
>>> index c53f8476c68d..80f75a1075b4 100644
>>> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
>>> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
>>> @@ -27,6 +27,35 @@ struct cmdq_instruction {
>>> u8 op;
>>> };
>>>
>>> +int cmdq_dev_get_client_reg(struct device *dev,
>>> + struct cmdq_client_reg *client_reg, int idx)
>>> +{
>>
>> Can't we do/call this in cmdq_mbox_create parsing the number of gce-client-reg
>> properties we have and allocating these using a pointer to cmdq_client_reg in
>> cmdq_client?
>> We will have to free the pointer then in cmdq_mbox_destroy.
>>
>> Regards,
>> Matthias
>
> I don't think we need to keep the cmdq_client_reg in cmdq_client
> structure.
> Because our client will have own data structure, they will copy the
> client_reg information into their own structure.
>
> In the design now, we do not allocate the cmdq_client_reg, client pass
> the cmdq_client_reg pointer into this API.
> Client will destroy the pointer after they get the information they
> want.
>

My point wasn't so much about the lifecycle of the object, but the fact that we
add another call, which can be already full-filled by a necessary previous call
to cmdq_mbox_create. So I would prefer to add the information gathering for
cmdq_client_reg in this call, and let it live there for the time cmdq_client
lives. In the end we are talking about 40 bits of memory.

Regards,
Matthias

> Thanks for the comments so much.
>
> Bibby
>
>>
>>> + struct of_phandle_args spec;
>>> + int err;
>>> +
>>> + if (!client_reg)
>>> + return -ENOENT;
>>> +
>>> + err = of_parse_phandle_with_fixed_args(dev->of_node,
>>> + "mediatek,gce-client-reg",
>>> + 3, idx, &spec);
>>> + if (err < 0) {
>>> + dev_err(dev,
>>> + "error %d can't parse gce-client-reg property (%d)",
>>> + err, idx);
>>> +
>>> + return err;
>>> + }
>>> +
>>> + client_reg->subsys = (u8)spec.args[0];
>>> + client_reg->offset = (u16)spec.args[1];
>>> + client_reg->size = (u16)spec.args[2];
>>> + of_node_put(spec.np);
>>> +
>>> + return 0;
>>> +}
>>> +EXPORT_SYMBOL(cmdq_dev_get_client_reg);
>>> +
>>> static void cmdq_client_timeout(struct timer_list *t)
>>> {
>>> struct cmdq_client *client = from_timer(client, t, timer);
>>> diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
>>> index a345870a6d10..02ddd60b212f 100644
>>> --- a/include/linux/soc/mediatek/mtk-cmdq.h
>>> +++ b/include/linux/soc/mediatek/mtk-cmdq.h
>>> @@ -15,6 +15,12 @@
>>>
>>> struct cmdq_pkt;
>>>
>>> +struct cmdq_client_reg {
>>> + u8 subsys;
>>> + u16 offset;
>>> + u16 size;
>>> +};
>>> +
>>> struct cmdq_client {
>>> spinlock_t lock;
>>> u32 pkt_cnt;
>>> @@ -24,6 +30,21 @@ struct cmdq_client {
>>> u32 timeout_ms; /* in unit of microsecond */
>>> };
>>>
>>> +/**
>>> + * cmdq_dev_get_client_reg() - parse cmdq client reg from the device
>>> + * node of CMDQ client
>>> + * @dev: device of CMDQ mailbox client
>>> + * @client_reg: CMDQ client reg pointer
>>> + * @idx: the index of desired reg
>>> + *
>>> + * Return: 0 for success; else the error code is returned
>>> + *
>>> + * Help CMDQ client parsing the cmdq client reg
>>> + * from the device node of CMDQ client.
>>> + */
>>> +int cmdq_dev_get_client_reg(struct device *dev,
>>> + struct cmdq_client_reg *client_reg, int idx);
>>> +
>>> /**
>>> * cmdq_mbox_create() - create CMDQ mailbox client and channel
>>> * @dev: device of CMDQ mailbox client
>>>
>
>

2019-08-28 08:34:22

by Bibby Hsieh

[permalink] [raw]
Subject: Re: [RESEND, PATCH v13 11/12] soc: mediatek: cmdq: add cmdq_dev_get_client_reg function

On Tue, 2019-08-27 at 12:13 +0200, Matthias Brugger wrote:
>
> On 27/08/2019 05:59, Bibby Hsieh wrote:
> > On Fri, 2019-08-23 at 16:21 +0200, Matthias Brugger wrote:
> >>
> >> On 20/08/2019 10:49, Bibby Hsieh wrote:
> >>> GCE cannot know the register base address, this function
> >>> can help cmdq client to get the cmdq_client_reg structure.
> >>>
> >>> Signed-off-by: Bibby Hsieh <[email protected]>
> >>> Reviewed-by: CK Hu <[email protected]>
> >>> ---
> >>> drivers/soc/mediatek/mtk-cmdq-helper.c | 29 ++++++++++++++++++++++++++
> >>> include/linux/soc/mediatek/mtk-cmdq.h | 21 +++++++++++++++++++
> >>> 2 files changed, 50 insertions(+)
> >>>
> >>> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>> index c53f8476c68d..80f75a1075b4 100644
> >>> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>> @@ -27,6 +27,35 @@ struct cmdq_instruction {
> >>> u8 op;
> >>> };
> >>>
> >>> +int cmdq_dev_get_client_reg(struct device *dev,
> >>> + struct cmdq_client_reg *client_reg, int idx)
> >>> +{
> >>
> >> Can't we do/call this in cmdq_mbox_create parsing the number of gce-client-reg
> >> properties we have and allocating these using a pointer to cmdq_client_reg in
> >> cmdq_client?
> >> We will have to free the pointer then in cmdq_mbox_destroy.
> >>
> >> Regards,
> >> Matthias
> >
> > I don't think we need to keep the cmdq_client_reg in cmdq_client
> > structure.
> > Because our client will have own data structure, they will copy the
> > client_reg information into their own structure.
> >
> > In the design now, we do not allocate the cmdq_client_reg, client pass
> > the cmdq_client_reg pointer into this API.
> > Client will destroy the pointer after they get the information they
> > want.
> >
>
> My point wasn't so much about the lifecycle of the object, but the fact that we
> add another call, which can be already full-filled by a necessary previous call
> to cmdq_mbox_create. So I would prefer to add the information gathering for
> cmdq_client_reg in this call, and let it live there for the time cmdq_client
> lives. In the end we are talking about 40 bits of memory.
>

Thanks for the comments. :D

Actually, I'm working for developing the chandes for MTK DRM apply cmdq
interface.
For MTK DRM, all the components included in MTK_CRTC use one mailbox
channel. According to [1], we create mailbox channel by mmsys device
node after get all the informations (include cmdq_client_reg) about
every device node of display components respectively. Please refer to
[2], [3] and [4], I'm going to upstream them recently.

If create mailbox channel and get the cmdq_client_reg in the same device
node, your suggestion is good for me.
But from display and mdp's viewpoint now, I don't think it is convenient
for them.

So I still prefer separate this function out of cmdq_mbox_create.:D


[1]
https://elixir.bootlin.com/linux/latest/source/arch/arm64/boot/dts/mediatek/mt8173.dtsi#907
[2] get cmdq_client_reg in mtk_ddp_comp_init()
https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/1746354/12/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c#431
[3] create mailbox channel in mtk_drm_crtc_create()
https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/1746354/12/drivers/gpu/drm/mediatek/mtk_drm_crtc.c#814
[4] After component_bind_all(), the mtk_drm_crtc_create will be called
https://chromium.googlesource.com/chromiumos/third_party/kernel/+/e15c2dc6ceb4810a2090cd11a512932095866559/drivers/gpu/drm/mediatek/mtk_drm_drv.c#452

Thanks.
Bibby

> Regards,
> Matthias
>
> > Thanks for the comments so much.
> >
> > Bibby
> >
> >>
> >>> + struct of_phandle_args spec;
> >>> + int err;
> >>> +
> >>> + if (!client_reg)
> >>> + return -ENOENT;
> >>> +
> >>> + err = of_parse_phandle_with_fixed_args(dev->of_node,
> >>> + "mediatek,gce-client-reg",
> >>> + 3, idx, &spec);
> >>> + if (err < 0) {
> >>> + dev_err(dev,
> >>> + "error %d can't parse gce-client-reg property (%d)",
> >>> + err, idx);
> >>> +
> >>> + return err;
> >>> + }
> >>> +
> >>> + client_reg->subsys = (u8)spec.args[0];
> >>> + client_reg->offset = (u16)spec.args[1];
> >>> + client_reg->size = (u16)spec.args[2];
> >>> + of_node_put(spec.np);
> >>> +
> >>> + return 0;
> >>> +}
> >>> +EXPORT_SYMBOL(cmdq_dev_get_client_reg);
> >>> +
> >>> static void cmdq_client_timeout(struct timer_list *t)
> >>> {
> >>> struct cmdq_client *client = from_timer(client, t, timer);
> >>> diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
> >>> index a345870a6d10..02ddd60b212f 100644
> >>> --- a/include/linux/soc/mediatek/mtk-cmdq.h
> >>> +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> >>> @@ -15,6 +15,12 @@
> >>>
> >>> struct cmdq_pkt;
> >>>
> >>> +struct cmdq_client_reg {
> >>> + u8 subsys;
> >>> + u16 offset;
> >>> + u16 size;
> >>> +};
> >>> +
> >>> struct cmdq_client {
> >>> spinlock_t lock;
> >>> u32 pkt_cnt;
> >>> @@ -24,6 +30,21 @@ struct cmdq_client {
> >>> u32 timeout_ms; /* in unit of microsecond */
> >>> };
> >>>
> >>> +/**
> >>> + * cmdq_dev_get_client_reg() - parse cmdq client reg from the device
> >>> + * node of CMDQ client
> >>> + * @dev: device of CMDQ mailbox client
> >>> + * @client_reg: CMDQ client reg pointer
> >>> + * @idx: the index of desired reg
> >>> + *
> >>> + * Return: 0 for success; else the error code is returned
> >>> + *
> >>> + * Help CMDQ client parsing the cmdq client reg
> >>> + * from the device node of CMDQ client.
> >>> + */
> >>> +int cmdq_dev_get_client_reg(struct device *dev,
> >>> + struct cmdq_client_reg *client_reg, int idx);
> >>> +
> >>> /**
> >>> * cmdq_mbox_create() - create CMDQ mailbox client and channel
> >>> * @dev: device of CMDQ mailbox client
> >>>
> >
> >