Re: [PATCH] [media] mtk-mdp: Fix g_/s_selection capture/compose logic

2017-04-27 Thread houlong wei
On Thu, 2017-04-13 at 14:50 +0800, Wu-Cheng Li (李務誠) wrote:
> Reviewed-by: Wu-Cheng Li 
> 
> On Thu, Apr 13, 2017 at 12:18 PM, Minghsiu Tsai
>  wrote:
> > From: Daniel Kurtz 
> >
> > Experiments show that the:
> >  (1) mtk-mdp uses the _MPLANE form of CAPTURE/OUTPUT
> >  (2) CAPTURE types use CROP targets, and OUTPUT types use COMPOSE targets
> >
> > Signed-off-by: Daniel Kurtz 
> > Signed-off-by: Minghsiu Tsai 
Acked-by:Houlong Wei 
> >
> > ---
> >  drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c | 18 +-
> >  1 file changed, 9 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c 
> > b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> > index 13afe48..8ab7ca0 100644
> > --- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> > +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> > @@ -837,12 +837,12 @@ static int mtk_mdp_m2m_g_selection(struct file *file, 
> > void *fh,
> > struct mtk_mdp_ctx *ctx = fh_to_ctx(fh);
> > bool valid = false;
> >
> > -   if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
> > -   if (mtk_mdp_is_target_compose(s->target))
> > -   valid = true;
> > -   } else if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
> > +   if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
> > if (mtk_mdp_is_target_crop(s->target))
> > valid = true;
> > +   } else if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
> > +   if (mtk_mdp_is_target_compose(s->target))
> > +   valid = true;
> > }
> > if (!valid) {
> > mtk_mdp_dbg(1, "[%d] invalid type:%d,%u", ctx->id, s->type,
> > @@ -907,12 +907,12 @@ static int mtk_mdp_m2m_s_selection(struct file *file, 
> > void *fh,
> > int ret;
> > bool valid = false;
> >
> > -   if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
> > -   if (s->target == V4L2_SEL_TGT_COMPOSE)
> > -   valid = true;
> > -   } else if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
> > +   if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
> > if (s->target == V4L2_SEL_TGT_CROP)
> > valid = true;
> > +   } else if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
> > +   if (s->target == V4L2_SEL_TGT_COMPOSE)
> > +   valid = true;
> > }
> > if (!valid) {
> > mtk_mdp_dbg(1, "[%d] invalid type:%d,%u", ctx->id, s->type,
> > @@ -925,7 +925,7 @@ static int mtk_mdp_m2m_s_selection(struct file *file, 
> > void *fh,
> > if (ret)
> > return ret;
> >
> > -   if (mtk_mdp_is_target_crop(s->target))
> > +   if (mtk_mdp_is_target_compose(s->target))
> > frame = >s_frame;
> > else
> > frame = >d_frame;
> > --
> > 1.9.1
> >




[PATCH v22 2/4] mailbox: mediatek: Add Mediatek CMDQ driver

2018-06-27 Thread Houlong Wei
This patch is first version of Mediatek Command Queue(CMDQ) driver. The
CMDQ is used to help write registers with critical time limitation,
such as updating display configuration during the vblank. It controls
Global Command Engine (GCE) hardware to achieve this requirement.
Currently, CMDQ only supports display related hardwares, but we expect
it can be extended to other hardwares for future requirements.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
Signed-off-by: CK Hu 
---
 drivers/mailbox/Kconfig  |   10 +
 drivers/mailbox/Makefile |2 +
 drivers/mailbox/mtk-cmdq-mailbox.c   |  634 ++
 include/linux/mailbox/mtk-cmdq-mailbox.h |   70 
 4 files changed, 716 insertions(+)
 create mode 100644 drivers/mailbox/mtk-cmdq-mailbox.c
 create mode 100644 include/linux/mailbox/mtk-cmdq-mailbox.h

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index e63d29a..2bbabc9 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -189,4 +189,14 @@ config STM32_IPCC
  Mailbox implementation for STMicroelectonics STM32 family chips
  with hardware for Inter-Processor Communication Controller (IPCC)
  between processors. Say Y here if you want to have this support.
+
+config MTK_CMDQ_MBOX
+   tristate "MediaTek CMDQ Mailbox Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ mailbox driver. The CMDQ is used to help read/write registers with
+ critical time limitation, such as updating display configuration
+ during the vblank.
 endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 4d501be..4b00804 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -40,3 +40,5 @@ obj-$(CONFIG_QCOM_APCS_IPC)   += qcom-apcs-ipc-mailbox.o
 obj-$(CONFIG_TEGRA_HSP_MBOX)   += tegra-hsp.o
 
 obj-$(CONFIG_STM32_IPCC)   += stm32-ipcc.o
+
+obj-$(CONFIG_MTK_CMDQ_MBOX)+= mtk-cmdq-mailbox.o
diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
b/drivers/mailbox/mtk-cmdq-mailbox.c
new file mode 100644
index 000..93d87cb
--- /dev/null
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -0,0 +1,634 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_OP_CODE_MASK  (0xff << CMDQ_OP_CODE_SHIFT)
+#define CMDQ_TIMEOUT_MS1000
+#define CMDQ_IRQ_MASK  0x
+#define CMDQ_NUM_CMD(t)(t->cmd_buf_size / 
CMDQ_INST_SIZE)
+
+#define CMDQ_CURR_IRQ_STATUS   0x10
+#define CMDQ_THR_SLOT_CYCLES   0x30
+#define CMDQ_THR_BASE  0x100
+#define CMDQ_THR_SIZE  0x80
+#define CMDQ_THR_WARM_RESET0x00
+#define CMDQ_THR_ENABLE_TASK   0x04
+#define CMDQ_THR_SUSPEND_TASK  0x08
+#define CMDQ_THR_CURR_STATUS   0x0c
+#define CMDQ_THR_IRQ_STATUS0x10
+#define CMDQ_THR_IRQ_ENABLE0x14
+#define CMDQ_THR_CURR_ADDR 0x20
+#define CMDQ_THR_END_ADDR  0x24
+#define CMDQ_THR_WAIT_TOKEN0x30
+#define CMDQ_THR_PRIORITY  0x40
+
+#define CMDQ_NO_TIMEOUT0xu
+#define CMDQ_THR_ACTIVE_SLOT_CYCLES0x3200
+#define CMDQ_THR_ENABLED   0x1
+#define CMDQ_THR_DISABLED  0x0
+#define CMDQ_THR_SUSPEND   0x1
+#define CMDQ_THR_RESUME0x0
+#define CMDQ_THR_STATUS_SUSPENDED  BIT(1)
+#define CMDQ_THR_DO_WARM_RESET BIT(0)
+#define CMDQ_THR_IRQ_DONE  0x1
+#define CMDQ_THR_IRQ_ERROR 0x12
+#define CMDQ_THR_IRQ_EN(CMDQ_THR_IRQ_ERROR | 
CMDQ_THR_IRQ_DONE)
+#define CMDQ_THR_IS_WAITINGBIT(31)
+
+#define CMDQ_JUMP_BY_OFFSET0x1000
+#define CMDQ_JUMP_BY_PA0x1001
+
+struct cmdq_thread {
+   struct mbox_chan*chan;
+   void __iomem*base;
+   struct list_headtask_busy_list;
+   struct timer_list   timeout;
+   u32 timeout_ms;
+   u32 priority;
+   boolatomic_exec;
+};
+
+struct cmdq_task {
+   struct cmdq *cmdq;
+   struct list_headlist_entry;
+   dma_addr_t  pa_base;
+   struct cmdq_thread  *thread;
+   struct cmdq_pkt *pkt; /* the packet sent from mailbox client */
+};
+
+struct cmdq {
+   struct mbox_controller  mbox;
+   void __iomem*base;
+   u32 irq;
+   u32 thread_nr;
+   struct cmdq_thread  *thread;

[PATCH v22 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-06-27 Thread Houlong Wei
Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 drivers/soc/mediatek/Kconfig   |   12 ++
 drivers/soc/mediatek/Makefile  |1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c |  258 
 include/linux/soc/mediatek/mtk-cmdq.h  |  132 
 4 files changed, 403 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
 create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index a7d0667..17bd759 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -4,6 +4,18 @@
 menu "MediaTek SoC drivers"
depends on ARCH_MEDIATEK || COMPILE_TEST
 
+config MTK_CMDQ
+   tristate "MediaTek CMDQ Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select MAILBOX
+   select MTK_CMDQ_MBOX
+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
 config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
select REGMAP
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..64ce5ee 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
 obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
 obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
new file mode 100644
index 000..6c66091
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -0,0 +1,258 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_ARG_A_WRITE_MASK  0x
+#define CMDQ_WRITE_ENABLE_MASK BIT(0)
+#define CMDQ_EOC_IRQ_ENBIT(0)
+#define CMDQ_EOC_CMD   ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
+   << 32 | CMDQ_EOC_IRQ_EN)
+
+int cmdq_pkt_realloc_cmd_buffer(struct cmdq_pkt *pkt, size_t size)
+{
+   void *new_buf;
+
+   new_buf = krealloc(pkt->va_base, size, GFP_KERNEL | __GFP_ZERO);
+   if (!new_buf)
+   return -ENOMEM;
+   pkt->va_base = new_buf;
+   pkt->buf_size = size;
+
+   return 0;
+}
+EXPORT_SYMBOL(cmdq_pkt_realloc_cmd_buffer);
+
+struct cmdq_client *cmdq_mbox_create(struct device *dev, int index)
+{
+   struct cmdq_client *client;
+   long err = 0;
+
+   client = kzalloc(sizeof(*client), GFP_KERNEL);
+   if (!client)
+   return (struct cmdq_client *)-ENOMEM;
+
+   client->client.dev = dev;
+   client->client.tx_block = false;
+   client->chan = mbox_request_channel(>client, index);
+
+   if (IS_ERR(client->chan)) {
+   dev_err(dev, "failed to request channel\n");
+   err = PTR_ERR(client->chan);
+   kfree(client);
+
+   return (struct cmdq_client *)err;
+   }
+
+   return client;
+}
+EXPORT_SYMBOL(cmdq_mbox_create);
+
+void cmdq_mbox_destroy(struct cmdq_client *client)
+{
+   mbox_free_channel(client->chan);
+   kfree(client);
+}
+EXPORT_SYMBOL(cmdq_mbox_destroy);
+
+int cmdq_pkt_create(struct cmdq_pkt **pkt_ptr)
+{
+   struct cmdq_pkt *pkt;
+   int err;
+
+   pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
+   if (!pkt)
+   return -ENOMEM;
+   err = cmdq_pkt_realloc_cmd_buffer(pkt, PAGE_SIZE);
+   if (err < 0) {
+   kfree(pkt);
+   return err;
+   }
+   *pkt_ptr = pkt;
+
+   return 0;
+}
+EXPORT_SYMBOL(cmdq_pkt_create);
+
+void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
+{
+   kfree(pkt->va_base);
+   kfree(pkt);
+}
+EXPORT_SYMBOL(cmdq_pkt_destroy);
+
+static bool cmdq_pkt_is_finalized(struct cmdq_pkt *pkt)
+{
+   u64 *expect_eoc;
+
+   if (pkt->cmd_buf_size < CMDQ_INST_SIZE << 1)
+   return false;
+
+   expect_eoc = pkt->va_base + pkt->cmd_buf_size - (CMDQ_INST_SIZE << 1);
+   if (*expect_eoc == CMDQ_EOC_CMD)
+   return true;
+
+   return false;
+}
+
+static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
+  u32 arg_a, u32 arg_b)
+{
+   u64 *cmd_ptr;
+   int err;
+
+   if (WARN_ON(cmdq_pkt_is_finalized(pkt)))
+   return -EBUSY;
+   if (unlikely(pkt->cmd_buf_size + CMDQ_INST_SIZE > pkt->buf_size)) {
+   err = cmdq_pkt_realloc_cmd_buffer(pkt, pkt->buf_size <<

[PATCH v22 3/4] arm64: dts: mt8173: Add GCE node

2018-06-27 Thread Houlong Wei
This patch adds the device node of the GCE hardware for CMDQ module.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi |   11 +++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 94597e3..d180a6d 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "mt8173-pinfunc.h"
 
 / {
@@ -519,6 +520,16 @@
status = "disabled";
};
 
+   gce: gce@10212000 {
+   compatible = "mediatek,mt8173-gce";
+   reg = <0 0x10212000 0 0x1000>;
+   interrupts = ;
+   clocks = < CLK_INFRA_GCE>;
+   clock-names = "gce";
+   thread-num = ;
+   #mbox-cells = <4>;
+   };
+
mipi_tx0: mipi-dphy@10215000 {
compatible = "mediatek,mt8173-mipi-tx";
reg = <0 0x10215000 0 0x1000>;
-- 
1.7.9.5



[PATCH v22 1/4] dt-bindings: soc: Add documentation for the MediaTek GCE unit

2018-06-27 Thread Houlong Wei
This adds documentation for the MediaTek Global Command Engine (GCE) unit
found in MT8173 SoCs.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
Hi Rob,
  I don't add your ACK in this version since the dt-binding description
has been changed. Thanks.
---
 .../devicetree/bindings/mailbox/mtk-gce.txt|   65 
 include/dt-bindings/gce/mt8173-gce.h   |   48 +++
 2 files changed, 113 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk-gce.txt
 create mode 100644 include/dt-bindings/gce/mt8173-gce.h

diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt 
b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
new file mode 100644
index 000..26f65a4
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
@@ -0,0 +1,65 @@
+MediaTek GCE
+===
+
+The Global Command Engine (GCE) is used to help read/write registers with
+critical time limitation, such as updating display configuration during the
+vblank. The GCE can be used to implement the Command Queue (CMDQ) driver.
+
+CMDQ driver uses mailbox framework for communication. Please refer to
+mailbox.txt for generic information about mailbox device-tree bindings.
+
+Required properties:
+- compatible: Must be "mediatek,mt8173-gce"
+- reg: Address range of the GCE unit
+- interrupts: The interrupt signal from the GCE block
+- clock: Clocks according to the common clock binding
+- clock-names: Must be "gce" to stand for GCE clock
+- thread-num: Maximum threads count of GCE.
+- #mbox-cells: Should be 4.
+   < channel timeout priority atomic_exec>
+   phandle: Label name of a gce node.
+   channel: Channel of mailbox. Be equal to the thread id of GCE.
+   timeout: Maximum time of software waiting GCE processing done, in unit
+   of millisecond.
+   priority: Priority of GCE thread.
+   atomic_exec: GCE processing continuous packets of commands in atomic
+   way.
+
+Required properties for a client device:
+- mboxes: Client use mailbox to communicate with GCE, it should have this
+  property and list of phandle, mailbox specifiers.
+- gce-subsys: Specify the sub-system id which is corresponding to the register
+  address.
+
+Optional properties for a client device:
+- gce-event: Specify the event if the client has any. Because the event is
+  parsed by client, so client can replace 'gce-event' with other meaningful
+  name.
+
+Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h'. Such 
as
+thread number, sub-system ids, thread priority, event ids.
+
+Example:
+
+   gce: gce@10212000 {
+   compatible = "mediatek,mt8173-gce";
+   reg = <0 0x10212000 0 0x1000>;
+   interrupts = ;
+   clocks = < CLK_INFRA_GCE>;
+   clock-names = "gce";
+   thread-num = CMDQ_THR_MAX_COUNT;
+   #mbox-cells = <4>;
+   };
+
+Example for a client device:
+
+   mmsys: clock-controller@1400 {
+   compatible = "mediatek,mt8173-mmsys";
+   mboxes = < 0 2000 CMDQ_THR_PRIO_LOWEST 1>,
+< 1 2000 CMDQ_THR_PRIO_LOWEST 1>;
+   gce-subsys = ;
+   mutex-event-eof = ;
+
+   ...
+   };
diff --git a/include/dt-bindings/gce/mt8173-gce.h 
b/include/dt-bindings/gce/mt8173-gce.h
new file mode 100644
index 000..89eb3b8
--- /dev/null
+++ b/include/dt-bindings/gce/mt8173-gce.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Houlong Wei 
+ *
+ */
+
+#ifndef _DT_BINDINGS_GCE_MT8173_H
+#define _DT_BINDINGS_GCE_MT8173_H
+
+#define CMDQ_NO_TIMEOUT0x
+
+#define CMDQ_THR_MAX_COUNT 16
+
+/* GCE HW thread priority */
+#define CMDQ_THR_PRIO_LOWEST   0
+#define CMDQ_THR_PRIO_HIGHEST  1
+
+/* GCE SUBSYS */
+#define SUBSYS_14001
+#define SUBSYS_14012
+#define SUBSYS_14023
+
+/* GCE HW EVENT */
+#define CMDQ_EVENT_DISP_OVL0_SOF   11
+#define CMDQ_EVENT_DISP_OVL1_SOF   12
+#define CMDQ_EVENT_DISP_RDMA0_SOF  13
+#define CMDQ_EVENT_DISP_RDMA1_SOF  14
+#define CMDQ_EVENT_DISP_RDMA2_SOF  15
+#define CMDQ_EVENT_DISP_WDMA0_SOF  16
+#define CMDQ_EVENT_DISP_WDMA1_SOF  17
+#define CMDQ_EVENT_DISP_OVL0_EOF   39
+#define CMDQ_EVENT_DISP_OVL1_EOF   40
+#define CMDQ_EVENT_DISP_RDMA0_EOF  41
+#define CMDQ_EVENT_DISP_RDMA1_EOF  42
+#define CMDQ_EVENT_DISP_RDMA2_EOF  43
+#define CMDQ_EVENT_DISP_WDMA0_EOF  44
+#define CMDQ_EVENT_DISP_WDMA1_EOF  45
+#define CMDQ_EVENT_MUTEX0_STREAM_EOF   53
+#define CMDQ_EVENT_MUTEX1_STREAM_EOF   54
+#define CMDQ_EVENT_MUTE

[PATCH v22 0/4] MediaTek MT8173 CMDQ support

2018-06-27 Thread Houlong Wei
Hi,

This is Mediatek MT8173 Command Queue(CMDQ) driver. The CMDQ is used
to help write registers with critical time limitation, such as
updating display configuration during the vblank. It controls Global
Command Engine (GCE) hardware to achieve this requirement.

Changes since v21:
 -rebase on v4.18-rc1
 -remove subsys code and event id definition from mtk-cmdq-helper.c
 -add mt8173-gce.h to define the subsys code and envent id
Changes since v20:
 -rebase on v4.15-rc1
 -move dma_map_single outside of spinlock
Changes since v19:
- rebase to v4.10-rc2

Houlong Wei (4):
  dt-bindings: soc: Add documentation for the MediaTek GCE unit
  mailbox: mediatek: Add Mediatek CMDQ driver
  arm64: dts: mt8173: Add GCE node
  soc: mediatek: Add Mediatek CMDQ helper

 .../devicetree/bindings/mailbox/mtk-gce.txt|   65 ++
 arch/arm64/boot/dts/mediatek/mt8173.dtsi   |   11 +
 drivers/mailbox/Kconfig|   10 +
 drivers/mailbox/Makefile   |2 +
 drivers/mailbox/mtk-cmdq-mailbox.c |  633 
 drivers/soc/mediatek/Kconfig   |   12 +
 drivers/soc/mediatek/Makefile  |1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c |  258 
 include/dt-bindings/gce/mt8173-gce.h   |   48 ++
 include/linux/mailbox/mtk-cmdq-mailbox.h   |   70 +++
 include/linux/soc/mediatek/mtk-cmdq.h  |  132 
 11 files changed, 1242 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk-gce.txt
 create mode 100644 drivers/mailbox/mtk-cmdq-mailbox.c
 create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
 create mode 100644 include/dt-bindings/gce/mt8173-gce.h
 create mode 100644 include/linux/mailbox/mtk-cmdq-mailbox.h
 create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

-- 
1.7.9.5 



Re: [PATCH v21 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-06-27 Thread houlong wei
On Tue, 2018-02-06 at 10:52 +0800, CK Hu wrote:
> Hi, Houlong:
> 
> I've some inline comment.
> 
> On Wed, 2018-01-31 at 15:28 +0800, houlong@mediatek.com wrote:
> > From: "hs.l...@mediatek.com" 
> >
> > Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.
> >
> > Signed-off-by: Houlong Wei 
> > Signed-off-by: HS Liao 
> > ---
> >  drivers/soc/mediatek/Kconfig   |   12 ++
> >  drivers/soc/mediatek/Makefile  |1 +
> >  drivers/soc/mediatek/mtk-cmdq-helper.c |  322 
> > 
> >  include/linux/soc/mediatek/mtk-cmdq.h  |  174 +
> >  4 files changed, 509 insertions(+)
> >  create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
> >  create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h
> >
> > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > index a7d0667..e66582e 100644
> > --- a/drivers/soc/mediatek/Kconfig
> > +++ b/drivers/soc/mediatek/Kconfig
> > @@ -4,6 +4,18 @@
> >  menu "MediaTek SoC drivers"
> >  depends on ARCH_MEDIATEK || COMPILE_TEST
> >
> > +config MTK_CMDQ
> > +bool "MediaTek CMDQ Support"
> > +depends on ARM64 && ( ARCH_MEDIATEK || COMPILE_TEST )
> > +select MAILBOX
> > +select MTK_CMDQ_MBOX
> > +select MTK_INFRACFG
> > +help
> > +  Say yes here to add support for the MediaTek Command Queue (CMDQ)
> > +  driver. The CMDQ is used to help read/write registers with critical
> > +  time limitation, such as updating display configuration during the
> > +  vblank.
> > +
> >  config MTK_INFRACFG
> >  bool "MediaTek INFRACFG Support"
> >  select REGMAP
> > diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> > index 12998b0..64ce5ee 100644
> > --- a/drivers/soc/mediatek/Makefile
> > +++ b/drivers/soc/mediatek/Makefile
> > @@ -1,3 +1,4 @@
> > +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
> >  obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
> >  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
> >  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > new file mode 100644
> > index 000..80d0558
> > --- /dev/null
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -0,0 +1,322 @@
> > +/*
> > + * Copyright (c) 2015 MediaTek Inc.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define CMDQ_ARG_A_WRITE_MASK0x
> > +#define CMDQ_WRITE_ENABLE_MASKBIT(0)
> > +#define CMDQ_EOC_IRQ_ENBIT(0)
> > +#define CMDQ_EOC_CMD((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
> > +<< 32 | CMDQ_EOC_IRQ_EN)
> > +
> > +struct cmdq_subsys {
> > +u32base;
> > +intid;
> > +};
> > +
> > +static const struct cmdq_subsys gce_subsys[] = {
> > +{0x1400, 1},
> > +{0x1401, 2},
> > +{0x1402, 3},
> > +};
> 
> I think subsys definition varies by different SoC, so it's better to
> pass these definition from device tree to driver (client driver), and
> client driver pass this subsys in the related interface. For example,
> 
> in include/dt-bindings/gce/mt8173-gce.h, you define
> 
> #define GCE_SUBSYS_14001
> #define GCE_SUBSYS_14012
> #define GCE_SUBSYS_14023
> 
> in device tree, place the subsys definition in client device node,
> 
> #include "dt-bindings/gce/mt8173-gce.h"
> 
> ovl0: ovl@1400c000 {
> compatible = "mediatek,mt8173-disp-ovl";
> gce-subsys = ;
> ...
> };
> 
> And client driver pass subsys in the related interface,
> 
> int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32
> value);
> 
> So, for another SoC, you just need to modify device tree and you do not
> need to modify driver.

Hi CK, thanks for your suggestion. I do it in v22.

> > +
> > +static int cmdq_subsys_base_to_id(u32 base)
> > 

Re: [PATCH v21 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-06-27 Thread houlong wei
On Wed, 2018-02-21 at 16:05 +0800, CK Hu wrote:
> Hi, Houlong:
> 
> I've one more inline comment.
> 
> On Wed, 2018-01-31 at 15:28 +0800, houlong@mediatek.com wrote:
> > From: "hs.l...@mediatek.com" 
> > 
> > Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.
> > 
> > Signed-off-by: Houlong Wei 
> > Signed-off-by: HS Liao 
> > ---
> >  drivers/soc/mediatek/Kconfig   |   12 ++
> >  drivers/soc/mediatek/Makefile  |1 +
> >  drivers/soc/mediatek/mtk-cmdq-helper.c |  322 
> > 
> >  include/linux/soc/mediatek/mtk-cmdq.h  |  174 +
> >  4 files changed, 509 insertions(+)
> >  create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
> >  create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h
> > 
> > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > index a7d0667..e66582e 100644
> > --- a/drivers/soc/mediatek/Kconfig
> > +++ b/drivers/soc/mediatek/Kconfig
> > @@ -4,6 +4,18 @@
> >  menu "MediaTek SoC drivers"
> > depends on ARCH_MEDIATEK || COMPILE_TEST
> >  
> > +config MTK_CMDQ
> > +   bool "MediaTek CMDQ Support"
> > +   depends on ARM64 && ( ARCH_MEDIATEK || COMPILE_TEST )
> > +   select MAILBOX
> > +   select MTK_CMDQ_MBOX
> > +   select MTK_INFRACFG
> > +   help
> > + Say yes here to add support for the MediaTek Command Queue (CMDQ)
> > + driver. The CMDQ is used to help read/write registers with critical
> > + time limitation, such as updating display configuration during the
> > + vblank.
> > +
> >  config MTK_INFRACFG
> > bool "MediaTek INFRACFG Support"
> > select REGMAP
> > diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> > index 12998b0..64ce5ee 100644
> > --- a/drivers/soc/mediatek/Makefile
> > +++ b/drivers/soc/mediatek/Makefile
> > @@ -1,3 +1,4 @@
> > +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
> >  obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
> >  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
> >  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > new file mode 100644
> > index 000..80d0558
> > --- /dev/null
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -0,0 +1,322 @@
> > +/*
> > + * Copyright (c) 2015 MediaTek Inc.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define CMDQ_ARG_A_WRITE_MASK  0x
> > +#define CMDQ_WRITE_ENABLE_MASK BIT(0)
> > +#define CMDQ_EOC_IRQ_ENBIT(0)
> > +#define CMDQ_EOC_CMD   ((u64)((CMDQ_CODE_EOC << 
> > CMDQ_OP_CODE_SHIFT)) \
> > +   << 32 | CMDQ_EOC_IRQ_EN)
> > +
> > +struct cmdq_subsys {
> > +   u32 base;
> > +   int id;
> > +};
> > +
> > +static const struct cmdq_subsys gce_subsys[] = {
> > +   {0x1400, 1},
> > +   {0x1401, 2},
> > +   {0x1402, 3},
> > +};
> > +
> > +static int cmdq_subsys_base_to_id(u32 base)
> > +{
> > +   int i;
> > +
> > +   for (i = 0; i < ARRAY_SIZE(gce_subsys); i++)
> > +   if (gce_subsys[i].base == base)
> > +   return gce_subsys[i].id;
> > +   return -EFAULT;
> > +}
> > +
> > +static int cmdq_pkt_realloc_cmd_buffer(struct cmdq_pkt *pkt, size_t size)
> > +{
> > +   void *new_buf;
> > +
> > +   new_buf = krealloc(pkt->va_base, size, GFP_KERNEL | __GFP_ZERO);
> > +   if (!new_buf)
> > +   return -ENOMEM;
> > +   pkt->va_base = new_buf;
> > +   pkt->buf_size = size;
> > +   return 0;
> > +}
> > +
> > +struct cmdq_base *cmdq_register_device(struct device *dev)
> > +{
> > +   struct cmdq_base *cmdq_base;
> > +   struct resource res;
> 

Re: [PATCH v21 2/4] mailbox: mediatek: Add Mediatek CMDQ driver

2018-06-27 Thread houlong wei
On Wed, 2018-02-21 at 11:53 +0800, CK Hu wrote:
> Hi, Houlong:
> 
> I've one inline comment.
> 
> On Wed, 2018-01-31 at 15:28 +0800, houlong@mediatek.com wrote:
> > From: "hs.l...@mediatek.com" 
> > 
> > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > CMDQ is used to help write registers with critical time limitation,
> > such as updating display configuration during the vblank. It controls
> > Global Command Engine (GCE) hardware to achieve this requirement.
> > Currently, CMDQ only supports display related hardwares, but we expect
> > it can be extended to other hardwares for future requirements.
> > 
> > Signed-off-by: Houlong Wei 
> > Signed-off-by: HS Liao 
> > Signed-off-by: CK Hu 
> > ---
> >  drivers/mailbox/Kconfig  |   10 +
> >  drivers/mailbox/Makefile |2 +
> >  drivers/mailbox/mtk-cmdq-mailbox.c   |  594 
> > ++
> >  include/linux/mailbox/mtk-cmdq-mailbox.h |   77 
> >  4 files changed, 683 insertions(+)
> >  create mode 100644 drivers/mailbox/mtk-cmdq-mailbox.c
> >  create mode 100644 include/linux/mailbox/mtk-cmdq-mailbox.h
> > 
> > diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
> > index ba2f152..43bb26f 100644
> > --- a/drivers/mailbox/Kconfig
> > +++ b/drivers/mailbox/Kconfig
> > @@ -171,4 +171,14 @@ config BCM_FLEXRM_MBOX
> >   Mailbox implementation of the Broadcom FlexRM ring manager,
> >   which provides access to various offload engines on Broadcom
> >   SoCs. Say Y here if you want to use the Broadcom FlexRM.
> > +
> > +config MTK_CMDQ_MBOX
> > +   bool "MediaTek CMDQ Mailbox Support"
> > +   depends on ARM64 && ( ARCH_MEDIATEK || COMPILE_TEST )
> > +   select MTK_INFRACFG
> > +   help
> > + Say yes here to add support for the MediaTek Command Queue (CMDQ)
> > + mailbox driver. The CMDQ is used to help read/write registers with
> > + critical time limitation, such as updating display configuration
> > + during the vblank.
> >  endif
> > diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
> > index 4896f8d..484d341 100644
> > --- a/drivers/mailbox/Makefile
> > +++ b/drivers/mailbox/Makefile
> > @@ -36,3 +36,5 @@ obj-$(CONFIG_BCM_FLEXRM_MBOX) += bcm-flexrm-mailbox.o
> >  obj-$(CONFIG_QCOM_APCS_IPC)+= qcom-apcs-ipc-mailbox.o
> >  
> >  obj-$(CONFIG_TEGRA_HSP_MBOX)   += tegra-hsp.o
> > +
> > +obj-$(CONFIG_MTK_CMDQ_MBOX)+= mtk-cmdq-mailbox.o
> > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
> > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > new file mode 100644
> > index 000..394a335
> > --- /dev/null
> > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > @@ -0,0 +1,594 @@
> > +/*
> > + * Copyright (c) 2015 MediaTek Inc.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define CMDQ_THR_MAX_COUNT 16
> > +#define CMDQ_OP_CODE_MASK  (0xff << CMDQ_OP_CODE_SHIFT)
> > +#define CMDQ_TIMEOUT_MS1000
> > +#define CMDQ_IRQ_MASK  0x
> > +#define CMDQ_NUM_CMD(t)(t->cmd_buf_size / 
> > CMDQ_INST_SIZE)
> > +
> > +#define CMDQ_CURR_IRQ_STATUS   0x10
> > +#define CMDQ_THR_SLOT_CYCLES   0x30
> > +
> > +#define CMDQ_THR_BASE  0x100
> > +#define CMDQ_THR_SIZE  0x80
> > +#define CMDQ_THR_WARM_RESET0x00
> > +#define CMDQ_THR_ENABLE_TASK   0x04
> > +#define CMDQ_THR_SUSPEND_TASK  0x08
> > +#define CMDQ_THR_CURR_STATUS   0x0c
> > +#define CMDQ_THR_IRQ_STATUS0x10
> > +#define CMDQ_THR_IRQ_ENABLE0x14
> > +#define CMDQ_THR_CURR_ADDR 0

Re: [PATCH v22 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-07-03 Thread houlong wei
On Fri, 2018-06-29 at 17:22 +0800, CK Hu wrote:
> Hi, Houlong:
> 
> On Fri, 2018-06-29 at 07:32 +0800, houlong wei wrote:
> > On Thu, 2018-06-28 at 18:41 +0800, CK Hu wrote:
> > > Hi, Houlong:
> > > 
> > > Some inline comment.
> > > 
> > > On Wed, 2018-06-27 at 19:16 +0800, Houlong Wei wrote:
> > > > Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.
> > > > 
> > > > Signed-off-by: Houlong Wei 
> > > > Signed-off-by: HS Liao 
> > > > ---
> > > >  drivers/soc/mediatek/Kconfig   |   12 ++
> > > >  drivers/soc/mediatek/Makefile  |1 +
> > > >  drivers/soc/mediatek/mtk-cmdq-helper.c |  258 
> > > > 
> > > >  include/linux/soc/mediatek/mtk-cmdq.h  |  132 
> > > >  4 files changed, 403 insertions(+)
> > > >  create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
> > > >  create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h
> > > > 
> > > > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > > > index a7d0667..17bd759 100644
> > > > --- a/drivers/soc/mediatek/Kconfig
> > > > +++ b/drivers/soc/mediatek/Kconfig
> > > > @@ -4,6 +4,18 @@
> > > >  menu "MediaTek SoC drivers"
> > > > depends on ARCH_MEDIATEK || COMPILE_TEST
> > > >  
> > > 
> 
> [...]
> 
> > > > +
> > > > +static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
> > > > +{
> > > > +   int err;
> > > > +
> > > > +   if (cmdq_pkt_is_finalized(pkt))
> > > > +   return 0;
> > > > +
> > > > +   /* insert EOC and generate IRQ for each command iteration */
> > > > +   err = cmdq_pkt_append_command(pkt, CMDQ_CODE_EOC, 0, 
> > > > CMDQ_EOC_IRQ_EN);
> > > > +   if (err < 0)
> > > > +   return err;
> > > > +
> > > > +   /* JUMP to end */
> > > > +   err = cmdq_pkt_append_command(pkt, CMDQ_CODE_JUMP, 0, 
> > > > CMDQ_JUMP_PASS);
> > > > +   if (err < 0)
> > > > +   return err;
> > > > +
> > > > +   return 0;
> > > > +}
> > > > +
> > > > +int cmdq_pkt_flush_async(struct cmdq_client *client, struct cmdq_pkt 
> > > > *pkt,
> > > > +cmdq_async_flush_cb cb, void *data)
> > > > +{
> > > > +   int err;
> > > > +   struct device *dev;
> > > > +   dma_addr_t dma_addr;
> > > > +
> > > > +   err = cmdq_pkt_finalize(pkt);
> > > > +   if (err < 0)
> > > > +   return err;
> > > > +
> > > > +   dev = client->chan->mbox->dev;
> > > > +   dma_addr = dma_map_single(dev, pkt->va_base, pkt->cmd_buf_size,
> > > > +   DMA_TO_DEVICE);
> > > 
> > > You map here, but I could not find unmap, so the unmap should be done in
> > > client driver. I would prefer a symmetric map/unmap which means that
> > > both map and unmap are done in client driver. I think you put map here
> > > because you should map after finalize. 
> > 
> > The unmap is done before callback to client, in function
> > cmdq_task_exec_done, mtk-cmdq-mailbox.c.
> 
> You put unmap in mailbox controller, and map here (here would be mailbox
> client), so this is not symmetric. If the code is asymmetric, it's easy
> to cause bug and not easy to maintain. So I would like move both
> map/unmap to client driver.
> 

Since map/unmap is common code for client drivers, can we move unmap to
CMDQ helper and do not put in client driver?

> > 
> > > Therefore, export
> > > cmdq_pkt_finalize() to client driver and let client do finalize, so
> > > there is no finalize in flush function. This method have a benefit that
> > > if client reuse command buffer, it need not to map/unmap frequently.
> > 
> > If client reuse command buffer or cmdq_pkt(command queue packet), client
> > will add new commands to the cmdq_pkt, so map/unmap are necessary for
> > each cmdq_pkt flush.
> 
> If the buffer size is 4K bytes, client driver could map the whole 4K at
> initialization. Before it write new command, it call
> dma_sync_single_for_cpu(), after it write new command, it call
> dma_sync_single_for_dev

Re: [PATCH v22 2/4] mailbox: mediatek: Add Mediatek CMDQ driver

2018-07-03 Thread houlong wei
On Fri, 2018-06-29 at 15:08 +0800, CK Hu wrote:
> Hi, Houlong:
> 
> Some inline comment.
> 
> On Wed, 2018-06-27 at 19:16 +0800, Houlong Wei wrote:
> > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > CMDQ is used to help write registers with critical time limitation,
> > such as updating display configuration during the vblank. It controls
> > Global Command Engine (GCE) hardware to achieve this requirement.
> > Currently, CMDQ only supports display related hardwares, but we expect
> > it can be extended to other hardwares for future requirements.
> > 
> > Signed-off-by: Houlong Wei 
> > Signed-off-by: HS Liao 
> > Signed-off-by: CK Hu 
> > ---
> >  drivers/mailbox/Kconfig  |   10 +
> >  drivers/mailbox/Makefile |2 +
> >  drivers/mailbox/mtk-cmdq-mailbox.c   |  634 
> > ++
> >  include/linux/mailbox/mtk-cmdq-mailbox.h |   70 
> >  4 files changed, 716 insertions(+)
> >  create mode 100644 drivers/mailbox/mtk-cmdq-mailbox.c
> >  create mode 100644 include/linux/mailbox/mtk-cmdq-mailbox.h
> > 
> 
> [...]
> 
> > +
> > +static int cmdq_thread_reset(struct cmdq *cmdq, struct cmdq_thread *thread)
> > +{
> > +   u32 warm_reset;
> > +
> > +   writel(CMDQ_THR_DO_WARM_RESET, thread->base + CMDQ_THR_WARM_RESET);
> > +   if (readl_poll_timeout_atomic(thread->base + CMDQ_THR_WARM_RESET,
> > +   warm_reset, !(warm_reset & CMDQ_THR_DO_WARM_RESET),
> > +   0, 10)) {
> > +   dev_err(cmdq->mbox.dev, "reset GCE thread 0x%x failed\n",
> > +   (u32)(thread->base - cmdq->base));
> > +   return -EFAULT;
> > +   }
> > +   writel(CMDQ_THR_ACTIVE_SLOT_CYCLES, cmdq->base + CMDQ_THR_SLOT_CYCLES);
> 
> The CMDQ_THR_SLOT_CYCLES looks like not relevant to reset. Maybe you
> just need to set this value when startup.

Will move configuration of CMDQ_THR_SLOT_CYCLES to cmdq_xlate() where is
startup of a GCE thread.

> 
> > +
> > +   return 0;
> > +}
> > +
> 
> [...]
> 
> > +
> > +static void cmdq_task_exec(struct cmdq_pkt *pkt, struct cmdq_thread 
> > *thread)
> > +{
> > +   struct cmdq *cmdq;
> > +   struct cmdq_task *task;
> > +   unsigned long curr_pa, end_pa;
> > +
> > +   cmdq = dev_get_drvdata(thread->chan->mbox->dev);
> > +
> > +   /* Client should not flush new tasks if suspended. */
> > +   WARN_ON(cmdq->suspended);
> > +
> > +   task = kzalloc(sizeof(*task), GFP_ATOMIC);
> > +   task->cmdq = cmdq;
> > +   INIT_LIST_HEAD(>list_entry);
> > +   task->pa_base = pkt->pa_base;
> > +   task->thread = thread;
> > +   task->pkt = pkt;
> > +
> > +   if (list_empty(>task_busy_list)) {
> > +   WARN_ON(clk_enable(cmdq->clock) < 0);
> > +   WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
> > +
> > +   writel(task->pa_base, thread->base + CMDQ_THR_CURR_ADDR);
> > +   writel(task->pa_base + pkt->cmd_buf_size,
> > +  thread->base + CMDQ_THR_END_ADDR);
> > +   writel(thread->priority, thread->base + CMDQ_THR_PRIORITY);
> > +   writel(CMDQ_THR_IRQ_EN, thread->base + CMDQ_THR_IRQ_ENABLE);
> > +   writel(CMDQ_THR_ENABLED, thread->base + CMDQ_THR_ENABLE_TASK);
> > +
> > +   if (thread->timeout_ms != CMDQ_NO_TIMEOUT)
> > +   mod_timer(>timeout,
> > +   jiffies + msecs_to_jiffies(thread->timeout_ms));
> 
> I think the timeout processing should be done by client driver. The
> total time to execute a command buffer does not depend on GCE HW speed
> because the WFE (wait for event) command would wait for client HW event,
> so the total time depend on how long a client HW send this event to GCE
> and the timeout processing should be client driver's job. Each client
> may have different timeout processing mechanism, for example, if display
> could dynamic change panel frame rate between 120Hz and 60Hz, and the
> timeout time is 2 frame, so it may dynamically change timeout time
> between 17ms and 33ms. Another reason is that display have interrupt
> every vblank, and it could check timeout in that interrupt, so the timer
> in cmdq driver looks redundant. Because each client would define its own
> timeout processing mechanism, so it's not wise to put timeout processing
> in cmdq driver.

The client drivers' owners strongly hope to keep th

Re: [PATCH v22 1/4] dt-bindings: soc: Add documentation for the MediaTek GCE unit

2018-07-03 Thread houlong wei
On Tue, 2018-07-03 at 10:30 +0800, Rob Herring wrote:
> On Wed, Jun 27, 2018 at 07:16:09PM +0800, Houlong Wei wrote:
> > This adds documentation for the MediaTek Global Command Engine (GCE) unit
> > found in MT8173 SoCs.
> > 
> > Signed-off-by: Houlong Wei 
> > Signed-off-by: HS Liao 
> > ---
> > Hi Rob,
> >   I don't add your ACK in this version since the dt-binding description
> > has been changed. Thanks.
> > ---
> >  .../devicetree/bindings/mailbox/mtk-gce.txt|   65 
> > 
> >  include/dt-bindings/gce/mt8173-gce.h   |   48 +++
> >  2 files changed, 113 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/mailbox/mtk-gce.txt
> >  create mode 100644 include/dt-bindings/gce/mt8173-gce.h
> > 
> > diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt 
> > b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
> > new file mode 100644
> > index 000..26f65a4
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
> > @@ -0,0 +1,65 @@
> > +MediaTek GCE
> > +===
> > +
> > +The Global Command Engine (GCE) is used to help read/write registers with
> > +critical time limitation, such as updating display configuration during the
> > +vblank. The GCE can be used to implement the Command Queue (CMDQ) driver.
> > +
> > +CMDQ driver uses mailbox framework for communication. Please refer to
> > +mailbox.txt for generic information about mailbox device-tree bindings.
> > +
> > +Required properties:
> > +- compatible: Must be "mediatek,mt8173-gce"
> > +- reg: Address range of the GCE unit
> > +- interrupts: The interrupt signal from the GCE block
> > +- clock: Clocks according to the common clock binding
> > +- clock-names: Must be "gce" to stand for GCE clock
> > +- thread-num: Maximum threads count of GCE.
> 
> mediatek,thread-num
> 
> Is this needed for anything other than error checking the thread id in 
> the mbox cells? if that's it, then drop it. 
> 

'thread-num' is used to configure the GCE thread number, which is the
channel number of gce mailbox. This property is read in
cmdq_probe()/mtk-cmdq-mailbox.c and a mailbox's channel array is
allocated according to the number.
Since the thread number may be different on different SoC, we wish it
could be configured in device tree.

> > +- #mbox-cells: Should be 4.
> > +   < channel timeout priority atomic_exec>
> > +   phandle: Label name of a gce node.
> > +   channel: Channel of mailbox. Be equal to the thread id of GCE.
> > +   timeout: Maximum time of software waiting GCE processing done, in unit
> > +   of millisecond.
> > +   priority: Priority of GCE thread.
> > +   atomic_exec: GCE processing continuous packets of commands in atomic
> > +   way.
> > +
> > +Required properties for a client device:
> > +- mboxes: Client use mailbox to communicate with GCE, it should have this
> > +  property and list of phandle, mailbox specifiers.
> > +- gce-subsys: Specify the sub-system id which is corresponding to the 
> > register
> > +  address.
> 
> What is this for?

You mean the new added property 'gce-subsys'?  
It is used for GCE to distinguish the high 16-bit of a hardware register
address. When a client driver packets a register setting into a GCE
instruction, it uses a sub-system code and register offset instead of
the 32-bit register address.
Since sub-system code may be different on different SoC, we wish it
could be configured in device tree.

> 
> > +
> > +Optional properties for a client device:
> > +- gce-event: Specify the event if the client has any. Because the event is
> > +  parsed by client, so client can replace 'gce-event' with other meaningful
> > +  name.
> 
> If the client sets the name, then no point having here. It must be 
> documented in the client binding. But then, what is this for in the 
> first place?

Since display driver will use GCE firstly, so we will move the
description to
'Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt'
when display driver start using the GCE driver.
Is that ok?

> 
> > +
> > +Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h'. 
> > Such as
> > +thread number, sub-system ids, thread priority, event ids.
> > +
> > +Example:
> > +
> > +   gce: gce@10212000 {
> 
> mailbox@...

Will do.

> 
> > +   compatible = "mediatek,mt8173-gce";
> > +   reg = <0 0x10212000 0 0x1000>;
&

Re: FW: [PATCH v20 2/4] mailbox: mediatek: Add Mediatek CMDQ driver

2018-01-08 Thread houlong wei
Hi Jassi,

Sorry for reply so late.
According to previous discussion, there are two methods to move
dma_map_single() outside of spin_lock.
(1) put in mtk-cmdq-helper.c, as described by HS on 2017-02-09.
  > I think a trade-off solution is to put in mtk-cmdq-helper.c.
  > Although it is a mailbox client, it is not a CMDQ client.
  > We can include mailbox_controller.h in mtk-cmdq-helper.c (instead of
mtk-cmdq.h), and then map dma at cmdq_pkt_flush_async before
mbox_send_message.

  > pkt->pa_base = dma_map_single(client->chan->mbox->dev, pkt->va_base,
  >  pkt->cmd_buf_size, DMA_TO_DEVICE);
(2) schedule a tasklet in send_data().

After internal discussion with HS and other experts, now we prefer
method (1).
How do you think about it?

Thanks
Houlong


> -Original Message-
> From: Horng-Shyang Liao [mailto:hs.l...@mediatek.com] 
> Sent: Thursday, February 23, 2017 8:48 PM
> To: Jassi Brar <jassisinghb...@gmail.com>
> Cc: Rob Herring <robh...@kernel.org>; Matthias Brugger 
> <matthias@gmail.com>; Daniel Kurtz <djku...@chromium.org>; Sascha Hauer 
> <s.ha...@pengutronix.de>; Devicetree List <devicet...@vger.kernel.org>; Linux 
> Kernel Mailing List <linux-kernel@vger.kernel.org>; 
> linux-arm-ker...@lists.infradead.org; linux-media...@lists.infradead.org; 
> srv_heupstream <srv_heupstr...@mediatek.com>; Sascha Hauer 
> <ker...@pengutronix.de>; Philipp Zabel <p.za...@pengutronix.de>; Nicolas 
> Boichat <drink...@chromium.org>; CK Hu (胡俊光) <ck...@mediatek.com>; Cawa Cheng 
> (鄭曄禧) <cawa.ch...@mediatek.com>; Bibby Hsieh (謝濟遠) 
> <bibby.hs...@mediatek.com>; YT Shen (沈岳霆) <yt.s...@mediatek.com>; Daoyuan 
> Huang (黃道原) <daoyuan.hu...@mediatek.com>; Damon Chu (朱峻賢) 
> <damon@mediatek.com>; Josh-YC Liu (劉育誠) <josh-yc@mediatek.com>; Glory 
> Hung (洪智瑋) <glory.h...@mediatek.com>; Jiaguang Zhang (张加广) 
> <jiaguang.zh...@mediatek.com>; Dennis-YC Hsieh (謝宇哲) 
> <dennis-yc.hs...@mediatek.com>; Monica Wang (王孟婷) <monica.w...@mediatek.com>; 
> Houlong Wei (魏厚龙) <houlong@mediatek.com>; Hs Liao (廖宏祥) 
> <hs.l...@mediatek.com>
> Subject: Re: [PATCH v20 2/4] mailbox: mediatek: Add Mediatek CMDQ driver
> 
> On Thu, 2017-02-23 at 09:40 +0530, Jassi Brar wrote:
> > On Wed, Feb 22, 2017 at 8:42 AM, Horng-Shyang Liao <hs.l...@mediatek.com> 
> > wrote:
> > > On Thu, 2017-02-16 at 21:02 +0530, Jassi Brar wrote:
> > >> On Mon, Feb 6, 2017 at 11:07 AM, Horng-Shyang Liao 
> > >> <hs.l...@mediatek.com> wrote:
> > >> > Hi Jassi,
> > >> >
> > >> > On Wed, 2017-02-01 at 10:52 +0530, Jassi Brar wrote:
> > >> >> On Thu, Jan 26, 2017 at 2:07 PM, Horng-Shyang Liao 
> > >> >> <hs.l...@mediatek.com> wrote:
> > >> >> > Hi Jassi,
> > >> >> >
> > >> >> > On Thu, 2017-01-26 at 10:08 +0530, Jassi Brar wrote:
> > >> >> >> On Wed, Jan 4, 2017 at 8:36 AM, HS Liao <hs.l...@mediatek.com> 
> > >> >> >> wrote:
> > >> >> >>
> > >> >> >> > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
> > >> >> >> > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > >> >> >> > new file mode 100644
> > >> >> >> > index 000..747bcd3
> > >> >> >> > --- /dev/null
> > >> >> >> > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > >> >> >>
> > >> >> >> ...
> > >> >> >>
> > >> >> >> > +static void cmdq_task_exec(struct cmdq_pkt *pkt, struct 
> > >> >> >> > +cmdq_thread *thread) {
> > >> >> >> > +   struct cmdq *cmdq;
> > >> >> >> > +   struct cmdq_task *task;
> > >> >> >> > +   unsigned long curr_pa, end_pa;
> > >> >> >> > +
> > >> >> >> > +   cmdq = dev_get_drvdata(thread->chan->mbox->dev);
> > >> >> >> > +
> > >> >> >> > +   /* Client should not flush new tasks if suspended. */
> > >> >> >> > +   WARN_ON(cmdq->suspended);
> > >> >> >> > +
> > >> >> >> > +   task = kzalloc(sizeof(*task), GFP_ATOMIC);
> > >> >> >> > +   task->cmdq = cmdq;
> > >> >> >> > + 

Re: FW: [PATCH v20 2/4] mailbox: mediatek: Add Mediatek CMDQ driver

2018-01-18 Thread houlong wei
Hi Jassi,

There is one request for one GCE h/w buffer which contains a list of
registers operation.
I will resubmit a version and please review again.

Thanks,
Houlong

On Thu, 2018-01-18 at 16:01 +0800, Jassi Brar wrote:
> On Mon, Jan 8, 2018 at 2:08 PM, houlong wei <houlong@mediatek.com> wrote:
> > Hi Jassi,
> >
> > Sorry for reply so late.
> > According to previous discussion, there are two methods to move
> > dma_map_single() outside of spin_lock.
> > (1) put in mtk-cmdq-helper.c, as described by HS on 2017-02-09.
> >   > I think a trade-off solution is to put in mtk-cmdq-helper.c.
> >   > Although it is a mailbox client, it is not a CMDQ client.
> >   > We can include mailbox_controller.h in mtk-cmdq-helper.c (instead of
> > mtk-cmdq.h), and then map dma at cmdq_pkt_flush_async before
> > mbox_send_message.
> >
> >   > pkt->pa_base = dma_map_single(client->chan->mbox->dev, pkt->va_base,
> >   >  pkt->cmd_buf_size, DMA_TO_DEVICE);
> > (2) schedule a tasklet in send_data().
> >
> > After internal discussion with HS and other experts, now we prefer
> > method (1).
> > How do you think about it?
> >
> I don't exactly see how you mean but please remember send_data()
> callback is supposed to be atomic ... it is protected by
> spin_lock_irqsave/restore in drivers/mailbox/mailbox.c:msg_submit()
> 
> BTW, how many requests max can be queued in the GCE h/w buffer?
> And since it's been over a year now, could you please resubmit after
> checking for checkpatch with the --strict option?
> 
> Thanks.




Re: [PATCH v20 2/4] mailbox: mediatek: Add Mediatek CMDQ driver

2018-01-17 Thread houlong wei
Hi Jassi,

We prefer to use method (1) to move dma_map_single() outside of
spin_lock. Do you have any comment about this?

Thanks,
Houlong

On Mon, 2018-01-08 at 16:38 +0800, houlong wei wrote:
> Hi Jassi,
> 
> Sorry for reply so late.
> According to previous discussion, there are two methods to move
> dma_map_single() outside of spin_lock.
> (1) put in mtk-cmdq-helper.c, as described by HS on 2017-02-09.
>   > I think a trade-off solution is to put in mtk-cmdq-helper.c.
>   > Although it is a mailbox client, it is not a CMDQ client.
>   > We can include mailbox_controller.h in mtk-cmdq-helper.c (instead of
> mtk-cmdq.h), and then map dma at cmdq_pkt_flush_async before
> mbox_send_message.
> 
>   > pkt->pa_base = dma_map_single(client->chan->mbox->dev, pkt->va_base,
>   >  pkt->cmd_buf_size, DMA_TO_DEVICE);
> (2) schedule a tasklet in send_data().
> 
> After internal discussion with HS and other experts, now we prefer
> method (1).
> How do you think about it?
> 
> Thanks
> Houlong
> 
> 
> > -Original Message-
> > From: Horng-Shyang Liao [mailto:hs.l...@mediatek.com]
> > Sent: Thursday, February 23, 2017 8:48 PM
> > To: Jassi Brar <jassisinghb...@gmail.com>
> > Cc: Rob Herring <robh...@kernel.org>; Matthias Brugger 
> > <matthias@gmail.com>; Daniel Kurtz <djku...@chromium.org>; Sascha Hauer 
> > <s.ha...@pengutronix.de>; Devicetree List <devicet...@vger.kernel.org>; 
> > Linux Kernel Mailing List <linux-kernel@vger.kernel.org>; 
> > linux-arm-ker...@lists.infradead.org; linux-media...@lists.infradead.org; 
> > srv_heupstream <srv_heupstr...@mediatek.com>; Sascha Hauer 
> > <ker...@pengutronix.de>; Philipp Zabel <p.za...@pengutronix.de>; Nicolas 
> > Boichat <drink...@chromium.org>; CK Hu (胡俊光) <ck...@mediatek.com>; Cawa 
> > Cheng (鄭曄禧) <cawa.ch...@mediatek.com>; Bibby Hsieh (謝濟遠) 
> > <bibby.hs...@mediatek.com>; YT Shen (沈岳霆) <yt.s...@mediatek.com>; Daoyuan 
> > Huang (黃道原) <daoyuan.hu...@mediatek.com>; Damon Chu (朱峻賢) 
> > <damon@mediatek.com>; Josh-YC Liu (劉育誠) <josh-yc@mediatek.com>; 
> > Glory Hung (洪智瑋) <glory.h...@mediatek.com>; Jiaguang Zhang (张加广) 
> > <jiaguang.zh...@mediatek.com>; Dennis-YC Hsieh (謝宇哲) 
> > <dennis-yc.hs...@mediatek.com>; Monica Wang (王孟婷) 
> > <monica.w...@mediatek.com>; Houlong Wei (魏厚龙) <houlong@mediatek.com>; 
> > Hs Liao (廖宏祥) <hs.l...@mediatek.com>
> > Subject: Re: [PATCH v20 2/4] mailbox: mediatek: Add Mediatek CMDQ driver
> >
> > On Thu, 2017-02-23 at 09:40 +0530, Jassi Brar wrote:
> > > On Wed, Feb 22, 2017 at 8:42 AM, Horng-Shyang Liao <hs.l...@mediatek.com> 
> > > wrote:
> > > > On Thu, 2017-02-16 at 21:02 +0530, Jassi Brar wrote:
> > > >> On Mon, Feb 6, 2017 at 11:07 AM, Horng-Shyang Liao 
> > > >> <hs.l...@mediatek.com> wrote:
> > > >> > Hi Jassi,
> > > >> >
> > > >> > On Wed, 2017-02-01 at 10:52 +0530, Jassi Brar wrote:
> > > >> >> On Thu, Jan 26, 2017 at 2:07 PM, Horng-Shyang Liao 
> > > >> >> <hs.l...@mediatek.com> wrote:
> > > >> >> > Hi Jassi,
> > > >> >> >
> > > >> >> > On Thu, 2017-01-26 at 10:08 +0530, Jassi Brar wrote:
> > > >> >> >> On Wed, Jan 4, 2017 at 8:36 AM, HS Liao <hs.l...@mediatek.com> 
> > > >> >> >> wrote:
> > > >> >> >>
> > > >> >> >> > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c
> > > >> >> >> > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > >> >> >> > new file mode 100644
> > > >> >> >> > index 000..747bcd3
> > > >> >> >> > --- /dev/null
> > > >> >> >> > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > >> >> >>
> > > >> >> >> ...
> > > >> >> >>
> > > >> >> >> > +static void cmdq_task_exec(struct cmdq_pkt *pkt, struct
> > > >> >> >> > +cmdq_thread *thread) {
> > > >> >> >> > +   struct cmdq *cmdq;
> > > >> >> >> > +   struct cmdq_task *task;
> > > >> >> >> > +   unsigned long curr_pa, end_pa;
> > > >> >> >> > +
> > > >>

Re: FW: [PATCH v20 2/4] mailbox: mediatek: Add Mediatek CMDQ driver

2018-01-17 Thread houlong wei
Sorry to send the mail again because I missed some mail lists by
mistake.

Hi Jassi,

We prefer to use method (1) to move dma_map_single() outside of
spin_lock. Do you have any comment about this?

Thanks,
Houlong

On Mon, 2018-01-08 at 16:38 +0800, houlong wei wrote:
> Hi Jassi,
> 
> Sorry for reply so late.
> According to previous discussion, there are two methods to move
> dma_map_single() outside of spin_lock.
> (1) put in mtk-cmdq-helper.c, as described by HS on 2017-02-09.
>   > I think a trade-off solution is to put in mtk-cmdq-helper.c.
>   > Although it is a mailbox client, it is not a CMDQ client.
>   > We can include mailbox_controller.h in mtk-cmdq-helper.c (instead of
> mtk-cmdq.h), and then map dma at cmdq_pkt_flush_async before
> mbox_send_message.
> 
>   > pkt->pa_base = dma_map_single(client->chan->mbox->dev, pkt->va_base,
>   >  pkt->cmd_buf_size, DMA_TO_DEVICE);
> (2) schedule a tasklet in send_data().
> 
> After internal discussion with HS and other experts, now we prefer
> method (1).
> How do you think about it?
> 
> Thanks
> Houlong
> 
> 
> > -Original Message-
> > From: Horng-Shyang Liao [mailto:hs.l...@mediatek.com] 
> > Sent: Thursday, February 23, 2017 8:48 PM
> > To: Jassi Brar <jassisinghb...@gmail.com>
> > Cc: Rob Herring <robh...@kernel.org>; Matthias Brugger 
> > <matthias@gmail.com>; Daniel Kurtz <djku...@chromium.org>; Sascha Hauer 
> > <s.ha...@pengutronix.de>; Devicetree List <devicet...@vger.kernel.org>; 
> > Linux Kernel Mailing List <linux-kernel@vger.kernel.org>; 
> > linux-arm-ker...@lists.infradead.org; linux-media...@lists.infradead.org; 
> > srv_heupstream <srv_heupstr...@mediatek.com>; Sascha Hauer 
> > <ker...@pengutronix.de>; Philipp Zabel <p.za...@pengutronix.de>; Nicolas 
> > Boichat <drink...@chromium.org>; CK Hu (胡俊光) <ck...@mediatek.com>; Cawa 
> > Cheng (鄭曄禧) <cawa.ch...@mediatek.com>; Bibby Hsieh (謝濟遠) 
> > <bibby.hs...@mediatek.com>; YT Shen (沈岳霆) <yt.s...@mediatek.com>; Daoyuan 
> > Huang (黃道原) <daoyuan.hu...@mediatek.com>; Damon Chu (朱峻賢) 
> > <damon@mediatek.com>; Josh-YC Liu (劉育誠) <josh-yc@mediatek.com>; 
> > Glory Hung (洪智瑋) <glory.h...@mediatek.com>; Jiaguang Zhang (张加广) 
> > <jiaguang.zh...@mediatek.com>; Dennis-YC Hsieh (謝宇哲) 
> > <dennis-yc.hs...@mediatek.com>; Monica Wang (王孟婷) 
> > <monica.w...@mediatek.com>; Houlong Wei (魏厚龙) <houlong@mediatek.com>; 
> > Hs Liao (廖宏祥) <hs.l...@mediatek.com>
> > Subject: Re: [PATCH v20 2/4] mailbox: mediatek: Add Mediatek CMDQ driver
> > 
> > On Thu, 2017-02-23 at 09:40 +0530, Jassi Brar wrote:
> > > On Wed, Feb 22, 2017 at 8:42 AM, Horng-Shyang Liao <hs.l...@mediatek.com> 
> > > wrote:
> > > > On Thu, 2017-02-16 at 21:02 +0530, Jassi Brar wrote:
> > > >> On Mon, Feb 6, 2017 at 11:07 AM, Horng-Shyang Liao 
> > > >> <hs.l...@mediatek.com> wrote:
> > > >> > Hi Jassi,
> > > >> >
> > > >> > On Wed, 2017-02-01 at 10:52 +0530, Jassi Brar wrote:
> > > >> >> On Thu, Jan 26, 2017 at 2:07 PM, Horng-Shyang Liao 
> > > >> >> <hs.l...@mediatek.com> wrote:
> > > >> >> > Hi Jassi,
> > > >> >> >
> > > >> >> > On Thu, 2017-01-26 at 10:08 +0530, Jassi Brar wrote:
> > > >> >> >> On Wed, Jan 4, 2017 at 8:36 AM, HS Liao <hs.l...@mediatek.com> 
> > > >> >> >> wrote:
> > > >> >> >>
> > > >> >> >> > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
> > > >> >> >> > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > >> >> >> > new file mode 100644
> > > >> >> >> > index 000..747bcd3
> > > >> >> >> > --- /dev/null
> > > >> >> >> > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > >> >> >>
> > > >> >> >> ...
> > > >> >> >>
> > > >> >> >> > +static void cmdq_task_exec(struct cmdq_pkt *pkt, struct 
> > > >> >> >> > +cmdq_thread *thread) {
> > > >> >> >> > +   struct cmdq *cmdq;
> > > >> >> >> > +   struct cmdq_task *task;
> > > >> >> >> > +   unsigned long curr_p

Re: [PATCH v21 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-02-08 Thread houlong wei
On Tue, 2018-02-06 at 10:52 +0800, CK Hu wrote:
> Hi, Houlong:
> 
> I've some inline comment.
> 
> On Wed, 2018-01-31 at 15:28 +0800, houlong@mediatek.com wrote:
> > From: "hs.l...@mediatek.com" <hs.l...@mediatek.com>
> >
> > Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.
> >
> > Signed-off-by: Houlong Wei <houlong@mediatek.com>
> > Signed-off-by: HS Liao <hs.l...@mediatek.com>
> > ---
> >  drivers/soc/mediatek/Kconfig   |   12 ++
> >  drivers/soc/mediatek/Makefile  |1 +
> >  drivers/soc/mediatek/mtk-cmdq-helper.c |  322 
> > 
> >  include/linux/soc/mediatek/mtk-cmdq.h  |  174 +
> >  4 files changed, 509 insertions(+)
> >  create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
> >  create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h
> >
> > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > index a7d0667..e66582e 100644
> > --- a/drivers/soc/mediatek/Kconfig
> > +++ b/drivers/soc/mediatek/Kconfig
> > @@ -4,6 +4,18 @@
> >  menu "MediaTek SoC drivers"
> >  depends on ARCH_MEDIATEK || COMPILE_TEST
> >
> > +config MTK_CMDQ
> > +bool "MediaTek CMDQ Support"
> > +depends on ARM64 && ( ARCH_MEDIATEK || COMPILE_TEST )
> > +select MAILBOX
> > +select MTK_CMDQ_MBOX
> > +select MTK_INFRACFG
> > +help
> > +  Say yes here to add support for the MediaTek Command Queue (CMDQ)
> > +  driver. The CMDQ is used to help read/write registers with critical
> > +  time limitation, such as updating display configuration during the
> > +  vblank.
> > +
> >  config MTK_INFRACFG
> >  bool "MediaTek INFRACFG Support"
> >  select REGMAP
> > diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> > index 12998b0..64ce5ee 100644
> > --- a/drivers/soc/mediatek/Makefile
> > +++ b/drivers/soc/mediatek/Makefile
> > @@ -1,3 +1,4 @@
> > +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
> >  obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
> >  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
> >  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > new file mode 100644
> > index 000..80d0558
> > --- /dev/null
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -0,0 +1,322 @@
> > +/*
> > + * Copyright (c) 2015 MediaTek Inc.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define CMDQ_ARG_A_WRITE_MASK0x
> > +#define CMDQ_WRITE_ENABLE_MASKBIT(0)
> > +#define CMDQ_EOC_IRQ_ENBIT(0)
> > +#define CMDQ_EOC_CMD((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
> > +<< 32 | CMDQ_EOC_IRQ_EN)
> > +
> > +struct cmdq_subsys {
> > +u32base;
> > +intid;
> > +};
> > +
> > +static const struct cmdq_subsys gce_subsys[] = {
> > +{0x1400, 1},
> > +{0x1401, 2},
> > +{0x1402, 3},
> > +};
> 
> I think subsys definition varies by different SoC, so it's better to
> pass these definition from device tree to driver (client driver), and
> client driver pass this subsys in the related interface. For example,
> 
> in include/dt-bindings/gce/mt8173-gce.h, you define
> 
> #define GCE_SUBSYS_14001
> #define GCE_SUBSYS_14012
> #define GCE_SUBSYS_14023
> 
> in device tree, place the subsys definition in client device node,
> 
> #include "dt-bindings/gce/mt8173-gce.h"
> 
> ovl0: ovl@1400c000 {
> compatible = "mediatek,mt8173-disp-ovl";
> gce-subsys = ;
> ...
> };
> 
> And client driver pass subsys in the related interface,
> 
> int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32
> value);
> 
> So, for another SoC, you just need to modify device tree and you do not
> need to modify driver.
> > +
> > +static int cmdq_sub

Re: [PATCH v23 3/4] arm64: dts: mt8173: Add GCE node

2018-08-14 Thread houlong wei
On Wed, 2018-07-25 at 09:26 +0800, Houlong Wei wrote:
> This patch adds the device node of the GCE hardware for CMDQ module.
> 
> Signed-off-by: Houlong Wei 
> Signed-off-by: HS Liao 
> ---
>  arch/arm64/boot/dts/mediatek/mt8173.dtsi |   10 ++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi 
> b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
> index 94597e3..97b1ec6 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
> @@ -18,6 +18,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include "mt8173-pinfunc.h"
>  
>  / {
> @@ -519,6 +520,15 @@
>   status = "disabled";
>   };
>  
> + gce: mailbox@10212000 {
> + compatible = "mediatek,mt8173-gce";
> + reg = <0 0x10212000 0 0x1000>;
> + interrupts = ;
> + clocks = < CLK_INFRA_GCE>;
> + clock-names = "gce";
> + #mbox-cells = <3>;
> + };
> +
>   mipi_tx0: mipi-dphy@10215000 {
>   compatible = "mediatek,mt8173-mipi-tx";
>   reg = <0 0x10215000 0 0x1000>;

Hi Matthias,
  Could you please review this patch when you are available? Thanks a
lot.



Re: [PATCH v23 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-08-14 Thread houlong wei
On Wed, 2018-07-25 at 09:26 +0800, Houlong Wei wrote:
> Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.
> 
> Signed-off-by: Houlong Wei 
> Signed-off-by: HS Liao 
> ---
>  drivers/soc/mediatek/Kconfig   |   12 ++
>  drivers/soc/mediatek/Makefile  |1 +
>  drivers/soc/mediatek/mtk-cmdq-helper.c |  291 
> 
>  include/linux/soc/mediatek/mtk-cmdq.h  |  135 +++
>  4 files changed, 439 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
>  create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h
> 
> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> index a7d0667..17bd759 100644
> --- a/drivers/soc/mediatek/Kconfig
> +++ b/drivers/soc/mediatek/Kconfig
> @@ -4,6 +4,18 @@
>  menu "MediaTek SoC drivers"
>   depends on ARCH_MEDIATEK || COMPILE_TEST
>  
> +config MTK_CMDQ
> + tristate "MediaTek CMDQ Support"
> + depends on ARCH_MEDIATEK || COMPILE_TEST
> + select MAILBOX
> + select MTK_CMDQ_MBOX
> + select MTK_INFRACFG
> + help
> +   Say yes here to add support for the MediaTek Command Queue (CMDQ)
> +   driver. The CMDQ is used to help read/write registers with critical
> +   time limitation, such as updating display configuration during the
> +   vblank.
> +
>  config MTK_INFRACFG
>   bool "MediaTek INFRACFG Support"
>   select REGMAP
> diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> index 12998b0..64ce5ee 100644
> --- a/drivers/soc/mediatek/Makefile
> +++ b/drivers/soc/mediatek/Makefile
> @@ -1,3 +1,4 @@
> +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
>  obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
>  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
>  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> b/drivers/soc/mediatek/mtk-cmdq-helper.c
> new file mode 100644
> index 000..e4dbb7e
> --- /dev/null
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -0,0 +1,291 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// Copyright (c) 2018 MediaTek Inc.
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define CMDQ_ARG_A_WRITE_MASK0x
> +#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)
> +
> +static void cmdq_client_timeout(struct timer_list *t)
> +{
> + struct cmdq_client *client = from_timer(client, t, timer);
> +
> + dev_err(client->client.dev, "cmdq timeout!\n");
> +}
> +
> +struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 
> timeout)
> +{
> + struct cmdq_client *client;
> +
> + client = kzalloc(sizeof(*client), GFP_KERNEL);
> + if (!client)
> + return (struct cmdq_client *)-ENOMEM;
> +
> + client->timeout_ms = timeout;
> + if (timeout != CMDQ_NO_TIMEOUT) {
> + spin_lock_init(>lock);
> + timer_setup(>timer, cmdq_client_timeout, 0);
> + }
> + client->pkt_cnt = 0;
> + client->client.dev = dev;
> + client->client.tx_block = false;
> + client->chan = mbox_request_channel(>client, index);
> +
> + if (IS_ERR(client->chan)) {
> + long err = 0;
> +
> + dev_err(dev, "failed to request channel\n");
> + err = PTR_ERR(client->chan);
> + kfree(client);
> +
> + return (struct cmdq_client *)err;
> + }
> +
> + return client;
> +}
> +EXPORT_SYMBOL(cmdq_mbox_create);
> +
> +void cmdq_mbox_destroy(struct cmdq_client *client)
> +{
> + if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
> + spin_lock(>lock);
> + del_timer_sync(>timer);
> + spin_unlock(>lock);
> + }
> + mbox_free_channel(client->chan);
> + kfree(client);
> +}
> +EXPORT_SYMBOL(cmdq_mbox_destroy);
> +
> +int cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt **pkt_ptr,
> + size_t size)
> +{
> + struct cmdq_pkt *pkt;
> + struct device *dev;
> + dma_addr_t dma_addr;
> +
> + pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
> + if (!pkt)
> + return -ENOMEM;
> + pkt->va_base = kzalloc(size, GFP_KERNEL);
> + if (!pkt->va_base) {
> + kfree(pkt);
> + return -ENOMEM;
> + }
> + pkt-&g

[PATCH] mailbox: mediatek: Add check for possible failure of kzalloc

2018-08-21 Thread Houlong Wei
The patch 623a6143a845("mailbox: mediatek: Add Mediatek CMDQ driver")
introduce the following static checker warning:
  drivers/mailbox/mtk-cmdq-mailbox.c:366 cmdq_mbox_send_data()
  error: potential null dereference 'task'.  (kzalloc returns null)

Fixes: 623a6143a845 ("mailbox: mediatek: Add Mediatek CMDQ driver")
Reported-by: Dan Carpenter 
Signed-off-by: Houlong Wei 
---
 drivers/mailbox/mtk-cmdq-mailbox.c |3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
b/drivers/mailbox/mtk-cmdq-mailbox.c
index aec46d5..f7cc29c 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -363,6 +363,9 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void 
*data)
WARN_ON(cmdq->suspended);
 
task = kzalloc(sizeof(*task), GFP_ATOMIC);
+   if (!task)
+   return -ENOMEM;
+
task->cmdq = cmdq;
INIT_LIST_HEAD(>list_entry);
task->pa_base = pkt->pa_base;
-- 
1.7.9.5



[PATCH v23 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-07-24 Thread Houlong Wei
Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 drivers/soc/mediatek/Kconfig   |   12 ++
 drivers/soc/mediatek/Makefile  |1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c |  291 
 include/linux/soc/mediatek/mtk-cmdq.h  |  135 +++
 4 files changed, 439 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
 create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index a7d0667..17bd759 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -4,6 +4,18 @@
 menu "MediaTek SoC drivers"
depends on ARCH_MEDIATEK || COMPILE_TEST
 
+config MTK_CMDQ
+   tristate "MediaTek CMDQ Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select MAILBOX
+   select MTK_CMDQ_MBOX
+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
 config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
select REGMAP
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..64ce5ee 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
 obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
 obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
new file mode 100644
index 000..e4dbb7e
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -0,0 +1,291 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018 MediaTek Inc.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_ARG_A_WRITE_MASK  0x
+#define CMDQ_WRITE_ENABLE_MASK BIT(0)
+#define CMDQ_EOC_IRQ_ENBIT(0)
+#define CMDQ_EOC_CMD   ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
+   << 32 | CMDQ_EOC_IRQ_EN)
+
+static void cmdq_client_timeout(struct timer_list *t)
+{
+   struct cmdq_client *client = from_timer(client, t, timer);
+
+   dev_err(client->client.dev, "cmdq timeout!\n");
+}
+
+struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 
timeout)
+{
+   struct cmdq_client *client;
+
+   client = kzalloc(sizeof(*client), GFP_KERNEL);
+   if (!client)
+   return (struct cmdq_client *)-ENOMEM;
+
+   client->timeout_ms = timeout;
+   if (timeout != CMDQ_NO_TIMEOUT) {
+   spin_lock_init(>lock);
+   timer_setup(>timer, cmdq_client_timeout, 0);
+   }
+   client->pkt_cnt = 0;
+   client->client.dev = dev;
+   client->client.tx_block = false;
+   client->chan = mbox_request_channel(>client, index);
+
+   if (IS_ERR(client->chan)) {
+   long err = 0;
+
+   dev_err(dev, "failed to request channel\n");
+   err = PTR_ERR(client->chan);
+   kfree(client);
+
+   return (struct cmdq_client *)err;
+   }
+
+   return client;
+}
+EXPORT_SYMBOL(cmdq_mbox_create);
+
+void cmdq_mbox_destroy(struct cmdq_client *client)
+{
+   if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
+   spin_lock(>lock);
+   del_timer_sync(>timer);
+   spin_unlock(>lock);
+   }
+   mbox_free_channel(client->chan);
+   kfree(client);
+}
+EXPORT_SYMBOL(cmdq_mbox_destroy);
+
+int cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt **pkt_ptr,
+   size_t size)
+{
+   struct cmdq_pkt *pkt;
+   struct device *dev;
+   dma_addr_t dma_addr;
+
+   pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
+   if (!pkt)
+   return -ENOMEM;
+   pkt->va_base = kzalloc(size, GFP_KERNEL);
+   if (!pkt->va_base) {
+   kfree(pkt);
+   return -ENOMEM;
+   }
+   pkt->buf_size = size;
+   pkt->cl = (void *)client;
+
+   dev = client->chan->mbox->dev;
+   dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
+   DMA_TO_DEVICE);
+   if (dma_mapping_error(dev, dma_addr)) {
+   dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
+   kfree(pkt->va_base);
+   kfree(pkt);
+   return -ENOMEM;
+   }
+
+   pkt->pa_base = dma_addr;
+   *pkt_ptr = pkt;
+
+   return 0;
+}
+EXPORT_SYMBOL(cmdq_pkt_create);
+
+void cmdq_pkt_destroy(struct cmdq_pkt *pk

[PATCH v23 1/4] dt-bindings: soc: Add documentation for the MediaTek GCE unit

2018-07-24 Thread Houlong Wei
This adds documentation for the MediaTek Global Command Engine (GCE) unit
found in MT8173 SoCs.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 .../devicetree/bindings/mailbox/mtk-gce.txt|   57 
 include/dt-bindings/gce/mt8173-gce.h   |   44 +++
 2 files changed, 101 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk-gce.txt
 create mode 100644 include/dt-bindings/gce/mt8173-gce.h

diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt 
b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
new file mode 100644
index 000..7d72b21
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
@@ -0,0 +1,57 @@
+MediaTek GCE
+===
+
+The Global Command Engine (GCE) is used to help read/write registers with
+critical time limitation, such as updating display configuration during the
+vblank. The GCE can be used to implement the Command Queue (CMDQ) driver.
+
+CMDQ driver uses mailbox framework for communication. Please refer to
+mailbox.txt for generic information about mailbox device-tree bindings.
+
+Required properties:
+- compatible: Must be "mediatek,mt8173-gce"
+- reg: Address range of the GCE unit
+- interrupts: The interrupt signal from the GCE block
+- clock: Clocks according to the common clock binding
+- clock-names: Must be "gce" to stand for GCE clock
+- #mbox-cells: Should be 3.
+   < channel priority atomic_exec>
+   phandle: Label name of a gce node.
+   channel: Channel of mailbox. Be equal to the thread id of GCE.
+   priority: Priority of GCE thread.
+   atomic_exec: GCE processing continuous packets of commands in atomic
+   way.
+
+Required properties for a client device:
+- mboxes: Client use mailbox to communicate with GCE, it should have this
+  property and list of phandle, mailbox specifiers.
+- mediatek,gce-subsys: u32, specify the sub-system id which is corresponding
+  to the register address.
+
+Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h'. Such 
as
+sub-system ids, thread priority, event ids.
+
+Example:
+
+   gce: gce@10212000 {
+   compatible = "mediatek,mt8173-gce";
+   reg = <0 0x10212000 0 0x1000>;
+   interrupts = ;
+   clocks = < CLK_INFRA_GCE>;
+   clock-names = "gce";
+   thread-num = CMDQ_THR_MAX_COUNT;
+   #mbox-cells = <3>;
+   };
+
+Example for a client device:
+
+   mmsys: clock-controller@1400 {
+   compatible = "mediatek,mt8173-mmsys";
+   mboxes = < 0 CMDQ_THR_PRIO_LOWEST 1>,
+< 1 CMDQ_THR_PRIO_LOWEST 1>;
+   mediatek,gce-subsys = ;
+   mutex-event-eof = ;
+
+   ...
+   };
diff --git a/include/dt-bindings/gce/mt8173-gce.h 
b/include/dt-bindings/gce/mt8173-gce.h
new file mode 100644
index 000..ffcf94b
--- /dev/null
+++ b/include/dt-bindings/gce/mt8173-gce.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Houlong Wei 
+ *
+ */
+
+#ifndef _DT_BINDINGS_GCE_MT8173_H
+#define _DT_BINDINGS_GCE_MT8173_H
+
+/* GCE HW thread priority */
+#define CMDQ_THR_PRIO_LOWEST   0
+#define CMDQ_THR_PRIO_HIGHEST  1
+
+/* GCE SUBSYS */
+#define SUBSYS_14001
+#define SUBSYS_14012
+#define SUBSYS_14023
+
+/* GCE HW EVENT */
+#define CMDQ_EVENT_DISP_OVL0_SOF   11
+#define CMDQ_EVENT_DISP_OVL1_SOF   12
+#define CMDQ_EVENT_DISP_RDMA0_SOF  13
+#define CMDQ_EVENT_DISP_RDMA1_SOF  14
+#define CMDQ_EVENT_DISP_RDMA2_SOF  15
+#define CMDQ_EVENT_DISP_WDMA0_SOF  16
+#define CMDQ_EVENT_DISP_WDMA1_SOF  17
+#define CMDQ_EVENT_DISP_OVL0_EOF   39
+#define CMDQ_EVENT_DISP_OVL1_EOF   40
+#define CMDQ_EVENT_DISP_RDMA0_EOF  41
+#define CMDQ_EVENT_DISP_RDMA1_EOF  42
+#define CMDQ_EVENT_DISP_RDMA2_EOF  43
+#define CMDQ_EVENT_DISP_WDMA0_EOF  44
+#define CMDQ_EVENT_DISP_WDMA1_EOF  45
+#define CMDQ_EVENT_MUTEX0_STREAM_EOF   53
+#define CMDQ_EVENT_MUTEX1_STREAM_EOF   54
+#define CMDQ_EVENT_MUTEX2_STREAM_EOF   55
+#define CMDQ_EVENT_MUTEX3_STREAM_EOF   56
+#define CMDQ_EVENT_MUTEX4_STREAM_EOF   57
+#define CMDQ_EVENT_DISP_RDMA0_UNDERRUN 63
+#define CMDQ_EVENT_DISP_RDMA1_UNDERRUN 64
+#define CMDQ_EVENT_DISP_RDMA2_UNDERRUN 65
+
+#endif
-- 
1.7.9.5



[PATCH v23 0/4] MediaTek MT8173 CMDQ support

2018-07-24 Thread Houlong Wei
Hi,

This is Mediatek MT8173 Command Queue(CMDQ) driver. The CMDQ is used
to help write registers with critical time limitation, such as
updating display configuration during the vblank. It controls Global
Command Engine (GCE) hardware to achieve this requirement.

Changes since v22:
 -remove properties 'timeout' and 'thread-num' from device tree
 -move timer from CMDQ driver to CMDQ helper
 -move dma unmap from CMDQ driver to CMDQ helper
 -config thread number in CMDQ match table
 -remove reallocate mechanism and let client specify the cmdq buffer size
 -let client specify the timeout time
Changes since v21:
 -rebase on v4.18-rc1
 -remove subsys code and event id definition from mtk-cmdq-helper.c
 -add mt8173-gce.h to define the subsys code and envent id
Changes since v20:
 -rebase on v4.15-rc1
 -move dma_map_single outside of spinlock
Changes since v19:
- rebase to v4.10-rc2

Houlong Wei (4):
  dt-bindings: soc: Add documentation for the MediaTek GCE unit
  mailbox: mediatek: Add Mediatek CMDQ driver
  arm64: dts: mt8173: Add GCE node
  soc: mediatek: Add Mediatek CMDQ helper

 .../devicetree/bindings/mailbox/mtk-gce.txt|  57 +++
 arch/arm64/boot/dts/mediatek/mt8173.dtsi   |  10 +
 drivers/mailbox/Kconfig|  10 +
 drivers/mailbox/Makefile   |   2 +
 drivers/mailbox/mtk-cmdq-mailbox.c | 569 +
 drivers/soc/mediatek/Kconfig   |  12 +
 drivers/soc/mediatek/Makefile  |   1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c | 291 +++
 include/dt-bindings/gce/mt8173-gce.h   |  44 ++
 include/linux/mailbox/mtk-cmdq-mailbox.h   |  77 +++
 include/linux/soc/mediatek/mtk-cmdq.h  | 135 +
 11 files changed, 1208 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk-gce.txt
 create mode 100644 drivers/mailbox/mtk-cmdq-mailbox.c
 create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
 create mode 100644 include/dt-bindings/gce/mt8173-gce.h
 create mode 100644 include/linux/mailbox/mtk-cmdq-mailbox.h
 create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

-- 
2.12.5
 



[PATCH v23 3/4] arm64: dts: mt8173: Add GCE node

2018-07-24 Thread Houlong Wei
This patch adds the device node of the GCE hardware for CMDQ module.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi |   10 ++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 94597e3..97b1ec6 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "mt8173-pinfunc.h"
 
 / {
@@ -519,6 +520,15 @@
status = "disabled";
};
 
+   gce: mailbox@10212000 {
+   compatible = "mediatek,mt8173-gce";
+   reg = <0 0x10212000 0 0x1000>;
+   interrupts = ;
+   clocks = < CLK_INFRA_GCE>;
+   clock-names = "gce";
+   #mbox-cells = <3>;
+   };
+
mipi_tx0: mipi-dphy@10215000 {
compatible = "mediatek,mt8173-mipi-tx";
reg = <0 0x10215000 0 0x1000>;
-- 
1.7.9.5



[PATCH v23 2/4] mailbox: mediatek: Add Mediatek CMDQ driver

2018-07-24 Thread Houlong Wei
This patch is first version of Mediatek Command Queue(CMDQ) driver. The
CMDQ is used to help write registers with critical time limitation,
such as updating display configuration during the vblank. It controls
Global Command Engine (GCE) hardware to achieve this requirement.
Currently, CMDQ only supports display related hardwares, but we expect
it can be extended to other hardwares for future requirements.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
Signed-off-by: CK Hu 
---
 drivers/mailbox/Kconfig  |   10 +
 drivers/mailbox/Makefile |2 +
 drivers/mailbox/mtk-cmdq-mailbox.c   |  569 ++
 include/linux/mailbox/mtk-cmdq-mailbox.h |   77 
 4 files changed, 658 insertions(+)
 create mode 100644 drivers/mailbox/mtk-cmdq-mailbox.c
 create mode 100644 include/linux/mailbox/mtk-cmdq-mailbox.h

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index e63d29a..2bbabc9 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -189,4 +189,14 @@ config STM32_IPCC
  Mailbox implementation for STMicroelectonics STM32 family chips
  with hardware for Inter-Processor Communication Controller (IPCC)
  between processors. Say Y here if you want to have this support.
+
+config MTK_CMDQ_MBOX
+   tristate "MediaTek CMDQ Mailbox Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ mailbox driver. The CMDQ is used to help read/write registers with
+ critical time limitation, such as updating display configuration
+ during the vblank.
 endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 4d501be..4b00804 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -40,3 +40,5 @@ obj-$(CONFIG_QCOM_APCS_IPC)   += qcom-apcs-ipc-mailbox.o
 obj-$(CONFIG_TEGRA_HSP_MBOX)   += tegra-hsp.o
 
 obj-$(CONFIG_STM32_IPCC)   += stm32-ipcc.o
+
+obj-$(CONFIG_MTK_CMDQ_MBOX)+= mtk-cmdq-mailbox.o
diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
b/drivers/mailbox/mtk-cmdq-mailbox.c
new file mode 100644
index 000..6f92c5e
--- /dev/null
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -0,0 +1,569 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018 MediaTek Inc.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_OP_CODE_MASK  (0xff << CMDQ_OP_CODE_SHIFT)
+#define CMDQ_IRQ_MASK  0x
+#define CMDQ_NUM_CMD(t)(t->cmd_buf_size / 
CMDQ_INST_SIZE)
+
+#define CMDQ_CURR_IRQ_STATUS   0x10
+#define CMDQ_THR_SLOT_CYCLES   0x30
+#define CMDQ_THR_BASE  0x100
+#define CMDQ_THR_SIZE  0x80
+#define CMDQ_THR_WARM_RESET0x00
+#define CMDQ_THR_ENABLE_TASK   0x04
+#define CMDQ_THR_SUSPEND_TASK  0x08
+#define CMDQ_THR_CURR_STATUS   0x0c
+#define CMDQ_THR_IRQ_STATUS0x10
+#define CMDQ_THR_IRQ_ENABLE0x14
+#define CMDQ_THR_CURR_ADDR 0x20
+#define CMDQ_THR_END_ADDR  0x24
+#define CMDQ_THR_WAIT_TOKEN0x30
+#define CMDQ_THR_PRIORITY  0x40
+
+#define CMDQ_THR_ACTIVE_SLOT_CYCLES0x3200
+#define CMDQ_THR_ENABLED   0x1
+#define CMDQ_THR_DISABLED  0x0
+#define CMDQ_THR_SUSPEND   0x1
+#define CMDQ_THR_RESUME0x0
+#define CMDQ_THR_STATUS_SUSPENDED  BIT(1)
+#define CMDQ_THR_DO_WARM_RESET BIT(0)
+#define CMDQ_THR_IRQ_DONE  0x1
+#define CMDQ_THR_IRQ_ERROR 0x12
+#define CMDQ_THR_IRQ_EN(CMDQ_THR_IRQ_ERROR | 
CMDQ_THR_IRQ_DONE)
+#define CMDQ_THR_IS_WAITINGBIT(31)
+
+#define CMDQ_JUMP_BY_OFFSET0x1000
+#define CMDQ_JUMP_BY_PA0x1001
+
+struct cmdq_thread {
+   struct mbox_chan*chan;
+   void __iomem*base;
+   struct list_headtask_busy_list;
+   u32 priority;
+   boolatomic_exec;
+};
+
+struct cmdq_task {
+   struct cmdq *cmdq;
+   struct list_headlist_entry;
+   dma_addr_t  pa_base;
+   struct cmdq_thread  *thread;
+   struct cmdq_pkt *pkt; /* the packet sent from mailbox client */
+};
+
+struct cmdq {
+   struct mbox_controller  mbox;
+   void __iomem*base;
+   u32 irq;
+   u32 thread_nr;
+   struct cmdq_thread  *thread;
+   struct clk  *clock;
+   boolsuspended;
+};
+
+static int cmdq_thread_suspend(struct cmdq *cmdq, struct cmdq_thread *thread)
+{
+   u32 status;
+
+   writel(CMDQ_

Re: [PATCH v23 3/4] arm64: dts: mt8173: Add GCE node

2018-09-09 Thread houlong wei
On Wed, 2018-08-15 at 09:48 +0800, houlong wei wrote:
> On Wed, 2018-07-25 at 09:26 +0800, Houlong Wei wrote:
> > This patch adds the device node of the GCE hardware for CMDQ module.
> > [...]

Hello Matthias,
   Sorry to disturb you. Are you availabe to review this patch and give
your comment? Thanks a lot.

Regards
Houlong




Re: [PATCH v23 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-09-09 Thread houlong wei
On Wed, 2018-08-15 at 09:46 +0800, houlong wei wrote:
> On Wed, 2018-07-25 at 09:26 +0800, Houlong Wei wrote:
> > Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.
> >[...]

Hello Matthias,
   Sorry to disturb you. Could you please review this patch and give
your comment? Thanks a lot.

Regards
Houlong



Re: [PATCH v22 2/4] mailbox: mediatek: Add Mediatek CMDQ driver

2018-07-05 Thread houlong wei
On Wed, 2018-07-04 at 17:03 +0800, CK Hu wrote:
> Hi, Houlong:
> 
> On Wed, 2018-07-04 at 08:10 +0800, houlong wei wrote:
> > On Fri, 2018-06-29 at 15:08 +0800, CK Hu wrote:
> > > Hi, Houlong:
> > > 
> > > Some inline comment.
> > > 
> > > On Wed, 2018-06-27 at 19:16 +0800, Houlong Wei wrote:
> > > > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > > > CMDQ is used to help write registers with critical time limitation,
> > > > such as updating display configuration during the vblank. It controls
> > > > Global Command Engine (GCE) hardware to achieve this requirement.
> > > > Currently, CMDQ only supports display related hardwares, but we expect
> > > > it can be extended to other hardwares for future requirements.
> > > > 
> > > > Signed-off-by: Houlong Wei 
> > > > Signed-off-by: HS Liao 
> > > > Signed-off-by: CK Hu 
> > > > ---
> > > >  drivers/mailbox/Kconfig  |   10 +
> > > >  drivers/mailbox/Makefile |2 +
> > > >  drivers/mailbox/mtk-cmdq-mailbox.c   |  634 
> > > > ++
> > > >  include/linux/mailbox/mtk-cmdq-mailbox.h |   70 
> > > >  4 files changed, 716 insertions(+)
> > > >  create mode 100644 drivers/mailbox/mtk-cmdq-mailbox.c
> > > >  create mode 100644 include/linux/mailbox/mtk-cmdq-mailbox.h
> > > > 
> > > 
> > > [...]
> > > 
> > > > +
> > > > +static int cmdq_thread_reset(struct cmdq *cmdq, struct cmdq_thread 
> > > > *thread)
> > > > +{
> > > > +   u32 warm_reset;
> > > > +
> > > > +   writel(CMDQ_THR_DO_WARM_RESET, thread->base + 
> > > > CMDQ_THR_WARM_RESET);
> > > > +   if (readl_poll_timeout_atomic(thread->base + 
> > > > CMDQ_THR_WARM_RESET,
> > > > +   warm_reset, !(warm_reset & 
> > > > CMDQ_THR_DO_WARM_RESET),
> > > > +   0, 10)) {
> > > > +   dev_err(cmdq->mbox.dev, "reset GCE thread 0x%x 
> > > > failed\n",
> > > > +   (u32)(thread->base - cmdq->base));
> > > > +   return -EFAULT;
> > > > +   }
> > > > +   writel(CMDQ_THR_ACTIVE_SLOT_CYCLES, cmdq->base + 
> > > > CMDQ_THR_SLOT_CYCLES);
> > > 
> > > The CMDQ_THR_SLOT_CYCLES looks like not relevant to reset. Maybe you
> > > just need to set this value when startup.
> > 
> > Will move configuration of CMDQ_THR_SLOT_CYCLES to cmdq_xlate() where is
> > startup of a GCE thread.
> > 

Since cmdq_xlate() is called when a client requests a channel, it may be
called more than once. Will move it to cmdq_probe().

> > > 
> > > > +
> > > > +   return 0;
> > > > +}
> > > > +
> > > 
> > > [...]
> > > 
> > > > +
> > > > +static void cmdq_task_exec(struct cmdq_pkt *pkt, struct cmdq_thread 
> > > > *thread)
> > > > +{
> > > > +   struct cmdq *cmdq;
> > > > +   struct cmdq_task *task;
> > > > +   unsigned long curr_pa, end_pa;
> > > > +
> > > > +   cmdq = dev_get_drvdata(thread->chan->mbox->dev);
> > > > +
> > > > +   /* Client should not flush new tasks if suspended. */
> > > > +   WARN_ON(cmdq->suspended);
> > > > +
> > > > +   task = kzalloc(sizeof(*task), GFP_ATOMIC);
> > > > +   task->cmdq = cmdq;
> > > > +   INIT_LIST_HEAD(>list_entry);
> > > > +   task->pa_base = pkt->pa_base;
> > > > +   task->thread = thread;
> > > > +   task->pkt = pkt;
> > > > +
> > > > +   if (list_empty(>task_busy_list)) {
> > > > +   WARN_ON(clk_enable(cmdq->clock) < 0);
> > > > +   WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
> > > > +
> > > > +   writel(task->pa_base, thread->base + 
> > > > CMDQ_THR_CURR_ADDR);
> > > > +   writel(task->pa_base + pkt->cmd_buf_size,
> > > > +  thread->base + CMDQ_THR_END_ADDR);
> > > > +   writel(thread->priority, thread->base + 
> > > > CMDQ_THR_PRIORITY);

Re: [PATCH v22 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-07-05 Thread houlong wei
On Wed, 2018-07-04 at 10:39 +0800, CK Hu wrote:
> Hi, Houlong:
> 
> On Wed, 2018-07-04 at 08:47 +0800, houlong wei wrote:
> > On Fri, 2018-06-29 at 17:22 +0800, CK Hu wrote:
> > > Hi, Houlong:
> > > 
> > > On Fri, 2018-06-29 at 07:32 +0800, houlong wei wrote:
> > > > On Thu, 2018-06-28 at 18:41 +0800, CK Hu wrote:
> > > > > Hi, Houlong:
> > > > > 
> > > > > Some inline comment.
> > > > > 
> > > > > On Wed, 2018-06-27 at 19:16 +0800, Houlong Wei wrote:
> > > > > > Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op 
> > > > > > code.
> > > > > > 
> > > > > > Signed-off-by: Houlong Wei 
> > > > > > Signed-off-by: HS Liao 
> > > > > > ---
> > > > > >  drivers/soc/mediatek/Kconfig   |   12 ++
> > > > > >  drivers/soc/mediatek/Makefile  |1 +
> > > > > >  drivers/soc/mediatek/mtk-cmdq-helper.c |  258 
> > > > > > 
> > > > > >  include/linux/soc/mediatek/mtk-cmdq.h  |  132 
> > > > > >  4 files changed, 403 insertions(+)
> > > > > >  create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
> > > > > >  create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h
> > > > > > 
> > > > > > diff --git a/drivers/soc/mediatek/Kconfig 
> > > > > > b/drivers/soc/mediatek/Kconfig
> > > > > > index a7d0667..17bd759 100644
> > > > > > --- a/drivers/soc/mediatek/Kconfig
> > > > > > +++ b/drivers/soc/mediatek/Kconfig
> > > > > > @@ -4,6 +4,18 @@
> > > > > >  menu "MediaTek SoC drivers"
> > > > > > depends on ARCH_MEDIATEK || COMPILE_TEST
> > > > > >  
> > > > > 
> > > 
> > > [...]
> > > 
> > > > > > +
> > > > > > +static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
> > > > > > +{
> > > > > > +   int err;
> > > > > > +
> > > > > > +   if (cmdq_pkt_is_finalized(pkt))
> > > > > > +   return 0;
> > > > > > +
> > > > > > +   /* insert EOC and generate IRQ for each command iteration */
> > > > > > +   err = cmdq_pkt_append_command(pkt, CMDQ_CODE_EOC, 0, 
> > > > > > CMDQ_EOC_IRQ_EN);
> > > > > > +   if (err < 0)
> > > > > > +   return err;
> > > > > > +
> > > > > > +   /* JUMP to end */
> > > > > > +   err = cmdq_pkt_append_command(pkt, CMDQ_CODE_JUMP, 0, 
> > > > > > CMDQ_JUMP_PASS);
> > > > > > +   if (err < 0)
> > > > > > +   return err;
> > > > > > +
> > > > > > +   return 0;
> > > > > > +}
> > > > > > +
> > > > > > +int cmdq_pkt_flush_async(struct cmdq_client *client, struct 
> > > > > > cmdq_pkt *pkt,
> > > > > > +cmdq_async_flush_cb cb, void *data)
> > > > > > +{
> > > > > > +   int err;
> > > > > > +   struct device *dev;
> > > > > > +   dma_addr_t dma_addr;
> > > > > > +
> > > > > > +   err = cmdq_pkt_finalize(pkt);
> > > > > > +   if (err < 0)
> > > > > > +   return err;
> > > > > > +
> > > > > > +   dev = client->chan->mbox->dev;
> > > > > > +   dma_addr = dma_map_single(dev, pkt->va_base, pkt->cmd_buf_size,
> > > > > > +   DMA_TO_DEVICE);
> > > > > 
> > > > > You map here, but I could not find unmap, so the unmap should be done 
> > > > > in
> > > > > client driver. I would prefer a symmetric map/unmap which means that
> > > > > both map and unmap are done in client driver. I think you put map here
> > > > > because you should map after finalize. 
> > > > 
> > > > The unmap is done before callback to client, in function
> > > > cmdq_task_exec_done, mtk-cmdq-mailbox.c.
> > > 
> > > You put unmap in mailbox controller, and map here (here would be mailbox
> > > client), so this is not symmetric. If the code is asymmetric, it's easy
>

Re: [PATCH v22 1/4] dt-bindings: soc: Add documentation for the MediaTek GCE unit

2018-07-05 Thread houlong wei
On Fri, 2018-07-06 at 04:08 +0800, Rob Herring wrote:
> On Tue, Jul 3, 2018 at 5:39 PM houlong wei  wrote:
> >
> > On Tue, 2018-07-03 at 10:30 +0800, Rob Herring wrote:
> > > On Wed, Jun 27, 2018 at 07:16:09PM +0800, Houlong Wei wrote:
> > > > This adds documentation for the MediaTek Global Command Engine (GCE) 
> > > > unit
> > > > found in MT8173 SoCs.
> > > >
> > > > Signed-off-by: Houlong Wei 
> > > > Signed-off-by: HS Liao 
> > > > ---
> > > > Hi Rob,
> > > >   I don't add your ACK in this version since the dt-binding description
> > > > has been changed. Thanks.
> > > > ---
> > > >  .../devicetree/bindings/mailbox/mtk-gce.txt|   65 
> > > > 
> > > >  include/dt-bindings/gce/mt8173-gce.h   |   48 
> > > > +++
> > > >  2 files changed, 113 insertions(+)
> > > >  create mode 100644 
> > > > Documentation/devicetree/bindings/mailbox/mtk-gce.txt
> > > >  create mode 100644 include/dt-bindings/gce/mt8173-gce.h
> > > >
> > > > diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt 
> > > > b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
> > > > new file mode 100644
> > > > index 000..26f65a4
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
> > > > @@ -0,0 +1,65 @@
> > > > +MediaTek GCE
> > > > +===
> > > > +
> > > > +The Global Command Engine (GCE) is used to help read/write registers 
> > > > with
> > > > +critical time limitation, such as updating display configuration 
> > > > during the
> > > > +vblank. The GCE can be used to implement the Command Queue (CMDQ) 
> > > > driver.
> > > > +
> > > > +CMDQ driver uses mailbox framework for communication. Please refer to
> > > > +mailbox.txt for generic information about mailbox device-tree bindings.
> > > > +
> > > > +Required properties:
> > > > +- compatible: Must be "mediatek,mt8173-gce"
> > > > +- reg: Address range of the GCE unit
> > > > +- interrupts: The interrupt signal from the GCE block
> > > > +- clock: Clocks according to the common clock binding
> > > > +- clock-names: Must be "gce" to stand for GCE clock
> > > > +- thread-num: Maximum threads count of GCE.
> > >
> > > mediatek,thread-num
> > >
> > > Is this needed for anything other than error checking the thread id in
> > > the mbox cells? if that's it, then drop it.
> > >
> >
> > 'thread-num' is used to configure the GCE thread number, which is the
> > channel number of gce mailbox. This property is read in
> > cmdq_probe()/mtk-cmdq-mailbox.c and a mailbox's channel array is
> > allocated according to the number.
> > Since the thread number may be different on different SoC, we wish it
> > could be configured in device tree.
> 
> You should have different compatible strings for different SoCs and
> can imply the number of threads from that.
> 

Thanks. Will remove 'thread-num' form device tree and put it in match
table of cmdq dirver.

> Or if the number of threads doesn't vary greatly, just allocate the
> max # of channels. Or allocate the per thread data when a thread is
> actually in use.
> 
> >
> > > > +- #mbox-cells: Should be 4.
> > > > +   < channel timeout priority atomic_exec>
> > > > +   phandle: Label name of a gce node.
> > > > +   channel: Channel of mailbox. Be equal to the thread id of GCE.
> > > > +   timeout: Maximum time of software waiting GCE processing done, in 
> > > > unit
> > > > +   of millisecond.
> > > > +   priority: Priority of GCE thread.
> > > > +   atomic_exec: GCE processing continuous packets of commands in atomic
> > > > +   way.
> > > > +
> > > > +Required properties for a client device:
> > > > +- mboxes: Client use mailbox to communicate with GCE, it should have 
> > > > this
> > > > +  property and list of phandle, mailbox specifiers.
> > > > +- gce-subsys: Specify the sub-system id which is corresponding to the 
> > > > register
> > > > +  address.
> > >
> > > What is this for?
> >
> > You mean the new added property 'gce-subsys'?
> > I

Re: [PATCH v22 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-06-28 Thread houlong wei
On Thu, 2018-06-28 at 18:41 +0800, CK Hu wrote:
> Hi, Houlong:
> 
> Some inline comment.
> 
> On Wed, 2018-06-27 at 19:16 +0800, Houlong Wei wrote:
> > Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.
> > 
> > Signed-off-by: Houlong Wei 
> > Signed-off-by: HS Liao 
> > ---
> >  drivers/soc/mediatek/Kconfig   |   12 ++
> >  drivers/soc/mediatek/Makefile  |1 +
> >  drivers/soc/mediatek/mtk-cmdq-helper.c |  258 
> > 
> >  include/linux/soc/mediatek/mtk-cmdq.h  |  132 
> >  4 files changed, 403 insertions(+)
> >  create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
> >  create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h
> > 
> > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > index a7d0667..17bd759 100644
> > --- a/drivers/soc/mediatek/Kconfig
> > +++ b/drivers/soc/mediatek/Kconfig
> > @@ -4,6 +4,18 @@
> >  menu "MediaTek SoC drivers"
> > depends on ARCH_MEDIATEK || COMPILE_TEST
> >  
> 
> [...]
> 
> > +
> > +int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u32 event)
> > +{
> > +   u32 arg_b;
> > +
> > +   if (event >= CMDQ_MAX_EVENT || event < 0)
> 
> The type of event is 'u32', so checking 'event < 0' is redundant.

will fix.

> 
> > +   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;
> > +
> > +   return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event, arg_b);
> > +}
> > +EXPORT_SYMBOL(cmdq_pkt_wfe);
> > +
> > +int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u32 event)
> > +{
> > +   if (event >= CMDQ_MAX_EVENT || event < 0)
> 
> The type of event is 'u32', so checking 'event < 0' is redundant.

Will fix.

> 
> > +   return -EINVAL;
> > +
> > +   return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event,
> > +  CMDQ_WFE_UPDATE);
> > +}
> > +EXPORT_SYMBOL(cmdq_pkt_clear_event);
> > +
> > +static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
> > +{
> > +   int err;
> > +
> > +   if (cmdq_pkt_is_finalized(pkt))
> > +   return 0;
> > +
> > +   /* insert EOC and generate IRQ for each command iteration */
> > +   err = cmdq_pkt_append_command(pkt, CMDQ_CODE_EOC, 0, CMDQ_EOC_IRQ_EN);
> > +   if (err < 0)
> > +   return err;
> > +
> > +   /* JUMP to end */
> > +   err = cmdq_pkt_append_command(pkt, CMDQ_CODE_JUMP, 0, CMDQ_JUMP_PASS);
> > +   if (err < 0)
> > +   return err;
> > +
> > +   return 0;
> > +}
> > +
> > +int cmdq_pkt_flush_async(struct cmdq_client *client, struct cmdq_pkt *pkt,
> > +cmdq_async_flush_cb cb, void *data)
> > +{
> > +   int err;
> > +   struct device *dev;
> > +   dma_addr_t dma_addr;
> > +
> > +   err = cmdq_pkt_finalize(pkt);
> > +   if (err < 0)
> > +   return err;
> > +
> > +   dev = client->chan->mbox->dev;
> > +   dma_addr = dma_map_single(dev, pkt->va_base, pkt->cmd_buf_size,
> > +   DMA_TO_DEVICE);
> 
> You map here, but I could not find unmap, so the unmap should be done in
> client driver. I would prefer a symmetric map/unmap which means that
> both map and unmap are done in client driver. I think you put map here
> because you should map after finalize. 

The unmap is done before callback to client, in function
cmdq_task_exec_done, mtk-cmdq-mailbox.c.

> Therefore, export
> cmdq_pkt_finalize() to client driver and let client do finalize, so
> there is no finalize in flush function. This method have a benefit that
> if client reuse command buffer, it need not to map/unmap frequently.

If client reuse command buffer or cmdq_pkt(command queue packet), client
will add new commands to the cmdq_pkt, so map/unmap are necessary for
each cmdq_pkt flush.

> 
> Regards,
> CK
> 
> > +   if (dma_mapping_error(dev, dma_addr)) {
> > +   dev_err(client->chan->mbox->dev, "dma map failed\n");
> > +   return -ENOMEM;
> > +   }
> > +
> > +   pkt->pa_base = dma_addr;
> > +   pkt->cb.cb = cb;
> > +   pkt->cb.data = data;
> > +
> > +   mbox_send_message(client->chan, pkt);
> > +   /*

Re: [PATCH v21 2/4] mailbox: mediatek: Add Mediatek CMDQ driver

2018-06-28 Thread houlong wei
On Thu, 2018-06-28 at 09:57 +0800, CK Hu wrote:
> Hi, Houlong:
> 
> On Wed, 2018-06-27 at 19:53 +0800, houlong wei wrote:
> > On Wed, 2018-02-21 at 11:53 +0800, CK Hu wrote:
> > > Hi, Houlong:
> > > 
> > > I've one inline comment.
> > > 
> > > On Wed, 2018-01-31 at 15:28 +0800, houlong@mediatek.com wrote:
> > > > From: "hs.l...@mediatek.com" 
> > > > 
> > > > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > > > CMDQ is used to help write registers with critical time limitation,
> > > > such as updating display configuration during the vblank. It controls
> > > > Global Command Engine (GCE) hardware to achieve this requirement.
> > > > Currently, CMDQ only supports display related hardwares, but we expect
> > > > it can be extended to other hardwares for future requirements.
> > > > 
> > > > Signed-off-by: Houlong Wei 
> > > > Signed-off-by: HS Liao 
> > > > Signed-off-by: CK Hu 
> > > > ---
> > > >  drivers/mailbox/Kconfig  |   10 +
> > > >  drivers/mailbox/Makefile |2 +
> > > >  drivers/mailbox/mtk-cmdq-mailbox.c   |  594 
> > > > ++
> > > >  include/linux/mailbox/mtk-cmdq-mailbox.h |   77 
> > > >  4 files changed, 683 insertions(+)
> > > >  create mode 100644 drivers/mailbox/mtk-cmdq-mailbox.c
> > > >  create mode 100644 include/linux/mailbox/mtk-cmdq-mailbox.h
> > > > 
> > > > diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
> > > > index ba2f152..43bb26f 100644
> > > > --- a/drivers/mailbox/Kconfig
> > > > +++ b/drivers/mailbox/Kconfig
> > > > @@ -171,4 +171,14 @@ config BCM_FLEXRM_MBOX
> > > >   Mailbox implementation of the Broadcom FlexRM ring manager,
> > > >   which provides access to various offload engines on Broadcom
> > > >   SoCs. Say Y here if you want to use the Broadcom FlexRM.
> > > > +
> 
> [...]
> 
> > > > +
> > > > +static void cmdq_task_exec(struct cmdq_pkt *pkt, struct cmdq_thread 
> > > > *thread)
> > > > +{
> > > > +   struct cmdq *cmdq;
> > > > +   struct cmdq_task *task;
> > > > +   unsigned long curr_pa, end_pa;
> > > > +
> > > > +   cmdq = dev_get_drvdata(thread->chan->mbox->dev);
> > > > +
> > > > +   /* Client should not flush new tasks if suspended. */
> > > > +   WARN_ON(cmdq->suspended);
> > > > +
> > > > +   task = kzalloc(sizeof(*task), GFP_ATOMIC);
> > > > +   task->cmdq = cmdq;
> > > > +   INIT_LIST_HEAD(>list_entry);
> > > > +   task->pa_base = pkt->pa_base;
> > > > +   task->thread = thread;
> > > > +   task->pkt = pkt;
> > > > +
> > > > +   if (list_empty(>task_busy_list)) {
> > > > +   WARN_ON(clk_enable(cmdq->clock) < 0);
> > > > +   WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
> > > > +
> > > > +   writel(task->pa_base, thread->base + 
> > > > CMDQ_THR_CURR_ADDR);
> > > > +   writel(task->pa_base + pkt->cmd_buf_size,
> > > > +  thread->base + CMDQ_THR_END_ADDR);
> > > > +   writel(CMDQ_THR_IRQ_EN, thread->base + 
> > > > CMDQ_THR_IRQ_ENABLE);
> > > > +   writel(CMDQ_THR_ENABLED, thread->base + 
> > > > CMDQ_THR_ENABLE_TASK);
> > > > +
> > > > +   mod_timer(>timeout,
> > > > + jiffies + msecs_to_jiffies(CMDQ_TIMEOUT_MS));
> > > > +   } else {
> > > > +   WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
> > > > +   curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR);
> > > > +   end_pa = readl(thread->base + CMDQ_THR_END_ADDR);
> > > > +
> > > > +   /*
> > > > +* Atomic execution should remove the following wfe, 
> > > > i.e. only
> > > > +* wait event at first task, and prevent to pause when 
> > > > running.
> > > > +*/
> > > > +   if (thread->atomic_exec

[PATCH v26 2/2] soc: mediatek: Add Mediatek CMDQ helper

2018-10-07 Thread Houlong Wei
Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 drivers/soc/mediatek/Kconfig   |   12 ++
 drivers/soc/mediatek/Makefile  |1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c |  292 
 include/linux/soc/mediatek/mtk-cmdq.h  |  133 +++
 4 files changed, 438 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
 create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index a7d0667..17bd759 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -4,6 +4,18 @@
 menu "MediaTek SoC drivers"
depends on ARCH_MEDIATEK || COMPILE_TEST
 
+config MTK_CMDQ
+   tristate "MediaTek CMDQ Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select MAILBOX
+   select MTK_CMDQ_MBOX
+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
 config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
select REGMAP
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..64ce5ee 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
 obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
 obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
new file mode 100644
index 000..45aa0cf
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018 MediaTek Inc.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_ARG_A_WRITE_MASK  0x
+#define CMDQ_WRITE_ENABLE_MASK BIT(0)
+#define CMDQ_EOC_IRQ_ENBIT(0)
+#define CMDQ_EOC_CMD   ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
+   << 32 | CMDQ_EOC_IRQ_EN)
+
+static void cmdq_client_timeout(struct timer_list *t)
+{
+   struct cmdq_client *client = from_timer(client, t, timer);
+
+   dev_err(client->client.dev, "cmdq timeout!\n");
+}
+
+struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 
timeout)
+{
+   struct cmdq_client *client;
+
+   client = kzalloc(sizeof(*client), GFP_KERNEL);
+   if (!client)
+   return (struct cmdq_client *)-ENOMEM;
+
+   client->timeout_ms = timeout;
+   if (timeout != CMDQ_NO_TIMEOUT) {
+   spin_lock_init(>lock);
+   timer_setup(>timer, cmdq_client_timeout, 0);
+   }
+   client->pkt_cnt = 0;
+   client->client.dev = dev;
+   client->client.tx_block = false;
+   client->chan = mbox_request_channel(>client, index);
+
+   if (IS_ERR(client->chan)) {
+   long err;
+
+   dev_err(dev, "failed to request channel\n");
+   err = PTR_ERR(client->chan);
+   kfree(client);
+
+   return ERR_PTR(err);
+   }
+
+   return client;
+}
+EXPORT_SYMBOL(cmdq_mbox_create);
+
+void cmdq_mbox_destroy(struct cmdq_client *client)
+{
+   if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
+   spin_lock(>lock);
+   del_timer_sync(>timer);
+   spin_unlock(>lock);
+   }
+   mbox_free_channel(client->chan);
+   kfree(client);
+}
+EXPORT_SYMBOL(cmdq_mbox_destroy);
+
+struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
+{
+   struct cmdq_pkt *pkt;
+   struct device *dev;
+   dma_addr_t dma_addr;
+
+   pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
+   if (!pkt)
+   return ERR_PTR(-ENOMEM);
+   pkt->va_base = kzalloc(size, GFP_KERNEL);
+   if (!pkt->va_base) {
+   kfree(pkt);
+   return ERR_PTR(-ENOMEM);
+   }
+   pkt->buf_size = size;
+   pkt->cl = (void *)client;
+
+   dev = client->chan->mbox->dev;
+   dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
+ DMA_TO_DEVICE);
+   if (dma_mapping_error(dev, dma_addr)) {
+   dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
+   kfree(pkt->va_base);
+   kfree(pkt);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   pkt->pa_base = dma_addr;
+
+   return pkt;
+}
+EXPORT_SYMBOL(cmdq_pkt_create);
+
+void cmdq_pkt_destroy(struct cmdq_pkt *pk

[PATCH v26 1/2] arm64: dts: mt8173: Add GCE node

2018-10-07 Thread Houlong Wei
This patch adds the device node of the GCE hardware for CMDQ module.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi |   10 ++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index abd2f15..412ffd4 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "mt8173-pinfunc.h"
 
 / {
@@ -521,6 +522,15 @@
status = "disabled";
};
 
+   gce: mailbox@10212000 {
+   compatible = "mediatek,mt8173-gce";
+   reg = <0 0x10212000 0 0x1000>;
+   interrupts = ;
+   clocks = < CLK_INFRA_GCE>;
+   clock-names = "gce";
+   #mbox-cells = <3>;
+   };
+
mipi_tx0: mipi-dphy@10215000 {
compatible = "mediatek,mt8173-mipi-tx";
reg = <0 0x10215000 0 0x1000>;
-- 
1.7.9.5



[PATCH v26 0/2] MediaTek MT8173 CMDQ support

2018-10-07 Thread Houlong Wei
Hi,

This is Mediatek MT8173 Command Queue(CMDQ) driver. The CMDQ is used
to help write registers with critical time limitation, such as
updating display configuration during the vblank. It controls Global
Command Engine (GCE) hardware to achieve this requirement.

Changes since v25:
 -Replace WARN_ON() with WARN_ONCE() and add debug information.
Changes since v24:
 -move WARN_ON() into cmdq_pkt_append_command() from outside
Changes since v23:
 -rebase on v4.19-rc1
 -revise return value of cmdq_mbox_create()
 -revise cmdq_pkt_create()
 -add MODULE_LICENSE() for mtk-cmdq-helper.c
 -adjust functions order in mtk-cmdq.h
Changes since v22:
 -remove properties 'timeout' and 'thread-num' from device tree
 -move timer from CMDQ driver to CMDQ helper
 -move dma unmap from CMDQ driver to CMDQ helper
 -config thread number in CMDQ match table
 -remove reallocate mechanism and let client specify the cmdq buffer size
 -let client specify the timeout time
Changes since v21:
 -rebase on v4.18-rc1
 -remove subsys code and event id definition from mtk-cmdq-helper.c
 -add mt8173-gce.h to define the subsys code and envent id
Changes since v20:
 -rebase on v4.15-rc1
 -move dma_map_single outside of spinlock
Changes since v19:
 -rebase to v4.10-rc2

Houlong Wei (2):
  arm64: dts: mt8173: Add GCE node
  soc: mediatek: Add Mediatek CMDQ helper

 arch/arm64/boot/dts/mediatek/mt8173.dtsi |   10 +
 drivers/soc/mediatek/Kconfig |   12 ++
 drivers/soc/mediatek/Makefile|1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c   |  292 ++
 include/linux/soc/mediatek/mtk-cmdq.h|  133 ++
 5 files changed, 448 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
 create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

-- 
1.7.9.5



Re: [PATCH v25 2/2] soc: mediatek: Add Mediatek CMDQ helper

2018-10-07 Thread houlong wei
On Sat, 2018-09-29 at 20:50 +0800, Matthias Brugger wrote:
> 
> On 29/09/2018 11:21, Houlong Wei wrote:
> [...]
> 
> > +static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code 
> > code,
> > +  u32 arg_a, u32 arg_b)
> > +{
> > +   u64 *cmd_ptr;
> > +
> > +   if (unlikely(pkt->cmd_buf_size + CMDQ_INST_SIZE > pkt->buf_size)) {
> > +   pkt->cmd_buf_size += CMDQ_INST_SIZE;
> 
> Can you plesae provide some example code of a driver that will use this API, I
> still don't understand why you need to update the cmd_buf_size here.

In our previous design, when appending a new command to buffer and the
buffer gets overflow, we will re-allocate a larger buffer to use.
CK.Hu had concern about the performance of buffer re-allocation. Please
refer:
http://lists.infradead.org/pipermail/linux-mediatek/2018-June/013797.html
One of his suggestions is that the consumer dynamically allocates buffer
with a initial size. Because the consumer doesn't know how to calculate
the buffer size. So we increase cmdq_buf_size here, that will help the
consumer get the buffer size in developing phase. In release driver
code, consumer passes a constant value to function call
cmdq_pkt_create(client, cmdq_buffer_size), cmdq_buffer_size is the
specified command queue buffer size.

> 
> > +   WARN_ON(1);
> 
> can we add some debug information:
> WARN_ON(1, "%s: buffer size too small for the amount of commands", __func__);
> 
> Would it make sense to use WARN_ONCE()?
> 
Yes, I will add debug information and use WARN_ONCE().

> > +   return -ENOMEM;
> > +   }
> > +   cmd_ptr = pkt->va_base + pkt->cmd_buf_size;
> > +   (*cmd_ptr) = (u64)((code << CMDQ_OP_CODE_SHIFT) | arg_a) << 32 | arg_b;
> > +   pkt->cmd_buf_size += CMDQ_INST_SIZE;
> > +
> > +   return 0;
> > +}
> 
> Thanks,
> Matthias




Re: [PATCH v26 2/2] soc: mediatek: Add Mediatek CMDQ helper

2018-10-24 Thread houlong wei
On Mon, 2018-10-08 at 11:43 +0800, Houlong Wei wrote:
> Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.
> 
> Signed-off-by: Houlong Wei 
> Signed-off-by: HS Liao 
> ---
>  drivers/soc/mediatek/Kconfig   |   12 ++
>  drivers/soc/mediatek/Makefile  |1 +
>  drivers/soc/mediatek/mtk-cmdq-helper.c |  292 
> 
>  include/linux/soc/mediatek/mtk-cmdq.h  |  133 +++
>  4 files changed, 438 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
>  create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h
> 
> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> index a7d0667..17bd759 100644
> --- a/drivers/soc/mediatek/Kconfig
> +++ b/drivers/soc/mediatek/Kconfig
> @@ -4,6 +4,18 @@
>  menu "MediaTek SoC drivers"
>  depends on ARCH_MEDIATEK || COMPILE_TEST
> 
> +config MTK_CMDQ
> +tristate "MediaTek CMDQ Support"
> +depends on ARCH_MEDIATEK || COMPILE_TEST
> +select MAILBOX
> +select MTK_CMDQ_MBOX
> +select MTK_INFRACFG
> +help
> +  Say yes here to add support for the MediaTek Command Queue (CMDQ)
> +  driver. The CMDQ is used to help read/write registers with critical
> +  time limitation, such as updating display configuration during the
> +  vblank.
> +
>  config MTK_INFRACFG
>  bool "MediaTek INFRACFG Support"
>  select REGMAP
> diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> index 12998b0..64ce5ee 100644
> --- a/drivers/soc/mediatek/Makefile
> +++ b/drivers/soc/mediatek/Makefile
> @@ -1,3 +1,4 @@
> +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
>  obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
>  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
>  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> b/drivers/soc/mediatek/mtk-cmdq-helper.c
> new file mode 100644
> index 000..45aa0cf
> --- /dev/null
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -0,0 +1,292 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// Copyright (c) 2018 MediaTek Inc.
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define CMDQ_ARG_A_WRITE_MASK0x
> +#define CMDQ_WRITE_ENABLE_MASKBIT(0)
> +#define CMDQ_EOC_IRQ_ENBIT(0)
> +#define CMDQ_EOC_CMD((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
> +<< 32 | CMDQ_EOC_IRQ_EN)
> +
> +static void cmdq_client_timeout(struct timer_list *t)
> +{
> +struct cmdq_client *client = from_timer(client, t, timer);
> +
> +dev_err(client->client.dev, "cmdq timeout!\n");
> +}
> +
> +struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 
> timeout)
> +{
> +struct cmdq_client *client;
> +
> +client = kzalloc(sizeof(*client), GFP_KERNEL);
> +if (!client)
> +return (struct cmdq_client *)-ENOMEM;
> +
> +client->timeout_ms = timeout;
> +if (timeout != CMDQ_NO_TIMEOUT) {
> +spin_lock_init(>lock);
> +timer_setup(>timer, cmdq_client_timeout, 0);
> +}
> +client->pkt_cnt = 0;
> +client->client.dev = dev;
> +client->client.tx_block = false;
> +client->chan = mbox_request_channel(>client, index);
> +
> +if (IS_ERR(client->chan)) {
> +long err;
> +
> +dev_err(dev, "failed to request channel\n");
> +err = PTR_ERR(client->chan);
> +kfree(client);
> +
> +return ERR_PTR(err);
> +}
> +
> +return client;
> +}
> +EXPORT_SYMBOL(cmdq_mbox_create);
> +
> +void cmdq_mbox_destroy(struct cmdq_client *client)
> +{
> +if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
> +spin_lock(>lock);
> +del_timer_sync(>timer);
> +spin_unlock(>lock);
> +}
> +mbox_free_channel(client->chan);
> +kfree(client);
> +}
> +EXPORT_SYMBOL(cmdq_mbox_destroy);
> +
> +struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
> +{
> +struct cmdq_pkt *pkt;
> +struct device *dev;
> +dma_addr_t dma_addr;
> +
> +pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
> +if (!pkt)
> +return ERR_PTR(-ENOMEM);
> +pkt->va_base = kzalloc(size, GFP_KERNEL);
> +if (!pkt->va_base) {
> +kfree(pkt);
> +return ERR_PTR(-ENOMEM);
> +}
> +pkt->buf_size = size;
> +pkt->cl = (void *)client;
> +
> +dev = client->chan->mbox->dev;
> +dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
> +  DMA_TO_DEVICE);
> +if (dma_mapping_error(dev, dma_addr)) {
> +dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
> +kfree(pkt->va_base);
> +kfree(pkt);
> +return ERR_PTR(-ENOMEM);
> +}
> +
> +pkt->pa_base = dma_addr;
> +
> +return pk

[PATCH v25 1/2] arm64: dts: mt8173: Add GCE node

2018-09-29 Thread Houlong Wei
This patch adds the device node of the GCE hardware for CMDQ module.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi |   10 ++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index abd2f15..412ffd4 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "mt8173-pinfunc.h"
 
 / {
@@ -521,6 +522,15 @@
status = "disabled";
};
 
+   gce: mailbox@10212000 {
+   compatible = "mediatek,mt8173-gce";
+   reg = <0 0x10212000 0 0x1000>;
+   interrupts = ;
+   clocks = < CLK_INFRA_GCE>;
+   clock-names = "gce";
+   #mbox-cells = <3>;
+   };
+
mipi_tx0: mipi-dphy@10215000 {
compatible = "mediatek,mt8173-mipi-tx";
reg = <0 0x10215000 0 0x1000>;
-- 
1.7.9.5



[PATCH v25 2/2] soc: mediatek: Add Mediatek CMDQ helper

2018-09-29 Thread Houlong Wei
Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 drivers/soc/mediatek/Kconfig   |   12 ++
 drivers/soc/mediatek/Makefile  |1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c |  291 
 include/linux/soc/mediatek/mtk-cmdq.h  |  133 +++
 4 files changed, 437 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
 create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index a7d0667..17bd759 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -4,6 +4,18 @@
 menu "MediaTek SoC drivers"
depends on ARCH_MEDIATEK || COMPILE_TEST
 
+config MTK_CMDQ
+   tristate "MediaTek CMDQ Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select MAILBOX
+   select MTK_CMDQ_MBOX
+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
 config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
select REGMAP
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..64ce5ee 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
 obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
 obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
new file mode 100644
index 000..86a7ab5
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -0,0 +1,291 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018 MediaTek Inc.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_ARG_A_WRITE_MASK  0x
+#define CMDQ_WRITE_ENABLE_MASK BIT(0)
+#define CMDQ_EOC_IRQ_ENBIT(0)
+#define CMDQ_EOC_CMD   ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
+   << 32 | CMDQ_EOC_IRQ_EN)
+
+static void cmdq_client_timeout(struct timer_list *t)
+{
+   struct cmdq_client *client = from_timer(client, t, timer);
+
+   dev_err(client->client.dev, "cmdq timeout!\n");
+}
+
+struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 
timeout)
+{
+   struct cmdq_client *client;
+
+   client = kzalloc(sizeof(*client), GFP_KERNEL);
+   if (!client)
+   return (struct cmdq_client *)-ENOMEM;
+
+   client->timeout_ms = timeout;
+   if (timeout != CMDQ_NO_TIMEOUT) {
+   spin_lock_init(>lock);
+   timer_setup(>timer, cmdq_client_timeout, 0);
+   }
+   client->pkt_cnt = 0;
+   client->client.dev = dev;
+   client->client.tx_block = false;
+   client->chan = mbox_request_channel(>client, index);
+
+   if (IS_ERR(client->chan)) {
+   long err;
+
+   dev_err(dev, "failed to request channel\n");
+   err = PTR_ERR(client->chan);
+   kfree(client);
+
+   return ERR_PTR(err);
+   }
+
+   return client;
+}
+EXPORT_SYMBOL(cmdq_mbox_create);
+
+void cmdq_mbox_destroy(struct cmdq_client *client)
+{
+   if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
+   spin_lock(>lock);
+   del_timer_sync(>timer);
+   spin_unlock(>lock);
+   }
+   mbox_free_channel(client->chan);
+   kfree(client);
+}
+EXPORT_SYMBOL(cmdq_mbox_destroy);
+
+struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
+{
+   struct cmdq_pkt *pkt;
+   struct device *dev;
+   dma_addr_t dma_addr;
+
+   pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
+   if (!pkt)
+   return ERR_PTR(-ENOMEM);
+   pkt->va_base = kzalloc(size, GFP_KERNEL);
+   if (!pkt->va_base) {
+   kfree(pkt);
+   return ERR_PTR(-ENOMEM);
+   }
+   pkt->buf_size = size;
+   pkt->cl = (void *)client;
+
+   dev = client->chan->mbox->dev;
+   dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
+ DMA_TO_DEVICE);
+   if (dma_mapping_error(dev, dma_addr)) {
+   dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
+   kfree(pkt->va_base);
+   kfree(pkt);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   pkt->pa_base = dma_addr;
+
+   return pkt;
+}
+EXPORT_SYMBOL(cmdq_pkt_create);
+
+void cmdq_pkt_destroy(struct cmdq_pkt *pk

MediaTek MT8173 CMDQ support

2018-09-29 Thread Houlong Wei
Hi,

This is Mediatek MT8173 Command Queue(CMDQ) driver. The CMDQ is used
to help write registers with critical time limitation, such as
updating display configuration during the vblank. It controls Global
Command Engine (GCE) hardware to achieve this requirement.

Changes since v24:
 -move WARN_ON() into cmdq_pkt_append_command() from outside
Changes since v23:
 -rebase on v4.19-rc1
 -revise return value of cmdq_mbox_create()
 -revise cmdq_pkt_create()
 -add MODULE_LICENSE() for mtk-cmdq-helper.c
 -adjust functions order in mtk-cmdq.h
Changes since v22:
 -remove properties 'timeout' and 'thread-num' from device tree
 -move timer from CMDQ driver to CMDQ helper
 -move dma unmap from CMDQ driver to CMDQ helper
 -config thread number in CMDQ match table
 -remove reallocate mechanism and let client specify the cmdq buffer size
 -let client specify the timeout time
Changes since v21:
 -rebase on v4.18-rc1
 -remove subsys code and event id definition from mtk-cmdq-helper.c
 -add mt8173-gce.h to define the subsys code and envent id
Changes since v20:
 -rebase on v4.15-rc1
 -move dma_map_single outside of spinlock
Changes since v19:
 -rebase to v4.10-rc2

Houlong Wei (2):
  arm64: dts: mt8173: Add GCE node
  soc: mediatek: Add Mediatek CMDQ helper

 arch/arm64/boot/dts/mediatek/mt8173.dtsi |   10 +
 drivers/soc/mediatek/Kconfig |   12 ++
 drivers/soc/mediatek/Makefile|1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c   |  291 ++
 include/linux/soc/mediatek/mtk-cmdq.h|  133 ++
 5 files changed, 447 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
 create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

-- 
1.7.9.5


Re: [PATCH v23 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-09-26 Thread houlong wei
On Wed, 2018-09-26 at 23:53 +0800, Matthias Brugger wrote:
> 
> On 25/07/2018 03:26, Houlong Wei wrote:
> > Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.
> > 
> > Signed-off-by: Houlong Wei 
> > Signed-off-by: HS Liao 
> > ---
> >  drivers/soc/mediatek/Kconfig   |   12 ++
> >  drivers/soc/mediatek/Makefile  |1 +
> >  drivers/soc/mediatek/mtk-cmdq-helper.c |  291 
> > 
> >  include/linux/soc/mediatek/mtk-cmdq.h  |  135 +++
> >  4 files changed, 439 insertions(+)
> >  create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
> >  create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

[...]

> > +
> > +struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 
> > timeout)
> > +{
> > +   struct cmdq_client *client;
> > +
> > +   client = kzalloc(sizeof(*client), GFP_KERNEL);
> > +   if (!client)
> > +   return (struct cmdq_client *)-ENOMEM;
> > +
> > +   client->timeout_ms = timeout;
> > +   if (timeout != CMDQ_NO_TIMEOUT) {
> > +   spin_lock_init(>lock);
> > +   timer_setup(>timer, cmdq_client_timeout, 0);
> > +   }
> > +   client->pkt_cnt = 0;
> > +   client->client.dev = dev;
> > +   client->client.tx_block = false;
> > +   client->chan = mbox_request_channel(>client, index);
> > +
> > +   if (IS_ERR(client->chan)) {
> > +   long err = 0;
> > +
> > +   dev_err(dev, "failed to request channel\n");
> > +   err = PTR_ERR(client->chan);
> > +   kfree(client);
> > +
> > +   return (struct cmdq_client *)err;
> 
> Can't we use
> return ERR_PTR(err);
> here?

Sure, will fix it.

> 
> > +   }
> > +
> > +   return client;
> > +}
> > +EXPORT_SYMBOL(cmdq_mbox_create);
> > +
> > +void cmdq_mbox_destroy(struct cmdq_client *client)
> > +{
> > +   if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
> > +   spin_lock(>lock);
> > +   del_timer_sync(>timer);
> > +   spin_unlock(>lock);
> > +   }
> > +   mbox_free_channel(client->chan);
> > +   kfree(client);
> > +}
> > +EXPORT_SYMBOL(cmdq_mbox_destroy);
> > +
> > +int cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt **pkt_ptr,
> > +   size_t size)
> 
> I suppose you are not returning the allocated cmdq_pkt to avoid checks for
> IS_ERR() logic in the consumer of this API. Am I correct?
> Do we really need a pointer to a pointer here? Can't we just use a struct
> cmdq_pkt *pkt as argument? That would make things easier.

Do you mean we change the argument 'struct cmdq_pkt **pkt_ptr' to
'struct cmdq_pkt *pkt', and the consumer allocate a struct cmdq_pkt
*pkt, then pass pkt as argument of this API?
If yes, the consumer still need to check the return value of this API.
For the current implementation, the consumer doesn't need check
IS_ERR(*pkt_ptr) if the return value equals to 0.

Since the consumer has to check the return value of this API once, to
make it simpler, I shall change the prototype to 
'struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t
size)' and change its implementation.

> 
> > +{
> > +   struct cmdq_pkt *pkt;
> > +   struct device *dev;
> > +   dma_addr_t dma_addr;
> > +
> > +   pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
> > +   if (!pkt)
> > +   return -ENOMEM;
> > +   pkt->va_base = kzalloc(size, GFP_KERNEL);
> > +   if (!pkt->va_base) {
> > +   kfree(pkt);
> > +   return -ENOMEM;
> > +   }
> > +   pkt->buf_size = size;
> > +   pkt->cl = (void *)client;
> > +
> > +   dev = client->chan->mbox->dev;
> > +   dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
> > +   DMA_TO_DEVICE);
> > +   if (dma_mapping_error(dev, dma_addr)) {
> > +   dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
> > +   kfree(pkt->va_base);
> > +   kfree(pkt);
> > +   return -ENOMEM;
> > +   }
> > +
> > +   pkt->pa_base = dma_addr;
> > +   *pkt_ptr = pkt;
> > +
> > +   return 0;
> > +}
> > +EXPORT_SYMBOL(cmdq_pkt_create);
> > +
> > +void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
> > +{
> > +   struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
> > +
> > +   dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
> > +

[PATCH v24 0/2] MediaTek MT8173 CMDQ support

2018-09-27 Thread Houlong Wei
Hi,

This is Mediatek MT8173 Command Queue(CMDQ) driver. The CMDQ is used
to help write registers with critical time limitation, such as
updating display configuration during the vblank. It controls Global
Command Engine (GCE) hardware to achieve this requirement.

Changes since v23:
 -rebase on v4.19-rc1
 -revise return value of cmdq_mbox_create()
 -revise cmdq_pkt_create()
 -add MODULE_LICENSE() for mtk-cmdq-helper.c
 -adjust functions order in mtk-cmdq.h
Changes since v22:
 -remove properties 'timeout' and 'thread-num' from device tree
 -move timer from CMDQ driver to CMDQ helper
 -move dma unmap from CMDQ driver to CMDQ helper
 -config thread number in CMDQ match table
 -remove reallocate mechanism and let client specify the cmdq buffer size
 -let client specify the timeout time
Changes since v21:
 -rebase on v4.18-rc1
 -remove subsys code and event id definition from mtk-cmdq-helper.c
 -add mt8173-gce.h to define the subsys code and envent id
Changes since v20:
 -rebase on v4.15-rc1
 -move dma_map_single outside of spinlock
Changes since v19:
 -rebase to v4.10-rc2

Houlong Wei (2):
  arm64: dts: mt8173: Add GCE node
  soc: mediatek: Add Mediatek CMDQ helper

 arch/arm64/boot/dts/mediatek/mt8173.dtsi |   10 +
 drivers/soc/mediatek/Kconfig |   12 ++
 drivers/soc/mediatek/Makefile|1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c   |  292 ++
 include/linux/soc/mediatek/mtk-cmdq.h|  133 ++
 5 files changed, 448 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
 create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

-- 
1.7.9.5


[PATCH v24 2/2] soc: mediatek: Add Mediatek CMDQ helper

2018-09-27 Thread Houlong Wei
Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 drivers/soc/mediatek/Kconfig   |   12 ++
 drivers/soc/mediatek/Makefile  |1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c |  292 
 include/linux/soc/mediatek/mtk-cmdq.h  |  133 +++
 4 files changed, 438 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
 create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index a7d0667..17bd759 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -4,6 +4,18 @@
 menu "MediaTek SoC drivers"
depends on ARCH_MEDIATEK || COMPILE_TEST
 
+config MTK_CMDQ
+   tristate "MediaTek CMDQ Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select MAILBOX
+   select MTK_CMDQ_MBOX
+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
 config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
select REGMAP
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..64ce5ee 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
 obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
 obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
new file mode 100644
index 000..3482dd7
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018 MediaTek Inc.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_ARG_A_WRITE_MASK  0x
+#define CMDQ_WRITE_ENABLE_MASK BIT(0)
+#define CMDQ_EOC_IRQ_ENBIT(0)
+#define CMDQ_EOC_CMD   ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
+   << 32 | CMDQ_EOC_IRQ_EN)
+
+static void cmdq_client_timeout(struct timer_list *t)
+{
+   struct cmdq_client *client = from_timer(client, t, timer);
+
+   dev_err(client->client.dev, "cmdq timeout!\n");
+}
+
+struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 
timeout)
+{
+   struct cmdq_client *client;
+
+   client = kzalloc(sizeof(*client), GFP_KERNEL);
+   if (!client)
+   return (struct cmdq_client *)-ENOMEM;
+
+   client->timeout_ms = timeout;
+   if (timeout != CMDQ_NO_TIMEOUT) {
+   spin_lock_init(>lock);
+   timer_setup(>timer, cmdq_client_timeout, 0);
+   }
+   client->pkt_cnt = 0;
+   client->client.dev = dev;
+   client->client.tx_block = false;
+   client->chan = mbox_request_channel(>client, index);
+
+   if (IS_ERR(client->chan)) {
+   long err;
+
+   dev_err(dev, "failed to request channel\n");
+   err = PTR_ERR(client->chan);
+   kfree(client);
+
+   return ERR_PTR(err);
+   }
+
+   return client;
+}
+EXPORT_SYMBOL(cmdq_mbox_create);
+
+void cmdq_mbox_destroy(struct cmdq_client *client)
+{
+   if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
+   spin_lock(>lock);
+   del_timer_sync(>timer);
+   spin_unlock(>lock);
+   }
+   mbox_free_channel(client->chan);
+   kfree(client);
+}
+EXPORT_SYMBOL(cmdq_mbox_destroy);
+
+struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
+{
+   struct cmdq_pkt *pkt;
+   struct device *dev;
+   dma_addr_t dma_addr;
+
+   pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
+   if (!pkt)
+   return ERR_PTR(-ENOMEM);
+   pkt->va_base = kzalloc(size, GFP_KERNEL);
+   if (!pkt->va_base) {
+   kfree(pkt);
+   return ERR_PTR(-ENOMEM);
+   }
+   pkt->buf_size = size;
+   pkt->cl = (void *)client;
+
+   dev = client->chan->mbox->dev;
+   dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
+ DMA_TO_DEVICE);
+   if (dma_mapping_error(dev, dma_addr)) {
+   dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
+   kfree(pkt->va_base);
+   kfree(pkt);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   pkt->pa_base = dma_addr;
+
+   return pkt;
+}
+EXPORT_SYMBOL(cmdq_pkt_create);
+
+void cmdq_pkt_destroy(struct cmdq_pkt *pk

[PATCH v24 1/2] arm64: dts: mt8173: Add GCE node

2018-09-27 Thread Houlong Wei
This patch adds the device node of the GCE hardware for CMDQ module.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi |   10 ++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index abd2f15..412ffd4 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "mt8173-pinfunc.h"
 
 / {
@@ -521,6 +522,15 @@
status = "disabled";
};
 
+   gce: mailbox@10212000 {
+   compatible = "mediatek,mt8173-gce";
+   reg = <0 0x10212000 0 0x1000>;
+   interrupts = ;
+   clocks = < CLK_INFRA_GCE>;
+   clock-names = "gce";
+   #mbox-cells = <3>;
+   };
+
mipi_tx0: mipi-dphy@10215000 {
compatible = "mediatek,mt8173-mipi-tx";
reg = <0 0x10215000 0 0x1000>;
-- 
1.7.9.5



Re: [PATCH v23 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-09-27 Thread houlong wei
On Thu, 2018-09-27 at 15:50 +0800, Matthias Brugger wrote:
> 
> On 27/09/2018 03:57, houlong wei wrote:
[...]
> >>> +
> >>> +static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code 
> >>> code,
> >>> +u32 arg_a, u32 arg_b)
> >>> +{
> >>> + u64 *cmd_ptr;
> >>> +
> >>> + if (unlikely(pkt->cmd_buf_size + CMDQ_INST_SIZE > pkt->buf_size)) {
> >>> + pkt->cmd_buf_size += CMDQ_INST_SIZE;
> >>
> >> Why do we update the cmd_buf_size here?
> > 
> > Because in developing phase of consumer driver, the consumer has to know
> > the real command buffer size after adding command failure. Then the
> > consumer will increase the size and run the cmdq flow (cmdq_pkt_create,
> > cmdq_pkt_write/wfe...) again. Finally, the consumer get the real size
> > and fix it.
> > 
> 
> But the consumer should know the size it needs for it's buffer and if not it
> should be able to decide on it's own how much space it needs. If he get's a
> -ENOMEM he implicitly knows that he has to increase the buf_size. Now the size
> depends on how many command he has pending and wasn't able to write to the 
> cmdq_pkt.
> 
> Regards,
> Matthias

The consumer doesn't know how to calculate the command buffer size that
he needs.
When the consumer driver is developing, he could ignore the return value
of cmdq_pkt_write and other command appending functions.
He can print the pkt->cmdq_buf_size after cmdq_pkt_flush() or
cmdq_pkt_flush_async() failure. Now he can get the buffer size he needs.

I copy your another comment here, so I can reply in one mail.
>>If we want to write out a warning to the kernel log, then we should
>>but that in the if (unlikely(pkt->cmd_buf_size + CMDQ_INST_SIZE
>>pkt->buf_size)) from cmdq_pkt_append_command to make it consistent
>>between cmdq_pkt_write, cmdq_pkt_write_mask and cmdq_pkt_finalize.

Thanks, I will move WARN_ON() into cmdq_pkt_append_command() before
returning -ENOMEM.

After your confirmation of the comments above, I will re-send a new
patch.






[PATCH v27 0/2] MediaTek MT8173 CMDQ support

2018-11-28 Thread Houlong Wei
Hi,

This is Mediatek MT8173 Command Queue(CMDQ) driver. The CMDQ is used
to help write registers with critical time limitation, such as
updating display configuration during the vblank. It controls Global
Command Engine (GCE) hardware to achieve this requirement.

Changes since v26:
 -rebase on v4.20-rc1
 -add comment to explain why cmdq_buf_size is increased in case of
  appending command failure
Changes since v25:
 -Replace WARN_ON() with WARN_ONCE() and add debug information.
Changes since v24:
 -move WARN_ON() into cmdq_pkt_append_command() from outside
Changes since v23:
 -rebase on v4.19-rc1
 -revise return value of cmdq_mbox_create()
 -revise cmdq_pkt_create()
 -add MODULE_LICENSE() for mtk-cmdq-helper.c
 -adjust functions order in mtk-cmdq.h
Changes since v22:
 -remove properties 'timeout' and 'thread-num' from device tree
 -move timer from CMDQ driver to CMDQ helper
 -move dma unmap from CMDQ driver to CMDQ helper
 -config thread number in CMDQ match table
 -remove reallocate mechanism and let client specify the cmdq buffer size
 -let client specify the timeout time
Changes since v21:
 -rebase on v4.18-rc1
 -remove subsys code and event id definition from mtk-cmdq-helper.c
 -add mt8173-gce.h to define the subsys code and envent id
Changes since v20:
 -rebase on v4.15-rc1
 -move dma_map_single outside of spinlock
Changes since v19:
 -rebase to v4.10-rc2

Houlong Wei (2):
  arm64: dts: mt8173: Add GCE node
  soc: mediatek: Add Mediatek CMDQ helper

 arch/arm64/boot/dts/mediatek/mt8173.dtsi |  10 +
 drivers/soc/mediatek/Kconfig |  12 +
 drivers/soc/mediatek/Makefile|   1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c   | 300 +++
 include/linux/soc/mediatek/mtk-cmdq.h| 133 ++
 5 files changed, 456 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
 create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

-- 
2.19.1



[PATCH v27 1/2] arm64: dts: mt8173: Add GCE node

2018-11-28 Thread Houlong Wei
This patch adds the device node of the GCE hardware for CMDQ module.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi |   10 ++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index abd2f15..412ffd4 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "mt8173-pinfunc.h"
 
 / {
@@ -521,6 +522,15 @@
status = "disabled";
};
 
+   gce: mailbox@10212000 {
+   compatible = "mediatek,mt8173-gce";
+   reg = <0 0x10212000 0 0x1000>;
+   interrupts = ;
+   clocks = < CLK_INFRA_GCE>;
+   clock-names = "gce";
+   #mbox-cells = <3>;
+   };
+
mipi_tx0: mipi-dphy@10215000 {
compatible = "mediatek,mt8173-mipi-tx";
reg = <0 0x10215000 0 0x1000>;
-- 
1.7.9.5



[PATCH v27 2/2] soc: mediatek: Add Mediatek CMDQ helper

2018-11-28 Thread Houlong Wei
Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 drivers/soc/mediatek/Kconfig   |   12 ++
 drivers/soc/mediatek/Makefile  |1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c |  300 
 include/linux/soc/mediatek/mtk-cmdq.h  |  133 ++
 4 files changed, 446 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
 create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index a7d0667..17bd759 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -4,6 +4,18 @@
 menu "MediaTek SoC drivers"
depends on ARCH_MEDIATEK || COMPILE_TEST
 
+config MTK_CMDQ
+   tristate "MediaTek CMDQ Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select MAILBOX
+   select MTK_CMDQ_MBOX
+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
 config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
select REGMAP
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..64ce5ee 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
 obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
 obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
new file mode 100644
index 000..ff9fef5
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018 MediaTek Inc.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_ARG_A_WRITE_MASK  0x
+#define CMDQ_WRITE_ENABLE_MASK BIT(0)
+#define CMDQ_EOC_IRQ_ENBIT(0)
+#define CMDQ_EOC_CMD   ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
+   << 32 | CMDQ_EOC_IRQ_EN)
+
+static void cmdq_client_timeout(struct timer_list *t)
+{
+   struct cmdq_client *client = from_timer(client, t, timer);
+
+   dev_err(client->client.dev, "cmdq timeout!\n");
+}
+
+struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 
timeout)
+{
+   struct cmdq_client *client;
+
+   client = kzalloc(sizeof(*client), GFP_KERNEL);
+   if (!client)
+   return (struct cmdq_client *)-ENOMEM;
+
+   client->timeout_ms = timeout;
+   if (timeout != CMDQ_NO_TIMEOUT) {
+   spin_lock_init(>lock);
+   timer_setup(>timer, cmdq_client_timeout, 0);
+   }
+   client->pkt_cnt = 0;
+   client->client.dev = dev;
+   client->client.tx_block = false;
+   client->chan = mbox_request_channel(>client, index);
+
+   if (IS_ERR(client->chan)) {
+   long err;
+
+   dev_err(dev, "failed to request channel\n");
+   err = PTR_ERR(client->chan);
+   kfree(client);
+
+   return ERR_PTR(err);
+   }
+
+   return client;
+}
+EXPORT_SYMBOL(cmdq_mbox_create);
+
+void cmdq_mbox_destroy(struct cmdq_client *client)
+{
+   if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
+   spin_lock(>lock);
+   del_timer_sync(>timer);
+   spin_unlock(>lock);
+   }
+   mbox_free_channel(client->chan);
+   kfree(client);
+}
+EXPORT_SYMBOL(cmdq_mbox_destroy);
+
+struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
+{
+   struct cmdq_pkt *pkt;
+   struct device *dev;
+   dma_addr_t dma_addr;
+
+   pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
+   if (!pkt)
+   return ERR_PTR(-ENOMEM);
+   pkt->va_base = kzalloc(size, GFP_KERNEL);
+   if (!pkt->va_base) {
+   kfree(pkt);
+   return ERR_PTR(-ENOMEM);
+   }
+   pkt->buf_size = size;
+   pkt->cl = (void *)client;
+
+   dev = client->chan->mbox->dev;
+   dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
+ DMA_TO_DEVICE);
+   if (dma_mapping_error(dev, dma_addr)) {
+   dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
+   kfree(pkt->va_base);
+   kfree(pkt);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   pkt->pa_base = dma_addr;
+
+   return pkt;
+}
+EXPORT_SYMBOL(cmdq_pkt_create);
+
+void cmdq_pkt_destroy(struct cmdq_pkt *pk

Re: FW: [PATCH v20 2/4] mailbox: mediatek: Add Mediatek CMDQ driver

2018-01-08 Thread houlong wei
Hi Jassi,

Sorry for reply so late.
According to previous discussion, there are two methods to move
dma_map_single() outside of spin_lock.
(1) put in mtk-cmdq-helper.c, as described by HS on 2017-02-09.
  > I think a trade-off solution is to put in mtk-cmdq-helper.c.
  > Although it is a mailbox client, it is not a CMDQ client.
  > We can include mailbox_controller.h in mtk-cmdq-helper.c (instead of
mtk-cmdq.h), and then map dma at cmdq_pkt_flush_async before
mbox_send_message.

  > pkt->pa_base = dma_map_single(client->chan->mbox->dev, pkt->va_base,
  >  pkt->cmd_buf_size, DMA_TO_DEVICE);
(2) schedule a tasklet in send_data().

After internal discussion with HS and other experts, now we prefer
method (1).
How do you think about it?

Thanks
Houlong


> -Original Message-
> From: Horng-Shyang Liao [mailto:hs.l...@mediatek.com] 
> Sent: Thursday, February 23, 2017 8:48 PM
> To: Jassi Brar 
> Cc: Rob Herring ; Matthias Brugger 
> ; Daniel Kurtz ; Sascha Hauer 
> ; Devicetree List ; Linux 
> Kernel Mailing List ; 
> linux-arm-ker...@lists.infradead.org; linux-media...@lists.infradead.org; 
> srv_heupstream ; Sascha Hauer 
> ; Philipp Zabel ; Nicolas 
> Boichat ; CK Hu (胡俊光) ; Cawa Cheng 
> (鄭曄禧) ; Bibby Hsieh (謝濟遠) 
> ; YT Shen (沈岳霆) ; Daoyuan 
> Huang (黃道原) ; Damon Chu (朱峻賢) 
> ; Josh-YC Liu (劉育誠) ; Glory 
> Hung (洪智瑋) ; Jiaguang Zhang (张加广) 
> ; Dennis-YC Hsieh (謝宇哲) 
> ; Monica Wang (王孟婷) ; 
> Houlong Wei (魏厚龙) ; Hs Liao (廖宏祥) 
> 
> Subject: Re: [PATCH v20 2/4] mailbox: mediatek: Add Mediatek CMDQ driver
> 
> On Thu, 2017-02-23 at 09:40 +0530, Jassi Brar wrote:
> > On Wed, Feb 22, 2017 at 8:42 AM, Horng-Shyang Liao  
> > wrote:
> > > On Thu, 2017-02-16 at 21:02 +0530, Jassi Brar wrote:
> > >> On Mon, Feb 6, 2017 at 11:07 AM, Horng-Shyang Liao 
> > >>  wrote:
> > >> > Hi Jassi,
> > >> >
> > >> > On Wed, 2017-02-01 at 10:52 +0530, Jassi Brar wrote:
> > >> >> On Thu, Jan 26, 2017 at 2:07 PM, Horng-Shyang Liao 
> > >> >>  wrote:
> > >> >> > Hi Jassi,
> > >> >> >
> > >> >> > On Thu, 2017-01-26 at 10:08 +0530, Jassi Brar wrote:
> > >> >> >> On Wed, Jan 4, 2017 at 8:36 AM, HS Liao  
> > >> >> >> wrote:
> > >> >> >>
> > >> >> >> > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
> > >> >> >> > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > >> >> >> > new file mode 100644
> > >> >> >> > index 000..747bcd3
> > >> >> >> > --- /dev/null
> > >> >> >> > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > >> >> >>
> > >> >> >> ...
> > >> >> >>
> > >> >> >> > +static void cmdq_task_exec(struct cmdq_pkt *pkt, struct 
> > >> >> >> > +cmdq_thread *thread) {
> > >> >> >> > +   struct cmdq *cmdq;
> > >> >> >> > +   struct cmdq_task *task;
> > >> >> >> > +   unsigned long curr_pa, end_pa;
> > >> >> >> > +
> > >> >> >> > +   cmdq = dev_get_drvdata(thread->chan->mbox->dev);
> > >> >> >> > +
> > >> >> >> > +   /* Client should not flush new tasks if suspended. */
> > >> >> >> > +   WARN_ON(cmdq->suspended);
> > >> >> >> > +
> > >> >> >> > +   task = kzalloc(sizeof(*task), GFP_ATOMIC);
> > >> >> >> > +   task->cmdq = cmdq;
> > >> >> >> > +   INIT_LIST_HEAD(>list_entry);
> > >> >> >> > +   task->pa_base = dma_map_single(cmdq->mbox.dev, 
> > >> >> >> > pkt->va_base,
> > >> >> >> > +  pkt->cmd_buf_size, 
> > >> >> >> > + DMA_TO_DEVICE);
> > >> >> >> >
> > >> >> >> You seem to parse the requests and responses, that should 
> > >> >> >> ideally be done in client driver.
> > >> >> >> Also, we are here in atomic context, can you move it in 
> > >> >> >> client driver (before the spin_lock)?
> > >> >> >> Maybe by adding a new 'pa_base' member as well in 'cmdq_pkt'.
> > >> >> >
> > >> >> > will do
> > >> >
> > >> > I agree with moving dma_map_single out from spin_lock.
> > >> >
> > >> > However, mailbox clients cannot map virtual memory to mailbox 
> > >> > controller's device for DMA.
> > >> >
> > >> If DMA is a resource used by MBox to transfer data, then yes the 
> > >> mapping needs to be done in the Mbox controller driver. To map 
> > >> memory outside of spinlock, you could schedule a tasklet in send_data() ?
> > >
> > > Hi Jassi,
> > >
> > > For CMDQ, the order of CMDQ tasks should be guaranteed.
> > > However, it seems tasklet cannot ensure this requirement.
> > >
> > > Quote from Linux Device Drivers 3rd edition ch7.
> > > "void tasklet_schedule(struct tasklet_struct *t);
> > >   Schedule the tasklet for execution. If a tasklet is scheduled 
> > > again before it has a chance to run, it runs only once"
> > >
> > Not sure what bothers you.
> > If you only add requests to a list, protected by some spinlock, during 
> > send_datam you could always iterate over (submit) requests in the 
> > order you queued them.
> 
> Hi Jassi,
> 
> OK. I will do it.
> 
> Thanks,
> HS
> 
> 
> 




[PATCH] soc: mediatek: cmdq: fixup possible timeout issue

2020-10-22 Thread Houlong Wei
Fixes: 576f1b4bc802 ("soc: mediatek: Add Mediatek CMDQ helper")

There may be possible timeout issue when lots of cmdq packets are
flushed to the same cmdq client. The necessary modifications are as
below.
1.Adjust the timer timeout period as client->timeout_ms * client->pkt_cnt.
2.Optimize the time to start the timer.

Signed-off-by: Houlong Wei 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index dc644cfb6419..31142c193527 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -350,7 +350,8 @@ static void cmdq_pkt_flush_async_cb(struct cmdq_cb_data 
data)
del_timer(>timer);
else
mod_timer(>timer, jiffies +
- msecs_to_jiffies(client->timeout_ms));
+ msecs_to_jiffies(client->timeout_ms *
+  client->pkt_cnt));
spin_unlock_irqrestore(>lock, flags);
}
 
@@ -379,9 +380,7 @@ int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, 
cmdq_async_flush_cb cb,
 
if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
spin_lock_irqsave(>lock, flags);
-   if (client->pkt_cnt++ == 0)
-   mod_timer(>timer, jiffies +
- msecs_to_jiffies(client->timeout_ms));
+   client->pkt_cnt++;
spin_unlock_irqrestore(>lock, flags);
}
 
@@ -391,6 +390,21 @@ int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, 
cmdq_async_flush_cb cb,
/* We can send next packet immediately, so just call txdone. */
mbox_client_txdone(client->chan, 0);
 
+   if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
+   spin_lock_irqsave(>lock, flags);
+   /*
+* GCE HW maybe execute too quickly and the callback function
+* may be invoked earlier. If this happens, pkt_cnt is reduced
+* by 1 in cmdq_pkt_flush_async_cb(). The timer is set only if
+* pkt_cnt is greater than 0.
+*/
+   if (client->pkt_cnt > 0)
+   mod_timer(>timer, jiffies +
+ msecs_to_jiffies(client->timeout_ms *
+  client->pkt_cnt));
+   spin_unlock_irqrestore(>lock, flags);
+   }
+
return 0;
 }
 EXPORT_SYMBOL(cmdq_pkt_flush_async);
-- 
2.18.0


Re: [PATCH v12 09/12] soc: mediatek: cmdq: define the instruction struct

2019-08-19 Thread houlong wei
On Mon, 2019-08-19 at 10:53 +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 
> Reviewed-by: CK Hu 
> ---
>  drivers/soc/mediatek/mtk-cmdq-helper.c   | 105 +++
>  include/linux/mailbox/mtk-cmdq-mailbox.h |   2 +
>  2 files changed, 73 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> b/drivers/soc/mediatek/mtk-cmdq-helper.c
> index 7aa0517ff2f3..e1e41914ed7a 100644
> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -9,12 +9,24 @@
>  #include 
>  #include 
>  
> -#define CMDQ_ARG_A_WRITE_MASK0x
>  #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,108 @@ 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;
> +
>   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 != 0x) {
> - 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;

I think we should consider the reusing command packet case, I commented
via link below and there were discussion before.
http://lists.infradead.org/pipermail/linux-mediatek/2019-August/022052.html
Before this patch, each 64-bit of an instruction is set. But now some
bits may be ignored and keep the original values. That may make us
confused when we analyze the instruction for debugging.

>   }
> - 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, 

Re: [PATCH v12 11/12] soc: mediatek: cmdq: add cmdq_dev_get_client_reg function

2019-08-19 Thread houlong wei
On Mon, 2019-08-19 at 10:53 +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 
> ---
>  drivers/soc/mediatek/mtk-cmdq-helper.c | 29 ++
>  include/linux/soc/mediatek/mtk-cmdq.h  | 21 +++
>  2 files changed, 50 insertions(+)
> 
[...]
>  
> +/**
> + * cmdq_dev_get_client_reg() - parse cmdq client reg from the device
> + *  node of CMDQ client
> + * @dev: device of CMDQ mailbox clienti

'clienti' looks like a typo, '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 pasing the cmdq client reg

'pasing' looks like a typo, 'parsing'?

> + * 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




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

2019-08-20 Thread houlong wei
Reviewed-by: Houlong Wei 

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 
> Reviewed-by: CK Hu 
> ---
>  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 
>  #include 
>  
> -#define CMDQ_ARG_A_WRITE_MASK0x
>  #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 != 0x) {
> - 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 (!in

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

2019-08-20 Thread houlong wei
Reviewed-by: Houlong Wei 





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

2019-08-20 Thread houlong wei
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 
> Reviewed-by: CK Hu 
> ---
>  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, );
> + 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 



Re: [RESEND, PATCH v13 10/12] soc: mediatek: cmdq: add polling function

2019-08-20 Thread houlong wei
On Tue, 2019-08-20 at 16:49 +0800, Bibby Hsieh wrote:
> add polling function in cmdq helper functions
> 
> Signed-off-by: Bibby Hsieh 
> Reviewed-by: CK Hu 
> ---
>  drivers/soc/mediatek/mtk-cmdq-helper.c   | 28 
>  include/linux/mailbox/mtk-cmdq-mailbox.h |  1 +
>  include/linux/soc/mediatek/mtk-cmdq.h| 15 +
>  3 files changed, 44 insertions(+)
> 
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> b/drivers/soc/mediatek/mtk-cmdq-helper.c
> index e3d5b0be8e79..c53f8476c68d 100644
> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -221,6 +221,34 @@ int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event)
>  }
>  EXPORT_SYMBOL(cmdq_pkt_clear_event);
>  
> +int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys,
> +   u16 offset, u32 value, u32 mask)
> +{
> + struct cmdq_instruction *inst;
> +
> + if (mask != 0x) {
> + inst = cmdq_pkt_append_command(pkt);
> + if (!inst)
> + return -ENOMEM;
> +
> + inst->op = CMDQ_CODE_MASK;
> + inst->value = ~mask;
> + offset = offset | 0x1;
> + }
> +
> + inst = cmdq_pkt_append_command(pkt);
> + if (!inst)
> + return -ENOMEM;
> +
> + inst->op = CMDQ_CODE_POLL;
> + inst->value = value;
> + inst->offset = offset;
> + inst->subsys = subsys;
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(cmdq_pkt_poll);
> +
>  static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
>  {
>   struct cmdq_instruction *inst;
> diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
> b/include/linux/mailbox/mtk-cmdq-mailbox.h
> index c8adedefaf42..9e3502945bc1 100644
> --- a/include/linux/mailbox/mtk-cmdq-mailbox.h
> +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
> @@ -46,6 +46,7 @@
>  enum cmdq_code {
>   CMDQ_CODE_MASK = 0x02,
>   CMDQ_CODE_WRITE = 0x04,
> + CMDQ_CODE_POLL = 0x08,
>   CMDQ_CODE_JUMP = 0x10,
>   CMDQ_CODE_WFE = 0x20,
>   CMDQ_CODE_EOC = 0x40,
> diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
> b/include/linux/soc/mediatek/mtk-cmdq.h
> index 9618debb9ceb..a345870a6d10 100644
> --- a/include/linux/soc/mediatek/mtk-cmdq.h
> +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> @@ -99,6 +99,21 @@ int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event);
>   */
>  int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event);
>  
> +/**
> + * cmdq_pkt_poll() - Append polling command to the CMDQ packet, ask GCE to
> + *execute an instruction that wait for a specified hardware
> + *register to check for the value. All GCE hardware
> + *threads will be blocked by this instruction.
> + * @pkt: the CMDQ packet
> + * @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_poll(struct cmdq_pkt *pkt, u8 subsys,
> +   u16 offset, u32 value, u32 mask);
>  /**
>   * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
>   *  packet and call back at the end of done packet

Reviewed-by: Houlong Wei 



Re: [PATCH v21 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-02-08 Thread houlong wei
On Tue, 2018-02-06 at 10:52 +0800, CK Hu wrote:
> Hi, Houlong:
> 
> I've some inline comment.
> 
> On Wed, 2018-01-31 at 15:28 +0800, houlong@mediatek.com wrote:
> > From: "hs.l...@mediatek.com" 
> >
> > Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.
> >
> > Signed-off-by: Houlong Wei 
> > Signed-off-by: HS Liao 
> > ---
> >  drivers/soc/mediatek/Kconfig   |   12 ++
> >  drivers/soc/mediatek/Makefile  |1 +
> >  drivers/soc/mediatek/mtk-cmdq-helper.c |  322 
> > 
> >  include/linux/soc/mediatek/mtk-cmdq.h  |  174 +
> >  4 files changed, 509 insertions(+)
> >  create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
> >  create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h
> >
> > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > index a7d0667..e66582e 100644
> > --- a/drivers/soc/mediatek/Kconfig
> > +++ b/drivers/soc/mediatek/Kconfig
> > @@ -4,6 +4,18 @@
> >  menu "MediaTek SoC drivers"
> >  depends on ARCH_MEDIATEK || COMPILE_TEST
> >
> > +config MTK_CMDQ
> > +bool "MediaTek CMDQ Support"
> > +depends on ARM64 && ( ARCH_MEDIATEK || COMPILE_TEST )
> > +select MAILBOX
> > +select MTK_CMDQ_MBOX
> > +select MTK_INFRACFG
> > +help
> > +  Say yes here to add support for the MediaTek Command Queue (CMDQ)
> > +  driver. The CMDQ is used to help read/write registers with critical
> > +  time limitation, such as updating display configuration during the
> > +  vblank.
> > +
> >  config MTK_INFRACFG
> >  bool "MediaTek INFRACFG Support"
> >  select REGMAP
> > diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> > index 12998b0..64ce5ee 100644
> > --- a/drivers/soc/mediatek/Makefile
> > +++ b/drivers/soc/mediatek/Makefile
> > @@ -1,3 +1,4 @@
> > +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
> >  obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
> >  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
> >  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > new file mode 100644
> > index 000..80d0558
> > --- /dev/null
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -0,0 +1,322 @@
> > +/*
> > + * Copyright (c) 2015 MediaTek Inc.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define CMDQ_ARG_A_WRITE_MASK0x
> > +#define CMDQ_WRITE_ENABLE_MASKBIT(0)
> > +#define CMDQ_EOC_IRQ_ENBIT(0)
> > +#define CMDQ_EOC_CMD((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
> > +<< 32 | CMDQ_EOC_IRQ_EN)
> > +
> > +struct cmdq_subsys {
> > +u32base;
> > +intid;
> > +};
> > +
> > +static const struct cmdq_subsys gce_subsys[] = {
> > +{0x1400, 1},
> > +{0x1401, 2},
> > +{0x1402, 3},
> > +};
> 
> I think subsys definition varies by different SoC, so it's better to
> pass these definition from device tree to driver (client driver), and
> client driver pass this subsys in the related interface. For example,
> 
> in include/dt-bindings/gce/mt8173-gce.h, you define
> 
> #define GCE_SUBSYS_14001
> #define GCE_SUBSYS_14012
> #define GCE_SUBSYS_14023
> 
> in device tree, place the subsys definition in client device node,
> 
> #include "dt-bindings/gce/mt8173-gce.h"
> 
> ovl0: ovl@1400c000 {
> compatible = "mediatek,mt8173-disp-ovl";
> gce-subsys = ;
> ...
> };
> 
> And client driver pass subsys in the related interface,
> 
> int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32
> value);
> 
> So, for another SoC, you just need to modify device tree and you do not
> need to modify driver.
> > +
> > +static int cmdq_subsys_base_to_id(u32 base)
> > +{
> > +int i;
> > +
> > +for (i = 0;

Re: [PATCH v20 2/4] mailbox: mediatek: Add Mediatek CMDQ driver

2018-01-17 Thread houlong wei
Hi Jassi,

We prefer to use method (1) to move dma_map_single() outside of
spin_lock. Do you have any comment about this?

Thanks,
Houlong

On Mon, 2018-01-08 at 16:38 +0800, houlong wei wrote:
> Hi Jassi,
> 
> Sorry for reply so late.
> According to previous discussion, there are two methods to move
> dma_map_single() outside of spin_lock.
> (1) put in mtk-cmdq-helper.c, as described by HS on 2017-02-09.
>   > I think a trade-off solution is to put in mtk-cmdq-helper.c.
>   > Although it is a mailbox client, it is not a CMDQ client.
>   > We can include mailbox_controller.h in mtk-cmdq-helper.c (instead of
> mtk-cmdq.h), and then map dma at cmdq_pkt_flush_async before
> mbox_send_message.
> 
>   > pkt->pa_base = dma_map_single(client->chan->mbox->dev, pkt->va_base,
>   >  pkt->cmd_buf_size, DMA_TO_DEVICE);
> (2) schedule a tasklet in send_data().
> 
> After internal discussion with HS and other experts, now we prefer
> method (1).
> How do you think about it?
> 
> Thanks
> Houlong
> 
> 
> > -Original Message-
> > From: Horng-Shyang Liao [mailto:hs.l...@mediatek.com]
> > Sent: Thursday, February 23, 2017 8:48 PM
> > To: Jassi Brar 
> > Cc: Rob Herring ; Matthias Brugger 
> > ; Daniel Kurtz ; Sascha Hauer 
> > ; Devicetree List ; 
> > Linux Kernel Mailing List ; 
> > linux-arm-ker...@lists.infradead.org; linux-media...@lists.infradead.org; 
> > srv_heupstream ; Sascha Hauer 
> > ; Philipp Zabel ; Nicolas 
> > Boichat ; CK Hu (胡俊光) ; Cawa 
> > Cheng (鄭曄禧) ; Bibby Hsieh (謝濟遠) 
> > ; YT Shen (沈岳霆) ; Daoyuan 
> > Huang (黃道原) ; Damon Chu (朱峻賢) 
> > ; Josh-YC Liu (劉育誠) ; 
> > Glory Hung (洪智瑋) ; Jiaguang Zhang (张加广) 
> > ; Dennis-YC Hsieh (謝宇哲) 
> > ; Monica Wang (王孟婷) 
> > ; Houlong Wei (魏厚龙) ; 
> > Hs Liao (廖宏祥) 
> > Subject: Re: [PATCH v20 2/4] mailbox: mediatek: Add Mediatek CMDQ driver
> >
> > On Thu, 2017-02-23 at 09:40 +0530, Jassi Brar wrote:
> > > On Wed, Feb 22, 2017 at 8:42 AM, Horng-Shyang Liao  
> > > wrote:
> > > > On Thu, 2017-02-16 at 21:02 +0530, Jassi Brar wrote:
> > > >> On Mon, Feb 6, 2017 at 11:07 AM, Horng-Shyang Liao 
> > > >>  wrote:
> > > >> > Hi Jassi,
> > > >> >
> > > >> > On Wed, 2017-02-01 at 10:52 +0530, Jassi Brar wrote:
> > > >> >> On Thu, Jan 26, 2017 at 2:07 PM, Horng-Shyang Liao 
> > > >> >>  wrote:
> > > >> >> > Hi Jassi,
> > > >> >> >
> > > >> >> > On Thu, 2017-01-26 at 10:08 +0530, Jassi Brar wrote:
> > > >> >> >> On Wed, Jan 4, 2017 at 8:36 AM, HS Liao  
> > > >> >> >> wrote:
> > > >> >> >>
> > > >> >> >> > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c
> > > >> >> >> > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > >> >> >> > new file mode 100644
> > > >> >> >> > index 000..747bcd3
> > > >> >> >> > --- /dev/null
> > > >> >> >> > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > >> >> >>
> > > >> >> >> ...
> > > >> >> >>
> > > >> >> >> > +static void cmdq_task_exec(struct cmdq_pkt *pkt, struct
> > > >> >> >> > +cmdq_thread *thread) {
> > > >> >> >> > +   struct cmdq *cmdq;
> > > >> >> >> > +   struct cmdq_task *task;
> > > >> >> >> > +   unsigned long curr_pa, end_pa;
> > > >> >> >> > +
> > > >> >> >> > +   cmdq = dev_get_drvdata(thread->chan->mbox->dev);
> > > >> >> >> > +
> > > >> >> >> > +   /* Client should not flush new tasks if suspended. */
> > > >> >> >> > +   WARN_ON(cmdq->suspended);
> > > >> >> >> > +
> > > >> >> >> > +   task = kzalloc(sizeof(*task), GFP_ATOMIC);
> > > >> >> >> > +   task->cmdq = cmdq;
> > > >> >> >> > +   INIT_LIST_HEAD(>list_entry);
> > > >> >> >> > +   task->pa_base = dma_map_single(cmdq->mbox.dev, 
> > > >> >> >> > pkt->va_base,
> > > >> >>

Re: FW: [PATCH v20 2/4] mailbox: mediatek: Add Mediatek CMDQ driver

2018-01-17 Thread houlong wei
Sorry to send the mail again because I missed some mail lists by
mistake.

Hi Jassi,

We prefer to use method (1) to move dma_map_single() outside of
spin_lock. Do you have any comment about this?

Thanks,
Houlong

On Mon, 2018-01-08 at 16:38 +0800, houlong wei wrote:
> Hi Jassi,
> 
> Sorry for reply so late.
> According to previous discussion, there are two methods to move
> dma_map_single() outside of spin_lock.
> (1) put in mtk-cmdq-helper.c, as described by HS on 2017-02-09.
>   > I think a trade-off solution is to put in mtk-cmdq-helper.c.
>   > Although it is a mailbox client, it is not a CMDQ client.
>   > We can include mailbox_controller.h in mtk-cmdq-helper.c (instead of
> mtk-cmdq.h), and then map dma at cmdq_pkt_flush_async before
> mbox_send_message.
> 
>   > pkt->pa_base = dma_map_single(client->chan->mbox->dev, pkt->va_base,
>   >  pkt->cmd_buf_size, DMA_TO_DEVICE);
> (2) schedule a tasklet in send_data().
> 
> After internal discussion with HS and other experts, now we prefer
> method (1).
> How do you think about it?
> 
> Thanks
> Houlong
> 
> 
> > -Original Message-
> > From: Horng-Shyang Liao [mailto:hs.l...@mediatek.com] 
> > Sent: Thursday, February 23, 2017 8:48 PM
> > To: Jassi Brar 
> > Cc: Rob Herring ; Matthias Brugger 
> > ; Daniel Kurtz ; Sascha Hauer 
> > ; Devicetree List ; 
> > Linux Kernel Mailing List ; 
> > linux-arm-ker...@lists.infradead.org; linux-media...@lists.infradead.org; 
> > srv_heupstream ; Sascha Hauer 
> > ; Philipp Zabel ; Nicolas 
> > Boichat ; CK Hu (胡俊光) ; Cawa 
> > Cheng (鄭曄禧) ; Bibby Hsieh (謝濟遠) 
> > ; YT Shen (沈岳霆) ; Daoyuan 
> > Huang (黃道原) ; Damon Chu (朱峻賢) 
> > ; Josh-YC Liu (劉育誠) ; 
> > Glory Hung (洪智瑋) ; Jiaguang Zhang (张加广) 
> > ; Dennis-YC Hsieh (謝宇哲) 
> > ; Monica Wang (王孟婷) 
> > ; Houlong Wei (魏厚龙) ; 
> > Hs Liao (廖宏祥) 
> > Subject: Re: [PATCH v20 2/4] mailbox: mediatek: Add Mediatek CMDQ driver
> > 
> > On Thu, 2017-02-23 at 09:40 +0530, Jassi Brar wrote:
> > > On Wed, Feb 22, 2017 at 8:42 AM, Horng-Shyang Liao  
> > > wrote:
> > > > On Thu, 2017-02-16 at 21:02 +0530, Jassi Brar wrote:
> > > >> On Mon, Feb 6, 2017 at 11:07 AM, Horng-Shyang Liao 
> > > >>  wrote:
> > > >> > Hi Jassi,
> > > >> >
> > > >> > On Wed, 2017-02-01 at 10:52 +0530, Jassi Brar wrote:
> > > >> >> On Thu, Jan 26, 2017 at 2:07 PM, Horng-Shyang Liao 
> > > >> >>  wrote:
> > > >> >> > Hi Jassi,
> > > >> >> >
> > > >> >> > On Thu, 2017-01-26 at 10:08 +0530, Jassi Brar wrote:
> > > >> >> >> On Wed, Jan 4, 2017 at 8:36 AM, HS Liao  
> > > >> >> >> wrote:
> > > >> >> >>
> > > >> >> >> > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
> > > >> >> >> > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > >> >> >> > new file mode 100644
> > > >> >> >> > index 000..747bcd3
> > > >> >> >> > --- /dev/null
> > > >> >> >> > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > >> >> >>
> > > >> >> >> ...
> > > >> >> >>
> > > >> >> >> > +static void cmdq_task_exec(struct cmdq_pkt *pkt, struct 
> > > >> >> >> > +cmdq_thread *thread) {
> > > >> >> >> > +   struct cmdq *cmdq;
> > > >> >> >> > +   struct cmdq_task *task;
> > > >> >> >> > +   unsigned long curr_pa, end_pa;
> > > >> >> >> > +
> > > >> >> >> > +   cmdq = dev_get_drvdata(thread->chan->mbox->dev);
> > > >> >> >> > +
> > > >> >> >> > +   /* Client should not flush new tasks if suspended. */
> > > >> >> >> > +   WARN_ON(cmdq->suspended);
> > > >> >> >> > +
> > > >> >> >> > +   task = kzalloc(sizeof(*task), GFP_ATOMIC);
> > > >> >> >> > +   task->cmdq = cmdq;
> > > >> >> >> > +   INIT_LIST_HEAD(>list_entry);
> > > >> >> >> > +   task->pa_base = dma_map_single(cmdq->mbox.dev, 
> > > >> &g

Re: FW: [PATCH v20 2/4] mailbox: mediatek: Add Mediatek CMDQ driver

2018-01-18 Thread houlong wei
Hi Jassi,

There is one request for one GCE h/w buffer which contains a list of
registers operation.
I will resubmit a version and please review again.

Thanks,
Houlong

On Thu, 2018-01-18 at 16:01 +0800, Jassi Brar wrote:
> On Mon, Jan 8, 2018 at 2:08 PM, houlong wei  wrote:
> > Hi Jassi,
> >
> > Sorry for reply so late.
> > According to previous discussion, there are two methods to move
> > dma_map_single() outside of spin_lock.
> > (1) put in mtk-cmdq-helper.c, as described by HS on 2017-02-09.
> >   > I think a trade-off solution is to put in mtk-cmdq-helper.c.
> >   > Although it is a mailbox client, it is not a CMDQ client.
> >   > We can include mailbox_controller.h in mtk-cmdq-helper.c (instead of
> > mtk-cmdq.h), and then map dma at cmdq_pkt_flush_async before
> > mbox_send_message.
> >
> >   > pkt->pa_base = dma_map_single(client->chan->mbox->dev, pkt->va_base,
> >   >  pkt->cmd_buf_size, DMA_TO_DEVICE);
> > (2) schedule a tasklet in send_data().
> >
> > After internal discussion with HS and other experts, now we prefer
> > method (1).
> > How do you think about it?
> >
> I don't exactly see how you mean but please remember send_data()
> callback is supposed to be atomic ... it is protected by
> spin_lock_irqsave/restore in drivers/mailbox/mailbox.c:msg_submit()
> 
> BTW, how many requests max can be queued in the GCE h/w buffer?
> And since it's been over a year now, could you please resubmit after
> checking for checkpatch with the --strict option?
> 
> Thanks.




Re: [PATCH] [media] media: mtk-mdp: fix reference count on old device tree

2019-07-12 Thread houlong wei



On Mon, 2019-07-08 at 17:06 +0800, Matthias Brugger wrote:
> 
> On 21/06/2019 13:32, Matthias Brugger wrote:
> > of_get_next_child() increments the reference count of the returning
> > device_node. Decrement it in the check if we are using the old or the
> > new DTB.
> > 
> > Fixes: ba1f1f70c2c0 ("[media] media: mtk-mdp: Fix mdp device tree")
> > Signed-off-by: Matthias Brugger 
> 
> Any comments on that?
> 

Hi Matthias,
Thanks for fixing the bug. Sorry to reply late~

Acked-by: Houlong Wei 


> > ---
> >  drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c 
> > b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> > index bbb24fb95b95..bafe53c5d54a 100644
> > --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> > +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> > @@ -118,7 +118,9 @@ static int mtk_mdp_probe(struct platform_device *pdev)
> > mutex_init(>vpulock);
> >  
> > /* Old dts had the components as child nodes */
> > -   if (of_get_next_child(dev->of_node, NULL)) {
> > +   parent = of_get_next_child(dev->of_node, NULL);
> > +   if (parent) {
> > +   of_node_put(parent);
> > parent = dev->of_node;
> > dev_warn(dev, "device tree is out of date\n");
> > } else {
> > 




Re: [PATCH v14 07/10] soc: mediatek: cmdq: define the instruction struct

2019-08-29 Thread houlong wei
On Thu, 2019-08-29 at 09:48 +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 
> Reviewed-by: CK Hu 
> Reviewed-by: Houlong Wei 
> ---
>  drivers/soc/mediatek/mtk-cmdq-helper.c   | 77 
>  include/linux/mailbox/mtk-cmdq-mailbox.h | 10 +++
>  2 files changed, 61 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> b/drivers/soc/mediatek/mtk-cmdq-helper.c
> index 7aa0517ff2f3..9472526ab076 100644
> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -9,12 +9,24 @@
>  #include 
>  #include 
>  
> -#define CMDQ_ARG_A_WRITE_MASK0x
>  #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,10 @@ 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 int cmdq_pkt_append_command(struct cmdq_pkt *pkt,
> +struct cmdq_instruction inst)

Can we use 'struct cmdq_instruction *inst' instead of 'struct
cmdq_instruction inst' to reduce stack memory consumption a bit?

>  {
> - u64 *cmd_ptr;
> + struct cmdq_instruction *cmd_ptr;
>  
>   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);
>   return -ENOMEM;
>   }
> +
>   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;
>  
>   return 0;
> @@ -138,24 +151,31 @@ 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)
>  {
> - u32 arg_a = (offset & CMDQ_ARG_A_WRITE_MASK) |
> - (subsys << CMDQ_SUBSYS_SHIFT);
> + struct cmdq_instruction inst;
> +
> + 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 cmdq_pkt_append_command(pkt, inst);
>  }
>  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;
> + struct cmdq_instruction inst = { {0} };
> + u16 offset_mask = offset;
>   int err = 0;
>  
>   if (mask != 0x) {
> - 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);
>   offset_mask |= CMDQ_WRITE_ENABLE_MASK;
>   }
> - err |= cmdq_pkt_write(pkt, value, subsys, offset_mask);
> + err |= cmdq_pkt_write(pkt, subsys, offset_mask, value);
>  
>   return err;
>  }
> @@ -163,43 +183,48 @@ EXPORT_SYMBOL(cmdq_pkt_write_mask);
>  
>  int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
>  {
> - u32 arg_b;
> + struct cmdq_instruction inst = { {0} };
>  
>   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.op = CMDQ_CODE_WFE;
> + inst.value = CMDQ_WFE_OPTION;
> + inst.event = event;
>  
> - return cmdq_pkt_append_command(pkt, CMD

Re: [PATCH v11 09/12] soc: mediatek: cmdq: define the instruction struct

2019-08-10 Thread houlong wei
Hi Bibby, I have inline comment in function cmdq_pkt_write_mask().

On Mon, 2019-07-29 at 15:01 +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 
> Reviewed-by: CK Hu 
> ---
>  drivers/soc/mediatek/mtk-cmdq-helper.c   | 103 +++
>  include/linux/mailbox/mtk-cmdq-mailbox.h |   2 +
>  2 files changed, 72 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> b/drivers/soc/mediatek/mtk-cmdq-helper.c
> index 7aa0517ff2f3..0886c4967ca4 100644
> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -9,12 +9,24 @@
>  #include 
>  #include 
>  
> -#define CMDQ_ARG_A_WRITE_MASK0x
>  #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,108 @@ 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;
> +
>   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)
>  {
> + struct cmdq_instruction *inst;
>   u32 offset_mask = offset;
> - int err = 0;
>  
>   if (mask != 0x) {
> - 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;


There were some discussion about how to reduce cmdq buffer allocation
times reuse a cmdq packet.Please refer to the below links.
https://patchwork.kernel.org/patch/10193349/
https://patchwork.kernel.org/patch/10491161/

If we reuse a cmdq packet, we get the cmdq instruction buffer which may
contains previous data. To generate correct instructions, we may need
consider how to clear the previous data.
1.Set all members of a cmdq_instruction instance.
  e.g. Add two lines of code below for this case.
inst->offset = 0;
inst->subsys = 0;
2. Before reuse a packet, do memset() for the command buffer.

How do you think about it?

>   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 | 

Re: [PATCH v11 11/12] soc: mediatek: cmdq: add cmdq_dev_get_client_reg function

2019-08-10 Thread houlong wei
On Mon, 2019-07-29 at 15:01 +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 
> ---
>  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 70ad4d806fac..9695b75cfc89 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, );
> + if (err < 0) {
> + dev_err(dev,
> + "error %d can't parse gce-client-reg property (%d)",
> + err, idx);
> +
> + return err;
> + }
> +
> + client_reg->subsys = spec.args[0];
> + client_reg->offset = spec.args[1];
> + client_reg->size = spec.args[2];

Maybe we need add type conversion to avoid compiling warnings.
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..be402c4c740e 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;
> @@ -142,4 +148,19 @@ int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, 
> cmdq_async_flush_cb cb,
>   */
>  int cmdq_pkt_flush(struct cmdq_pkt *pkt);
>  
> +/**
> + * cmdq_dev_get_client_reg() - parse cmdq client reg from the device
> + *  node of CMDQ client
> + * @dev: device of CMDQ mailbox clienti
> + * @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 pasing 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);
> +

Could we keep the same order of function declaration and implementation?

>  #endif   /* __MTK_CMDQ_H__ */




Re: [PATCH v11 12/12] arm64: dts: add gce node for mt8183

2019-08-10 Thread houlong wei
On Mon, 2019-07-29 at 15:01 +0800, Bibby Hsieh wrote:
> add gce device node for mt8183
> 
> Signed-off-by: Bibby Hsieh 
> ---
>  arch/arm64/boot/dts/mediatek/mt8183.dtsi | 10 ++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi 
> b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> index 08274bfcebd8..98d17d0bdebf 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> @@ -8,6 +8,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  / {
>   compatible = "mediatek,mt8183";
> @@ -212,6 +213,15 @@
>   clock-names = "spi", "wrap";
>   };
>  
> + gce: gce@10238000 {

Use mailbox@ instead of gce@, Rob suggested in
https://patchwork.kernel.org/patch/10491213/


> + compatible = "mediatek,mt8183-gce";
> + reg = <0 0x10238000 0 0x4000>;
> + interrupts = ;
> + #mbox-cells = <3>;
> + clocks = < CLK_INFRA_GCE>;
> + clock-names = "gce";
> + };
> +
>   uart0: serial@11002000 {
>   compatible = "mediatek,mt8183-uart",
>"mediatek,mt6577-uart";




Re: [PATCH v11 09/12] soc: mediatek: cmdq: define the instruction struct

2019-08-10 Thread houlong wei
On Sun, 2019-08-11 at 00:12 +0800, houlong wei wrote:
> Hi Bibby, I have inline comment in function cmdq_pkt_write_mask().
> 
> On Mon, 2019-07-29 at 15:01 +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 
> > Reviewed-by: CK Hu 
> > ---
> >  drivers/soc/mediatek/mtk-cmdq-helper.c   | 103 +++
> >  include/linux/mailbox/mtk-cmdq-mailbox.h |   2 +
> >  2 files changed, 72 insertions(+), 33 deletions(-)
> > 
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index 7aa0517ff2f3..0886c4967ca4 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -9,12 +9,24 @@
> >  #include 
> >  #include 
[...]
> >  
> >  int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
> > u16 offset, u32 value, u32 mask)
> >  {
> > +   struct cmdq_instruction *inst;
> > u32 offset_mask = offset;
> > -   int err = 0;
> >  
> > if (mask != 0x) {
> > -   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);

We need add a type conversion here, (u8)offset_mask, for your new
function type. Er... it's better to remove local variable 'offset_mask'
and replace it with 'offset'.

> >  }
[...]




[PATCH v22 0/4] MediaTek MT8173 CMDQ support

2018-06-27 Thread Houlong Wei
Hi,

This is Mediatek MT8173 Command Queue(CMDQ) driver. The CMDQ is used
to help write registers with critical time limitation, such as
updating display configuration during the vblank. It controls Global
Command Engine (GCE) hardware to achieve this requirement.

Changes since v21:
 -rebase on v4.18-rc1
 -remove subsys code and event id definition from mtk-cmdq-helper.c
 -add mt8173-gce.h to define the subsys code and envent id
Changes since v20:
 -rebase on v4.15-rc1
 -move dma_map_single outside of spinlock
Changes since v19:
- rebase to v4.10-rc2

Houlong Wei (4):
  dt-bindings: soc: Add documentation for the MediaTek GCE unit
  mailbox: mediatek: Add Mediatek CMDQ driver
  arm64: dts: mt8173: Add GCE node
  soc: mediatek: Add Mediatek CMDQ helper

 .../devicetree/bindings/mailbox/mtk-gce.txt|   65 ++
 arch/arm64/boot/dts/mediatek/mt8173.dtsi   |   11 +
 drivers/mailbox/Kconfig|   10 +
 drivers/mailbox/Makefile   |2 +
 drivers/mailbox/mtk-cmdq-mailbox.c |  633 
 drivers/soc/mediatek/Kconfig   |   12 +
 drivers/soc/mediatek/Makefile  |1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c |  258 
 include/dt-bindings/gce/mt8173-gce.h   |   48 ++
 include/linux/mailbox/mtk-cmdq-mailbox.h   |   70 +++
 include/linux/soc/mediatek/mtk-cmdq.h  |  132 
 11 files changed, 1242 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk-gce.txt
 create mode 100644 drivers/mailbox/mtk-cmdq-mailbox.c
 create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
 create mode 100644 include/dt-bindings/gce/mt8173-gce.h
 create mode 100644 include/linux/mailbox/mtk-cmdq-mailbox.h
 create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

-- 
1.7.9.5 



[PATCH v22 1/4] dt-bindings: soc: Add documentation for the MediaTek GCE unit

2018-06-27 Thread Houlong Wei
This adds documentation for the MediaTek Global Command Engine (GCE) unit
found in MT8173 SoCs.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
Hi Rob,
  I don't add your ACK in this version since the dt-binding description
has been changed. Thanks.
---
 .../devicetree/bindings/mailbox/mtk-gce.txt|   65 
 include/dt-bindings/gce/mt8173-gce.h   |   48 +++
 2 files changed, 113 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk-gce.txt
 create mode 100644 include/dt-bindings/gce/mt8173-gce.h

diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt 
b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
new file mode 100644
index 000..26f65a4
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
@@ -0,0 +1,65 @@
+MediaTek GCE
+===
+
+The Global Command Engine (GCE) is used to help read/write registers with
+critical time limitation, such as updating display configuration during the
+vblank. The GCE can be used to implement the Command Queue (CMDQ) driver.
+
+CMDQ driver uses mailbox framework for communication. Please refer to
+mailbox.txt for generic information about mailbox device-tree bindings.
+
+Required properties:
+- compatible: Must be "mediatek,mt8173-gce"
+- reg: Address range of the GCE unit
+- interrupts: The interrupt signal from the GCE block
+- clock: Clocks according to the common clock binding
+- clock-names: Must be "gce" to stand for GCE clock
+- thread-num: Maximum threads count of GCE.
+- #mbox-cells: Should be 4.
+   < channel timeout priority atomic_exec>
+   phandle: Label name of a gce node.
+   channel: Channel of mailbox. Be equal to the thread id of GCE.
+   timeout: Maximum time of software waiting GCE processing done, in unit
+   of millisecond.
+   priority: Priority of GCE thread.
+   atomic_exec: GCE processing continuous packets of commands in atomic
+   way.
+
+Required properties for a client device:
+- mboxes: Client use mailbox to communicate with GCE, it should have this
+  property and list of phandle, mailbox specifiers.
+- gce-subsys: Specify the sub-system id which is corresponding to the register
+  address.
+
+Optional properties for a client device:
+- gce-event: Specify the event if the client has any. Because the event is
+  parsed by client, so client can replace 'gce-event' with other meaningful
+  name.
+
+Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h'. Such 
as
+thread number, sub-system ids, thread priority, event ids.
+
+Example:
+
+   gce: gce@10212000 {
+   compatible = "mediatek,mt8173-gce";
+   reg = <0 0x10212000 0 0x1000>;
+   interrupts = ;
+   clocks = < CLK_INFRA_GCE>;
+   clock-names = "gce";
+   thread-num = CMDQ_THR_MAX_COUNT;
+   #mbox-cells = <4>;
+   };
+
+Example for a client device:
+
+   mmsys: clock-controller@1400 {
+   compatible = "mediatek,mt8173-mmsys";
+   mboxes = < 0 2000 CMDQ_THR_PRIO_LOWEST 1>,
+< 1 2000 CMDQ_THR_PRIO_LOWEST 1>;
+   gce-subsys = ;
+   mutex-event-eof = ;
+
+   ...
+   };
diff --git a/include/dt-bindings/gce/mt8173-gce.h 
b/include/dt-bindings/gce/mt8173-gce.h
new file mode 100644
index 000..89eb3b8
--- /dev/null
+++ b/include/dt-bindings/gce/mt8173-gce.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Houlong Wei 
+ *
+ */
+
+#ifndef _DT_BINDINGS_GCE_MT8173_H
+#define _DT_BINDINGS_GCE_MT8173_H
+
+#define CMDQ_NO_TIMEOUT0x
+
+#define CMDQ_THR_MAX_COUNT 16
+
+/* GCE HW thread priority */
+#define CMDQ_THR_PRIO_LOWEST   0
+#define CMDQ_THR_PRIO_HIGHEST  1
+
+/* GCE SUBSYS */
+#define SUBSYS_14001
+#define SUBSYS_14012
+#define SUBSYS_14023
+
+/* GCE HW EVENT */
+#define CMDQ_EVENT_DISP_OVL0_SOF   11
+#define CMDQ_EVENT_DISP_OVL1_SOF   12
+#define CMDQ_EVENT_DISP_RDMA0_SOF  13
+#define CMDQ_EVENT_DISP_RDMA1_SOF  14
+#define CMDQ_EVENT_DISP_RDMA2_SOF  15
+#define CMDQ_EVENT_DISP_WDMA0_SOF  16
+#define CMDQ_EVENT_DISP_WDMA1_SOF  17
+#define CMDQ_EVENT_DISP_OVL0_EOF   39
+#define CMDQ_EVENT_DISP_OVL1_EOF   40
+#define CMDQ_EVENT_DISP_RDMA0_EOF  41
+#define CMDQ_EVENT_DISP_RDMA1_EOF  42
+#define CMDQ_EVENT_DISP_RDMA2_EOF  43
+#define CMDQ_EVENT_DISP_WDMA0_EOF  44
+#define CMDQ_EVENT_DISP_WDMA1_EOF  45
+#define CMDQ_EVENT_MUTEX0_STREAM_EOF   53
+#define CMDQ_EVENT_MUTEX1_STREAM_EOF   54
+#define CMDQ_EVENT_MUTE

[PATCH v22 2/4] mailbox: mediatek: Add Mediatek CMDQ driver

2018-06-27 Thread Houlong Wei
This patch is first version of Mediatek Command Queue(CMDQ) driver. The
CMDQ is used to help write registers with critical time limitation,
such as updating display configuration during the vblank. It controls
Global Command Engine (GCE) hardware to achieve this requirement.
Currently, CMDQ only supports display related hardwares, but we expect
it can be extended to other hardwares for future requirements.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
Signed-off-by: CK Hu 
---
 drivers/mailbox/Kconfig  |   10 +
 drivers/mailbox/Makefile |2 +
 drivers/mailbox/mtk-cmdq-mailbox.c   |  634 ++
 include/linux/mailbox/mtk-cmdq-mailbox.h |   70 
 4 files changed, 716 insertions(+)
 create mode 100644 drivers/mailbox/mtk-cmdq-mailbox.c
 create mode 100644 include/linux/mailbox/mtk-cmdq-mailbox.h

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index e63d29a..2bbabc9 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -189,4 +189,14 @@ config STM32_IPCC
  Mailbox implementation for STMicroelectonics STM32 family chips
  with hardware for Inter-Processor Communication Controller (IPCC)
  between processors. Say Y here if you want to have this support.
+
+config MTK_CMDQ_MBOX
+   tristate "MediaTek CMDQ Mailbox Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ mailbox driver. The CMDQ is used to help read/write registers with
+ critical time limitation, such as updating display configuration
+ during the vblank.
 endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 4d501be..4b00804 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -40,3 +40,5 @@ obj-$(CONFIG_QCOM_APCS_IPC)   += qcom-apcs-ipc-mailbox.o
 obj-$(CONFIG_TEGRA_HSP_MBOX)   += tegra-hsp.o
 
 obj-$(CONFIG_STM32_IPCC)   += stm32-ipcc.o
+
+obj-$(CONFIG_MTK_CMDQ_MBOX)+= mtk-cmdq-mailbox.o
diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
b/drivers/mailbox/mtk-cmdq-mailbox.c
new file mode 100644
index 000..93d87cb
--- /dev/null
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -0,0 +1,634 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_OP_CODE_MASK  (0xff << CMDQ_OP_CODE_SHIFT)
+#define CMDQ_TIMEOUT_MS1000
+#define CMDQ_IRQ_MASK  0x
+#define CMDQ_NUM_CMD(t)(t->cmd_buf_size / 
CMDQ_INST_SIZE)
+
+#define CMDQ_CURR_IRQ_STATUS   0x10
+#define CMDQ_THR_SLOT_CYCLES   0x30
+#define CMDQ_THR_BASE  0x100
+#define CMDQ_THR_SIZE  0x80
+#define CMDQ_THR_WARM_RESET0x00
+#define CMDQ_THR_ENABLE_TASK   0x04
+#define CMDQ_THR_SUSPEND_TASK  0x08
+#define CMDQ_THR_CURR_STATUS   0x0c
+#define CMDQ_THR_IRQ_STATUS0x10
+#define CMDQ_THR_IRQ_ENABLE0x14
+#define CMDQ_THR_CURR_ADDR 0x20
+#define CMDQ_THR_END_ADDR  0x24
+#define CMDQ_THR_WAIT_TOKEN0x30
+#define CMDQ_THR_PRIORITY  0x40
+
+#define CMDQ_NO_TIMEOUT0xu
+#define CMDQ_THR_ACTIVE_SLOT_CYCLES0x3200
+#define CMDQ_THR_ENABLED   0x1
+#define CMDQ_THR_DISABLED  0x0
+#define CMDQ_THR_SUSPEND   0x1
+#define CMDQ_THR_RESUME0x0
+#define CMDQ_THR_STATUS_SUSPENDED  BIT(1)
+#define CMDQ_THR_DO_WARM_RESET BIT(0)
+#define CMDQ_THR_IRQ_DONE  0x1
+#define CMDQ_THR_IRQ_ERROR 0x12
+#define CMDQ_THR_IRQ_EN(CMDQ_THR_IRQ_ERROR | 
CMDQ_THR_IRQ_DONE)
+#define CMDQ_THR_IS_WAITINGBIT(31)
+
+#define CMDQ_JUMP_BY_OFFSET0x1000
+#define CMDQ_JUMP_BY_PA0x1001
+
+struct cmdq_thread {
+   struct mbox_chan*chan;
+   void __iomem*base;
+   struct list_headtask_busy_list;
+   struct timer_list   timeout;
+   u32 timeout_ms;
+   u32 priority;
+   boolatomic_exec;
+};
+
+struct cmdq_task {
+   struct cmdq *cmdq;
+   struct list_headlist_entry;
+   dma_addr_t  pa_base;
+   struct cmdq_thread  *thread;
+   struct cmdq_pkt *pkt; /* the packet sent from mailbox client */
+};
+
+struct cmdq {
+   struct mbox_controller  mbox;
+   void __iomem*base;
+   u32 irq;
+   u32 thread_nr;
+   struct cmdq_thread  *thread;

[PATCH v22 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-06-27 Thread Houlong Wei
Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 drivers/soc/mediatek/Kconfig   |   12 ++
 drivers/soc/mediatek/Makefile  |1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c |  258 
 include/linux/soc/mediatek/mtk-cmdq.h  |  132 
 4 files changed, 403 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
 create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index a7d0667..17bd759 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -4,6 +4,18 @@
 menu "MediaTek SoC drivers"
depends on ARCH_MEDIATEK || COMPILE_TEST
 
+config MTK_CMDQ
+   tristate "MediaTek CMDQ Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select MAILBOX
+   select MTK_CMDQ_MBOX
+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
 config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
select REGMAP
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..64ce5ee 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
 obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
 obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
new file mode 100644
index 000..6c66091
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -0,0 +1,258 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_ARG_A_WRITE_MASK  0x
+#define CMDQ_WRITE_ENABLE_MASK BIT(0)
+#define CMDQ_EOC_IRQ_ENBIT(0)
+#define CMDQ_EOC_CMD   ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
+   << 32 | CMDQ_EOC_IRQ_EN)
+
+int cmdq_pkt_realloc_cmd_buffer(struct cmdq_pkt *pkt, size_t size)
+{
+   void *new_buf;
+
+   new_buf = krealloc(pkt->va_base, size, GFP_KERNEL | __GFP_ZERO);
+   if (!new_buf)
+   return -ENOMEM;
+   pkt->va_base = new_buf;
+   pkt->buf_size = size;
+
+   return 0;
+}
+EXPORT_SYMBOL(cmdq_pkt_realloc_cmd_buffer);
+
+struct cmdq_client *cmdq_mbox_create(struct device *dev, int index)
+{
+   struct cmdq_client *client;
+   long err = 0;
+
+   client = kzalloc(sizeof(*client), GFP_KERNEL);
+   if (!client)
+   return (struct cmdq_client *)-ENOMEM;
+
+   client->client.dev = dev;
+   client->client.tx_block = false;
+   client->chan = mbox_request_channel(>client, index);
+
+   if (IS_ERR(client->chan)) {
+   dev_err(dev, "failed to request channel\n");
+   err = PTR_ERR(client->chan);
+   kfree(client);
+
+   return (struct cmdq_client *)err;
+   }
+
+   return client;
+}
+EXPORT_SYMBOL(cmdq_mbox_create);
+
+void cmdq_mbox_destroy(struct cmdq_client *client)
+{
+   mbox_free_channel(client->chan);
+   kfree(client);
+}
+EXPORT_SYMBOL(cmdq_mbox_destroy);
+
+int cmdq_pkt_create(struct cmdq_pkt **pkt_ptr)
+{
+   struct cmdq_pkt *pkt;
+   int err;
+
+   pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
+   if (!pkt)
+   return -ENOMEM;
+   err = cmdq_pkt_realloc_cmd_buffer(pkt, PAGE_SIZE);
+   if (err < 0) {
+   kfree(pkt);
+   return err;
+   }
+   *pkt_ptr = pkt;
+
+   return 0;
+}
+EXPORT_SYMBOL(cmdq_pkt_create);
+
+void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
+{
+   kfree(pkt->va_base);
+   kfree(pkt);
+}
+EXPORT_SYMBOL(cmdq_pkt_destroy);
+
+static bool cmdq_pkt_is_finalized(struct cmdq_pkt *pkt)
+{
+   u64 *expect_eoc;
+
+   if (pkt->cmd_buf_size < CMDQ_INST_SIZE << 1)
+   return false;
+
+   expect_eoc = pkt->va_base + pkt->cmd_buf_size - (CMDQ_INST_SIZE << 1);
+   if (*expect_eoc == CMDQ_EOC_CMD)
+   return true;
+
+   return false;
+}
+
+static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
+  u32 arg_a, u32 arg_b)
+{
+   u64 *cmd_ptr;
+   int err;
+
+   if (WARN_ON(cmdq_pkt_is_finalized(pkt)))
+   return -EBUSY;
+   if (unlikely(pkt->cmd_buf_size + CMDQ_INST_SIZE > pkt->buf_size)) {
+   err = cmdq_pkt_realloc_cmd_buffer(pkt, pkt->buf_size <<

[PATCH v22 3/4] arm64: dts: mt8173: Add GCE node

2018-06-27 Thread Houlong Wei
This patch adds the device node of the GCE hardware for CMDQ module.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi |   11 +++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 94597e3..d180a6d 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "mt8173-pinfunc.h"
 
 / {
@@ -519,6 +520,16 @@
status = "disabled";
};
 
+   gce: gce@10212000 {
+   compatible = "mediatek,mt8173-gce";
+   reg = <0 0x10212000 0 0x1000>;
+   interrupts = ;
+   clocks = < CLK_INFRA_GCE>;
+   clock-names = "gce";
+   thread-num = ;
+   #mbox-cells = <4>;
+   };
+
mipi_tx0: mipi-dphy@10215000 {
compatible = "mediatek,mt8173-mipi-tx";
reg = <0 0x10215000 0 0x1000>;
-- 
1.7.9.5



Re: [PATCH v21 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-06-27 Thread houlong wei
On Tue, 2018-02-06 at 10:52 +0800, CK Hu wrote:
> Hi, Houlong:
> 
> I've some inline comment.
> 
> On Wed, 2018-01-31 at 15:28 +0800, houlong@mediatek.com wrote:
> > From: "hs.l...@mediatek.com" 
> >
> > Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.
> >
> > Signed-off-by: Houlong Wei 
> > Signed-off-by: HS Liao 
> > ---
> >  drivers/soc/mediatek/Kconfig   |   12 ++
> >  drivers/soc/mediatek/Makefile  |1 +
> >  drivers/soc/mediatek/mtk-cmdq-helper.c |  322 
> > 
> >  include/linux/soc/mediatek/mtk-cmdq.h  |  174 +
> >  4 files changed, 509 insertions(+)
> >  create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
> >  create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h
> >
> > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > index a7d0667..e66582e 100644
> > --- a/drivers/soc/mediatek/Kconfig
> > +++ b/drivers/soc/mediatek/Kconfig
> > @@ -4,6 +4,18 @@
> >  menu "MediaTek SoC drivers"
> >  depends on ARCH_MEDIATEK || COMPILE_TEST
> >
> > +config MTK_CMDQ
> > +bool "MediaTek CMDQ Support"
> > +depends on ARM64 && ( ARCH_MEDIATEK || COMPILE_TEST )
> > +select MAILBOX
> > +select MTK_CMDQ_MBOX
> > +select MTK_INFRACFG
> > +help
> > +  Say yes here to add support for the MediaTek Command Queue (CMDQ)
> > +  driver. The CMDQ is used to help read/write registers with critical
> > +  time limitation, such as updating display configuration during the
> > +  vblank.
> > +
> >  config MTK_INFRACFG
> >  bool "MediaTek INFRACFG Support"
> >  select REGMAP
> > diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> > index 12998b0..64ce5ee 100644
> > --- a/drivers/soc/mediatek/Makefile
> > +++ b/drivers/soc/mediatek/Makefile
> > @@ -1,3 +1,4 @@
> > +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
> >  obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
> >  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
> >  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > new file mode 100644
> > index 000..80d0558
> > --- /dev/null
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -0,0 +1,322 @@
> > +/*
> > + * Copyright (c) 2015 MediaTek Inc.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define CMDQ_ARG_A_WRITE_MASK0x
> > +#define CMDQ_WRITE_ENABLE_MASKBIT(0)
> > +#define CMDQ_EOC_IRQ_ENBIT(0)
> > +#define CMDQ_EOC_CMD((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
> > +<< 32 | CMDQ_EOC_IRQ_EN)
> > +
> > +struct cmdq_subsys {
> > +u32base;
> > +intid;
> > +};
> > +
> > +static const struct cmdq_subsys gce_subsys[] = {
> > +{0x1400, 1},
> > +{0x1401, 2},
> > +{0x1402, 3},
> > +};
> 
> I think subsys definition varies by different SoC, so it's better to
> pass these definition from device tree to driver (client driver), and
> client driver pass this subsys in the related interface. For example,
> 
> in include/dt-bindings/gce/mt8173-gce.h, you define
> 
> #define GCE_SUBSYS_14001
> #define GCE_SUBSYS_14012
> #define GCE_SUBSYS_14023
> 
> in device tree, place the subsys definition in client device node,
> 
> #include "dt-bindings/gce/mt8173-gce.h"
> 
> ovl0: ovl@1400c000 {
> compatible = "mediatek,mt8173-disp-ovl";
> gce-subsys = ;
> ...
> };
> 
> And client driver pass subsys in the related interface,
> 
> int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32
> value);
> 
> So, for another SoC, you just need to modify device tree and you do not
> need to modify driver.

Hi CK, thanks for your suggestion. I do it in v22.

> > +
> > +static int cmdq_subsys_base_to_id(u32 base)
> > 

Re: [PATCH v21 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-06-27 Thread houlong wei
On Wed, 2018-02-21 at 16:05 +0800, CK Hu wrote:
> Hi, Houlong:
> 
> I've one more inline comment.
> 
> On Wed, 2018-01-31 at 15:28 +0800, houlong@mediatek.com wrote:
> > From: "hs.l...@mediatek.com" 
> > 
> > Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.
> > 
> > Signed-off-by: Houlong Wei 
> > Signed-off-by: HS Liao 
> > ---
> >  drivers/soc/mediatek/Kconfig   |   12 ++
> >  drivers/soc/mediatek/Makefile  |1 +
> >  drivers/soc/mediatek/mtk-cmdq-helper.c |  322 
> > 
> >  include/linux/soc/mediatek/mtk-cmdq.h  |  174 +
> >  4 files changed, 509 insertions(+)
> >  create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
> >  create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h
> > 
> > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > index a7d0667..e66582e 100644
> > --- a/drivers/soc/mediatek/Kconfig
> > +++ b/drivers/soc/mediatek/Kconfig
> > @@ -4,6 +4,18 @@
> >  menu "MediaTek SoC drivers"
> > depends on ARCH_MEDIATEK || COMPILE_TEST
> >  
> > +config MTK_CMDQ
> > +   bool "MediaTek CMDQ Support"
> > +   depends on ARM64 && ( ARCH_MEDIATEK || COMPILE_TEST )
> > +   select MAILBOX
> > +   select MTK_CMDQ_MBOX
> > +   select MTK_INFRACFG
> > +   help
> > + Say yes here to add support for the MediaTek Command Queue (CMDQ)
> > + driver. The CMDQ is used to help read/write registers with critical
> > + time limitation, such as updating display configuration during the
> > + vblank.
> > +
> >  config MTK_INFRACFG
> > bool "MediaTek INFRACFG Support"
> > select REGMAP
> > diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> > index 12998b0..64ce5ee 100644
> > --- a/drivers/soc/mediatek/Makefile
> > +++ b/drivers/soc/mediatek/Makefile
> > @@ -1,3 +1,4 @@
> > +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
> >  obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
> >  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
> >  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > new file mode 100644
> > index 000..80d0558
> > --- /dev/null
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -0,0 +1,322 @@
> > +/*
> > + * Copyright (c) 2015 MediaTek Inc.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define CMDQ_ARG_A_WRITE_MASK  0x
> > +#define CMDQ_WRITE_ENABLE_MASK BIT(0)
> > +#define CMDQ_EOC_IRQ_ENBIT(0)
> > +#define CMDQ_EOC_CMD   ((u64)((CMDQ_CODE_EOC << 
> > CMDQ_OP_CODE_SHIFT)) \
> > +   << 32 | CMDQ_EOC_IRQ_EN)
> > +
> > +struct cmdq_subsys {
> > +   u32 base;
> > +   int id;
> > +};
> > +
> > +static const struct cmdq_subsys gce_subsys[] = {
> > +   {0x1400, 1},
> > +   {0x1401, 2},
> > +   {0x1402, 3},
> > +};
> > +
> > +static int cmdq_subsys_base_to_id(u32 base)
> > +{
> > +   int i;
> > +
> > +   for (i = 0; i < ARRAY_SIZE(gce_subsys); i++)
> > +   if (gce_subsys[i].base == base)
> > +   return gce_subsys[i].id;
> > +   return -EFAULT;
> > +}
> > +
> > +static int cmdq_pkt_realloc_cmd_buffer(struct cmdq_pkt *pkt, size_t size)
> > +{
> > +   void *new_buf;
> > +
> > +   new_buf = krealloc(pkt->va_base, size, GFP_KERNEL | __GFP_ZERO);
> > +   if (!new_buf)
> > +   return -ENOMEM;
> > +   pkt->va_base = new_buf;
> > +   pkt->buf_size = size;
> > +   return 0;
> > +}
> > +
> > +struct cmdq_base *cmdq_register_device(struct device *dev)
> > +{
> > +   struct cmdq_base *cmdq_base;
> > +   struct resource res;
> 

Re: [PATCH v21 2/4] mailbox: mediatek: Add Mediatek CMDQ driver

2018-06-27 Thread houlong wei
On Wed, 2018-02-21 at 11:53 +0800, CK Hu wrote:
> Hi, Houlong:
> 
> I've one inline comment.
> 
> On Wed, 2018-01-31 at 15:28 +0800, houlong@mediatek.com wrote:
> > From: "hs.l...@mediatek.com" 
> > 
> > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > CMDQ is used to help write registers with critical time limitation,
> > such as updating display configuration during the vblank. It controls
> > Global Command Engine (GCE) hardware to achieve this requirement.
> > Currently, CMDQ only supports display related hardwares, but we expect
> > it can be extended to other hardwares for future requirements.
> > 
> > Signed-off-by: Houlong Wei 
> > Signed-off-by: HS Liao 
> > Signed-off-by: CK Hu 
> > ---
> >  drivers/mailbox/Kconfig  |   10 +
> >  drivers/mailbox/Makefile |2 +
> >  drivers/mailbox/mtk-cmdq-mailbox.c   |  594 
> > ++
> >  include/linux/mailbox/mtk-cmdq-mailbox.h |   77 
> >  4 files changed, 683 insertions(+)
> >  create mode 100644 drivers/mailbox/mtk-cmdq-mailbox.c
> >  create mode 100644 include/linux/mailbox/mtk-cmdq-mailbox.h
> > 
> > diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
> > index ba2f152..43bb26f 100644
> > --- a/drivers/mailbox/Kconfig
> > +++ b/drivers/mailbox/Kconfig
> > @@ -171,4 +171,14 @@ config BCM_FLEXRM_MBOX
> >   Mailbox implementation of the Broadcom FlexRM ring manager,
> >   which provides access to various offload engines on Broadcom
> >   SoCs. Say Y here if you want to use the Broadcom FlexRM.
> > +
> > +config MTK_CMDQ_MBOX
> > +   bool "MediaTek CMDQ Mailbox Support"
> > +   depends on ARM64 && ( ARCH_MEDIATEK || COMPILE_TEST )
> > +   select MTK_INFRACFG
> > +   help
> > + Say yes here to add support for the MediaTek Command Queue (CMDQ)
> > + mailbox driver. The CMDQ is used to help read/write registers with
> > + critical time limitation, such as updating display configuration
> > + during the vblank.
> >  endif
> > diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
> > index 4896f8d..484d341 100644
> > --- a/drivers/mailbox/Makefile
> > +++ b/drivers/mailbox/Makefile
> > @@ -36,3 +36,5 @@ obj-$(CONFIG_BCM_FLEXRM_MBOX) += bcm-flexrm-mailbox.o
> >  obj-$(CONFIG_QCOM_APCS_IPC)+= qcom-apcs-ipc-mailbox.o
> >  
> >  obj-$(CONFIG_TEGRA_HSP_MBOX)   += tegra-hsp.o
> > +
> > +obj-$(CONFIG_MTK_CMDQ_MBOX)+= mtk-cmdq-mailbox.o
> > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
> > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > new file mode 100644
> > index 000..394a335
> > --- /dev/null
> > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > @@ -0,0 +1,594 @@
> > +/*
> > + * Copyright (c) 2015 MediaTek Inc.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define CMDQ_THR_MAX_COUNT 16
> > +#define CMDQ_OP_CODE_MASK  (0xff << CMDQ_OP_CODE_SHIFT)
> > +#define CMDQ_TIMEOUT_MS1000
> > +#define CMDQ_IRQ_MASK  0x
> > +#define CMDQ_NUM_CMD(t)(t->cmd_buf_size / 
> > CMDQ_INST_SIZE)
> > +
> > +#define CMDQ_CURR_IRQ_STATUS   0x10
> > +#define CMDQ_THR_SLOT_CYCLES   0x30
> > +
> > +#define CMDQ_THR_BASE  0x100
> > +#define CMDQ_THR_SIZE  0x80
> > +#define CMDQ_THR_WARM_RESET0x00
> > +#define CMDQ_THR_ENABLE_TASK   0x04
> > +#define CMDQ_THR_SUSPEND_TASK  0x08
> > +#define CMDQ_THR_CURR_STATUS   0x0c
> > +#define CMDQ_THR_IRQ_STATUS0x10
> > +#define CMDQ_THR_IRQ_ENABLE0x14
> > +#define CMDQ_THR_CURR_ADDR 0

Re: [PATCH v21 2/4] mailbox: mediatek: Add Mediatek CMDQ driver

2018-06-28 Thread houlong wei
On Thu, 2018-06-28 at 09:57 +0800, CK Hu wrote:
> Hi, Houlong:
> 
> On Wed, 2018-06-27 at 19:53 +0800, houlong wei wrote:
> > On Wed, 2018-02-21 at 11:53 +0800, CK Hu wrote:
> > > Hi, Houlong:
> > > 
> > > I've one inline comment.
> > > 
> > > On Wed, 2018-01-31 at 15:28 +0800, houlong@mediatek.com wrote:
> > > > From: "hs.l...@mediatek.com" 
> > > > 
> > > > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > > > CMDQ is used to help write registers with critical time limitation,
> > > > such as updating display configuration during the vblank. It controls
> > > > Global Command Engine (GCE) hardware to achieve this requirement.
> > > > Currently, CMDQ only supports display related hardwares, but we expect
> > > > it can be extended to other hardwares for future requirements.
> > > > 
> > > > Signed-off-by: Houlong Wei 
> > > > Signed-off-by: HS Liao 
> > > > Signed-off-by: CK Hu 
> > > > ---
> > > >  drivers/mailbox/Kconfig  |   10 +
> > > >  drivers/mailbox/Makefile |2 +
> > > >  drivers/mailbox/mtk-cmdq-mailbox.c   |  594 
> > > > ++
> > > >  include/linux/mailbox/mtk-cmdq-mailbox.h |   77 
> > > >  4 files changed, 683 insertions(+)
> > > >  create mode 100644 drivers/mailbox/mtk-cmdq-mailbox.c
> > > >  create mode 100644 include/linux/mailbox/mtk-cmdq-mailbox.h
> > > > 
> > > > diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
> > > > index ba2f152..43bb26f 100644
> > > > --- a/drivers/mailbox/Kconfig
> > > > +++ b/drivers/mailbox/Kconfig
> > > > @@ -171,4 +171,14 @@ config BCM_FLEXRM_MBOX
> > > >   Mailbox implementation of the Broadcom FlexRM ring manager,
> > > >   which provides access to various offload engines on Broadcom
> > > >   SoCs. Say Y here if you want to use the Broadcom FlexRM.
> > > > +
> 
> [...]
> 
> > > > +
> > > > +static void cmdq_task_exec(struct cmdq_pkt *pkt, struct cmdq_thread 
> > > > *thread)
> > > > +{
> > > > +   struct cmdq *cmdq;
> > > > +   struct cmdq_task *task;
> > > > +   unsigned long curr_pa, end_pa;
> > > > +
> > > > +   cmdq = dev_get_drvdata(thread->chan->mbox->dev);
> > > > +
> > > > +   /* Client should not flush new tasks if suspended. */
> > > > +   WARN_ON(cmdq->suspended);
> > > > +
> > > > +   task = kzalloc(sizeof(*task), GFP_ATOMIC);
> > > > +   task->cmdq = cmdq;
> > > > +   INIT_LIST_HEAD(>list_entry);
> > > > +   task->pa_base = pkt->pa_base;
> > > > +   task->thread = thread;
> > > > +   task->pkt = pkt;
> > > > +
> > > > +   if (list_empty(>task_busy_list)) {
> > > > +   WARN_ON(clk_enable(cmdq->clock) < 0);
> > > > +   WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
> > > > +
> > > > +   writel(task->pa_base, thread->base + 
> > > > CMDQ_THR_CURR_ADDR);
> > > > +   writel(task->pa_base + pkt->cmd_buf_size,
> > > > +  thread->base + CMDQ_THR_END_ADDR);
> > > > +   writel(CMDQ_THR_IRQ_EN, thread->base + 
> > > > CMDQ_THR_IRQ_ENABLE);
> > > > +   writel(CMDQ_THR_ENABLED, thread->base + 
> > > > CMDQ_THR_ENABLE_TASK);
> > > > +
> > > > +   mod_timer(>timeout,
> > > > + jiffies + msecs_to_jiffies(CMDQ_TIMEOUT_MS));
> > > > +   } else {
> > > > +   WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
> > > > +   curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR);
> > > > +   end_pa = readl(thread->base + CMDQ_THR_END_ADDR);
> > > > +
> > > > +   /*
> > > > +* Atomic execution should remove the following wfe, 
> > > > i.e. only
> > > > +* wait event at first task, and prevent to pause when 
> > > > running.
> > > > +*/
> > > > +   if (thread->atomic_exec

Re: [PATCH v22 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-06-28 Thread houlong wei
On Thu, 2018-06-28 at 18:41 +0800, CK Hu wrote:
> Hi, Houlong:
> 
> Some inline comment.
> 
> On Wed, 2018-06-27 at 19:16 +0800, Houlong Wei wrote:
> > Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.
> > 
> > Signed-off-by: Houlong Wei 
> > Signed-off-by: HS Liao 
> > ---
> >  drivers/soc/mediatek/Kconfig   |   12 ++
> >  drivers/soc/mediatek/Makefile  |1 +
> >  drivers/soc/mediatek/mtk-cmdq-helper.c |  258 
> > 
> >  include/linux/soc/mediatek/mtk-cmdq.h  |  132 
> >  4 files changed, 403 insertions(+)
> >  create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
> >  create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h
> > 
> > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > index a7d0667..17bd759 100644
> > --- a/drivers/soc/mediatek/Kconfig
> > +++ b/drivers/soc/mediatek/Kconfig
> > @@ -4,6 +4,18 @@
> >  menu "MediaTek SoC drivers"
> > depends on ARCH_MEDIATEK || COMPILE_TEST
> >  
> 
> [...]
> 
> > +
> > +int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u32 event)
> > +{
> > +   u32 arg_b;
> > +
> > +   if (event >= CMDQ_MAX_EVENT || event < 0)
> 
> The type of event is 'u32', so checking 'event < 0' is redundant.

will fix.

> 
> > +   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;
> > +
> > +   return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event, arg_b);
> > +}
> > +EXPORT_SYMBOL(cmdq_pkt_wfe);
> > +
> > +int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u32 event)
> > +{
> > +   if (event >= CMDQ_MAX_EVENT || event < 0)
> 
> The type of event is 'u32', so checking 'event < 0' is redundant.

Will fix.

> 
> > +   return -EINVAL;
> > +
> > +   return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event,
> > +  CMDQ_WFE_UPDATE);
> > +}
> > +EXPORT_SYMBOL(cmdq_pkt_clear_event);
> > +
> > +static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
> > +{
> > +   int err;
> > +
> > +   if (cmdq_pkt_is_finalized(pkt))
> > +   return 0;
> > +
> > +   /* insert EOC and generate IRQ for each command iteration */
> > +   err = cmdq_pkt_append_command(pkt, CMDQ_CODE_EOC, 0, CMDQ_EOC_IRQ_EN);
> > +   if (err < 0)
> > +   return err;
> > +
> > +   /* JUMP to end */
> > +   err = cmdq_pkt_append_command(pkt, CMDQ_CODE_JUMP, 0, CMDQ_JUMP_PASS);
> > +   if (err < 0)
> > +   return err;
> > +
> > +   return 0;
> > +}
> > +
> > +int cmdq_pkt_flush_async(struct cmdq_client *client, struct cmdq_pkt *pkt,
> > +cmdq_async_flush_cb cb, void *data)
> > +{
> > +   int err;
> > +   struct device *dev;
> > +   dma_addr_t dma_addr;
> > +
> > +   err = cmdq_pkt_finalize(pkt);
> > +   if (err < 0)
> > +   return err;
> > +
> > +   dev = client->chan->mbox->dev;
> > +   dma_addr = dma_map_single(dev, pkt->va_base, pkt->cmd_buf_size,
> > +   DMA_TO_DEVICE);
> 
> You map here, but I could not find unmap, so the unmap should be done in
> client driver. I would prefer a symmetric map/unmap which means that
> both map and unmap are done in client driver. I think you put map here
> because you should map after finalize. 

The unmap is done before callback to client, in function
cmdq_task_exec_done, mtk-cmdq-mailbox.c.

> Therefore, export
> cmdq_pkt_finalize() to client driver and let client do finalize, so
> there is no finalize in flush function. This method have a benefit that
> if client reuse command buffer, it need not to map/unmap frequently.

If client reuse command buffer or cmdq_pkt(command queue packet), client
will add new commands to the cmdq_pkt, so map/unmap are necessary for
each cmdq_pkt flush.

> 
> Regards,
> CK
> 
> > +   if (dma_mapping_error(dev, dma_addr)) {
> > +   dev_err(client->chan->mbox->dev, "dma map failed\n");
> > +   return -ENOMEM;
> > +   }
> > +
> > +   pkt->pa_base = dma_addr;
> > +   pkt->cb.cb = cb;
> > +   pkt->cb.data = data;
> > +
> > +   mbox_send_message(client->chan, pkt);
> > +   /*

[PATCH v27 0/2] MediaTek MT8173 CMDQ support

2018-11-28 Thread Houlong Wei
Hi,

This is Mediatek MT8173 Command Queue(CMDQ) driver. The CMDQ is used
to help write registers with critical time limitation, such as
updating display configuration during the vblank. It controls Global
Command Engine (GCE) hardware to achieve this requirement.

Changes since v26:
 -rebase on v4.20-rc1
 -add comment to explain why cmdq_buf_size is increased in case of
  appending command failure
Changes since v25:
 -Replace WARN_ON() with WARN_ONCE() and add debug information.
Changes since v24:
 -move WARN_ON() into cmdq_pkt_append_command() from outside
Changes since v23:
 -rebase on v4.19-rc1
 -revise return value of cmdq_mbox_create()
 -revise cmdq_pkt_create()
 -add MODULE_LICENSE() for mtk-cmdq-helper.c
 -adjust functions order in mtk-cmdq.h
Changes since v22:
 -remove properties 'timeout' and 'thread-num' from device tree
 -move timer from CMDQ driver to CMDQ helper
 -move dma unmap from CMDQ driver to CMDQ helper
 -config thread number in CMDQ match table
 -remove reallocate mechanism and let client specify the cmdq buffer size
 -let client specify the timeout time
Changes since v21:
 -rebase on v4.18-rc1
 -remove subsys code and event id definition from mtk-cmdq-helper.c
 -add mt8173-gce.h to define the subsys code and envent id
Changes since v20:
 -rebase on v4.15-rc1
 -move dma_map_single outside of spinlock
Changes since v19:
 -rebase to v4.10-rc2

Houlong Wei (2):
  arm64: dts: mt8173: Add GCE node
  soc: mediatek: Add Mediatek CMDQ helper

 arch/arm64/boot/dts/mediatek/mt8173.dtsi |  10 +
 drivers/soc/mediatek/Kconfig |  12 +
 drivers/soc/mediatek/Makefile|   1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c   | 300 +++
 include/linux/soc/mediatek/mtk-cmdq.h| 133 ++
 5 files changed, 456 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
 create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

-- 
2.19.1



[PATCH v27 1/2] arm64: dts: mt8173: Add GCE node

2018-11-28 Thread Houlong Wei
This patch adds the device node of the GCE hardware for CMDQ module.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi |   10 ++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index abd2f15..412ffd4 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "mt8173-pinfunc.h"
 
 / {
@@ -521,6 +522,15 @@
status = "disabled";
};
 
+   gce: mailbox@10212000 {
+   compatible = "mediatek,mt8173-gce";
+   reg = <0 0x10212000 0 0x1000>;
+   interrupts = ;
+   clocks = < CLK_INFRA_GCE>;
+   clock-names = "gce";
+   #mbox-cells = <3>;
+   };
+
mipi_tx0: mipi-dphy@10215000 {
compatible = "mediatek,mt8173-mipi-tx";
reg = <0 0x10215000 0 0x1000>;
-- 
1.7.9.5



[PATCH v27 2/2] soc: mediatek: Add Mediatek CMDQ helper

2018-11-28 Thread Houlong Wei
Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 drivers/soc/mediatek/Kconfig   |   12 ++
 drivers/soc/mediatek/Makefile  |1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c |  300 
 include/linux/soc/mediatek/mtk-cmdq.h  |  133 ++
 4 files changed, 446 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
 create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index a7d0667..17bd759 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -4,6 +4,18 @@
 menu "MediaTek SoC drivers"
depends on ARCH_MEDIATEK || COMPILE_TEST
 
+config MTK_CMDQ
+   tristate "MediaTek CMDQ Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select MAILBOX
+   select MTK_CMDQ_MBOX
+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
 config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
select REGMAP
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..64ce5ee 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
 obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
 obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
new file mode 100644
index 000..ff9fef5
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018 MediaTek Inc.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_ARG_A_WRITE_MASK  0x
+#define CMDQ_WRITE_ENABLE_MASK BIT(0)
+#define CMDQ_EOC_IRQ_ENBIT(0)
+#define CMDQ_EOC_CMD   ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
+   << 32 | CMDQ_EOC_IRQ_EN)
+
+static void cmdq_client_timeout(struct timer_list *t)
+{
+   struct cmdq_client *client = from_timer(client, t, timer);
+
+   dev_err(client->client.dev, "cmdq timeout!\n");
+}
+
+struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 
timeout)
+{
+   struct cmdq_client *client;
+
+   client = kzalloc(sizeof(*client), GFP_KERNEL);
+   if (!client)
+   return (struct cmdq_client *)-ENOMEM;
+
+   client->timeout_ms = timeout;
+   if (timeout != CMDQ_NO_TIMEOUT) {
+   spin_lock_init(>lock);
+   timer_setup(>timer, cmdq_client_timeout, 0);
+   }
+   client->pkt_cnt = 0;
+   client->client.dev = dev;
+   client->client.tx_block = false;
+   client->chan = mbox_request_channel(>client, index);
+
+   if (IS_ERR(client->chan)) {
+   long err;
+
+   dev_err(dev, "failed to request channel\n");
+   err = PTR_ERR(client->chan);
+   kfree(client);
+
+   return ERR_PTR(err);
+   }
+
+   return client;
+}
+EXPORT_SYMBOL(cmdq_mbox_create);
+
+void cmdq_mbox_destroy(struct cmdq_client *client)
+{
+   if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
+   spin_lock(>lock);
+   del_timer_sync(>timer);
+   spin_unlock(>lock);
+   }
+   mbox_free_channel(client->chan);
+   kfree(client);
+}
+EXPORT_SYMBOL(cmdq_mbox_destroy);
+
+struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
+{
+   struct cmdq_pkt *pkt;
+   struct device *dev;
+   dma_addr_t dma_addr;
+
+   pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
+   if (!pkt)
+   return ERR_PTR(-ENOMEM);
+   pkt->va_base = kzalloc(size, GFP_KERNEL);
+   if (!pkt->va_base) {
+   kfree(pkt);
+   return ERR_PTR(-ENOMEM);
+   }
+   pkt->buf_size = size;
+   pkt->cl = (void *)client;
+
+   dev = client->chan->mbox->dev;
+   dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
+ DMA_TO_DEVICE);
+   if (dma_mapping_error(dev, dma_addr)) {
+   dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
+   kfree(pkt->va_base);
+   kfree(pkt);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   pkt->pa_base = dma_addr;
+
+   return pkt;
+}
+EXPORT_SYMBOL(cmdq_pkt_create);
+
+void cmdq_pkt_destroy(struct cmdq_pkt *pk

[PATCH] mailbox: mediatek: Add check for possible failure of kzalloc

2018-08-21 Thread Houlong Wei
The patch 623a6143a845("mailbox: mediatek: Add Mediatek CMDQ driver")
introduce the following static checker warning:
  drivers/mailbox/mtk-cmdq-mailbox.c:366 cmdq_mbox_send_data()
  error: potential null dereference 'task'.  (kzalloc returns null)

Fixes: 623a6143a845 ("mailbox: mediatek: Add Mediatek CMDQ driver")
Reported-by: Dan Carpenter 
Signed-off-by: Houlong Wei 
---
 drivers/mailbox/mtk-cmdq-mailbox.c |3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
b/drivers/mailbox/mtk-cmdq-mailbox.c
index aec46d5..f7cc29c 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -363,6 +363,9 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void 
*data)
WARN_ON(cmdq->suspended);
 
task = kzalloc(sizeof(*task), GFP_ATOMIC);
+   if (!task)
+   return -ENOMEM;
+
task->cmdq = cmdq;
INIT_LIST_HEAD(>list_entry);
task->pa_base = pkt->pa_base;
-- 
1.7.9.5



Re: [PATCH v23 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-08-14 Thread houlong wei
On Wed, 2018-07-25 at 09:26 +0800, Houlong Wei wrote:
> Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.
> 
> Signed-off-by: Houlong Wei 
> Signed-off-by: HS Liao 
> ---
>  drivers/soc/mediatek/Kconfig   |   12 ++
>  drivers/soc/mediatek/Makefile  |1 +
>  drivers/soc/mediatek/mtk-cmdq-helper.c |  291 
> 
>  include/linux/soc/mediatek/mtk-cmdq.h  |  135 +++
>  4 files changed, 439 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
>  create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h
> 
> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> index a7d0667..17bd759 100644
> --- a/drivers/soc/mediatek/Kconfig
> +++ b/drivers/soc/mediatek/Kconfig
> @@ -4,6 +4,18 @@
>  menu "MediaTek SoC drivers"
>   depends on ARCH_MEDIATEK || COMPILE_TEST
>  
> +config MTK_CMDQ
> + tristate "MediaTek CMDQ Support"
> + depends on ARCH_MEDIATEK || COMPILE_TEST
> + select MAILBOX
> + select MTK_CMDQ_MBOX
> + select MTK_INFRACFG
> + help
> +   Say yes here to add support for the MediaTek Command Queue (CMDQ)
> +   driver. The CMDQ is used to help read/write registers with critical
> +   time limitation, such as updating display configuration during the
> +   vblank.
> +
>  config MTK_INFRACFG
>   bool "MediaTek INFRACFG Support"
>   select REGMAP
> diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> index 12998b0..64ce5ee 100644
> --- a/drivers/soc/mediatek/Makefile
> +++ b/drivers/soc/mediatek/Makefile
> @@ -1,3 +1,4 @@
> +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
>  obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
>  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
>  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> b/drivers/soc/mediatek/mtk-cmdq-helper.c
> new file mode 100644
> index 000..e4dbb7e
> --- /dev/null
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -0,0 +1,291 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// Copyright (c) 2018 MediaTek Inc.
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define CMDQ_ARG_A_WRITE_MASK0x
> +#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)
> +
> +static void cmdq_client_timeout(struct timer_list *t)
> +{
> + struct cmdq_client *client = from_timer(client, t, timer);
> +
> + dev_err(client->client.dev, "cmdq timeout!\n");
> +}
> +
> +struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 
> timeout)
> +{
> + struct cmdq_client *client;
> +
> + client = kzalloc(sizeof(*client), GFP_KERNEL);
> + if (!client)
> + return (struct cmdq_client *)-ENOMEM;
> +
> + client->timeout_ms = timeout;
> + if (timeout != CMDQ_NO_TIMEOUT) {
> + spin_lock_init(>lock);
> + timer_setup(>timer, cmdq_client_timeout, 0);
> + }
> + client->pkt_cnt = 0;
> + client->client.dev = dev;
> + client->client.tx_block = false;
> + client->chan = mbox_request_channel(>client, index);
> +
> + if (IS_ERR(client->chan)) {
> + long err = 0;
> +
> + dev_err(dev, "failed to request channel\n");
> + err = PTR_ERR(client->chan);
> + kfree(client);
> +
> + return (struct cmdq_client *)err;
> + }
> +
> + return client;
> +}
> +EXPORT_SYMBOL(cmdq_mbox_create);
> +
> +void cmdq_mbox_destroy(struct cmdq_client *client)
> +{
> + if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
> + spin_lock(>lock);
> + del_timer_sync(>timer);
> + spin_unlock(>lock);
> + }
> + mbox_free_channel(client->chan);
> + kfree(client);
> +}
> +EXPORT_SYMBOL(cmdq_mbox_destroy);
> +
> +int cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt **pkt_ptr,
> + size_t size)
> +{
> + struct cmdq_pkt *pkt;
> + struct device *dev;
> + dma_addr_t dma_addr;
> +
> + pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
> + if (!pkt)
> + return -ENOMEM;
> + pkt->va_base = kzalloc(size, GFP_KERNEL);
> + if (!pkt->va_base) {
> + kfree(pkt);
> + return -ENOMEM;
> + }
> + pkt-&g

Re: [PATCH v23 3/4] arm64: dts: mt8173: Add GCE node

2018-08-14 Thread houlong wei
On Wed, 2018-07-25 at 09:26 +0800, Houlong Wei wrote:
> This patch adds the device node of the GCE hardware for CMDQ module.
> 
> Signed-off-by: Houlong Wei 
> Signed-off-by: HS Liao 
> ---
>  arch/arm64/boot/dts/mediatek/mt8173.dtsi |   10 ++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi 
> b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
> index 94597e3..97b1ec6 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
> @@ -18,6 +18,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include "mt8173-pinfunc.h"
>  
>  / {
> @@ -519,6 +520,15 @@
>   status = "disabled";
>   };
>  
> + gce: mailbox@10212000 {
> + compatible = "mediatek,mt8173-gce";
> + reg = <0 0x10212000 0 0x1000>;
> + interrupts = ;
> + clocks = < CLK_INFRA_GCE>;
> + clock-names = "gce";
> + #mbox-cells = <3>;
> + };
> +
>   mipi_tx0: mipi-dphy@10215000 {
>   compatible = "mediatek,mt8173-mipi-tx";
>   reg = <0 0x10215000 0 0x1000>;

Hi Matthias,
  Could you please review this patch when you are available? Thanks a
lot.



MediaTek MT8173 CMDQ support

2018-09-29 Thread Houlong Wei
Hi,

This is Mediatek MT8173 Command Queue(CMDQ) driver. The CMDQ is used
to help write registers with critical time limitation, such as
updating display configuration during the vblank. It controls Global
Command Engine (GCE) hardware to achieve this requirement.

Changes since v24:
 -move WARN_ON() into cmdq_pkt_append_command() from outside
Changes since v23:
 -rebase on v4.19-rc1
 -revise return value of cmdq_mbox_create()
 -revise cmdq_pkt_create()
 -add MODULE_LICENSE() for mtk-cmdq-helper.c
 -adjust functions order in mtk-cmdq.h
Changes since v22:
 -remove properties 'timeout' and 'thread-num' from device tree
 -move timer from CMDQ driver to CMDQ helper
 -move dma unmap from CMDQ driver to CMDQ helper
 -config thread number in CMDQ match table
 -remove reallocate mechanism and let client specify the cmdq buffer size
 -let client specify the timeout time
Changes since v21:
 -rebase on v4.18-rc1
 -remove subsys code and event id definition from mtk-cmdq-helper.c
 -add mt8173-gce.h to define the subsys code and envent id
Changes since v20:
 -rebase on v4.15-rc1
 -move dma_map_single outside of spinlock
Changes since v19:
 -rebase to v4.10-rc2

Houlong Wei (2):
  arm64: dts: mt8173: Add GCE node
  soc: mediatek: Add Mediatek CMDQ helper

 arch/arm64/boot/dts/mediatek/mt8173.dtsi |   10 +
 drivers/soc/mediatek/Kconfig |   12 ++
 drivers/soc/mediatek/Makefile|1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c   |  291 ++
 include/linux/soc/mediatek/mtk-cmdq.h|  133 ++
 5 files changed, 447 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
 create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

-- 
1.7.9.5


[PATCH v25 1/2] arm64: dts: mt8173: Add GCE node

2018-09-29 Thread Houlong Wei
This patch adds the device node of the GCE hardware for CMDQ module.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi |   10 ++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index abd2f15..412ffd4 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "mt8173-pinfunc.h"
 
 / {
@@ -521,6 +522,15 @@
status = "disabled";
};
 
+   gce: mailbox@10212000 {
+   compatible = "mediatek,mt8173-gce";
+   reg = <0 0x10212000 0 0x1000>;
+   interrupts = ;
+   clocks = < CLK_INFRA_GCE>;
+   clock-names = "gce";
+   #mbox-cells = <3>;
+   };
+
mipi_tx0: mipi-dphy@10215000 {
compatible = "mediatek,mt8173-mipi-tx";
reg = <0 0x10215000 0 0x1000>;
-- 
1.7.9.5



[PATCH v25 2/2] soc: mediatek: Add Mediatek CMDQ helper

2018-09-29 Thread Houlong Wei
Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 drivers/soc/mediatek/Kconfig   |   12 ++
 drivers/soc/mediatek/Makefile  |1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c |  291 
 include/linux/soc/mediatek/mtk-cmdq.h  |  133 +++
 4 files changed, 437 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
 create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index a7d0667..17bd759 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -4,6 +4,18 @@
 menu "MediaTek SoC drivers"
depends on ARCH_MEDIATEK || COMPILE_TEST
 
+config MTK_CMDQ
+   tristate "MediaTek CMDQ Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select MAILBOX
+   select MTK_CMDQ_MBOX
+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
 config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
select REGMAP
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..64ce5ee 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
 obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
 obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
new file mode 100644
index 000..86a7ab5
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -0,0 +1,291 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018 MediaTek Inc.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_ARG_A_WRITE_MASK  0x
+#define CMDQ_WRITE_ENABLE_MASK BIT(0)
+#define CMDQ_EOC_IRQ_ENBIT(0)
+#define CMDQ_EOC_CMD   ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
+   << 32 | CMDQ_EOC_IRQ_EN)
+
+static void cmdq_client_timeout(struct timer_list *t)
+{
+   struct cmdq_client *client = from_timer(client, t, timer);
+
+   dev_err(client->client.dev, "cmdq timeout!\n");
+}
+
+struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 
timeout)
+{
+   struct cmdq_client *client;
+
+   client = kzalloc(sizeof(*client), GFP_KERNEL);
+   if (!client)
+   return (struct cmdq_client *)-ENOMEM;
+
+   client->timeout_ms = timeout;
+   if (timeout != CMDQ_NO_TIMEOUT) {
+   spin_lock_init(>lock);
+   timer_setup(>timer, cmdq_client_timeout, 0);
+   }
+   client->pkt_cnt = 0;
+   client->client.dev = dev;
+   client->client.tx_block = false;
+   client->chan = mbox_request_channel(>client, index);
+
+   if (IS_ERR(client->chan)) {
+   long err;
+
+   dev_err(dev, "failed to request channel\n");
+   err = PTR_ERR(client->chan);
+   kfree(client);
+
+   return ERR_PTR(err);
+   }
+
+   return client;
+}
+EXPORT_SYMBOL(cmdq_mbox_create);
+
+void cmdq_mbox_destroy(struct cmdq_client *client)
+{
+   if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
+   spin_lock(>lock);
+   del_timer_sync(>timer);
+   spin_unlock(>lock);
+   }
+   mbox_free_channel(client->chan);
+   kfree(client);
+}
+EXPORT_SYMBOL(cmdq_mbox_destroy);
+
+struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
+{
+   struct cmdq_pkt *pkt;
+   struct device *dev;
+   dma_addr_t dma_addr;
+
+   pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
+   if (!pkt)
+   return ERR_PTR(-ENOMEM);
+   pkt->va_base = kzalloc(size, GFP_KERNEL);
+   if (!pkt->va_base) {
+   kfree(pkt);
+   return ERR_PTR(-ENOMEM);
+   }
+   pkt->buf_size = size;
+   pkt->cl = (void *)client;
+
+   dev = client->chan->mbox->dev;
+   dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
+ DMA_TO_DEVICE);
+   if (dma_mapping_error(dev, dma_addr)) {
+   dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
+   kfree(pkt->va_base);
+   kfree(pkt);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   pkt->pa_base = dma_addr;
+
+   return pkt;
+}
+EXPORT_SYMBOL(cmdq_pkt_create);
+
+void cmdq_pkt_destroy(struct cmdq_pkt *pk

Re: [PATCH] arm64: dts: add gce node for mt8183

2019-03-06 Thread houlong wei
On Thu, 2019-03-07 at 09:24 +0800, CK Hu wrote:
> Hi, Bibby:
> 
> On Wed, 2019-03-06 at 18:10 +0800, Bibby Hsieh wrote: 
> > This patch need based on v5.0-rc1 and these series
> > http://lists.infradead.org/pipermail/linux-mediatek/2019-February/017570.html
> > http://lists.infradead.org/pipermail/linux-mediatek/2019-February/017320.html
> > http://lists.infradead.org/pipermail/linux-mediatek/2019-January/017196.html
> > http://lists.infradead.org/pipermail/linux-mediatek/2019-March/018005.html
> > 
> > add gce device node for mt8183
> > 
> > Signed-off-by: Bibby Hsieh 
> > ---
> >  arch/arm64/boot/dts/mediatek/mt8183.dtsi | 13 +
> >  1 file changed, 13 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi 
> > b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> > index 165b859..5006368 100644
> > --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> > +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> > @@ -8,6 +8,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include "mt8183-pinfunc.h"
> >  
> >  / {
> > @@ -238,6 +239,18 @@
> > clock-names = "spi", "wrap";
> > };
> >  
> > +   gce: gce@10238000 {
> > +   compatible = "mediatek,mt8183-gce";
> > +   reg = <0 0x10238000 0 0x4000>;
> > +   interrupts = ;
> > +   thread-num = ;
> 
> I does not find 'thread-num' in binding document [1].
> 
> [1]
> https://www.kernel.org/doc/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
> 
> Regards,
> CK

The property "thread-num" is not used and and it was removed from the
properties description, but I forgot to remove it from the example. That
is misleading and I'm sorry for that. @Bibby, could you please help
remove it from the example in mtk-gce.txt if you would upload a new
version?
> 
> > +   #mbox-cells = <3>;
> > +   #gce-event-cells = <1>;
> > +   #gce-subsys-cells = <2>;
> > +   clocks = < CLK_INFRA_GCE>;
> > +   clock-names = "gce";
> > +   };
> > +
> > uart0: serial@11002000 {
> > compatible = "mediatek,mt8183-uart",
> >  "mediatek,mt6577-uart";
> 




Re: [PATCH v23 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-09-09 Thread houlong wei
On Wed, 2018-08-15 at 09:46 +0800, houlong wei wrote:
> On Wed, 2018-07-25 at 09:26 +0800, Houlong Wei wrote:
> > Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.
> >[...]

Hello Matthias,
   Sorry to disturb you. Could you please review this patch and give
your comment? Thanks a lot.

Regards
Houlong



Re: [PATCH v23 3/4] arm64: dts: mt8173: Add GCE node

2018-09-09 Thread houlong wei
On Wed, 2018-08-15 at 09:48 +0800, houlong wei wrote:
> On Wed, 2018-07-25 at 09:26 +0800, Houlong Wei wrote:
> > This patch adds the device node of the GCE hardware for CMDQ module.
> > [...]

Hello Matthias,
   Sorry to disturb you. Are you availabe to review this patch and give
your comment? Thanks a lot.

Regards
Houlong




[PATCH v23 0/4] MediaTek MT8173 CMDQ support

2018-07-24 Thread Houlong Wei
Hi,

This is Mediatek MT8173 Command Queue(CMDQ) driver. The CMDQ is used
to help write registers with critical time limitation, such as
updating display configuration during the vblank. It controls Global
Command Engine (GCE) hardware to achieve this requirement.

Changes since v22:
 -remove properties 'timeout' and 'thread-num' from device tree
 -move timer from CMDQ driver to CMDQ helper
 -move dma unmap from CMDQ driver to CMDQ helper
 -config thread number in CMDQ match table
 -remove reallocate mechanism and let client specify the cmdq buffer size
 -let client specify the timeout time
Changes since v21:
 -rebase on v4.18-rc1
 -remove subsys code and event id definition from mtk-cmdq-helper.c
 -add mt8173-gce.h to define the subsys code and envent id
Changes since v20:
 -rebase on v4.15-rc1
 -move dma_map_single outside of spinlock
Changes since v19:
- rebase to v4.10-rc2

Houlong Wei (4):
  dt-bindings: soc: Add documentation for the MediaTek GCE unit
  mailbox: mediatek: Add Mediatek CMDQ driver
  arm64: dts: mt8173: Add GCE node
  soc: mediatek: Add Mediatek CMDQ helper

 .../devicetree/bindings/mailbox/mtk-gce.txt|  57 +++
 arch/arm64/boot/dts/mediatek/mt8173.dtsi   |  10 +
 drivers/mailbox/Kconfig|  10 +
 drivers/mailbox/Makefile   |   2 +
 drivers/mailbox/mtk-cmdq-mailbox.c | 569 +
 drivers/soc/mediatek/Kconfig   |  12 +
 drivers/soc/mediatek/Makefile  |   1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c | 291 +++
 include/dt-bindings/gce/mt8173-gce.h   |  44 ++
 include/linux/mailbox/mtk-cmdq-mailbox.h   |  77 +++
 include/linux/soc/mediatek/mtk-cmdq.h  | 135 +
 11 files changed, 1208 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk-gce.txt
 create mode 100644 drivers/mailbox/mtk-cmdq-mailbox.c
 create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
 create mode 100644 include/dt-bindings/gce/mt8173-gce.h
 create mode 100644 include/linux/mailbox/mtk-cmdq-mailbox.h
 create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

-- 
2.12.5
 



[PATCH v23 1/4] dt-bindings: soc: Add documentation for the MediaTek GCE unit

2018-07-24 Thread Houlong Wei
This adds documentation for the MediaTek Global Command Engine (GCE) unit
found in MT8173 SoCs.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 .../devicetree/bindings/mailbox/mtk-gce.txt|   57 
 include/dt-bindings/gce/mt8173-gce.h   |   44 +++
 2 files changed, 101 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk-gce.txt
 create mode 100644 include/dt-bindings/gce/mt8173-gce.h

diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt 
b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
new file mode 100644
index 000..7d72b21
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
@@ -0,0 +1,57 @@
+MediaTek GCE
+===
+
+The Global Command Engine (GCE) is used to help read/write registers with
+critical time limitation, such as updating display configuration during the
+vblank. The GCE can be used to implement the Command Queue (CMDQ) driver.
+
+CMDQ driver uses mailbox framework for communication. Please refer to
+mailbox.txt for generic information about mailbox device-tree bindings.
+
+Required properties:
+- compatible: Must be "mediatek,mt8173-gce"
+- reg: Address range of the GCE unit
+- interrupts: The interrupt signal from the GCE block
+- clock: Clocks according to the common clock binding
+- clock-names: Must be "gce" to stand for GCE clock
+- #mbox-cells: Should be 3.
+   < channel priority atomic_exec>
+   phandle: Label name of a gce node.
+   channel: Channel of mailbox. Be equal to the thread id of GCE.
+   priority: Priority of GCE thread.
+   atomic_exec: GCE processing continuous packets of commands in atomic
+   way.
+
+Required properties for a client device:
+- mboxes: Client use mailbox to communicate with GCE, it should have this
+  property and list of phandle, mailbox specifiers.
+- mediatek,gce-subsys: u32, specify the sub-system id which is corresponding
+  to the register address.
+
+Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h'. Such 
as
+sub-system ids, thread priority, event ids.
+
+Example:
+
+   gce: gce@10212000 {
+   compatible = "mediatek,mt8173-gce";
+   reg = <0 0x10212000 0 0x1000>;
+   interrupts = ;
+   clocks = < CLK_INFRA_GCE>;
+   clock-names = "gce";
+   thread-num = CMDQ_THR_MAX_COUNT;
+   #mbox-cells = <3>;
+   };
+
+Example for a client device:
+
+   mmsys: clock-controller@1400 {
+   compatible = "mediatek,mt8173-mmsys";
+   mboxes = < 0 CMDQ_THR_PRIO_LOWEST 1>,
+< 1 CMDQ_THR_PRIO_LOWEST 1>;
+   mediatek,gce-subsys = ;
+   mutex-event-eof = ;
+
+   ...
+   };
diff --git a/include/dt-bindings/gce/mt8173-gce.h 
b/include/dt-bindings/gce/mt8173-gce.h
new file mode 100644
index 000..ffcf94b
--- /dev/null
+++ b/include/dt-bindings/gce/mt8173-gce.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Houlong Wei 
+ *
+ */
+
+#ifndef _DT_BINDINGS_GCE_MT8173_H
+#define _DT_BINDINGS_GCE_MT8173_H
+
+/* GCE HW thread priority */
+#define CMDQ_THR_PRIO_LOWEST   0
+#define CMDQ_THR_PRIO_HIGHEST  1
+
+/* GCE SUBSYS */
+#define SUBSYS_14001
+#define SUBSYS_14012
+#define SUBSYS_14023
+
+/* GCE HW EVENT */
+#define CMDQ_EVENT_DISP_OVL0_SOF   11
+#define CMDQ_EVENT_DISP_OVL1_SOF   12
+#define CMDQ_EVENT_DISP_RDMA0_SOF  13
+#define CMDQ_EVENT_DISP_RDMA1_SOF  14
+#define CMDQ_EVENT_DISP_RDMA2_SOF  15
+#define CMDQ_EVENT_DISP_WDMA0_SOF  16
+#define CMDQ_EVENT_DISP_WDMA1_SOF  17
+#define CMDQ_EVENT_DISP_OVL0_EOF   39
+#define CMDQ_EVENT_DISP_OVL1_EOF   40
+#define CMDQ_EVENT_DISP_RDMA0_EOF  41
+#define CMDQ_EVENT_DISP_RDMA1_EOF  42
+#define CMDQ_EVENT_DISP_RDMA2_EOF  43
+#define CMDQ_EVENT_DISP_WDMA0_EOF  44
+#define CMDQ_EVENT_DISP_WDMA1_EOF  45
+#define CMDQ_EVENT_MUTEX0_STREAM_EOF   53
+#define CMDQ_EVENT_MUTEX1_STREAM_EOF   54
+#define CMDQ_EVENT_MUTEX2_STREAM_EOF   55
+#define CMDQ_EVENT_MUTEX3_STREAM_EOF   56
+#define CMDQ_EVENT_MUTEX4_STREAM_EOF   57
+#define CMDQ_EVENT_DISP_RDMA0_UNDERRUN 63
+#define CMDQ_EVENT_DISP_RDMA1_UNDERRUN 64
+#define CMDQ_EVENT_DISP_RDMA2_UNDERRUN 65
+
+#endif
-- 
1.7.9.5



[PATCH v23 3/4] arm64: dts: mt8173: Add GCE node

2018-07-24 Thread Houlong Wei
This patch adds the device node of the GCE hardware for CMDQ module.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi |   10 ++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 94597e3..97b1ec6 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "mt8173-pinfunc.h"
 
 / {
@@ -519,6 +520,15 @@
status = "disabled";
};
 
+   gce: mailbox@10212000 {
+   compatible = "mediatek,mt8173-gce";
+   reg = <0 0x10212000 0 0x1000>;
+   interrupts = ;
+   clocks = < CLK_INFRA_GCE>;
+   clock-names = "gce";
+   #mbox-cells = <3>;
+   };
+
mipi_tx0: mipi-dphy@10215000 {
compatible = "mediatek,mt8173-mipi-tx";
reg = <0 0x10215000 0 0x1000>;
-- 
1.7.9.5



[PATCH v23 2/4] mailbox: mediatek: Add Mediatek CMDQ driver

2018-07-24 Thread Houlong Wei
This patch is first version of Mediatek Command Queue(CMDQ) driver. The
CMDQ is used to help write registers with critical time limitation,
such as updating display configuration during the vblank. It controls
Global Command Engine (GCE) hardware to achieve this requirement.
Currently, CMDQ only supports display related hardwares, but we expect
it can be extended to other hardwares for future requirements.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
Signed-off-by: CK Hu 
---
 drivers/mailbox/Kconfig  |   10 +
 drivers/mailbox/Makefile |2 +
 drivers/mailbox/mtk-cmdq-mailbox.c   |  569 ++
 include/linux/mailbox/mtk-cmdq-mailbox.h |   77 
 4 files changed, 658 insertions(+)
 create mode 100644 drivers/mailbox/mtk-cmdq-mailbox.c
 create mode 100644 include/linux/mailbox/mtk-cmdq-mailbox.h

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index e63d29a..2bbabc9 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -189,4 +189,14 @@ config STM32_IPCC
  Mailbox implementation for STMicroelectonics STM32 family chips
  with hardware for Inter-Processor Communication Controller (IPCC)
  between processors. Say Y here if you want to have this support.
+
+config MTK_CMDQ_MBOX
+   tristate "MediaTek CMDQ Mailbox Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ mailbox driver. The CMDQ is used to help read/write registers with
+ critical time limitation, such as updating display configuration
+ during the vblank.
 endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 4d501be..4b00804 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -40,3 +40,5 @@ obj-$(CONFIG_QCOM_APCS_IPC)   += qcom-apcs-ipc-mailbox.o
 obj-$(CONFIG_TEGRA_HSP_MBOX)   += tegra-hsp.o
 
 obj-$(CONFIG_STM32_IPCC)   += stm32-ipcc.o
+
+obj-$(CONFIG_MTK_CMDQ_MBOX)+= mtk-cmdq-mailbox.o
diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
b/drivers/mailbox/mtk-cmdq-mailbox.c
new file mode 100644
index 000..6f92c5e
--- /dev/null
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -0,0 +1,569 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018 MediaTek Inc.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_OP_CODE_MASK  (0xff << CMDQ_OP_CODE_SHIFT)
+#define CMDQ_IRQ_MASK  0x
+#define CMDQ_NUM_CMD(t)(t->cmd_buf_size / 
CMDQ_INST_SIZE)
+
+#define CMDQ_CURR_IRQ_STATUS   0x10
+#define CMDQ_THR_SLOT_CYCLES   0x30
+#define CMDQ_THR_BASE  0x100
+#define CMDQ_THR_SIZE  0x80
+#define CMDQ_THR_WARM_RESET0x00
+#define CMDQ_THR_ENABLE_TASK   0x04
+#define CMDQ_THR_SUSPEND_TASK  0x08
+#define CMDQ_THR_CURR_STATUS   0x0c
+#define CMDQ_THR_IRQ_STATUS0x10
+#define CMDQ_THR_IRQ_ENABLE0x14
+#define CMDQ_THR_CURR_ADDR 0x20
+#define CMDQ_THR_END_ADDR  0x24
+#define CMDQ_THR_WAIT_TOKEN0x30
+#define CMDQ_THR_PRIORITY  0x40
+
+#define CMDQ_THR_ACTIVE_SLOT_CYCLES0x3200
+#define CMDQ_THR_ENABLED   0x1
+#define CMDQ_THR_DISABLED  0x0
+#define CMDQ_THR_SUSPEND   0x1
+#define CMDQ_THR_RESUME0x0
+#define CMDQ_THR_STATUS_SUSPENDED  BIT(1)
+#define CMDQ_THR_DO_WARM_RESET BIT(0)
+#define CMDQ_THR_IRQ_DONE  0x1
+#define CMDQ_THR_IRQ_ERROR 0x12
+#define CMDQ_THR_IRQ_EN(CMDQ_THR_IRQ_ERROR | 
CMDQ_THR_IRQ_DONE)
+#define CMDQ_THR_IS_WAITINGBIT(31)
+
+#define CMDQ_JUMP_BY_OFFSET0x1000
+#define CMDQ_JUMP_BY_PA0x1001
+
+struct cmdq_thread {
+   struct mbox_chan*chan;
+   void __iomem*base;
+   struct list_headtask_busy_list;
+   u32 priority;
+   boolatomic_exec;
+};
+
+struct cmdq_task {
+   struct cmdq *cmdq;
+   struct list_headlist_entry;
+   dma_addr_t  pa_base;
+   struct cmdq_thread  *thread;
+   struct cmdq_pkt *pkt; /* the packet sent from mailbox client */
+};
+
+struct cmdq {
+   struct mbox_controller  mbox;
+   void __iomem*base;
+   u32 irq;
+   u32 thread_nr;
+   struct cmdq_thread  *thread;
+   struct clk  *clock;
+   boolsuspended;
+};
+
+static int cmdq_thread_suspend(struct cmdq *cmdq, struct cmdq_thread *thread)
+{
+   u32 status;
+
+   writel(CMDQ_

[PATCH v23 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-07-24 Thread Houlong Wei
Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.

Signed-off-by: Houlong Wei 
Signed-off-by: HS Liao 
---
 drivers/soc/mediatek/Kconfig   |   12 ++
 drivers/soc/mediatek/Makefile  |1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c |  291 
 include/linux/soc/mediatek/mtk-cmdq.h  |  135 +++
 4 files changed, 439 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
 create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index a7d0667..17bd759 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -4,6 +4,18 @@
 menu "MediaTek SoC drivers"
depends on ARCH_MEDIATEK || COMPILE_TEST
 
+config MTK_CMDQ
+   tristate "MediaTek CMDQ Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select MAILBOX
+   select MTK_CMDQ_MBOX
+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
 config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
select REGMAP
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..64ce5ee 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
 obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
 obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
new file mode 100644
index 000..e4dbb7e
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -0,0 +1,291 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018 MediaTek Inc.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_ARG_A_WRITE_MASK  0x
+#define CMDQ_WRITE_ENABLE_MASK BIT(0)
+#define CMDQ_EOC_IRQ_ENBIT(0)
+#define CMDQ_EOC_CMD   ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
+   << 32 | CMDQ_EOC_IRQ_EN)
+
+static void cmdq_client_timeout(struct timer_list *t)
+{
+   struct cmdq_client *client = from_timer(client, t, timer);
+
+   dev_err(client->client.dev, "cmdq timeout!\n");
+}
+
+struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 
timeout)
+{
+   struct cmdq_client *client;
+
+   client = kzalloc(sizeof(*client), GFP_KERNEL);
+   if (!client)
+   return (struct cmdq_client *)-ENOMEM;
+
+   client->timeout_ms = timeout;
+   if (timeout != CMDQ_NO_TIMEOUT) {
+   spin_lock_init(>lock);
+   timer_setup(>timer, cmdq_client_timeout, 0);
+   }
+   client->pkt_cnt = 0;
+   client->client.dev = dev;
+   client->client.tx_block = false;
+   client->chan = mbox_request_channel(>client, index);
+
+   if (IS_ERR(client->chan)) {
+   long err = 0;
+
+   dev_err(dev, "failed to request channel\n");
+   err = PTR_ERR(client->chan);
+   kfree(client);
+
+   return (struct cmdq_client *)err;
+   }
+
+   return client;
+}
+EXPORT_SYMBOL(cmdq_mbox_create);
+
+void cmdq_mbox_destroy(struct cmdq_client *client)
+{
+   if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
+   spin_lock(>lock);
+   del_timer_sync(>timer);
+   spin_unlock(>lock);
+   }
+   mbox_free_channel(client->chan);
+   kfree(client);
+}
+EXPORT_SYMBOL(cmdq_mbox_destroy);
+
+int cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt **pkt_ptr,
+   size_t size)
+{
+   struct cmdq_pkt *pkt;
+   struct device *dev;
+   dma_addr_t dma_addr;
+
+   pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
+   if (!pkt)
+   return -ENOMEM;
+   pkt->va_base = kzalloc(size, GFP_KERNEL);
+   if (!pkt->va_base) {
+   kfree(pkt);
+   return -ENOMEM;
+   }
+   pkt->buf_size = size;
+   pkt->cl = (void *)client;
+
+   dev = client->chan->mbox->dev;
+   dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
+   DMA_TO_DEVICE);
+   if (dma_mapping_error(dev, dma_addr)) {
+   dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
+   kfree(pkt->va_base);
+   kfree(pkt);
+   return -ENOMEM;
+   }
+
+   pkt->pa_base = dma_addr;
+   *pkt_ptr = pkt;
+
+   return 0;
+}
+EXPORT_SYMBOL(cmdq_pkt_create);
+
+void cmdq_pkt_destroy(struct cmdq_pkt *pk

Re: [PATCH v22 1/4] dt-bindings: soc: Add documentation for the MediaTek GCE unit

2018-07-03 Thread houlong wei
On Tue, 2018-07-03 at 10:30 +0800, Rob Herring wrote:
> On Wed, Jun 27, 2018 at 07:16:09PM +0800, Houlong Wei wrote:
> > This adds documentation for the MediaTek Global Command Engine (GCE) unit
> > found in MT8173 SoCs.
> > 
> > Signed-off-by: Houlong Wei 
> > Signed-off-by: HS Liao 
> > ---
> > Hi Rob,
> >   I don't add your ACK in this version since the dt-binding description
> > has been changed. Thanks.
> > ---
> >  .../devicetree/bindings/mailbox/mtk-gce.txt|   65 
> > 
> >  include/dt-bindings/gce/mt8173-gce.h   |   48 +++
> >  2 files changed, 113 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/mailbox/mtk-gce.txt
> >  create mode 100644 include/dt-bindings/gce/mt8173-gce.h
> > 
> > diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt 
> > b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
> > new file mode 100644
> > index 000..26f65a4
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
> > @@ -0,0 +1,65 @@
> > +MediaTek GCE
> > +===
> > +
> > +The Global Command Engine (GCE) is used to help read/write registers with
> > +critical time limitation, such as updating display configuration during the
> > +vblank. The GCE can be used to implement the Command Queue (CMDQ) driver.
> > +
> > +CMDQ driver uses mailbox framework for communication. Please refer to
> > +mailbox.txt for generic information about mailbox device-tree bindings.
> > +
> > +Required properties:
> > +- compatible: Must be "mediatek,mt8173-gce"
> > +- reg: Address range of the GCE unit
> > +- interrupts: The interrupt signal from the GCE block
> > +- clock: Clocks according to the common clock binding
> > +- clock-names: Must be "gce" to stand for GCE clock
> > +- thread-num: Maximum threads count of GCE.
> 
> mediatek,thread-num
> 
> Is this needed for anything other than error checking the thread id in 
> the mbox cells? if that's it, then drop it. 
> 

'thread-num' is used to configure the GCE thread number, which is the
channel number of gce mailbox. This property is read in
cmdq_probe()/mtk-cmdq-mailbox.c and a mailbox's channel array is
allocated according to the number.
Since the thread number may be different on different SoC, we wish it
could be configured in device tree.

> > +- #mbox-cells: Should be 4.
> > +   < channel timeout priority atomic_exec>
> > +   phandle: Label name of a gce node.
> > +   channel: Channel of mailbox. Be equal to the thread id of GCE.
> > +   timeout: Maximum time of software waiting GCE processing done, in unit
> > +   of millisecond.
> > +   priority: Priority of GCE thread.
> > +   atomic_exec: GCE processing continuous packets of commands in atomic
> > +   way.
> > +
> > +Required properties for a client device:
> > +- mboxes: Client use mailbox to communicate with GCE, it should have this
> > +  property and list of phandle, mailbox specifiers.
> > +- gce-subsys: Specify the sub-system id which is corresponding to the 
> > register
> > +  address.
> 
> What is this for?

You mean the new added property 'gce-subsys'?  
It is used for GCE to distinguish the high 16-bit of a hardware register
address. When a client driver packets a register setting into a GCE
instruction, it uses a sub-system code and register offset instead of
the 32-bit register address.
Since sub-system code may be different on different SoC, we wish it
could be configured in device tree.

> 
> > +
> > +Optional properties for a client device:
> > +- gce-event: Specify the event if the client has any. Because the event is
> > +  parsed by client, so client can replace 'gce-event' with other meaningful
> > +  name.
> 
> If the client sets the name, then no point having here. It must be 
> documented in the client binding. But then, what is this for in the 
> first place?

Since display driver will use GCE firstly, so we will move the
description to
'Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt'
when display driver start using the GCE driver.
Is that ok?

> 
> > +
> > +Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h'. 
> > Such as
> > +thread number, sub-system ids, thread priority, event ids.
> > +
> > +Example:
> > +
> > +   gce: gce@10212000 {
> 
> mailbox@...

Will do.

> 
> > +   compatible = "mediatek,mt8173-gce";
> > +   reg = <0 0x10212000 0 0x1000>;
&

Re: [PATCH v22 2/4] mailbox: mediatek: Add Mediatek CMDQ driver

2018-07-03 Thread houlong wei
On Fri, 2018-06-29 at 15:08 +0800, CK Hu wrote:
> Hi, Houlong:
> 
> Some inline comment.
> 
> On Wed, 2018-06-27 at 19:16 +0800, Houlong Wei wrote:
> > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > CMDQ is used to help write registers with critical time limitation,
> > such as updating display configuration during the vblank. It controls
> > Global Command Engine (GCE) hardware to achieve this requirement.
> > Currently, CMDQ only supports display related hardwares, but we expect
> > it can be extended to other hardwares for future requirements.
> > 
> > Signed-off-by: Houlong Wei 
> > Signed-off-by: HS Liao 
> > Signed-off-by: CK Hu 
> > ---
> >  drivers/mailbox/Kconfig  |   10 +
> >  drivers/mailbox/Makefile |2 +
> >  drivers/mailbox/mtk-cmdq-mailbox.c   |  634 
> > ++
> >  include/linux/mailbox/mtk-cmdq-mailbox.h |   70 
> >  4 files changed, 716 insertions(+)
> >  create mode 100644 drivers/mailbox/mtk-cmdq-mailbox.c
> >  create mode 100644 include/linux/mailbox/mtk-cmdq-mailbox.h
> > 
> 
> [...]
> 
> > +
> > +static int cmdq_thread_reset(struct cmdq *cmdq, struct cmdq_thread *thread)
> > +{
> > +   u32 warm_reset;
> > +
> > +   writel(CMDQ_THR_DO_WARM_RESET, thread->base + CMDQ_THR_WARM_RESET);
> > +   if (readl_poll_timeout_atomic(thread->base + CMDQ_THR_WARM_RESET,
> > +   warm_reset, !(warm_reset & CMDQ_THR_DO_WARM_RESET),
> > +   0, 10)) {
> > +   dev_err(cmdq->mbox.dev, "reset GCE thread 0x%x failed\n",
> > +   (u32)(thread->base - cmdq->base));
> > +   return -EFAULT;
> > +   }
> > +   writel(CMDQ_THR_ACTIVE_SLOT_CYCLES, cmdq->base + CMDQ_THR_SLOT_CYCLES);
> 
> The CMDQ_THR_SLOT_CYCLES looks like not relevant to reset. Maybe you
> just need to set this value when startup.

Will move configuration of CMDQ_THR_SLOT_CYCLES to cmdq_xlate() where is
startup of a GCE thread.

> 
> > +
> > +   return 0;
> > +}
> > +
> 
> [...]
> 
> > +
> > +static void cmdq_task_exec(struct cmdq_pkt *pkt, struct cmdq_thread 
> > *thread)
> > +{
> > +   struct cmdq *cmdq;
> > +   struct cmdq_task *task;
> > +   unsigned long curr_pa, end_pa;
> > +
> > +   cmdq = dev_get_drvdata(thread->chan->mbox->dev);
> > +
> > +   /* Client should not flush new tasks if suspended. */
> > +   WARN_ON(cmdq->suspended);
> > +
> > +   task = kzalloc(sizeof(*task), GFP_ATOMIC);
> > +   task->cmdq = cmdq;
> > +   INIT_LIST_HEAD(>list_entry);
> > +   task->pa_base = pkt->pa_base;
> > +   task->thread = thread;
> > +   task->pkt = pkt;
> > +
> > +   if (list_empty(>task_busy_list)) {
> > +   WARN_ON(clk_enable(cmdq->clock) < 0);
> > +   WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
> > +
> > +   writel(task->pa_base, thread->base + CMDQ_THR_CURR_ADDR);
> > +   writel(task->pa_base + pkt->cmd_buf_size,
> > +  thread->base + CMDQ_THR_END_ADDR);
> > +   writel(thread->priority, thread->base + CMDQ_THR_PRIORITY);
> > +   writel(CMDQ_THR_IRQ_EN, thread->base + CMDQ_THR_IRQ_ENABLE);
> > +   writel(CMDQ_THR_ENABLED, thread->base + CMDQ_THR_ENABLE_TASK);
> > +
> > +   if (thread->timeout_ms != CMDQ_NO_TIMEOUT)
> > +   mod_timer(>timeout,
> > +   jiffies + msecs_to_jiffies(thread->timeout_ms));
> 
> I think the timeout processing should be done by client driver. The
> total time to execute a command buffer does not depend on GCE HW speed
> because the WFE (wait for event) command would wait for client HW event,
> so the total time depend on how long a client HW send this event to GCE
> and the timeout processing should be client driver's job. Each client
> may have different timeout processing mechanism, for example, if display
> could dynamic change panel frame rate between 120Hz and 60Hz, and the
> timeout time is 2 frame, so it may dynamically change timeout time
> between 17ms and 33ms. Another reason is that display have interrupt
> every vblank, and it could check timeout in that interrupt, so the timer
> in cmdq driver looks redundant. Because each client would define its own
> timeout processing mechanism, so it's not wise to put timeout processing
> in cmdq driver.

The client drivers' owners strongly hope to keep th

Re: [PATCH v22 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-07-03 Thread houlong wei
On Fri, 2018-06-29 at 17:22 +0800, CK Hu wrote:
> Hi, Houlong:
> 
> On Fri, 2018-06-29 at 07:32 +0800, houlong wei wrote:
> > On Thu, 2018-06-28 at 18:41 +0800, CK Hu wrote:
> > > Hi, Houlong:
> > > 
> > > Some inline comment.
> > > 
> > > On Wed, 2018-06-27 at 19:16 +0800, Houlong Wei wrote:
> > > > Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.
> > > > 
> > > > Signed-off-by: Houlong Wei 
> > > > Signed-off-by: HS Liao 
> > > > ---
> > > >  drivers/soc/mediatek/Kconfig   |   12 ++
> > > >  drivers/soc/mediatek/Makefile  |1 +
> > > >  drivers/soc/mediatek/mtk-cmdq-helper.c |  258 
> > > > 
> > > >  include/linux/soc/mediatek/mtk-cmdq.h  |  132 
> > > >  4 files changed, 403 insertions(+)
> > > >  create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
> > > >  create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h
> > > > 
> > > > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > > > index a7d0667..17bd759 100644
> > > > --- a/drivers/soc/mediatek/Kconfig
> > > > +++ b/drivers/soc/mediatek/Kconfig
> > > > @@ -4,6 +4,18 @@
> > > >  menu "MediaTek SoC drivers"
> > > > depends on ARCH_MEDIATEK || COMPILE_TEST
> > > >  
> > > 
> 
> [...]
> 
> > > > +
> > > > +static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
> > > > +{
> > > > +   int err;
> > > > +
> > > > +   if (cmdq_pkt_is_finalized(pkt))
> > > > +   return 0;
> > > > +
> > > > +   /* insert EOC and generate IRQ for each command iteration */
> > > > +   err = cmdq_pkt_append_command(pkt, CMDQ_CODE_EOC, 0, 
> > > > CMDQ_EOC_IRQ_EN);
> > > > +   if (err < 0)
> > > > +   return err;
> > > > +
> > > > +   /* JUMP to end */
> > > > +   err = cmdq_pkt_append_command(pkt, CMDQ_CODE_JUMP, 0, 
> > > > CMDQ_JUMP_PASS);
> > > > +   if (err < 0)
> > > > +   return err;
> > > > +
> > > > +   return 0;
> > > > +}
> > > > +
> > > > +int cmdq_pkt_flush_async(struct cmdq_client *client, struct cmdq_pkt 
> > > > *pkt,
> > > > +cmdq_async_flush_cb cb, void *data)
> > > > +{
> > > > +   int err;
> > > > +   struct device *dev;
> > > > +   dma_addr_t dma_addr;
> > > > +
> > > > +   err = cmdq_pkt_finalize(pkt);
> > > > +   if (err < 0)
> > > > +   return err;
> > > > +
> > > > +   dev = client->chan->mbox->dev;
> > > > +   dma_addr = dma_map_single(dev, pkt->va_base, pkt->cmd_buf_size,
> > > > +   DMA_TO_DEVICE);
> > > 
> > > You map here, but I could not find unmap, so the unmap should be done in
> > > client driver. I would prefer a symmetric map/unmap which means that
> > > both map and unmap are done in client driver. I think you put map here
> > > because you should map after finalize. 
> > 
> > The unmap is done before callback to client, in function
> > cmdq_task_exec_done, mtk-cmdq-mailbox.c.
> 
> You put unmap in mailbox controller, and map here (here would be mailbox
> client), so this is not symmetric. If the code is asymmetric, it's easy
> to cause bug and not easy to maintain. So I would like move both
> map/unmap to client driver.
> 

Since map/unmap is common code for client drivers, can we move unmap to
CMDQ helper and do not put in client driver?

> > 
> > > Therefore, export
> > > cmdq_pkt_finalize() to client driver and let client do finalize, so
> > > there is no finalize in flush function. This method have a benefit that
> > > if client reuse command buffer, it need not to map/unmap frequently.
> > 
> > If client reuse command buffer or cmdq_pkt(command queue packet), client
> > will add new commands to the cmdq_pkt, so map/unmap are necessary for
> > each cmdq_pkt flush.
> 
> If the buffer size is 4K bytes, client driver could map the whole 4K at
> initialization. Before it write new command, it call
> dma_sync_single_for_cpu(), after it write new command, it call
> dma_sync_single_for_dev

Re: [PATCH v22 4/4] soc: mediatek: Add Mediatek CMDQ helper

2018-07-05 Thread houlong wei
On Wed, 2018-07-04 at 10:39 +0800, CK Hu wrote:
> Hi, Houlong:
> 
> On Wed, 2018-07-04 at 08:47 +0800, houlong wei wrote:
> > On Fri, 2018-06-29 at 17:22 +0800, CK Hu wrote:
> > > Hi, Houlong:
> > > 
> > > On Fri, 2018-06-29 at 07:32 +0800, houlong wei wrote:
> > > > On Thu, 2018-06-28 at 18:41 +0800, CK Hu wrote:
> > > > > Hi, Houlong:
> > > > > 
> > > > > Some inline comment.
> > > > > 
> > > > > On Wed, 2018-06-27 at 19:16 +0800, Houlong Wei wrote:
> > > > > > Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op 
> > > > > > code.
> > > > > > 
> > > > > > Signed-off-by: Houlong Wei 
> > > > > > Signed-off-by: HS Liao 
> > > > > > ---
> > > > > >  drivers/soc/mediatek/Kconfig   |   12 ++
> > > > > >  drivers/soc/mediatek/Makefile  |1 +
> > > > > >  drivers/soc/mediatek/mtk-cmdq-helper.c |  258 
> > > > > > 
> > > > > >  include/linux/soc/mediatek/mtk-cmdq.h  |  132 
> > > > > >  4 files changed, 403 insertions(+)
> > > > > >  create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
> > > > > >  create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h
> > > > > > 
> > > > > > diff --git a/drivers/soc/mediatek/Kconfig 
> > > > > > b/drivers/soc/mediatek/Kconfig
> > > > > > index a7d0667..17bd759 100644
> > > > > > --- a/drivers/soc/mediatek/Kconfig
> > > > > > +++ b/drivers/soc/mediatek/Kconfig
> > > > > > @@ -4,6 +4,18 @@
> > > > > >  menu "MediaTek SoC drivers"
> > > > > > depends on ARCH_MEDIATEK || COMPILE_TEST
> > > > > >  
> > > > > 
> > > 
> > > [...]
> > > 
> > > > > > +
> > > > > > +static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
> > > > > > +{
> > > > > > +   int err;
> > > > > > +
> > > > > > +   if (cmdq_pkt_is_finalized(pkt))
> > > > > > +   return 0;
> > > > > > +
> > > > > > +   /* insert EOC and generate IRQ for each command iteration */
> > > > > > +   err = cmdq_pkt_append_command(pkt, CMDQ_CODE_EOC, 0, 
> > > > > > CMDQ_EOC_IRQ_EN);
> > > > > > +   if (err < 0)
> > > > > > +   return err;
> > > > > > +
> > > > > > +   /* JUMP to end */
> > > > > > +   err = cmdq_pkt_append_command(pkt, CMDQ_CODE_JUMP, 0, 
> > > > > > CMDQ_JUMP_PASS);
> > > > > > +   if (err < 0)
> > > > > > +   return err;
> > > > > > +
> > > > > > +   return 0;
> > > > > > +}
> > > > > > +
> > > > > > +int cmdq_pkt_flush_async(struct cmdq_client *client, struct 
> > > > > > cmdq_pkt *pkt,
> > > > > > +cmdq_async_flush_cb cb, void *data)
> > > > > > +{
> > > > > > +   int err;
> > > > > > +   struct device *dev;
> > > > > > +   dma_addr_t dma_addr;
> > > > > > +
> > > > > > +   err = cmdq_pkt_finalize(pkt);
> > > > > > +   if (err < 0)
> > > > > > +   return err;
> > > > > > +
> > > > > > +   dev = client->chan->mbox->dev;
> > > > > > +   dma_addr = dma_map_single(dev, pkt->va_base, pkt->cmd_buf_size,
> > > > > > +   DMA_TO_DEVICE);
> > > > > 
> > > > > You map here, but I could not find unmap, so the unmap should be done 
> > > > > in
> > > > > client driver. I would prefer a symmetric map/unmap which means that
> > > > > both map and unmap are done in client driver. I think you put map here
> > > > > because you should map after finalize. 
> > > > 
> > > > The unmap is done before callback to client, in function
> > > > cmdq_task_exec_done, mtk-cmdq-mailbox.c.
> > > 
> > > You put unmap in mailbox controller, and map here (here would be mailbox
> > > client), so this is not symmetric. If the code is asymmetric, it's easy
>

Re: [PATCH v22 2/4] mailbox: mediatek: Add Mediatek CMDQ driver

2018-07-05 Thread houlong wei
On Wed, 2018-07-04 at 17:03 +0800, CK Hu wrote:
> Hi, Houlong:
> 
> On Wed, 2018-07-04 at 08:10 +0800, houlong wei wrote:
> > On Fri, 2018-06-29 at 15:08 +0800, CK Hu wrote:
> > > Hi, Houlong:
> > > 
> > > Some inline comment.
> > > 
> > > On Wed, 2018-06-27 at 19:16 +0800, Houlong Wei wrote:
> > > > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > > > CMDQ is used to help write registers with critical time limitation,
> > > > such as updating display configuration during the vblank. It controls
> > > > Global Command Engine (GCE) hardware to achieve this requirement.
> > > > Currently, CMDQ only supports display related hardwares, but we expect
> > > > it can be extended to other hardwares for future requirements.
> > > > 
> > > > Signed-off-by: Houlong Wei 
> > > > Signed-off-by: HS Liao 
> > > > Signed-off-by: CK Hu 
> > > > ---
> > > >  drivers/mailbox/Kconfig  |   10 +
> > > >  drivers/mailbox/Makefile |2 +
> > > >  drivers/mailbox/mtk-cmdq-mailbox.c   |  634 
> > > > ++
> > > >  include/linux/mailbox/mtk-cmdq-mailbox.h |   70 
> > > >  4 files changed, 716 insertions(+)
> > > >  create mode 100644 drivers/mailbox/mtk-cmdq-mailbox.c
> > > >  create mode 100644 include/linux/mailbox/mtk-cmdq-mailbox.h
> > > > 
> > > 
> > > [...]
> > > 
> > > > +
> > > > +static int cmdq_thread_reset(struct cmdq *cmdq, struct cmdq_thread 
> > > > *thread)
> > > > +{
> > > > +   u32 warm_reset;
> > > > +
> > > > +   writel(CMDQ_THR_DO_WARM_RESET, thread->base + 
> > > > CMDQ_THR_WARM_RESET);
> > > > +   if (readl_poll_timeout_atomic(thread->base + 
> > > > CMDQ_THR_WARM_RESET,
> > > > +   warm_reset, !(warm_reset & 
> > > > CMDQ_THR_DO_WARM_RESET),
> > > > +   0, 10)) {
> > > > +   dev_err(cmdq->mbox.dev, "reset GCE thread 0x%x 
> > > > failed\n",
> > > > +   (u32)(thread->base - cmdq->base));
> > > > +   return -EFAULT;
> > > > +   }
> > > > +   writel(CMDQ_THR_ACTIVE_SLOT_CYCLES, cmdq->base + 
> > > > CMDQ_THR_SLOT_CYCLES);
> > > 
> > > The CMDQ_THR_SLOT_CYCLES looks like not relevant to reset. Maybe you
> > > just need to set this value when startup.
> > 
> > Will move configuration of CMDQ_THR_SLOT_CYCLES to cmdq_xlate() where is
> > startup of a GCE thread.
> > 

Since cmdq_xlate() is called when a client requests a channel, it may be
called more than once. Will move it to cmdq_probe().

> > > 
> > > > +
> > > > +   return 0;
> > > > +}
> > > > +
> > > 
> > > [...]
> > > 
> > > > +
> > > > +static void cmdq_task_exec(struct cmdq_pkt *pkt, struct cmdq_thread 
> > > > *thread)
> > > > +{
> > > > +   struct cmdq *cmdq;
> > > > +   struct cmdq_task *task;
> > > > +   unsigned long curr_pa, end_pa;
> > > > +
> > > > +   cmdq = dev_get_drvdata(thread->chan->mbox->dev);
> > > > +
> > > > +   /* Client should not flush new tasks if suspended. */
> > > > +   WARN_ON(cmdq->suspended);
> > > > +
> > > > +   task = kzalloc(sizeof(*task), GFP_ATOMIC);
> > > > +   task->cmdq = cmdq;
> > > > +   INIT_LIST_HEAD(>list_entry);
> > > > +   task->pa_base = pkt->pa_base;
> > > > +   task->thread = thread;
> > > > +   task->pkt = pkt;
> > > > +
> > > > +   if (list_empty(>task_busy_list)) {
> > > > +   WARN_ON(clk_enable(cmdq->clock) < 0);
> > > > +   WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
> > > > +
> > > > +   writel(task->pa_base, thread->base + 
> > > > CMDQ_THR_CURR_ADDR);
> > > > +   writel(task->pa_base + pkt->cmd_buf_size,
> > > > +  thread->base + CMDQ_THR_END_ADDR);
> > > > +   writel(thread->priority, thread->base + 
> > > > CMDQ_THR_PRIORITY);

Re: [PATCH v22 1/4] dt-bindings: soc: Add documentation for the MediaTek GCE unit

2018-07-05 Thread houlong wei
On Fri, 2018-07-06 at 04:08 +0800, Rob Herring wrote:
> On Tue, Jul 3, 2018 at 5:39 PM houlong wei  wrote:
> >
> > On Tue, 2018-07-03 at 10:30 +0800, Rob Herring wrote:
> > > On Wed, Jun 27, 2018 at 07:16:09PM +0800, Houlong Wei wrote:
> > > > This adds documentation for the MediaTek Global Command Engine (GCE) 
> > > > unit
> > > > found in MT8173 SoCs.
> > > >
> > > > Signed-off-by: Houlong Wei 
> > > > Signed-off-by: HS Liao 
> > > > ---
> > > > Hi Rob,
> > > >   I don't add your ACK in this version since the dt-binding description
> > > > has been changed. Thanks.
> > > > ---
> > > >  .../devicetree/bindings/mailbox/mtk-gce.txt|   65 
> > > > 
> > > >  include/dt-bindings/gce/mt8173-gce.h   |   48 
> > > > +++
> > > >  2 files changed, 113 insertions(+)
> > > >  create mode 100644 
> > > > Documentation/devicetree/bindings/mailbox/mtk-gce.txt
> > > >  create mode 100644 include/dt-bindings/gce/mt8173-gce.h
> > > >
> > > > diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt 
> > > > b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
> > > > new file mode 100644
> > > > index 000..26f65a4
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
> > > > @@ -0,0 +1,65 @@
> > > > +MediaTek GCE
> > > > +===
> > > > +
> > > > +The Global Command Engine (GCE) is used to help read/write registers 
> > > > with
> > > > +critical time limitation, such as updating display configuration 
> > > > during the
> > > > +vblank. The GCE can be used to implement the Command Queue (CMDQ) 
> > > > driver.
> > > > +
> > > > +CMDQ driver uses mailbox framework for communication. Please refer to
> > > > +mailbox.txt for generic information about mailbox device-tree bindings.
> > > > +
> > > > +Required properties:
> > > > +- compatible: Must be "mediatek,mt8173-gce"
> > > > +- reg: Address range of the GCE unit
> > > > +- interrupts: The interrupt signal from the GCE block
> > > > +- clock: Clocks according to the common clock binding
> > > > +- clock-names: Must be "gce" to stand for GCE clock
> > > > +- thread-num: Maximum threads count of GCE.
> > >
> > > mediatek,thread-num
> > >
> > > Is this needed for anything other than error checking the thread id in
> > > the mbox cells? if that's it, then drop it.
> > >
> >
> > 'thread-num' is used to configure the GCE thread number, which is the
> > channel number of gce mailbox. This property is read in
> > cmdq_probe()/mtk-cmdq-mailbox.c and a mailbox's channel array is
> > allocated according to the number.
> > Since the thread number may be different on different SoC, we wish it
> > could be configured in device tree.
> 
> You should have different compatible strings for different SoCs and
> can imply the number of threads from that.
> 

Thanks. Will remove 'thread-num' form device tree and put it in match
table of cmdq dirver.

> Or if the number of threads doesn't vary greatly, just allocate the
> max # of channels. Or allocate the per thread data when a thread is
> actually in use.
> 
> >
> > > > +- #mbox-cells: Should be 4.
> > > > +   < channel timeout priority atomic_exec>
> > > > +   phandle: Label name of a gce node.
> > > > +   channel: Channel of mailbox. Be equal to the thread id of GCE.
> > > > +   timeout: Maximum time of software waiting GCE processing done, in 
> > > > unit
> > > > +   of millisecond.
> > > > +   priority: Priority of GCE thread.
> > > > +   atomic_exec: GCE processing continuous packets of commands in atomic
> > > > +   way.
> > > > +
> > > > +Required properties for a client device:
> > > > +- mboxes: Client use mailbox to communicate with GCE, it should have 
> > > > this
> > > > +  property and list of phandle, mailbox specifiers.
> > > > +- gce-subsys: Specify the sub-system id which is corresponding to the 
> > > > register
> > > > +  address.
> > >
> > > What is this for?
> >
> > You mean the new added property 'gce-subsys'?
> > I

Re: [PATCH v26 2/2] soc: mediatek: Add Mediatek CMDQ helper

2018-10-24 Thread houlong wei
On Mon, 2018-10-08 at 11:43 +0800, Houlong Wei wrote:
> Add Mediatek CMDQ helper to create CMDQ packet and assemble GCE op code.
> 
> Signed-off-by: Houlong Wei 
> Signed-off-by: HS Liao 
> ---
>  drivers/soc/mediatek/Kconfig   |   12 ++
>  drivers/soc/mediatek/Makefile  |1 +
>  drivers/soc/mediatek/mtk-cmdq-helper.c |  292 
> 
>  include/linux/soc/mediatek/mtk-cmdq.h  |  133 +++
>  4 files changed, 438 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mtk-cmdq-helper.c
>  create mode 100644 include/linux/soc/mediatek/mtk-cmdq.h
> 
> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> index a7d0667..17bd759 100644
> --- a/drivers/soc/mediatek/Kconfig
> +++ b/drivers/soc/mediatek/Kconfig
> @@ -4,6 +4,18 @@
>  menu "MediaTek SoC drivers"
>  depends on ARCH_MEDIATEK || COMPILE_TEST
> 
> +config MTK_CMDQ
> +tristate "MediaTek CMDQ Support"
> +depends on ARCH_MEDIATEK || COMPILE_TEST
> +select MAILBOX
> +select MTK_CMDQ_MBOX
> +select MTK_INFRACFG
> +help
> +  Say yes here to add support for the MediaTek Command Queue (CMDQ)
> +  driver. The CMDQ is used to help read/write registers with critical
> +  time limitation, such as updating display configuration during the
> +  vblank.
> +
>  config MTK_INFRACFG
>  bool "MediaTek INFRACFG Support"
>  select REGMAP
> diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> index 12998b0..64ce5ee 100644
> --- a/drivers/soc/mediatek/Makefile
> +++ b/drivers/soc/mediatek/Makefile
> @@ -1,3 +1,4 @@
> +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
>  obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
>  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
>  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> b/drivers/soc/mediatek/mtk-cmdq-helper.c
> new file mode 100644
> index 000..45aa0cf
> --- /dev/null
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -0,0 +1,292 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// Copyright (c) 2018 MediaTek Inc.
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define CMDQ_ARG_A_WRITE_MASK0x
> +#define CMDQ_WRITE_ENABLE_MASKBIT(0)
> +#define CMDQ_EOC_IRQ_ENBIT(0)
> +#define CMDQ_EOC_CMD((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
> +<< 32 | CMDQ_EOC_IRQ_EN)
> +
> +static void cmdq_client_timeout(struct timer_list *t)
> +{
> +struct cmdq_client *client = from_timer(client, t, timer);
> +
> +dev_err(client->client.dev, "cmdq timeout!\n");
> +}
> +
> +struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 
> timeout)
> +{
> +struct cmdq_client *client;
> +
> +client = kzalloc(sizeof(*client), GFP_KERNEL);
> +if (!client)
> +return (struct cmdq_client *)-ENOMEM;
> +
> +client->timeout_ms = timeout;
> +if (timeout != CMDQ_NO_TIMEOUT) {
> +spin_lock_init(>lock);
> +timer_setup(>timer, cmdq_client_timeout, 0);
> +}
> +client->pkt_cnt = 0;
> +client->client.dev = dev;
> +client->client.tx_block = false;
> +client->chan = mbox_request_channel(>client, index);
> +
> +if (IS_ERR(client->chan)) {
> +long err;
> +
> +dev_err(dev, "failed to request channel\n");
> +err = PTR_ERR(client->chan);
> +kfree(client);
> +
> +return ERR_PTR(err);
> +}
> +
> +return client;
> +}
> +EXPORT_SYMBOL(cmdq_mbox_create);
> +
> +void cmdq_mbox_destroy(struct cmdq_client *client)
> +{
> +if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
> +spin_lock(>lock);
> +del_timer_sync(>timer);
> +spin_unlock(>lock);
> +}
> +mbox_free_channel(client->chan);
> +kfree(client);
> +}
> +EXPORT_SYMBOL(cmdq_mbox_destroy);
> +
> +struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
> +{
> +struct cmdq_pkt *pkt;
> +struct device *dev;
> +dma_addr_t dma_addr;
> +
> +pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
> +if (!pkt)
> +return ERR_PTR(-ENOMEM);
> +pkt->va_base = kzalloc(size, GFP_KERNEL);
> +if (!pkt->va_base) {
> +kfree(pkt);
> +return ERR_PTR(-ENOMEM);
> +}
> +pkt->buf_size = size;
> +pkt->cl = (void *)client;
> +
> +dev = client->chan->mbox->dev;
> +dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
> +  DMA_TO_DEVICE);
> +if (dma_mapping_error(dev, dma_addr)) {
> +dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
> +kfree(pkt->va_base);
> +kfree(pkt);
> +return ERR_PTR(-ENOMEM);
> +}
> +
> +pkt->pa_base = dma_addr;
> +
> +return pk

  1   2   >