Re: [PATCH v6] support gce on mt6779 platform

2020-05-31 Thread Dennis-YC Hsieh
Hi Jassi,

Thanks for your comment

On Sat, 2020-05-30 at 15:34 -0500, Jassi Brar wrote:
> On Thu, May 28, 2020 at 12:05 PM Dennis YC Hsieh
>  wrote:
> >
> > This patch support gce on mt6779 platform.
> >
> > Change since v5:
> > - spearate address shift code in client helper and mailbox controller
> > - separate write_s/write_s_mask and write_s_value/write_s_mask_value so that
> >   client can decide use mask or not
> > - fix typo in header
> >
> > Change since v4:
> > - do not clear disp event again in drm driver
> > - symbolize value 1 to jump relative
> >
> > [... snip ...]
> >
> >
> >
> > Dennis YC Hsieh (16):
> >   dt-binding: gce: add gce header file for mt6779
> >   mailbox: cmdq: variablize address shift in platform
> >   mailbox: cmdq: support mt6779 gce platform definition
> >   mailbox: mediatek: cmdq: clear task in channel before shutdown
> >   soc: mediatek: cmdq: return send msg error code
> >   soc: mediatek: cmdq: add address shift in jump
> >   soc: mediatek: cmdq: add assign function
> >   soc: mediatek: cmdq: add write_s function
> >   soc: mediatek: cmdq: add write_s_mask function
> >   soc: mediatek: cmdq: add read_s function
> >   soc: mediatek: cmdq: add write_s value function
> >   soc: mediatek: cmdq: add write_s_mask value function
> >   soc: mediatek: cmdq: export finalize function
> >   soc: mediatek: cmdq: add jump function
> >   soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api
> >   soc: mediatek: cmdq: add set event function
> >
> >  .../devicetree/bindings/mailbox/mtk-gce.txt   |   8 +-
> >  drivers/gpu/drm/mediatek/mtk_drm_crtc.c   |   3 +-
> >  drivers/mailbox/mtk-cmdq-mailbox.c| 101 ++--
> >  drivers/soc/mediatek/mtk-cmdq-helper.c| 163 -
> >  include/dt-bindings/gce/mt6779-gce.h  | 222 ++
> >  include/linux/mailbox/mtk-cmdq-mailbox.h  |  10 +-
> >  include/linux/soc/mediatek/mtk-cmdq.h | 125 +-
> >
> Please break the patchset into two. The lower mailbox related changes
> with soc changes on top.

Ok, I'll separate patches into two patchset, thanks.


Regards,
Dennis

> 
> thanks



Re: [PATCH 3/3] mailbox: mediatek: Remove busylist

2019-02-11 Thread Dennis-YC Hsieh
Hi CK,

On Tue, 2019-01-29 at 17:20 +0800, Houlong Wei (魏厚龙) wrote:
> -Original Message-
> From: CK Hu [mailto:ck...@mediatek.com] 
> Sent: Wednesday, January 16, 2019 1:05 PM
> To: Jassi Brar ; Matthias Brugger 
> ; Houlong Wei (魏厚龙) 
> Cc: linux-kernel@vger.kernel.org; linux-arm-ker...@lists.infradead.org; 
> linux-media...@lists.infradead.org; srv_heupstream 
> ; CK Hu (胡俊光) 
> Subject: [PATCH 3/3] mailbox: mediatek: Remove busylist
> 
> After implement abort_data, controller need not to implement its own queue. 
> Remove busylist because it's useless.

Remove busy list in controller makes client driver have no way to queue
pkt in gce hardware thread, which may hurt display and multimedia
performance since each pkt waits IRQ delay before previous pkt. Suggest
keep busy list design.


Regards,
Dennis

> 
> Signed-off-by: CK Hu 
> ---
>  drivers/mailbox/mtk-cmdq-mailbox.c | 255 -
>  1 file changed, 29 insertions(+), 226 deletions(-)
> 
> diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
> b/drivers/mailbox/mtk-cmdq-mailbox.c
> index f2219f263ef6..45c59f677ecb 100644
> --- a/drivers/mailbox/mtk-cmdq-mailbox.c
> +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> @@ -16,9 +16,7 @@
>  #include 
>  #include 
>  
> -#define CMDQ_OP_CODE_MASK(0xff << CMDQ_OP_CODE_SHIFT)
>  #define CMDQ_IRQ_MASK0x
> -#define CMDQ_NUM_CMD(t)  (t->cmd_buf_size / 
> CMDQ_INST_SIZE)
>  
>  #define CMDQ_CURR_IRQ_STATUS 0x10
>  #define CMDQ_THR_SLOT_CYCLES 0x30
> @@ -47,22 +45,10 @@
>  #define CMDQ_THR_IRQ_EN  (CMDQ_THR_IRQ_ERROR | 
> CMDQ_THR_IRQ_DONE)
>  #define CMDQ_THR_IS_WAITING  BIT(31)
>  
> -#define CMDQ_JUMP_BY_OFFSET  0x1000
> -#define CMDQ_JUMP_BY_PA  0x1001
> -
>  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 */
>  };
>  
> @@ -130,171 +116,47 @@ static void cmdq_thread_disable(struct cmdq *cmdq, 
> struct cmdq_thread *thread)
>   writel(CMDQ_THR_DISABLED, thread->base + CMDQ_THR_ENABLE_TASK);  }
>  
> -/* notify GCE to re-fetch commands by setting GCE thread PC */ -static void 
> cmdq_thread_invalidate_fetched_data(struct cmdq_thread *thread) -{
> - writel(readl(thread->base + CMDQ_THR_CURR_ADDR),
> -thread->base + CMDQ_THR_CURR_ADDR);
> -}
> -
> -static void cmdq_task_insert_into_thread(struct cmdq_task *task) -{
> - struct device *dev = task->cmdq->mbox.dev;
> - struct cmdq_thread *thread = task->thread;
> - struct cmdq_task *prev_task = list_last_entry(
> - &thread->task_busy_list, typeof(*task), list_entry);
> - u64 *prev_task_base = prev_task->pkt->va_base;
> -
> - /* let previous task jump to this task */
> - dma_sync_single_for_cpu(dev, prev_task->pa_base,
> - prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE);
> - prev_task_base[CMDQ_NUM_CMD(prev_task->pkt) - 1] =
> - (u64)CMDQ_JUMP_BY_PA << 32 | task->pa_base;
> - dma_sync_single_for_device(dev, prev_task->pa_base,
> -prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE);
> -
> - cmdq_thread_invalidate_fetched_data(thread);
> -}
> -
> -static bool cmdq_command_is_wfe(u64 cmd) -{
> - u64 wfe_option = CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | CMDQ_WFE_WAIT_VALUE;
> - u64 wfe_op = (u64)(CMDQ_CODE_WFE << CMDQ_OP_CODE_SHIFT) << 32;
> - u64 wfe_mask = (u64)CMDQ_OP_CODE_MASK << 32 | 0x;
> -
> - return ((cmd & wfe_mask) == (wfe_op | wfe_option));
> -}
> -
> -/* we assume tasks in the same display GCE thread are waiting the same 
> event. */ -static void cmdq_task_remove_wfe(struct cmdq_task *task) -{
> - struct device *dev = task->cmdq->mbox.dev;
> - u64 *base = task->pkt->va_base;
> - int i;
> -
> - dma_sync_single_for_cpu(dev, task->pa_base, task->pkt->cmd_buf_size,
> - DMA_TO_DEVICE);
> - for (i = 0; i < CMDQ_NUM_CMD(task->pkt); i++)
> - if (cmdq_command_is_wfe(base[i]))
> - base[i] = (u64)CMDQ_JUMP_BY_OFFSET << 32 |
> -   CMDQ_JUMP_PASS;
> - dma_sync_single_for_device(dev, task->pa_base, task->pkt->cmd_buf_size,
> -DMA_TO_DEVICE);
> -}
> -
>  static bool cmdq_thread_is_in_wfe(struct cmdq_thread *thread)  {
>   return readl(thread->base + CMDQ_THR_WAIT_TOKEN) & CMDQ_THR_IS_WAITING; 
>  }
>  
> -static void cmdq_thread_wait_end(struct cmdq_thread *thread,
> -   

Re: [PATCH 3/3] mailbox: mediatek: Remove busylist

2019-02-14 Thread Dennis-YC Hsieh
Hi CK,

On Fri, 2019-02-15 at 00:01 +0800, CK Hu wrote:
> Hi, Dennis:
> 
> On Tue, 2019-02-12 at 10:18 +0800, Dennis-YC Hsieh wrote:
> > Hi CK,
> > 
> > On Tue, 2019-01-29 at 17:20 +0800, Houlong Wei (魏厚龙) wrote:
> > > -Original Message-
> > > From: CK Hu [mailto:ck...@mediatek.com] 
> > > Sent: Wednesday, January 16, 2019 1:05 PM
> > > To: Jassi Brar ; Matthias Brugger 
> > > ; Houlong Wei (魏厚龙) 
> > > Cc: linux-kernel@vger.kernel.org; linux-arm-ker...@lists.infradead.org; 
> > > linux-media...@lists.infradead.org; srv_heupstream 
> > > ; CK Hu (胡俊光) 
> > > Subject: [PATCH 3/3] mailbox: mediatek: Remove busylist
> > > 
> > > After implement abort_data, controller need not to implement its own 
> > > queue. Remove busylist because it's useless.
> > 
> > Remove busy list in controller makes client driver have no way to queue
> > pkt in gce hardware thread, which may hurt display and multimedia
> > performance since each pkt waits IRQ delay before previous pkt. Suggest
> > keep busy list design.
> 
> If some client driver need gce to cascade pkt to prevent irq delay, I
> should keep busylist. For drm driver, I still want to apply the first
> two patches of this series and remove atomic feature because drm could
> keep just one pkt and reuse it to prevent frequently allocate/free pkt
> and the total commands executed in vblank period would be
> well-controlled. Do you have any concern about removing atomic feature?
> 
> Regards,
> CK
> 

I have no concern on remove atomic feature.


Regards,
Dennis


> > 
> > 
> > Regards,
> > Dennis
> > 
> > > 
> > > Signed-off-by: CK Hu 
> > > ---
> > >  drivers/mailbox/mtk-cmdq-mailbox.c | 255 -
> > >  1 file changed, 29 insertions(+), 226 deletions(-)
> > > 
> > > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
> > > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > index f2219f263ef6..45c59f677ecb 100644
> > > --- a/drivers/mailbox/mtk-cmdq-mailbox.c
> > > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > @@ -16,9 +16,7 @@
> > >  #include 
> > >  #include 
> > >  
> > > -#define CMDQ_OP_CODE_MASK(0xff << CMDQ_OP_CODE_SHIFT)
> > >  #define CMDQ_IRQ_MASK0x
> > > -#define CMDQ_NUM_CMD(t)  (t->cmd_buf_size / 
> > > CMDQ_INST_SIZE)
> > >  
> > >  #define CMDQ_CURR_IRQ_STATUS 0x10
> > >  #define CMDQ_THR_SLOT_CYCLES 0x30
> > > @@ -47,22 +45,10 @@
> > >  #define CMDQ_THR_IRQ_EN  (CMDQ_THR_IRQ_ERROR | 
> > > CMDQ_THR_IRQ_DONE)
> > >  #define CMDQ_THR_IS_WAITING  BIT(31)
> > >  
> > > -#define CMDQ_JUMP_BY_OFFSET  0x1000
> > > -#define CMDQ_JUMP_BY_PA  0x1001
> > > -
> > >  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 */
> > >  };
> > >  
> > > @@ -130,171 +116,47 @@ static void cmdq_thread_disable(struct cmdq *cmdq, 
> > > struct cmdq_thread *thread)
> > >   writel(CMDQ_THR_DISABLED, thread->base + CMDQ_THR_ENABLE_TASK);  }
> > >  
> > > -/* notify GCE to re-fetch commands by setting GCE thread PC */ -static 
> > > void cmdq_thread_invalidate_fetched_data(struct cmdq_thread *thread) -{
> > > - writel(readl(thread->base + CMDQ_THR_CURR_ADDR),
> > > -thread->base + CMDQ_THR_CURR_ADDR);
> > > -}
> > > -
> > > -static void cmdq_task_insert_into_thread(struct cmdq_task *task) -{
> > > - struct device *dev = task->cmdq->mbox.dev;
> > > - struct cmdq_thread *thread = task->thread;
> > > - struct cmdq_task *prev_task = list_last_entry(
> > > - &thread->task_busy_list, typeof(*task), list_entry);
> > > - u64 *prev_task_base = prev_task->pkt->va_base;
> > > -
> > > - /* let previous task jump to th

Re: [PATCH v4 09/12] soc: mediatek: cmdq: add polling function

2019-04-23 Thread Dennis-YC Hsieh
Hi Bibby,


On Mon, 2019-04-15 at 20:58 +0800, Bibby Hsieh wrote:
> add polling function in cmdq helper functions
> 
> Signed-off-by: Bibby Hsieh 
> ---
>  drivers/soc/mediatek/mtk-cmdq-helper.c   | 30 
>  include/linux/mailbox/mtk-cmdq-mailbox.h |  1 +
>  include/linux/soc/mediatek/mtk-cmdq.h| 15 
>  3 files changed, 46 insertions(+)
> 
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> b/drivers/soc/mediatek/mtk-cmdq-helper.c
> index d3873ab21db3..80856b8c2385 100644
> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -231,6 +231,36 @@ 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)
> +{
> + int err;
> +
> + if (mask != 0x) {
> + err = cmdq_pkt_append_command(pkt, CMDQ_GET_ARG_C(~mask),
> +   CMDQ_GET_ARG_B(~mask),
> +   CMDQ_IMMEDIATE_VALUE,
> +   CMDQ_IMMEDIATE_VALUE,
> +   CMDQ_IMMEDIATE_VALUE,
> +   CMDQ_IMMEDIATE_VALUE,
> +   CMDQ_IMMEDIATE_VALUE,
> +   CMDQ_CODE_MASK);
> +
> + if (err != 0)
> + return err;
> + }
> + offset = offset | 0x1;

Does this "or" operation make gce use mask? If it does, maybe it should
move into brace?


Regards,
Dennis

> +
> + return cmdq_pkt_append_command(pkt, CMDQ_GET_ARG_C(value),
> +CMDQ_GET_ARG_B(value),
> +offset, subsys,
> +CMDQ_IMMEDIATE_VALUE,
> +CMDQ_IMMEDIATE_VALUE,
> +CMDQ_IMMEDIATE_VALUE,
> +CMDQ_CODE_POLL);
> +}
> +EXPORT_SYMBOL(cmdq_pkt_poll);
> +
>  static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
>  {
>   int err;
> diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
> b/include/linux/mailbox/mtk-cmdq-mailbox.h
> index f21801d32a3a..1dfd5ed5c8c5 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 52f69c8db8de..0651a0bffa54 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




[PATCH v3 6/9] soc: mediatek: cmdq: add write_s_mask value function

2020-07-07 Thread Dennis YC Hsieh
add write_s_mask_value function in cmdq helper functions which
writes a constant value to address with mask and large dma
access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |   21 +
 include/linux/soc/mediatek/mtk-cmdq.h  |   15 +++
 2 files changed, 36 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 4e86b65815fc..b6e25f216605 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -294,6 +294,27 @@ int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_value);
 
+int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+   u16 addr_low, u32 value, u32 mask)
+{
+   struct cmdq_instruction inst = {};
+   int err;
+
+   inst.op = CMDQ_CODE_MASK;
+   inst.mask = ~mask;
+   err = cmdq_pkt_append_command(pkt, inst);
+   if (err < 0)
+   return err;
+
+   inst.op = CMDQ_CODE_WRITE_S_MASK;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.value = value;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index ae73e10da274..d9390d76ee14 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -165,6 +165,21 @@ int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
   u16 addr_low, u32 value);
 
 /**
+ * cmdq_pkt_write_s_mask_value() - append write_s command with mask to the CMDQ
+ *packet which write value to a physical
+ *address
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @value: the specified target value
+ * @mask:  the specified target mask
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+   u16 addr_low, u32 value, u32 mask);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v3 8/9] soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api

2020-07-07 Thread Dennis YC Hsieh
Add clear parameter to let client decide if
event should be clear to 0 after GCE receive it.

Change since v2:
- Keep behavior in drm crtc driver and
  separate bug fix code into another patch.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |2 +-
 drivers/soc/mediatek/mtk-cmdq-helper.c   |5 +++--
 include/linux/mailbox/mtk-cmdq-mailbox.h |3 +--
 include/linux/soc/mediatek/mtk-cmdq.h|5 +++--
 4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index ec6c9ffbf35e..c84e7a14d4a8 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -490,7 +490,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
*mtk_crtc)
mbox_flush(mtk_crtc->cmdq_client->chan, 2000);
cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE);
cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
-   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event);
+   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, true);
mtk_crtc_ddp_config(crtc, cmdq_handle);
cmdq_pkt_finalize(cmdq_handle);
cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index d55dc3296105..505651b0d715 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -316,15 +316,16 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
 
-int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear)
 {
struct cmdq_instruction inst = { {0} };
+   u32 clear_option = clear ? CMDQ_WFE_UPDATE : 0;
 
if (event >= CMDQ_MAX_EVENT)
return -EINVAL;
 
inst.op = CMDQ_CODE_WFE;
-   inst.value = CMDQ_WFE_OPTION;
+   inst.value = CMDQ_WFE_OPTION | clear_option;
inst.event = event;
 
return cmdq_pkt_append_command(pkt, inst);
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index efbd8a9eb2d1..d5a983d65f05 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -28,8 +28,7 @@
  * bit 16-27: update value
  * bit 31: 1 - update, 0 - no update
  */
-#define CMDQ_WFE_OPTION(CMDQ_WFE_UPDATE | 
CMDQ_WFE_WAIT | \
-   CMDQ_WFE_WAIT_VALUE)
+#define CMDQ_WFE_OPTION(CMDQ_WFE_WAIT | 
CMDQ_WFE_WAIT_VALUE)
 
 /** cmdq event maximum */
 #define CMDQ_MAX_EVENT 0x3ff
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 34354e952f60..960704d75994 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -182,11 +182,12 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 /**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
- * @event: the desired event type to "wait and CLEAR"
+ * @event: the desired event type to wait
+ * @clear: clear event or not after event arrive
  *
  * Return: 0 for success; else the error code is returned
  */
-int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event);
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear);
 
 /**
  * cmdq_pkt_clear_event() - append clear event command to the CMDQ packet
-- 
1.7.9.5


[PATCH v3 3/9] soc: mediatek: cmdq: add write_s_mask function

2020-07-07 Thread Dennis YC Hsieh
add write_s_mask function in cmdq helper functions which
writes value contains in internal register to address
with mask and large dma access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   23 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|   18 ++
 3 files changed, 42 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 880349b3f16c..550e9e7e3ff2 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -242,6 +242,29 @@ int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s);
 
+int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+ u16 addr_low, u16 src_reg_idx, u32 mask)
+{
+   struct cmdq_instruction inst = {};
+   int err;
+
+   inst.op = CMDQ_CODE_MASK;
+   inst.mask = ~mask;
+   err = cmdq_pkt_append_command(pkt, inst);
+   if (err < 0)
+   return err;
+
+   inst.mask = 0;
+   inst.op = CMDQ_CODE_WRITE_S_MASK;
+   inst.src_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.src_reg = src_reg_idx;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_mask);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 1f76cfedb16d..90d1d8e64412 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -61,6 +61,7 @@ enum cmdq_code {
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
CMDQ_CODE_WRITE_S = 0x90,
+   CMDQ_CODE_WRITE_S_MASK = 0x91,
CMDQ_CODE_LOGIC = 0xa0,
 };
 
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 9b0c57a0063d..53230341bf94 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -122,6 +122,24 @@ int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 u16 addr_low, u16 src_reg_idx);
 
 /**
+ * cmdq_pkt_write_s_mask() - append write_s with mask command to the CMDQ 
packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @src_reg_idx:   the CMDQ internal register ID which cache source value
+ * @mask:  the specified target address mask, use U32_MAX if no need
+ *
+ * Return: 0 for success; else the error code is returned
+ *
+ * Support write value to physical address without subsys. Use CMDQ_ADDR_HIGH()
+ * to get high address and call cmdq_pkt_assign() to assign value into internal
+ * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter when
+ * call to this function.
+ */
+int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+ u16 addr_low, u16 src_reg_idx, u32 mask);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v3 0/9] support cmdq helper function on mt6779 platform

2020-07-07 Thread Dennis YC Hsieh
This patch support more gce helper function on mt6779 platform.

depends on patch: support gce on mt6779 platform

and depends on following applied patches
soc: mediatek: cmdq: add set event function
soc: mediatek: cmdq: export finalize function
soc: mediatek: cmdq: add assign function

Change since v2:
- Keep behavior in drm crtc driver and
  separate bug fix code into another patch.

Change since v1:
- Rename cmdq_mbox_shift() to cmdq_get_shift_pa().


Dennis YC Hsieh (9):
  soc: mediatek: cmdq: add address shift in jump
  soc: mediatek: cmdq: add write_s function
  soc: mediatek: cmdq: add write_s_mask function
  soc: mediatek: cmdq: add read_s function
  soc: mediatek: cmdq: add write_s value function
  soc: mediatek: cmdq: add write_s_mask value function
  soc: mediatek: cmdq: add jump function
  soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api
  drm/mediatek: reduce clear event

 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |   2 +-
 drivers/soc/mediatek/mtk-cmdq-helper.c   | 113 ++-
 include/linux/mailbox/mtk-cmdq-mailbox.h |   6 +-
 include/linux/soc/mediatek/mtk-cmdq.h|  93 ++-
 4 files changed, 206 insertions(+), 8 deletions(-)

-- 
2.18.0

[PATCH v3 2/9] soc: mediatek: cmdq: add write_s function

2020-07-07 Thread Dennis YC Hsieh
add write_s function in cmdq helper functions which
writes value contains in internal register to address
with large dma access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   19 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|   19 +++
 3 files changed, 39 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 9faf78fbed3a..880349b3f16c 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -18,6 +18,10 @@ struct cmdq_instruction {
union {
u32 value;
u32 mask;
+   struct {
+   u16 arg_c;
+   u16 src_reg;
+   };
};
union {
u16 offset;
@@ -223,6 +227,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_mask);
 
+int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+u16 addr_low, u16 src_reg_idx)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_WRITE_S;
+   inst.src_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.src_reg = src_reg_idx;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 05eea1aef5aa..1f76cfedb16d 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -60,6 +60,7 @@ enum cmdq_code {
CMDQ_CODE_JUMP = 0x10,
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
+   CMDQ_CODE_WRITE_S = 0x90,
CMDQ_CODE_LOGIC = 0xa0,
 };
 
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 2249ecaf77e4..9b0c57a0063d 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -12,6 +12,8 @@
 #include 
 
 #define CMDQ_NO_TIMEOUT0xu
+#define CMDQ_ADDR_HIGH(addr)   ((u32)(((addr) >> 16) & GENMASK(31, 0)))
+#define CMDQ_ADDR_LOW(addr)((u16)(addr) | BIT(1))
 
 struct cmdq_pkt;
 
@@ -103,6 +105,23 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
u16 offset, u32 value, u32 mask);
 
 /**
+ * cmdq_pkt_write_s() - append write_s command to the CMDQ packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @src_reg_idx:   the CMDQ internal register ID which cache source value
+ *
+ * Return: 0 for success; else the error code is returned
+ *
+ * Support write value to physical address without subsys. Use CMDQ_ADDR_HIGH()
+ * to get high address and call cmdq_pkt_assign() to assign value into internal
+ * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter when
+ * call to this function.
+ */
+int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+u16 addr_low, u16 src_reg_idx);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v3 1/9] soc: mediatek: cmdq: add address shift in jump

2020-07-07 Thread Dennis YC Hsieh
Add address shift when compose jump instruction
to compatible with 35bit format.

Change since v1:
- Rename cmdq_mbox_shift() to cmdq_get_shift_pa().

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index dc644cfb6419..9faf78fbed3a 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -329,7 +329,8 @@ int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 
/* JUMP to end */
inst.op = CMDQ_CODE_JUMP;
-   inst.value = CMDQ_JUMP_PASS;
+   inst.value = CMDQ_JUMP_PASS >>
+   cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan);
err = cmdq_pkt_append_command(pkt, inst);
 
return err;
-- 
1.7.9.5


[PATCH v3 9/9] drm/mediatek: reduce clear event

2020-07-07 Thread Dennis YC Hsieh
No need to clear event again since event always clear before wait.
This fix depend on patch:
  "soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api"

Fixes: 2f965be7f9008 ("drm/mediatek: apply CMDQ control flow")
Signed-off-by: Dennis YC Hsieh 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index c84e7a14d4a8..ba6cf956b239 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -490,7 +490,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
*mtk_crtc)
mbox_flush(mtk_crtc->cmdq_client->chan, 2000);
cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE);
cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
-   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, true);
+   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
mtk_crtc_ddp_config(crtc, cmdq_handle);
cmdq_pkt_finalize(cmdq_handle);
cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
-- 
1.7.9.5


[PATCH v3 7/9] soc: mediatek: cmdq: add jump function

2020-07-07 Thread Dennis YC Hsieh
Add jump function so that client can jump to any address which
contains instruction.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |   13 +
 include/linux/soc/mediatek/mtk-cmdq.h  |   11 +++
 2 files changed, 24 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index b6e25f216605..d55dc3296105 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -13,6 +13,7 @@
 #define CMDQ_POLL_ENABLE_MASK  BIT(0)
 #define CMDQ_EOC_IRQ_ENBIT(0)
 #define CMDQ_REG_TYPE  1
+#define CMDQ_JUMP_RELATIVE 1
 
 struct cmdq_instruction {
union {
@@ -407,6 +408,18 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 
value)
 }
 EXPORT_SYMBOL(cmdq_pkt_assign);
 
+int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_JUMP;
+   inst.offset = CMDQ_JUMP_RELATIVE;
+   inst.value = addr >>
+   cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan);
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_jump);
+
 int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index d9390d76ee14..34354e952f60 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -253,6 +253,17 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
 int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
 
 /**
+ * cmdq_pkt_jump() - Append jump command to the CMDQ packet, ask GCE
+ *  to execute an instruction that change current thread PC to
+ *  a physical address which should contains more instruction.
+ * @pkt:the CMDQ packet
+ * @addr:   physical address of target instruction buffer
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr);
+
+/**
  * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
  * @pkt:   the CMDQ packet
  *
-- 
1.7.9.5


[PATCH v3 5/9] soc: mediatek: cmdq: add write_s value function

2020-07-07 Thread Dennis YC Hsieh
add write_s function in cmdq helper functions which
writes a constant value to address with large dma
access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |   14 ++
 include/linux/soc/mediatek/mtk-cmdq.h  |   13 +
 2 files changed, 27 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index ed9f5e63c195..4e86b65815fc 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -280,6 +280,20 @@ int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_mask);
 
+int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+  u16 addr_low, u32 value)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_WRITE_S;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.value = value;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_value);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index cd7ec714344e..ae73e10da274 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -152,6 +152,19 @@ int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
  u16 addr_low, u16 src_reg_idx, u32 mask);
 
 /**
+ * cmdq_pkt_write_s_value() - append write_s command to the CMDQ packet which
+ *   write value to a physical address
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @value: the specified target value
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+  u16 addr_low, u32 value);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v3 4/9] soc: mediatek: cmdq: add read_s function

2020-07-07 Thread Dennis YC Hsieh
Add read_s function in cmdq helper functions which support read value from
register or dma physical address into gce internal register.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   15 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|   12 
 3 files changed, 28 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 550e9e7e3ff2..ed9f5e63c195 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -227,6 +227,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_mask);
 
+int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, u16 addr_low,
+   u16 reg_idx)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_READ_S;
+   inst.dst_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.reg_dst = reg_idx;
+   inst.src_reg = addr_low;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_read_s);
+
 int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
 u16 addr_low, u16 src_reg_idx)
 {
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 90d1d8e64412..efbd8a9eb2d1 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -60,6 +60,7 @@ enum cmdq_code {
CMDQ_CODE_JUMP = 0x10,
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
+   CMDQ_CODE_READ_S = 0x80,
CMDQ_CODE_WRITE_S = 0x90,
CMDQ_CODE_WRITE_S_MASK = 0x91,
CMDQ_CODE_LOGIC = 0xa0,
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 53230341bf94..cd7ec714344e 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -104,6 +104,18 @@ struct cmdq_client *cmdq_mbox_create(struct device *dev, 
int index,
 int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
u16 offset, u32 value, u32 mask);
 
+/*
+ * cmdq_pkt_read_s() - append read_s command to the CMDQ packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @reg_idx:   the CMDQ internal register ID to cache read data
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, u16 addr_low,
+   u16 reg_idx);
+
 /**
  * cmdq_pkt_write_s() - append write_s command to the CMDQ packet
  * @pkt:   the CMDQ packet
-- 
1.7.9.5


Re: [PATCH v7 2/4] mailbox: cmdq: variablize address shift in platform

2020-06-22 Thread Dennis-YC Hsieh
Hi Bibby,

Thanks for your comment.

On Mon, 2020-06-22 at 10:33 +0800, Bibby Hsieh wrote:
> On Sun, 2020-06-21 at 21:22 +0800, Dennis YC Hsieh wrote:
> > Some gce hardware shift pc and end address in register to support
> > large dram addressing.
> > Implement gce address shift when write or read pc and end register.
> > And add shift bit in platform definition.
> > 
> > Signed-off-by: Dennis YC Hsieh 
> > ---
> >  drivers/mailbox/mtk-cmdq-mailbox.c   |   61 
> > ++
> >  include/linux/mailbox/mtk-cmdq-mailbox.h |2 +
> >  2 files changed, 48 insertions(+), 15 deletions(-)
> > 
> > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
> > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > index 9a6ce9f5a7db..4dbee9258127 100644
> > --- a/drivers/mailbox/mtk-cmdq-mailbox.c
> > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > @@ -76,8 +76,22 @@ struct cmdq {
> > struct cmdq_thread  *thread;
> > struct clk  *clock;
> > boolsuspended;
> > +   u8  shift_pa;
> >  };
> >  
> > +struct gce_plat {
> > +   u32 thread_nr;
> > +   u8 shift;
> > +};
> > +
> > +u8 cmdq_mbox_shift(struct mbox_chan *chan)
> 
> How about rename this function as cmdq_get_shift_pa()?

ok, I'll rename it, thanks


Regards,
Dennis


> 
> 
> Bibby
> 
> > +{
> > +   struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox);
> > +
> > +   return cmdq->shift_pa;
> > +}
> > +EXPORT_SYMBOL(cmdq_mbox_shift);
> > +
> >  static int cmdq_thread_suspend(struct cmdq *cmdq, struct cmdq_thread 
> > *thread)
> >  {
> > u32 status;
> > @@ -183,7 +197,7 @@ static void cmdq_task_remove_wfe(struct cmdq_task *task)
> > for (i = 0; i < CMDQ_NUM_CMD(task->pkt); i++)
> > if (cmdq_command_is_wfe(base[i]))
> > base[i] = (u64)CMDQ_JUMP_BY_OFFSET << 32 |
> > - CMDQ_JUMP_PASS;
> > + CMDQ_JUMP_PASS >> task->cmdq->shift_pa;
> > dma_sync_single_for_device(dev, task->pa_base, task->pkt->cmd_buf_size,
> >DMA_TO_DEVICE);
> >  }
> > @@ -221,13 +235,15 @@ static void cmdq_task_handle_error(struct cmdq_task 
> > *task)
> >  {
> > struct cmdq_thread *thread = task->thread;
> > struct cmdq_task *next_task;
> > +   struct cmdq *cmdq = task->cmdq;
> >  
> > -   dev_err(task->cmdq->mbox.dev, "task 0x%p error\n", task);
> > -   WARN_ON(cmdq_thread_suspend(task->cmdq, thread) < 0);
> > +   dev_err(cmdq->mbox.dev, "task 0x%p error\n", task);
> > +   WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
> > next_task = list_first_entry_or_null(&thread->task_busy_list,
> > struct cmdq_task, list_entry);
> > if (next_task)
> > -   writel(next_task->pa_base, thread->base + CMDQ_THR_CURR_ADDR);
> > +   writel(next_task->pa_base >> cmdq->shift_pa,
> > +  thread->base + CMDQ_THR_CURR_ADDR);
> > cmdq_thread_resume(thread);
> >  }
> >  
> > @@ -257,7 +273,7 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
> > else
> > return;
> >  
> > -   curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR);
> > +   curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) << cmdq->shift_pa;
> >  
> > list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
> >  list_entry) {
> > @@ -373,16 +389,20 @@ static int cmdq_mbox_send_data(struct mbox_chan 
> > *chan, void *data)
> > 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,
> > +   writel(task->pa_base >> cmdq->shift_pa,
> > +  thread->base + CMDQ_THR_CURR_ADDR);
> > +   writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->shift_pa,
> >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_ENABL

Re: [PATCH v1 0/11] support cmdq helper function on mt6779 platform

2020-06-22 Thread Dennis-YC Hsieh
Hi Bibby,


On Mon, 2020-06-22 at 10:40 +0800, Bibby Hsieh wrote:
> Hi, Dennis,
> 
> Please add "depends on patch: support gce on mt6779 platform" in cover
> letter. Thanks

ok will do, thanks


Regards,
Dennis


> 
> Bibby
> 
> On Sun, 2020-06-21 at 22:18 +0800, Dennis YC Hsieh wrote:
> > This patch support cmdq helper function on mt6779 platform,
> > based on "support gce on mt6779 platform" patchset.
> > 
> > 
> > Dennis YC Hsieh (11):
> >   soc: mediatek: cmdq: add address shift in jump
> >   soc: mediatek: cmdq: add assign function
> >   soc: mediatek: cmdq: add write_s function
> >   soc: mediatek: cmdq: add write_s_mask function
> >   soc: mediatek: cmdq: add read_s function
> >   soc: mediatek: cmdq: add write_s value function
> >   soc: mediatek: cmdq: add write_s_mask value function
> >   soc: mediatek: cmdq: export finalize function
> >   soc: mediatek: cmdq: add jump function
> >   soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api
> >   soc: mediatek: cmdq: add set event function
> > 
> >  drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |   3 +-
> >  drivers/soc/mediatek/mtk-cmdq-helper.c   | 159 +--
> >  include/linux/mailbox/mtk-cmdq-mailbox.h |   8 +-
> >  include/linux/soc/mediatek/mtk-cmdq.h| 124 +-
> >  4 files changed, 280 insertions(+), 14 deletions(-)
> > 
> 
> 



Re: [PATCH v1 03/11] soc: mediatek: cmdq: add write_s function

2020-06-22 Thread Dennis-YC Hsieh
Hi Matthias,

thanks for your comment.

On Mon, 2020-06-22 at 13:07 +0200, Matthias Brugger wrote:
> 
> On 21/06/2020 16:18, Dennis YC Hsieh wrote:
> > add write_s function in cmdq helper functions which
> > writes value contains in internal register to address
> > with large dma access support.
> > 
> > Signed-off-by: Dennis YC Hsieh 
> > ---
> >  drivers/soc/mediatek/mtk-cmdq-helper.c   |   19 +++
> >  include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
> >  include/linux/soc/mediatek/mtk-cmdq.h|   19 +++
> >  3 files changed, 39 insertions(+)
> > 
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index bf32e3b2ca6c..817a5a97dbe5 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -18,6 +18,10 @@ struct cmdq_instruction {
> > union {
> > u32 value;
> > u32 mask;
> > +   struct {
> > +   u16 arg_c;
> > +   u16 src_reg;
> > +   };
> > };
> > union {
> > u16 offset;
> > @@ -222,6 +226,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 
> > subsys,
> >  }
> >  EXPORT_SYMBOL(cmdq_pkt_write_mask);
> >  
> > +int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> > +u16 addr_low, u16 src_reg_idx)
> > +{
> 
> Do I understand correctly that we use CMDQ_ADDR_HIGH(addr) and
> CMDQ_ADDR_LOW(addr) to calculate in the client high_addr_reg_idx and addr_low
> respectively?
> 
> In that case I think a better interface would be to pass the address and do 
> the
> high/low calculation in the cmdq_pkt_write_s

Not exactly. The high_addr_reg_idx parameter is index of internal
register (which store address bit[47:16]), not result of
CMDQ_ADDR_HIGH(addr). 

The CMDQ_ADDR_HIGH macro use in patch 02/11 cmdq_pkt_assign() api. This
api helps assign address bit[47:16] into one of internal register by
index. And same index could be use in cmdq_pkt_write_s(). The gce
combine bit[47:16] in internal register and bit[15:0] in addr_low
parameter to final address. So it is better to keep interface in this
way.


Regards,
Dennis

> 
> Regards,
> Matthias
> 
> > +   struct cmdq_instruction inst = {};
> > +
> > +   inst.op = CMDQ_CODE_WRITE_S;
> > +   inst.src_t = CMDQ_REG_TYPE;
> > +   inst.sop = high_addr_reg_idx;
> > +   inst.offset = addr_low;
> > +   inst.src_reg = src_reg_idx;
> > +
> > +   return cmdq_pkt_append_command(pkt, inst);
> > +}
> > +EXPORT_SYMBOL(cmdq_pkt_write_s);
> > +
> >  int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
> >  {
> > struct cmdq_instruction inst = { {0} };
> > diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
> > b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > index 121c3bb6d3de..ee67dd3b86f5 100644
> > --- a/include/linux/mailbox/mtk-cmdq-mailbox.h
> > +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > @@ -59,6 +59,7 @@ enum cmdq_code {
> > CMDQ_CODE_JUMP = 0x10,
> > CMDQ_CODE_WFE = 0x20,
> > CMDQ_CODE_EOC = 0x40,
> > +   CMDQ_CODE_WRITE_S = 0x90,
> > CMDQ_CODE_LOGIC = 0xa0,
> >  };
> >  
> > diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
> > b/include/linux/soc/mediatek/mtk-cmdq.h
> > index 83340211e1d3..e1c5a7549b4f 100644
> > --- a/include/linux/soc/mediatek/mtk-cmdq.h
> > +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> > @@ -12,6 +12,8 @@
> >  #include 
> >  
> >  #define CMDQ_NO_TIMEOUT0xu
> > +#define CMDQ_ADDR_HIGH(addr)   ((u32)(((addr) >> 16) & GENMASK(31, 0)))
> > +#define CMDQ_ADDR_LOW(addr)((u16)(addr) | BIT(1))
> >  
> >  struct cmdq_pkt;
> >  
> > @@ -103,6 +105,23 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 
> > subsys,
> > u16 offset, u32 value, u32 mask);
> >  
> >  /**
> > + * cmdq_pkt_write_s() - append write_s command to the CMDQ packet
> > + * @pkt:   the CMDQ packet
> > + * @high_addr_reg_idx: internal register ID which contains high 
> > address of pa
> > + * @addr_low:  low address of pa
> > + * @src_reg_idx:   the CMDQ internal register ID which cache source value
> > + *
> > + * Return: 0 for success; else the error code is returned
> > + *
> > + * Support write value to physical address without subsys. Use 
> > CMDQ_ADDR_HIGH()
> > + * to get high address and call cmdq_pkt_assign() to assign value into 
> > internal
> > + * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter 
> > when
> > + * call to this function.
> > + */
> > +int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> > +u16 addr_low, u16 src_reg_idx);
> > +
> > +/**
> >   * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
> >   * @pkt:   the CMDQ packet
> >   * @event: the desired event type to "wait and CLEAR"
> > 



Re: [PATCH v1 10/11] soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api

2020-06-22 Thread Dennis-YC Hsieh
Hi Matthias,

thanks for your comment.

On Mon, 2020-06-22 at 13:19 +0200, Matthias Brugger wrote:
> 
> On 21/06/2020 16:18, Dennis YC Hsieh wrote:
> > Add clear parameter to let client decide if
> > event should be clear to 0 after GCE receive it.
> > 
> > Signed-off-by: Dennis YC Hsieh 
> > Reviewed-by: CK Hu 
> > ---
> >  drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |2 +-
> >  drivers/soc/mediatek/mtk-cmdq-helper.c   |5 +++--
> >  include/linux/mailbox/mtk-cmdq-mailbox.h |3 +--
> >  include/linux/soc/mediatek/mtk-cmdq.h|5 +++--
> >  4 files changed, 8 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> > b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > index 7daaabc26eb1..a065b3a412cf 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > @@ -488,7 +488,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
> > *mtk_crtc)
> > if (mtk_crtc->cmdq_client) {
> > cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE);
> > cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
> > -   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event);
> > +   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
> 
> This does not set CMDQ_WFE_UPDATE while the old code did. Is this a bug fix 
> or a
> bug in the code?
> If it's a fix, please provide a fixes tag.

no need to to update again since event always clear before wait.
I'll provide a fix tag, thanks.


Regards,
Dennis

> 
> Thanks,
> Matthias
> 
> > mtk_crtc_ddp_config(crtc, cmdq_handle);
> > cmdq_pkt_finalize(cmdq_handle);
> > cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index 009f86ae72c6..13f78c9b5901 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -315,15 +315,16 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, 
> > u8 high_addr_reg_idx,
> >  }
> >  EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
> >  
> > -int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
> > +int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear)
> >  {
> > struct cmdq_instruction inst = { {0} };
> > +   u32 clear_option = clear ? CMDQ_WFE_UPDATE : 0;
> >  
> > if (event >= CMDQ_MAX_EVENT)
> > return -EINVAL;
> >  
> > inst.op = CMDQ_CODE_WFE;
> > -   inst.value = CMDQ_WFE_OPTION;
> > +   inst.value = CMDQ_WFE_OPTION | clear_option;
> > inst.event = event;
> >  
> > return cmdq_pkt_append_command(pkt, inst);
> > diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
> > b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > index 3f6bc0dfd5da..42d2a30e6a70 100644
> > --- a/include/linux/mailbox/mtk-cmdq-mailbox.h
> > +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > @@ -27,8 +27,7 @@
> >   * bit 16-27: update value
> >   * bit 31: 1 - update, 0 - no update
> >   */
> > -#define CMDQ_WFE_OPTION(CMDQ_WFE_UPDATE | 
> > CMDQ_WFE_WAIT | \
> > -   CMDQ_WFE_WAIT_VALUE)
> > +#define CMDQ_WFE_OPTION(CMDQ_WFE_WAIT | 
> > CMDQ_WFE_WAIT_VALUE)
> >  
> >  /** cmdq event maximum */
> >  #define CMDQ_MAX_EVENT 0x3ff
> > diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
> > b/include/linux/soc/mediatek/mtk-cmdq.h
> > index 18364d81e8f7..4b5f5d154bad 100644
> > --- a/include/linux/soc/mediatek/mtk-cmdq.h
> > +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> > @@ -182,11 +182,12 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, 
> > u8 high_addr_reg_idx,
> >  /**
> >   * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
> >   * @pkt:   the CMDQ packet
> > - * @event: the desired event type to "wait and CLEAR"
> > + * @event: the desired event type to wait
> > + * @clear: clear event or not after event arrive
> >   *
> >   * Return: 0 for success; else the error code is returned
> >   */
> > -int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event);
> > +int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear);
> >  
> >  /**
> >   * cmdq_pkt_clear_event() - append clear event command to the CMDQ packet
> > 



Re: [PATCH v1 03/11] soc: mediatek: cmdq: add write_s function

2020-06-22 Thread Dennis-YC Hsieh
Hi Matthias,

On Mon, 2020-06-22 at 17:54 +0200, Matthias Brugger wrote:
> 
> On 22/06/2020 17:36, Dennis-YC Hsieh wrote:
> > Hi Matthias,
> > 
> > thanks for your comment.
> > 
> > On Mon, 2020-06-22 at 13:07 +0200, Matthias Brugger wrote:
> >>
> >> On 21/06/2020 16:18, Dennis YC Hsieh wrote:
> >>> add write_s function in cmdq helper functions which
> >>> writes value contains in internal register to address
> >>> with large dma access support.
> >>>
> >>> Signed-off-by: Dennis YC Hsieh 
> >>> ---
> >>>  drivers/soc/mediatek/mtk-cmdq-helper.c   |   19 +++
> >>>  include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
> >>>  include/linux/soc/mediatek/mtk-cmdq.h|   19 +++
> >>>  3 files changed, 39 insertions(+)
> >>>
> >>> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> >>> b/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>> index bf32e3b2ca6c..817a5a97dbe5 100644
> >>> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>> @@ -18,6 +18,10 @@ struct cmdq_instruction {
> >>>   union {
> >>>   u32 value;
> >>>   u32 mask;
> >>> + struct {
> >>> + u16 arg_c;
> >>> + u16 src_reg;
> >>> + };
> >>>   };
> >>>   union {
> >>>   u16 offset;
> >>> @@ -222,6 +226,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 
> >>> subsys,
> >>>  }
> >>>  EXPORT_SYMBOL(cmdq_pkt_write_mask);
> >>>  
> >>> +int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> >>> +  u16 addr_low, u16 src_reg_idx)
> >>> +{
> >>
> >> Do I understand correctly that we use CMDQ_ADDR_HIGH(addr) and
> >> CMDQ_ADDR_LOW(addr) to calculate in the client high_addr_reg_idx and 
> >> addr_low
> >> respectively?
> >>
> >> In that case I think a better interface would be to pass the address and 
> >> do the
> >> high/low calculation in the cmdq_pkt_write_s
> > 
> > Not exactly. The high_addr_reg_idx parameter is index of internal
> > register (which store address bit[47:16]), not result of
> > CMDQ_ADDR_HIGH(addr). 
> > 
> > The CMDQ_ADDR_HIGH macro use in patch 02/11 cmdq_pkt_assign() api. This
> > api helps assign address bit[47:16] into one of internal register by
> > index. And same index could be use in cmdq_pkt_write_s(). The gce
> > combine bit[47:16] in internal register and bit[15:0] in addr_low
> > parameter to final address. So it is better to keep interface in this
> > way.
> > 
> 
> Got it, but then why don't we call cmdq_pkt_assign() in cmdq_pkt_write_s()? 
> This
> way we would get a clean API for what we want to do.
> Do we expect other users of cmdq_pkt_assign()? Otherwise we could keep it
> private the this file and don't export it.

Considering this case: write 2 register 0xaabb00c0 0xaabb00d0.

If we call assign inside write_s api it will be:
assign aabb to internal reg 0
write reg 0 + 0x00c0
assign aabb to internal reg 0
write reg 0 + 0x00d0


But if we let client decide timing to call assign, it will be like:
assign aabb to internal reg 0
write reg 0 + 0x00c0
write reg 0 + 0x00d0


The first way uses 4 command and second one uses only 3 command.
Thus it is better to let client call assign explicitly.

> 
> By the way, why do you postfix the _s, I understand that it reflects the large
> DMA access but I wonder why you choose '_s'.
> 

The name of this command is "write_s" which is hardware spec.
I'm just following it since it is a common language between gce sw/hw
designers.


Regards,
Dennis

> Regards,
> Matthias
> 
> > 
> > Regards,
> > Dennis
> > 
> >>
> >> Regards,
> >> Matthias
> >>
> >>> + struct cmdq_instruction inst = {};
> >>> +
> >>> + inst.op = CMDQ_CODE_WRITE_S;
> >>> + inst.src_t = CMDQ_REG_TYPE;
> >>> + inst.sop = high_addr_reg_idx;
> >>> + inst.offset = addr_low;
> >>> + inst.src_reg = src_reg_idx;
> >>> +
> >>> + return cmdq_pkt_append_command(pkt, inst);
> >>> +}
> >>> +EXPORT_SYMBOL(cmdq_pkt_write_s);
> >>> +
> >>>  int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
> >>>  {
> >>>   struct cmdq_instruction

Re: [PATCH v1 03/11] soc: mediatek: cmdq: add write_s function

2020-06-22 Thread Dennis-YC Hsieh
Hi Matthias,


On Mon, 2020-06-22 at 19:08 +0200, Matthias Brugger wrote:
> 
> On 22/06/2020 18:12, Dennis-YC Hsieh wrote:
> > Hi Matthias,
> > 
> > On Mon, 2020-06-22 at 17:54 +0200, Matthias Brugger wrote:
> >>
> >> On 22/06/2020 17:36, Dennis-YC Hsieh wrote:
> >>> Hi Matthias,
> >>>
> >>> thanks for your comment.
> >>>
> >>> On Mon, 2020-06-22 at 13:07 +0200, Matthias Brugger wrote:
> >>>>
> >>>> On 21/06/2020 16:18, Dennis YC Hsieh wrote:
> >>>>> add write_s function in cmdq helper functions which
> >>>>> writes value contains in internal register to address
> >>>>> with large dma access support.
> >>>>>
> >>>>> Signed-off-by: Dennis YC Hsieh 
> >>>>> ---
> >>>>>  drivers/soc/mediatek/mtk-cmdq-helper.c   |   19 +++
> >>>>>  include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
> >>>>>  include/linux/soc/mediatek/mtk-cmdq.h|   19 +++
> >>>>>  3 files changed, 39 insertions(+)
> >>>>>
> >>>>> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> >>>>> b/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>>>> index bf32e3b2ca6c..817a5a97dbe5 100644
> >>>>> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>>>> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>>>> @@ -18,6 +18,10 @@ struct cmdq_instruction {
> >>>>> union {
> >>>>> u32 value;
> >>>>> u32 mask;
> >>>>> +   struct {
> >>>>> +   u16 arg_c;
> >>>>> +   u16 src_reg;
> >>>>> +   };
> >>>>> };
> >>>>> union {
> >>>>> u16 offset;
> >>>>> @@ -222,6 +226,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 
> >>>>> subsys,
> >>>>>  }
> >>>>>  EXPORT_SYMBOL(cmdq_pkt_write_mask);
> >>>>>  
> >>>>> +int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> >>>>> +u16 addr_low, u16 src_reg_idx)
> >>>>> +{
> >>>>
> >>>> Do I understand correctly that we use CMDQ_ADDR_HIGH(addr) and
> >>>> CMDQ_ADDR_LOW(addr) to calculate in the client high_addr_reg_idx and 
> >>>> addr_low
> >>>> respectively?
> >>>>
> >>>> In that case I think a better interface would be to pass the address and 
> >>>> do the
> >>>> high/low calculation in the cmdq_pkt_write_s
> >>>
> >>> Not exactly. The high_addr_reg_idx parameter is index of internal
> >>> register (which store address bit[47:16]), not result of
> >>> CMDQ_ADDR_HIGH(addr). 
> >>>
> >>> The CMDQ_ADDR_HIGH macro use in patch 02/11 cmdq_pkt_assign() api. This
> >>> api helps assign address bit[47:16] into one of internal register by
> >>> index. And same index could be use in cmdq_pkt_write_s(). The gce
> >>> combine bit[47:16] in internal register and bit[15:0] in addr_low
> >>> parameter to final address. So it is better to keep interface in this
> >>> way.
> >>>
> >>
> >> Got it, but then why don't we call cmdq_pkt_assign() in 
> >> cmdq_pkt_write_s()? This
> >> way we would get a clean API for what we want to do.
> >> Do we expect other users of cmdq_pkt_assign()? Otherwise we could keep it
> >> private the this file and don't export it.
> > 
> > Considering this case: write 2 register 0xaabb00c0 0xaabb00d0.
> > 
> > If we call assign inside write_s api it will be:
> > assign aabb to internal reg 0
> > write reg 0 + 0x00c0
> > assign aabb to internal reg 0
> > write reg 0 + 0x00d0
> > 
> > 
> > But if we let client decide timing to call assign, it will be like:
> > assign aabb to internal reg 0
> > write reg 0 + 0x00c0
> > write reg 0 + 0x00d0
> > 
> 
> Ok, thanks for clarification. Is this something you exepect to see in the gce
> consumer driver?
> 

yes it is, less command means better performance and save memory, so it
is a good practice for consumer.

> > 
> > The first way uses 4 command and second one uses only 3 comm

[PATCH v6 08/16] soc: mediatek: cmdq: add write_s function

2020-05-28 Thread Dennis YC Hsieh
add write_s function in cmdq helper functions which
writes value contains in internal register to address
with large dma access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   | 21 -
 include/linux/mailbox/mtk-cmdq-mailbox.h |  1 +
 include/linux/soc/mediatek/mtk-cmdq.h| 20 
 3 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 33153d17c9d9..ee24c0ec0a24 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -18,6 +18,10 @@ struct cmdq_instruction {
union {
u32 value;
u32 mask;
+   struct {
+   u16 arg_c;
+   u16 src_reg;
+   };
};
union {
u16 offset;
@@ -29,7 +33,7 @@ struct cmdq_instruction {
struct {
u8 sop:5;
u8 arg_c_t:1;
-   u8 arg_b_t:1;
+   u8 src_t:1;
u8 dst_t:1;
};
};
@@ -222,6 +226,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_mask);
 
+int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+u16 addr_low, u16 src_reg_idx)
+{
+   struct cmdq_instruction inst = { {0} };
+
+   inst.op = CMDQ_CODE_WRITE_S;
+   inst.src_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.src_reg = src_reg_idx;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 121c3bb6d3de..ee67dd3b86f5 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -59,6 +59,7 @@ enum cmdq_code {
CMDQ_CODE_JUMP = 0x10,
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
+   CMDQ_CODE_WRITE_S = 0x90,
CMDQ_CODE_LOGIC = 0xa0,
 };
 
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 83340211e1d3..d623f1aa7814 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -12,6 +12,8 @@
 #include 
 
 #define CMDQ_NO_TIMEOUT0xu
+#define CMDQ_ADDR_HIGH(addr)   ((u32)(((addr) >> 16) & GENMASK(31, 0)))
+#define CMDQ_ADDR_LOW(addr)((u16)(addr) | BIT(1))
 
 struct cmdq_pkt;
 
@@ -102,6 +104,24 @@ int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 
offset, u32 value);
 int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
u16 offset, u32 value, u32 mask);
 
+/**
+ * cmdq_pkt_write_s() - append write_s command to the CMDQ packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @src_reg_idx:   the CMDQ internal register ID which cache source value
+ * @mask:  the specified target address mask, use U32_MAX if no need
+ *
+ * Return: 0 for success; else the error code is returned
+ *
+ * Support write value to physical address without subsys. Use CMDQ_ADDR_HIGH()
+ * to get high address and call cmdq_pkt_assign() to assign value into internal
+ * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter when
+ * call to this function.
+ */
+int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+u16 addr_low, u16 src_reg_idx);
+
 /**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
-- 
2.18.0


[PATCH v6 12/16] soc: mediatek: cmdq: add write_s_mask value function

2020-05-28 Thread Dennis YC Hsieh
add write_s_mask_value function in cmdq helper functions which
writes a constant value to address with mask and large dma
access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 21 +
 include/linux/soc/mediatek/mtk-cmdq.h  | 15 +++
 2 files changed, 36 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 12095a1b701b..4b07da56c7bb 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -293,6 +293,27 @@ int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_value);
 
+int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+   u16 addr_low, u32 value, u32 mask)
+{
+   struct cmdq_instruction inst = { {0} };
+   int err;
+
+   inst.op = CMDQ_CODE_MASK;
+   inst.mask = ~mask;
+   err = cmdq_pkt_append_command(pkt, inst);
+   if (err < 0)
+   return err;
+
+   inst.op = CMDQ_CODE_WRITE_S_MASK;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.value = value;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index bb36750be58c..28a50c3cf6a1 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -165,6 +165,21 @@ int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
   u16 addr_low, u32 value);
 
+/**
+ * cmdq_pkt_write_s_mask_value() - append write_s command with mask to the CMDQ
+ *packet which write value to a physical
+ *address
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @value: the specified target value
+ * @mask:  the specified target mask
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+   u16 addr_low, u32 value, u32 mask);
+
 /**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
-- 
2.18.0


[PATCH v6 06/16] soc: mediatek: cmdq: add address shift in jump

2020-05-28 Thread Dennis YC Hsieh
Add address shift when compose jump instruction
to compatible with 35bit format.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index c67081759728..98f23ba3ba47 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -291,7 +291,8 @@ static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 
/* JUMP to end */
inst.op = CMDQ_CODE_JUMP;
-   inst.value = CMDQ_JUMP_PASS;
+   inst.value = CMDQ_JUMP_PASS >>
+   cmdq_mbox_shift(((struct cmdq_client *)pkt->cl)->chan);
err = cmdq_pkt_append_command(pkt, inst);
 
return err;
-- 
2.18.0


[PATCH v6 16/16] soc: mediatek: cmdq: add set event function

2020-05-28 Thread Dennis YC Hsieh
Add set event function in cmdq helper functions to set specific event.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   | 15 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |  1 +
 include/linux/soc/mediatek/mtk-cmdq.h|  9 +
 3 files changed, 25 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 9e9a4c81553a..e9b1dd31f63b 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -346,6 +346,21 @@ int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event)
 }
 EXPORT_SYMBOL(cmdq_pkt_clear_event);
 
+int cmdq_pkt_set_event(struct cmdq_pkt *pkt, u16 event)
+{
+   struct cmdq_instruction inst = { {0} };
+
+   if (event >= CMDQ_MAX_EVENT)
+   return -EINVAL;
+
+   inst.op = CMDQ_CODE_WFE;
+   inst.value = CMDQ_WFE_UPDATE | CMDQ_WFE_UPDATE_VALUE;
+   inst.event = event;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_set_event);
+
 int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys,
  u16 offset, u32 value)
 {
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 42d2a30e6a70..ba2d811183a9 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -17,6 +17,7 @@
 #define CMDQ_JUMP_PASS CMDQ_INST_SIZE
 
 #define CMDQ_WFE_UPDATEBIT(31)
+#define CMDQ_WFE_UPDATE_VALUE  BIT(16)
 #define CMDQ_WFE_WAIT  BIT(15)
 #define CMDQ_WFE_WAIT_VALUE0x1
 
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 3216ccfff4a9..ea26020e63bf 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -199,6 +199,15 @@ int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool 
clear);
  */
 int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event);
 
+/**
+ * cmdq_pkt_set_event() - append set event command to the CMDQ packet
+ * @pkt:   the CMDQ packet
+ * @event: the desired event to be set
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_set_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
-- 
2.18.0


[PATCH v6 00/16] support gce on mt6779 platform

2020-05-28 Thread Dennis YC Hsieh
This patch support gce on mt6779 platform.

Change since v5:
- spearate address shift code in client helper and mailbox controller
- separate write_s/write_s_mask and write_s_value/write_s_mask_value so that
  client can decide use mask or not
- fix typo in header

Change since v4:
- do not clear disp event again in drm driver
- symbolize value 1 to jump relative

[... snip ...]

*** BLURB HERE ***

Dennis YC Hsieh (16):
  dt-binding: gce: add gce header file for mt6779
  mailbox: cmdq: variablize address shift in platform
  mailbox: cmdq: support mt6779 gce platform definition
  mailbox: mediatek: cmdq: clear task in channel before shutdown
  soc: mediatek: cmdq: return send msg error code
  soc: mediatek: cmdq: add address shift in jump
  soc: mediatek: cmdq: add assign function
  soc: mediatek: cmdq: add write_s function
  soc: mediatek: cmdq: add write_s_mask function
  soc: mediatek: cmdq: add read_s function
  soc: mediatek: cmdq: add write_s value function
  soc: mediatek: cmdq: add write_s_mask value function
  soc: mediatek: cmdq: export finalize function
  soc: mediatek: cmdq: add jump function
  soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api
  soc: mediatek: cmdq: add set event function

 .../devicetree/bindings/mailbox/mtk-gce.txt   |   8 +-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c   |   3 +-
 drivers/mailbox/mtk-cmdq-mailbox.c| 101 ++--
 drivers/soc/mediatek/mtk-cmdq-helper.c| 163 -
 include/dt-bindings/gce/mt6779-gce.h  | 222 ++
 include/linux/mailbox/mtk-cmdq-mailbox.h  |  10 +-
 include/linux/soc/mediatek/mtk-cmdq.h | 125 +-
 7 files changed, 599 insertions(+), 33 deletions(-)
 create mode 100644 include/dt-bindings/gce/mt6779-gce.h

-- 
2.18.0


[PATCH v6 14/16] soc: mediatek: cmdq: add jump function

2020-05-28 Thread Dennis YC Hsieh
Add jump function so that client can jump to any address which
contains instruction.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 13 +
 include/linux/soc/mediatek/mtk-cmdq.h  | 11 +++
 2 files changed, 24 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index ebcdd30cd783..5cf9e71b7900 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -13,6 +13,7 @@
 #define CMDQ_POLL_ENABLE_MASK  BIT(0)
 #define CMDQ_EOC_IRQ_ENBIT(0)
 #define CMDQ_REG_TYPE  1
+#define CMDQ_JUMP_RELATIVE 1
 
 struct cmdq_instruction {
union {
@@ -391,6 +392,18 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 
value)
 }
 EXPORT_SYMBOL(cmdq_pkt_assign);
 
+int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr)
+{
+   struct cmdq_instruction inst = { {0} };
+
+   inst.op = CMDQ_CODE_JUMP;
+   inst.offset = CMDQ_JUMP_RELATIVE;
+   inst.value = addr >>
+   cmdq_mbox_shift(((struct cmdq_client *)pkt->cl)->chan);
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_jump);
+
 int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 703cffcd55bd..9494b293bad9 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -244,6 +244,17 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
  */
 int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
 
+/**
+ * cmdq_pkt_jump() - Append jump command to the CMDQ packet, ask GCE
+ *  to execute an instruction that change current thread PC to
+ *  a physical address which should contains more instruction.
+ * @pkt:the CMDQ packet
+ * @addr:   physical address of target instruction buffer
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr);
+
 /**
  * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
  * @pkt:   the CMDQ packet
-- 
2.18.0


[PATCH v6 15/16] soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api

2020-05-28 Thread Dennis YC Hsieh
Add clear parameter to let client decide if
event should be clear to 0 after GCE receive it.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  | 2 +-
 drivers/soc/mediatek/mtk-cmdq-helper.c   | 5 +++--
 include/linux/mailbox/mtk-cmdq-mailbox.h | 3 +--
 include/linux/soc/mediatek/mtk-cmdq.h| 5 +++--
 4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 7daaabc26eb1..a065b3a412cf 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -488,7 +488,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
*mtk_crtc)
if (mtk_crtc->cmdq_client) {
cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE);
cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
-   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event);
+   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
mtk_crtc_ddp_config(crtc, cmdq_handle);
cmdq_pkt_finalize(cmdq_handle);
cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 5cf9e71b7900..9e9a4c81553a 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -315,15 +315,16 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
 
-int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear)
 {
struct cmdq_instruction inst = { {0} };
+   u32 clear_option = clear ? CMDQ_WFE_UPDATE : 0;
 
if (event >= CMDQ_MAX_EVENT)
return -EINVAL;
 
inst.op = CMDQ_CODE_WFE;
-   inst.value = CMDQ_WFE_OPTION;
+   inst.value = CMDQ_WFE_OPTION | clear_option;
inst.event = event;
 
return cmdq_pkt_append_command(pkt, inst);
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 3f6bc0dfd5da..42d2a30e6a70 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -27,8 +27,7 @@
  * bit 16-27: update value
  * bit 31: 1 - update, 0 - no update
  */
-#define CMDQ_WFE_OPTION(CMDQ_WFE_UPDATE | 
CMDQ_WFE_WAIT | \
-   CMDQ_WFE_WAIT_VALUE)
+#define CMDQ_WFE_OPTION(CMDQ_WFE_WAIT | 
CMDQ_WFE_WAIT_VALUE)
 
 /** cmdq event maximum */
 #define CMDQ_MAX_EVENT 0x3ff
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 9494b293bad9..3216ccfff4a9 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -183,11 +183,12 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 /**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
- * @event: the desired event type to "wait and CLEAR"
+ * @event: the desired event type to wait
+ * @clear: clear event or not after event arrive
  *
  * Return: 0 for success; else the error code is returned
  */
-int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event);
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear);
 
 /**
  * cmdq_pkt_clear_event() - append clear event command to the CMDQ packet
-- 
2.18.0


[PATCH v6 02/16] mailbox: cmdq: variablize address shift in platform

2020-05-28 Thread Dennis YC Hsieh
Some gce hardware shift pc and end address in register to support
large dram addressing.
Implement gce address shift when write or read pc and end register.
And add shift bit in platform definition.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/mailbox/mtk-cmdq-mailbox.c   | 61 ++--
 include/linux/mailbox/mtk-cmdq-mailbox.h |  2 +
 2 files changed, 48 insertions(+), 15 deletions(-)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
b/drivers/mailbox/mtk-cmdq-mailbox.c
index 9a6ce9f5a7db..4dbee9258127 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -76,8 +76,22 @@ struct cmdq {
struct cmdq_thread  *thread;
struct clk  *clock;
boolsuspended;
+   u8  shift_pa;
 };
 
+struct gce_plat {
+   u32 thread_nr;
+   u8 shift;
+};
+
+u8 cmdq_mbox_shift(struct mbox_chan *chan)
+{
+   struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox);
+
+   return cmdq->shift_pa;
+}
+EXPORT_SYMBOL(cmdq_mbox_shift);
+
 static int cmdq_thread_suspend(struct cmdq *cmdq, struct cmdq_thread *thread)
 {
u32 status;
@@ -183,7 +197,7 @@ static void cmdq_task_remove_wfe(struct cmdq_task *task)
for (i = 0; i < CMDQ_NUM_CMD(task->pkt); i++)
if (cmdq_command_is_wfe(base[i]))
base[i] = (u64)CMDQ_JUMP_BY_OFFSET << 32 |
- CMDQ_JUMP_PASS;
+ CMDQ_JUMP_PASS >> task->cmdq->shift_pa;
dma_sync_single_for_device(dev, task->pa_base, task->pkt->cmd_buf_size,
   DMA_TO_DEVICE);
 }
@@ -221,13 +235,15 @@ static void cmdq_task_handle_error(struct cmdq_task *task)
 {
struct cmdq_thread *thread = task->thread;
struct cmdq_task *next_task;
+   struct cmdq *cmdq = task->cmdq;
 
-   dev_err(task->cmdq->mbox.dev, "task 0x%p error\n", task);
-   WARN_ON(cmdq_thread_suspend(task->cmdq, thread) < 0);
+   dev_err(cmdq->mbox.dev, "task 0x%p error\n", task);
+   WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
next_task = list_first_entry_or_null(&thread->task_busy_list,
struct cmdq_task, list_entry);
if (next_task)
-   writel(next_task->pa_base, thread->base + CMDQ_THR_CURR_ADDR);
+   writel(next_task->pa_base >> cmdq->shift_pa,
+  thread->base + CMDQ_THR_CURR_ADDR);
cmdq_thread_resume(thread);
 }
 
@@ -257,7 +273,7 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
else
return;
 
-   curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR);
+   curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) << cmdq->shift_pa;
 
list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
 list_entry) {
@@ -373,16 +389,20 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, 
void *data)
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,
+   writel(task->pa_base >> cmdq->shift_pa,
+  thread->base + CMDQ_THR_CURR_ADDR);
+   writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->shift_pa,
   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);
} 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);
+   curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) <<
+   cmdq->shift_pa;
+   end_pa = readl(thread->base + CMDQ_THR_END_ADDR) <<
+   cmdq->shift_pa;
 
/*
 * Atomic execution should remove the following wfe, i.e. only
@@ -395,7 +415,7 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void 
*data)
cmdq_thread_wait_end(thread, end_pa);
WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
/* set to this task directly */
-   writel(task->pa_base,
+   writel(task->pa_base >> cmdq->shift_pa,
   thread->b

[PATCH v6 03/16] mailbox: cmdq: support mt6779 gce platform definition

2020-05-28 Thread Dennis YC Hsieh
Add gce v4 hardware support with different thread number and shift.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
Reviewed-by: Matthias Brugger 
---
 drivers/mailbox/mtk-cmdq-mailbox.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
b/drivers/mailbox/mtk-cmdq-mailbox.c
index 4dbee9258127..9994ac9426d6 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -572,10 +572,12 @@ static const struct dev_pm_ops cmdq_pm_ops = {
 
 static const struct gce_plat gce_plat_v2 = {.thread_nr = 16};
 static const struct gce_plat gce_plat_v3 = {.thread_nr = 24};
+static const struct gce_plat gce_plat_v4 = {.thread_nr = 24, .shift = 3};
 
 static const struct of_device_id cmdq_of_ids[] = {
{.compatible = "mediatek,mt8173-gce", .data = (void *)&gce_plat_v2},
{.compatible = "mediatek,mt8183-gce", .data = (void *)&gce_plat_v3},
+   {.compatible = "mediatek,mt6779-gce", .data = (void *)&gce_plat_v4},
{}
 };
 
-- 
2.18.0


[PATCH v6 04/16] mailbox: mediatek: cmdq: clear task in channel before shutdown

2020-05-28 Thread Dennis YC Hsieh
Do success callback in channel when shutdown. For those task not finish,
callback with error code thus client has chance to cleanup or reset.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
---
 drivers/mailbox/mtk-cmdq-mailbox.c | 38 ++
 1 file changed, 38 insertions(+)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
b/drivers/mailbox/mtk-cmdq-mailbox.c
index 9994ac9426d6..b56d340c8982 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -387,6 +387,12 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, 
void *data)
 
if (list_empty(&thread->task_busy_list)) {
WARN_ON(clk_enable(cmdq->clock) < 0);
+   /*
+* The thread reset will clear thread related register to 0,
+* including pc, end, priority, irq, suspend and enable. Thus
+* set CMDQ_THR_ENABLED to CMDQ_THR_ENABLE_TASK will enable
+* thread and make it running.
+*/
WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
 
writel(task->pa_base >> cmdq->shift_pa,
@@ -450,6 +456,38 @@ static int cmdq_mbox_startup(struct mbox_chan *chan)
 
 static void cmdq_mbox_shutdown(struct mbox_chan *chan)
 {
+   struct cmdq_thread *thread = (struct cmdq_thread *)chan->con_priv;
+   struct cmdq *cmdq = dev_get_drvdata(chan->mbox->dev);
+   struct cmdq_task *task, *tmp;
+   unsigned long flags;
+
+   spin_lock_irqsave(&thread->chan->lock, flags);
+   if (list_empty(&thread->task_busy_list))
+   goto done;
+
+   WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
+
+   /* make sure executed tasks have success callback */
+   cmdq_thread_irq_handler(cmdq, thread);
+   if (list_empty(&thread->task_busy_list))
+   goto done;
+
+   list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
+list_entry) {
+   cmdq_task_exec_done(task, CMDQ_CB_ERROR);
+   kfree(task);
+   }
+
+   cmdq_thread_disable(cmdq, thread);
+   clk_disable(cmdq->clock);
+done:
+   /*
+* The thread->task_busy_list empty means thread already disable. The
+* cmdq_mbox_send_data() always reset thread which clear disable and
+* suspend statue when first pkt send to channel, so there is no need
+* to do any operation here, only unlock and leave.
+*/
+   spin_unlock_irqrestore(&thread->chan->lock, flags);
 }
 
 static const struct mbox_chan_ops cmdq_mbox_chan_ops = {
-- 
2.18.0


[PATCH v6 10/16] soc: mediatek: cmdq: add read_s function

2020-05-28 Thread Dennis YC Hsieh
Add read_s function in cmdq helper functions which support read value from
register or dma physical address into gce internal register.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   | 15 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |  1 +
 include/linux/soc/mediatek/mtk-cmdq.h| 13 +
 3 files changed, 29 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 58a414790471..02ac0ca23f6e 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -226,6 +226,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_mask);
 
+int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, u16 addr_low,
+   u16 reg_idx)
+{
+   struct cmdq_instruction inst = { {0} };
+
+   inst.op = CMDQ_CODE_READ_S;
+   inst.dst_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.reg_dst = reg_idx;
+   inst.src_reg = addr_low;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_read_s);
+
 int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
 u16 addr_low, u16 src_reg_idx)
 {
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 8ef87e1bd03b..3f6bc0dfd5da 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -59,6 +59,7 @@ enum cmdq_code {
CMDQ_CODE_JUMP = 0x10,
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
+   CMDQ_CODE_READ_S = 0x80,
CMDQ_CODE_WRITE_S = 0x90,
CMDQ_CODE_WRITE_S_MASK = 0x91,
CMDQ_CODE_LOGIC = 0xa0,
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index ca9c75fd8125..c07baa1534ca 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -104,6 +104,19 @@ int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 
offset, u32 value);
 int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
u16 offset, u32 value, u32 mask);
 
+/*
+ * cmdq_pkt_read_s() - append read_s command to the CMDQ packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @addr:  the physical address of register or dma to read
+ * @reg_idx:   the CMDQ internal register ID to cache read data
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, u16 addr_low,
+   u16 reg_idx);
+
 /**
  * cmdq_pkt_write_s() - append write_s command to the CMDQ packet
  * @pkt:   the CMDQ packet
-- 
2.18.0


[PATCH v6 09/16] soc: mediatek: cmdq: add write_s_mask function

2020-05-28 Thread Dennis YC Hsieh
add write_s_mask function in cmdq helper functions which
writes value contains in internal register to address
with mask and large dma access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   | 23 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |  1 +
 include/linux/soc/mediatek/mtk-cmdq.h| 19 ++-
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index ee24c0ec0a24..58a414790471 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -241,6 +241,29 @@ int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s);
 
+int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+ u16 addr_low, u16 src_reg_idx, u32 mask)
+{
+   struct cmdq_instruction inst = { {0} };
+   int err;
+
+   inst.op = CMDQ_CODE_MASK;
+   inst.mask = ~mask;
+   err = cmdq_pkt_append_command(pkt, inst);
+   if (err < 0)
+   return err;
+
+   inst.mask = 0;
+   inst.op = CMDQ_CODE_WRITE_S_MASK;
+   inst.src_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.src_reg = src_reg_idx;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_mask);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index ee67dd3b86f5..8ef87e1bd03b 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -60,6 +60,7 @@ enum cmdq_code {
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
CMDQ_CODE_WRITE_S = 0x90,
+   CMDQ_CODE_WRITE_S_MASK = 0x91,
CMDQ_CODE_LOGIC = 0xa0,
 };
 
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index d623f1aa7814..ca9c75fd8125 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -110,7 +110,6 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
  * @high_addr_reg_idx: internal register ID which contains high address of pa
  * @addr_low:  low address of pa
  * @src_reg_idx:   the CMDQ internal register ID which cache source value
- * @mask:  the specified target address mask, use U32_MAX if no need
  *
  * Return: 0 for success; else the error code is returned
  *
@@ -122,6 +121,24 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
 int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
 u16 addr_low, u16 src_reg_idx);
 
+/**
+ * cmdq_pkt_write_s_mask() - append write_s with mask command to the CMDQ 
packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @src_reg_idx:   the CMDQ internal register ID which cache source value
+ * @mask:  the specified target address mask, use U32_MAX if no need
+ *
+ * Return: 0 for success; else the error code is returned
+ *
+ * Support write value to physical address without subsys. Use CMDQ_ADDR_HIGH()
+ * to get high address and call cmdq_pkt_assign() to assign value into internal
+ * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter when
+ * call to this function.
+ */
+int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+ u16 addr_low, u16 src_reg_idx, u32 mask);
+
 /**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
-- 
2.18.0


[PATCH v6 13/16] soc: mediatek: cmdq: export finalize function

2020-05-28 Thread Dennis YC Hsieh
Export finalize function to client which helps append eoc and jump
command to pkt. Let client decide call finalize or not.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
Acked-by: Chun-Kuang Hu 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c  | 7 ++-
 include/linux/soc/mediatek/mtk-cmdq.h   | 8 
 3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 0dfcd1787e65..7daaabc26eb1 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -490,6 +490,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
*mtk_crtc)
cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event);
mtk_crtc_ddp_config(crtc, cmdq_handle);
+   cmdq_pkt_finalize(cmdq_handle);
cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
}
 #endif
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 4b07da56c7bb..ebcdd30cd783 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -391,7 +391,7 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 
value)
 }
 EXPORT_SYMBOL(cmdq_pkt_assign);
 
-static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
+int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
struct cmdq_instruction inst = { {0} };
int err;
@@ -411,6 +411,7 @@ static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 
return err;
 }
+EXPORT_SYMBOL(cmdq_pkt_finalize);
 
 static void cmdq_pkt_flush_async_cb(struct cmdq_cb_data data)
 {
@@ -445,10 +446,6 @@ int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, 
cmdq_async_flush_cb cb,
unsigned long flags = 0;
struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
 
-   err = cmdq_pkt_finalize(pkt);
-   if (err < 0)
-   return err;
-
pkt->cb.cb = cb;
pkt->cb.data = data;
pkt->async_cb.cb = cmdq_pkt_flush_async_cb;
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 28a50c3cf6a1..703cffcd55bd 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -244,6 +244,14 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
  */
 int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
 
+/**
+ * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
+ * @pkt:   the CMDQ packet
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
+
 /**
  * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
  *  packet and call back at the end of done packet
-- 
2.18.0


[PATCH v6 11/16] soc: mediatek: cmdq: add write_s value function

2020-05-28 Thread Dennis YC Hsieh
add write_s function in cmdq helper functions which
writes a constant value to address with large dma
access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 14 ++
 include/linux/soc/mediatek/mtk-cmdq.h  | 13 +
 2 files changed, 27 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 02ac0ca23f6e..12095a1b701b 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -279,6 +279,20 @@ int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_mask);
 
+int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+  u16 addr_low, u32 value)
+{
+   struct cmdq_instruction inst = { {0} };
+
+   inst.op = CMDQ_CODE_WRITE_S;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.value = value;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_value);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index c07baa1534ca..bb36750be58c 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -152,6 +152,19 @@ int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
  u16 addr_low, u16 src_reg_idx, u32 mask);
 
+/**
+ * cmdq_pkt_write_s_value() - append write_s command to the CMDQ packet which
+ *   write value to a physical address
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @value: the specified target value
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+  u16 addr_low, u32 value);
+
 /**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
-- 
2.18.0


[PATCH v6] support gce on mt6779 platform

2020-05-28 Thread Dennis YC Hsieh
This patch support gce on mt6779 platform.

Change since v5:
- spearate address shift code in client helper and mailbox controller
- separate write_s/write_s_mask and write_s_value/write_s_mask_value so that
  client can decide use mask or not
- fix typo in header

Change since v4:
- do not clear disp event again in drm driver
- symbolize value 1 to jump relative

[... snip ...]



Dennis YC Hsieh (16):
  dt-binding: gce: add gce header file for mt6779
  mailbox: cmdq: variablize address shift in platform
  mailbox: cmdq: support mt6779 gce platform definition
  mailbox: mediatek: cmdq: clear task in channel before shutdown
  soc: mediatek: cmdq: return send msg error code
  soc: mediatek: cmdq: add address shift in jump
  soc: mediatek: cmdq: add assign function
  soc: mediatek: cmdq: add write_s function
  soc: mediatek: cmdq: add write_s_mask function
  soc: mediatek: cmdq: add read_s function
  soc: mediatek: cmdq: add write_s value function
  soc: mediatek: cmdq: add write_s_mask value function
  soc: mediatek: cmdq: export finalize function
  soc: mediatek: cmdq: add jump function
  soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api
  soc: mediatek: cmdq: add set event function

 .../devicetree/bindings/mailbox/mtk-gce.txt   |   8 +-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c   |   3 +-
 drivers/mailbox/mtk-cmdq-mailbox.c| 101 ++--
 drivers/soc/mediatek/mtk-cmdq-helper.c| 163 -
 include/dt-bindings/gce/mt6779-gce.h  | 222 ++
 include/linux/mailbox/mtk-cmdq-mailbox.h  |  10 +-
 include/linux/soc/mediatek/mtk-cmdq.h | 125 +-
 7 files changed, 599 insertions(+), 33 deletions(-)
 create mode 100644 include/dt-bindings/gce/mt6779-gce.h

-- 
2.18.0

[PATCH v6 07/16] soc: mediatek: cmdq: add assign function

2020-05-28 Thread Dennis YC Hsieh
Add assign function in cmdq helper which assign constant value into
internal register by index.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   | 24 +++-
 include/linux/mailbox/mtk-cmdq-mailbox.h |  1 +
 include/linux/soc/mediatek/mtk-cmdq.h| 14 ++
 3 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 98f23ba3ba47..33153d17c9d9 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -12,6 +12,7 @@
 #define CMDQ_WRITE_ENABLE_MASK BIT(0)
 #define CMDQ_POLL_ENABLE_MASK  BIT(0)
 #define CMDQ_EOC_IRQ_ENBIT(0)
+#define CMDQ_REG_TYPE  1
 
 struct cmdq_instruction {
union {
@@ -21,8 +22,17 @@ struct cmdq_instruction {
union {
u16 offset;
u16 event;
+   u16 reg_dst;
+   };
+   union {
+   u8 subsys;
+   struct {
+   u8 sop:5;
+   u8 arg_c_t:1;
+   u8 arg_b_t:1;
+   u8 dst_t:1;
+   };
};
-   u8 subsys;
u8 op;
 };
 
@@ -277,6 +287,18 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
 }
 EXPORT_SYMBOL(cmdq_pkt_poll_mask);
 
+int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
+{
+   struct cmdq_instruction inst = { {0} };
+
+   inst.op = CMDQ_CODE_LOGIC;
+   inst.dst_t = CMDQ_REG_TYPE;
+   inst.reg_dst = reg_idx;
+   inst.value = value;
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_assign);
+
 static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index dfe5b2eb85cc..121c3bb6d3de 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -59,6 +59,7 @@ enum cmdq_code {
CMDQ_CODE_JUMP = 0x10,
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
+   CMDQ_CODE_LOGIC = 0xa0,
 };
 
 enum cmdq_cb_status {
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index a74c1d5acdf3..83340211e1d3 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -152,6 +152,20 @@ int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys,
  */
 int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
   u16 offset, u32 value, u32 mask);
+
+/**
+ * cmdq_pkt_assign() - Append logic assign command to the CMDQ packet, ask GCE
+ *to execute an instruction that set a constant value into
+ *internal register and use as value, mask or address in
+ *read/write instruction.
+ * @pkt:   the CMDQ packet
+ * @reg_idx:   the CMDQ internal register ID
+ * @value: the specified value
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
+
 /**
  * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
  *  packet and call back at the end of done packet
-- 
2.18.0


[PATCH v6 01/16] dt-binding: gce: add gce header file for mt6779

2020-05-28 Thread Dennis YC Hsieh
Add documentation for the mt6779 gce.

Add gce header file defined the gce hardware event,
subsys number and constant for mt6779.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: Rob Herring 
Reviewed-by: CK Hu 
---
 .../devicetree/bindings/mailbox/mtk-gce.txt   |   8 +-
 include/dt-bindings/gce/mt6779-gce.h  | 222 ++
 2 files changed, 227 insertions(+), 3 deletions(-)
 create mode 100644 include/dt-bindings/gce/mt6779-gce.h

diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt 
b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
index 7b13787ab13d..82c0a83fed09 100644
--- a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
+++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
@@ -9,7 +9,8 @@ CMDQ driver uses mailbox framework for communication. Please 
refer to
 mailbox.txt for generic information about mailbox device-tree bindings.
 
 Required properties:
-- compatible: can be "mediatek,mt8173-gce" or "mediatek,mt8183-gce"
+- compatible: can be "mediatek,mt8173-gce", "mediatek,mt8183-gce" or
+  "mediatek,mt6779-gce".
 - reg: Address range of the GCE unit
 - interrupts: The interrupt signal from the GCE block
 - clock: Clocks according to the common clock binding
@@ -36,8 +37,9 @@ Optional properties for a client device:
   start_offset: the start offset of register address that GCE can access.
   size: the total size of register address that GCE can access.
 
-Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h'
-or 'dt-binding/gce/mt8183-gce.h'. Such as sub-system ids, thread priority, 
event ids.
+Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h',
+'dt-binding/gce/mt8183-gce.h' or 'dt-bindings/gce/mt6779-gce.h'. Such as
+sub-system ids, thread priority, event ids.
 
 Example:
 
diff --git a/include/dt-bindings/gce/mt6779-gce.h 
b/include/dt-bindings/gce/mt6779-gce.h
new file mode 100644
index ..06101316ace4
--- /dev/null
+++ b/include/dt-bindings/gce/mt6779-gce.h
@@ -0,0 +1,222 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Dennis-YC Hsieh 
+ */
+
+#ifndef _DT_BINDINGS_GCE_MT6779_H
+#define _DT_BINDINGS_GCE_MT6779_H
+
+#define CMDQ_NO_TIMEOUT0x
+
+/* GCE HW thread priority */
+#define CMDQ_THR_PRIO_LOWEST   0
+#define CMDQ_THR_PRIO_11
+#define CMDQ_THR_PRIO_22
+#define CMDQ_THR_PRIO_33
+#define CMDQ_THR_PRIO_44
+#define CMDQ_THR_PRIO_55
+#define CMDQ_THR_PRIO_66
+#define CMDQ_THR_PRIO_HIGHEST  7
+
+/* GCE subsys table */
+#define SUBSYS_13000
+#define SUBSYS_14001
+#define SUBSYS_14012
+#define SUBSYS_14023
+#define SUBSYS_15024
+#define SUBSYS_18805
+#define SUBSYS_18816
+#define SUBSYS_18827
+#define SUBSYS_18838
+#define SUBSYS_18849
+#define SUBSYS_100010
+#define SUBSYS_100111
+#define SUBSYS_100212
+#define SUBSYS_100313
+#define SUBSYS_100414
+#define SUBSYS_100515
+#define SUBSYS_102016
+#define SUBSYS_102817
+#define SUBSYS_170018
+#define SUBSYS_170119
+#define SUBSYS_170220
+#define SUBSYS_170321
+#define SUBSYS_180022
+#define SUBSYS_180123
+#define SUBSYS_180224
+#define SUBSYS_180425
+#define SUBSYS_180526
+#define SUBSYS_180827
+#define SUBSYS_180a28
+#define SUBSYS_180b29
+#define CMDQ_SUBSYS_OFF32
+
+/* GCE hardware events */
+#define CMDQ_EVENT_DISP_RDMA0_SOF  0
+#define CMDQ_EVENT_DISP_RDMA1_SOF  1
+#define CMDQ_EVENT_MDP_RDMA0_SOF   2
+#define CMDQ_EVENT_MDP_RDMA1_SOF   3
+#define CMDQ_EVENT_MDP_RSZ0_SOF4
+#define CMDQ_EVENT_MDP_RSZ1_SOF5
+#define CMDQ_EVENT_MDP_TDSHP_SOF   6
+#define CMDQ_EVENT_MDP_WROT0_SOF   7
+#define CMDQ_EVENT_MDP_WROT1_SOF   8
+#define CMDQ_EVENT_DISP_OVL0_SOF   9
+#define CMDQ_EVENT_DISP_2L_OVL0_SOF10
+#define CMDQ_EVENT_DISP_2L_OVL1_SOF11
+#define CMDQ_EVENT_DISP_WDMA0_SOF  12
+#define CMDQ_EVENT_DISP_COLOR0_SOF 13
+#define CMDQ_EVENT_DISP_CCORR0_SOF 14
+#define CMDQ_EVENT_DISP_AAL0_SOF   15
+#define CMDQ_EVENT_DISP_GAMMA0_SOF 16
+#define CMDQ_EVENT_DISP_DITHER0_SO

Re: [PATCH v6 08/16] soc: mediatek: cmdq: add write_s function

2020-05-28 Thread Dennis-YC Hsieh
Hi Matthias,

Thanks for your comment.

On Thu, 2020-05-28 at 23:08 +0200, Matthias Brugger wrote:
> 
> On 28/05/2020 19:04, Dennis YC Hsieh wrote:
> > add write_s function in cmdq helper functions which
> > writes value contains in internal register to address
> > with large dma access support.
> > 
> > Signed-off-by: Dennis YC Hsieh 
> > ---
> >  drivers/soc/mediatek/mtk-cmdq-helper.c   | 21 -
> >  include/linux/mailbox/mtk-cmdq-mailbox.h |  1 +
> >  include/linux/soc/mediatek/mtk-cmdq.h| 20 
> >  3 files changed, 41 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index 33153d17c9d9..ee24c0ec0a24 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -18,6 +18,10 @@ struct cmdq_instruction {
> > union {
> > u32 value;
> > u32 mask;
> > +   struct {
> > +   u16 arg_c;
> > +   u16 src_reg;
> > +   };
> > };
> > union {
> > u16 offset;
> > @@ -29,7 +33,7 @@ struct cmdq_instruction {
> > struct {
> > u8 sop:5;
> > u8 arg_c_t:1;
> > -   u8 arg_b_t:1;
> > +   u8 src_t:1;
> 
> This should be part of 7/16.

ok, I'll move it

> 
> > u8 dst_t:1;
> > };
> > };
> > @@ -222,6 +226,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 
> > subsys,
> >  }
> >  EXPORT_SYMBOL(cmdq_pkt_write_mask);
> >  
> > +int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> > +u16 addr_low, u16 src_reg_idx)
> > +{
> > +   struct cmdq_instruction inst = { {0} };
> 
> If you want an empty struct on the stack, I think {}; should be enough, right?

Yes, I'll change the style, thanks


Regards,
Dennis

> 
> Regards,
> Matthias
> 
> > +
> > +   inst.op = CMDQ_CODE_WRITE_S;
> > +   inst.src_t = CMDQ_REG_TYPE;
> > +   inst.sop = high_addr_reg_idx;
> > +   inst.offset = addr_low;
> > +   inst.src_reg = src_reg_idx;
> > +
> > +   return cmdq_pkt_append_command(pkt, inst);
> > +}
> > +EXPORT_SYMBOL(cmdq_pkt_write_s);
> > +
> >  int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
> >  {
> > struct cmdq_instruction inst = { {0} };
> > diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
> > b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > index 121c3bb6d3de..ee67dd3b86f5 100644
> > --- a/include/linux/mailbox/mtk-cmdq-mailbox.h
> > +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > @@ -59,6 +59,7 @@ enum cmdq_code {
> > CMDQ_CODE_JUMP = 0x10,
> > CMDQ_CODE_WFE = 0x20,
> > CMDQ_CODE_EOC = 0x40,
> > +   CMDQ_CODE_WRITE_S = 0x90,
> > CMDQ_CODE_LOGIC = 0xa0,
> >  };
> >  
> > diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
> > b/include/linux/soc/mediatek/mtk-cmdq.h
> > index 83340211e1d3..d623f1aa7814 100644
> > --- a/include/linux/soc/mediatek/mtk-cmdq.h
> > +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> > @@ -12,6 +12,8 @@
> >  #include 
> >  
> >  #define CMDQ_NO_TIMEOUT0xu
> > +#define CMDQ_ADDR_HIGH(addr)   ((u32)(((addr) >> 16) & GENMASK(31, 0)))
> > +#define CMDQ_ADDR_LOW(addr)((u16)(addr) | BIT(1))
> >  
> >  struct cmdq_pkt;
> >  
> > @@ -102,6 +104,24 @@ int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, 
> > u16 offset, u32 value);
> >  int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
> > u16 offset, u32 value, u32 mask);
> >  
> > +/**
> > + * cmdq_pkt_write_s() - append write_s command to the CMDQ packet
> > + * @pkt:   the CMDQ packet
> > + * @high_addr_reg_idx: internal register ID which contains high 
> > address of pa
> > + * @addr_low:  low address of pa
> > + * @src_reg_idx:   the CMDQ internal register ID which cache source value
> > + * @mask:  the specified target address mask, use U32_MAX if no need
> > + *
> > + * Return: 0 for success; else the error code is returned
> > + *
> > + * Support write value to physical address without subsys. Use 
> > CMDQ_ADDR_HIGH()
> > + * to get high address and call cmdq_pkt_assign() to assign value into 
> > internal
> > + * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter 
> > when
> > + * call to this function.
> > + */
> > +int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> > +u16 addr_low, u16 src_reg_idx);
> > +
> >  /**
> >   * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
> >   * @pkt:   the CMDQ packet
> > 



Re: [PATCH v5 09/13] soc: mediatek: cmdq: add write_s value function

2020-05-25 Thread Dennis-YC Hsieh

On Mon, 2020-05-25 at 10:39 +0200, Matthias Brugger wrote:
> 
> On 25/05/2020 04:27, Dennis-YC Hsieh wrote:
> > 
> > On Sun, 2020-05-24 at 20:13 +0200, Matthias Brugger wrote:
> >>
> >> On 24/05/2020 19:31, Dennis-YC Hsieh wrote:
> >>> Hi Matthias,
> >>>
> >>> Thanks for your comment.
> >>>
> >>> On Sat, 2020-05-16 at 20:20 +0200, Matthias Brugger wrote:
> >>>>
> >>>> On 08/03/2020 11:52, Dennis YC Hsieh wrote:
> >>>>> add write_s function in cmdq helper functions which
> >>>>> writes a constant value to address with large dma
> >>>>> access support.
> >>>>>
> >>>>> Signed-off-by: Dennis YC Hsieh 
> >>>>> Reviewed-by: CK Hu 
> >>>>> ---
> >>>>>  drivers/soc/mediatek/mtk-cmdq-helper.c | 26 ++
> >>>>>  include/linux/soc/mediatek/mtk-cmdq.h  | 14 ++
> >>>>>  2 files changed, 40 insertions(+)
> >>>>>
> >>>>> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> >>>>> b/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>>>> index 03c129230cd7..a9ebbabb7439 100644
> >>>>> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>>>> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>>>> @@ -269,6 +269,32 @@ int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 
> >>>>> high_addr_reg_idx,
> >>>>>  }
> >>>>>  EXPORT_SYMBOL(cmdq_pkt_write_s);
> >>>>>  
> >>>>> +int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> >>>>> +  u16 addr_low, u32 value, u32 mask)
> >>>>> +{
> >>>>> +   struct cmdq_instruction inst = { {0} };
> >>>>> +   int err;
> >>>>> +
> >>>>> +   if (mask != U32_MAX) {
> >>>>> +   inst.op = CMDQ_CODE_MASK;
> >>>>> +   inst.mask = ~mask;
> >>>>> +   err = cmdq_pkt_append_command(pkt, inst);
> >>>>> +   if (err < 0)
> >>>>> +   return err;
> >>>>> +
> >>>>> +   inst.op = CMDQ_CODE_WRITE_S_MASK;
> >>>>> +   } else {
> >>>>> +   inst.op = CMDQ_CODE_WRITE_S;
> >>>>> +   }
> >>>>> +
> >>>>> +   inst.sop = high_addr_reg_idx;
> >>>>
> >>>> Writing u16 value in a 5 bit wide variable?
> >>>
> >>> We need only 5 bits in this case. I'll change high_addr_reg_idx
> >>> parameter to u8.
> >>>
> >>
> >> Ok, please make sure to mask the value, so that it's explicit in the code 
> >> that
> >> we only use the lowest 5 bits of high_addr_reg_idx.
> > 
> > Is it necessary to mask the value?
> > Since sop already defined as "u8 sop:5;", I thought it is explicit that
> > only use 5 bits and compiler should do the rest jobs.
> 
> Yes but it makes the code more explicit if we have a
> inst.sop = high_addr_reg_idx & 0x1f;
> 
> What do you think?

The value assign to sop will restrict by hardware spec. Clients call
this function will define constant value and use it as parameter. So I
think we don't worry about client call this api with wrong value.


Regards,
Dennis

> 
> Regards,
> Matthias
> 
> > 
> > 
> > Regards,
> > Dennis
> > 
> >>
> >> Regards,
> >> Matthias
> >>
> >>>>
> >>>>> +   inst.offset = addr_low;
> >>>>> +   inst.value = value;
> >>>>> +
> >>>>> +   return cmdq_pkt_append_command(pkt, inst);
> >>>>> +}
> >>>>> +EXPORT_SYMBOL(cmdq_pkt_write_s_value);
> >>>>> +
> >>>>>  int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
> >>>>>  {
> >>>>> struct cmdq_instruction inst = { {0} };
> >>>>> diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
> >>>>> b/include/linux/soc/mediatek/mtk-cmdq.h
> >>>>> index 01b4184af310..fec292aac83c 100644
> >>>>> --- a/include/linux/soc/mediatek/mtk-cmdq.h
> >>>>> +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> >>>>> @@ -135,6 +135,20 @@ int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 
> >>>>> high_addr_reg_idx, u16 addr_low,
> >>>>>  int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> >>>>>  u16 addr_low, u16 src_reg_idx, u32 mask);
> >>>>>  
> >>>>> +/**
> >>>>> + * cmdq_pkt_write_s_value() - append write_s command with mask to the 
> >>>>> CMDQ
> >>>>> + *   packet which write value to a physical 
> >>>>> address
> >>>>> + * @pkt:   the CMDQ packet
> >>>>> + * @high_addr_reg_idx: internal regisger ID which contains high 
> >>>>> address of pa
> >>>>
> >>>> register
> >>>
> >>> will fix
> >>>
> >>>
> >>> Regards,
> >>> Dennis
> >>>
> >>>>
> >>>>> + * @addr_low:  low address of pa
> >>>>> + * @value: the specified target value
> >>>>> + * @mask:  the specified target mask
> >>>>> + *
> >>>>> + * Return: 0 for success; else the error code is returned
> >>>>> + */
> >>>>> +int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> >>>>> +  u16 addr_low, u32 value, u32 mask);
> >>>>> +
> >>>>>  /**
> >>>>>   * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
> >>>>>   * @pkt:   the CMDQ packet
> >>>>>
> >>>
> > 



Re: [PATCH v5 06/13] soc: mediatek: cmdq: add assign function

2020-05-24 Thread Dennis-YC Hsieh
Hi Matthias,

Thanks for your comment.

On Sat, 2020-05-16 at 19:59 +0200, Matthias Brugger wrote:
> 
> On 08/03/2020 11:52, Dennis YC Hsieh wrote:
> > Add assign function in cmdq helper which assign constant value into
> > internal register by index.
> > 
> > Signed-off-by: Dennis YC Hsieh 
> > Reviewed-by: CK Hu 
> > ---
> >  drivers/soc/mediatek/mtk-cmdq-helper.c   | 24 +++-
> >  include/linux/mailbox/mtk-cmdq-mailbox.h |  1 +
> >  include/linux/soc/mediatek/mtk-cmdq.h| 14 ++
> >  3 files changed, 38 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index 98f23ba3ba47..33153d17c9d9 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -12,6 +12,7 @@
> >  #define CMDQ_WRITE_ENABLE_MASK BIT(0)
> >  #define CMDQ_POLL_ENABLE_MASK  BIT(0)
> >  #define CMDQ_EOC_IRQ_ENBIT(0)
> > +#define CMDQ_REG_TYPE  1
> >  
> >  struct cmdq_instruction {
> > union {
> > @@ -21,8 +22,17 @@ struct cmdq_instruction {
> > union {
> > u16 offset;
> > u16 event;
> > +   u16 reg_dst;
> > +   };
> > +   union {
> > +   u8 subsys;
> > +   struct {
> > +   u8 sop:5;
> > +   u8 arg_c_t:1;
> > +   u8 arg_b_t:1;
> > +   u8 dst_t:1;
> > +   };
> 
> This union seems without context in this patch. Please drop.
> 

The dst_t use in cmdq_pkt_assign function so how about merge other
variables to reserved and leave dst_t ?

struct {
u8 reserved_t:7;
u8 dst_t:1;
};


Regards,
Dennis


> Regards,
> Matthias
> 
> > };
> > -   u8 subsys;
> > u8 op;
> >  };
> >  
> > @@ -277,6 +287,18 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
> >  }
> >  EXPORT_SYMBOL(cmdq_pkt_poll_mask);
> >  
> > +int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
> > +{
> > +   struct cmdq_instruction inst = { {0} };
> > +
> > +   inst.op = CMDQ_CODE_LOGIC;
> > +   inst.dst_t = CMDQ_REG_TYPE;
> > +   inst.reg_dst = reg_idx;
> > +   inst.value = value;
> > +   return cmdq_pkt_append_command(pkt, inst);
> > +}
> > +EXPORT_SYMBOL(cmdq_pkt_assign);
> > +
> >  static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
> >  {
> > struct cmdq_instruction inst = { {0} };
> > diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
> > b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > index dfe5b2eb85cc..121c3bb6d3de 100644
> > --- a/include/linux/mailbox/mtk-cmdq-mailbox.h
> > +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > @@ -59,6 +59,7 @@ enum cmdq_code {
> > CMDQ_CODE_JUMP = 0x10,
> > CMDQ_CODE_WFE = 0x20,
> > CMDQ_CODE_EOC = 0x40,
> > +   CMDQ_CODE_LOGIC = 0xa0,
> >  };
> >  
> >  enum cmdq_cb_status {
> > diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
> > b/include/linux/soc/mediatek/mtk-cmdq.h
> > index a74c1d5acdf3..83340211e1d3 100644
> > --- a/include/linux/soc/mediatek/mtk-cmdq.h
> > +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> > @@ -152,6 +152,20 @@ int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys,
> >   */
> >  int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
> >u16 offset, u32 value, u32 mask);
> > +
> > +/**
> > + * cmdq_pkt_assign() - Append logic assign command to the CMDQ packet, ask 
> > GCE
> > + *to execute an instruction that set a constant value into
> > + *internal register and use as value, mask or address in
> > + *read/write instruction.
> > + * @pkt:   the CMDQ packet
> > + * @reg_idx:   the CMDQ internal register ID
> > + * @value: the specified value
> > + *
> > + * Return: 0 for success; else the error code is returned
> > + */
> > +int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
> > +
> >  /**
> >   * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
> >   *  packet and call back at the end of done packet
> > 



Re: [PATCH v5 07/13] soc: mediatek: cmdq: add write_s function

2020-05-24 Thread Dennis-YC Hsieh
Hi Mattias,

Thanks for your comment.

On Sat, 2020-05-16 at 20:14 +0200, Matthias Brugger wrote:
> 
> On 08/03/2020 11:52, Dennis YC Hsieh wrote:
> > add write_s function in cmdq helper functions which
> > writes value contains in internal register to address
> > with large dma access support.
> > 
> > Signed-off-by: Dennis YC Hsieh 
> > Reviewed-by: CK Hu 
> > ---
> >  drivers/soc/mediatek/mtk-cmdq-helper.c   | 34 +++-
> >  include/linux/mailbox/mtk-cmdq-mailbox.h |  2 ++
> >  include/linux/soc/mediatek/mtk-cmdq.h| 20 ++
> >  3 files changed, 55 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index 33153d17c9d9..90f1ff2b4b00 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -18,6 +18,10 @@ struct cmdq_instruction {
> > union {
> > u32 value;
> > u32 mask;
> > +   struct {
> > +   u16 arg_c;
> > +   u16 src_reg;
> > +   };
> > };
> > union {
> > u16 offset;
> > @@ -29,7 +33,7 @@ struct cmdq_instruction {
> > struct {
> > u8 sop:5;
> > u8 arg_c_t:1;
> > -   u8 arg_b_t:1;
> > +   u8 src_t:1;
> 
> fixing patch 6/13 please. seems the struct should be added in this patch.

ok, will move to this patch.

> 
> > u8 dst_t:1;
> > };
> > };
> > @@ -222,6 +226,34 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 
> > subsys,
> >  }
> >  EXPORT_SYMBOL(cmdq_pkt_write_mask);
> >  
> > +int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> > +u16 addr_low, u16 src_reg_idx, u32 mask)
> > +{
> > +   struct cmdq_instruction inst = { {0} };
> > +   int err;
> > +
> > +   if (mask != U32_MAX) {
> > +   inst.op = CMDQ_CODE_MASK;
> > +   inst.mask = ~mask;
> > +   err = cmdq_pkt_append_command(pkt, inst);
> > +   if (err < 0)
> > +   return err;
> > +
> > +   inst.mask = 0;
> > +   inst.op = CMDQ_CODE_WRITE_S_MASK;
> > +   } else {
> > +   inst.op = CMDQ_CODE_WRITE_S;
> > +   }
> > +
> > +   inst.src_t = CMDQ_REG_TYPE;
> 
> Not defined.
> Please make sure that every patch compiles on it's own and does not add a
> regression. This is very helpful if we have to bisect the kernel in the 
> future.

May I know which part not defined? The src_t defined on top of this
patch and CMDQ_REG_TYPE defined in last patc (see 06/13).

> 
> > +   inst.sop = high_addr_reg_idx;
> > +   inst.offset = addr_low;
> > +   inst.src_reg = src_reg_idx;
> > +
> > +   return cmdq_pkt_append_command(pkt, inst);
> > +}
> > +EXPORT_SYMBOL(cmdq_pkt_write_s);
> > +
> >  int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
> >  {
> > struct cmdq_instruction inst = { {0} };
> > diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
> > b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > index 121c3bb6d3de..8ef87e1bd03b 100644
> > --- a/include/linux/mailbox/mtk-cmdq-mailbox.h
> > +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > @@ -59,6 +59,8 @@ enum cmdq_code {
> > CMDQ_CODE_JUMP = 0x10,
> > CMDQ_CODE_WFE = 0x20,
> > CMDQ_CODE_EOC = 0x40,
> > +   CMDQ_CODE_WRITE_S = 0x90,
> > +   CMDQ_CODE_WRITE_S_MASK = 0x91,
> > CMDQ_CODE_LOGIC = 0xa0,
> >  };
> >  
> > diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
> > b/include/linux/soc/mediatek/mtk-cmdq.h
> > index 83340211e1d3..c72d826d8934 100644
> > --- a/include/linux/soc/mediatek/mtk-cmdq.h
> > +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> > @@ -12,6 +12,8 @@
> >  #include 
> >  
> >  #define CMDQ_NO_TIMEOUT0xu
> > +#define CMDQ_ADDR_HIGH(addr)   ((u32)(((addr) >> 16) & GENMASK(31, 0)))
> > +#define CMDQ_ADDR_LOW(addr)((u16)(addr) | BIT(1))
> >  
> >  struct cmdq_pkt;
> >  
> > @@ -102,6 +104,24 @@ int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, 
> > u16 offset, u32 value);
> >  int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
> > u16 offset, u32 value, u32 mask);
> >  
> > +/**
> > + * cmdq_pkt_write_s() - append write_s command to the CMDQ packet

Re: [PATCH v5 09/13] soc: mediatek: cmdq: add write_s value function

2020-05-24 Thread Dennis-YC Hsieh
Hi Matthias,

Thanks for your comment.

On Sat, 2020-05-16 at 20:20 +0200, Matthias Brugger wrote:
> 
> On 08/03/2020 11:52, Dennis YC Hsieh wrote:
> > add write_s function in cmdq helper functions which
> > writes a constant value to address with large dma
> > access support.
> > 
> > Signed-off-by: Dennis YC Hsieh 
> > Reviewed-by: CK Hu 
> > ---
> >  drivers/soc/mediatek/mtk-cmdq-helper.c | 26 ++
> >  include/linux/soc/mediatek/mtk-cmdq.h  | 14 ++
> >  2 files changed, 40 insertions(+)
> > 
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index 03c129230cd7..a9ebbabb7439 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -269,6 +269,32 @@ int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 
> > high_addr_reg_idx,
> >  }
> >  EXPORT_SYMBOL(cmdq_pkt_write_s);
> >  
> > +int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> > +  u16 addr_low, u32 value, u32 mask)
> > +{
> > +   struct cmdq_instruction inst = { {0} };
> > +   int err;
> > +
> > +   if (mask != U32_MAX) {
> > +   inst.op = CMDQ_CODE_MASK;
> > +   inst.mask = ~mask;
> > +   err = cmdq_pkt_append_command(pkt, inst);
> > +   if (err < 0)
> > +   return err;
> > +
> > +   inst.op = CMDQ_CODE_WRITE_S_MASK;
> > +   } else {
> > +   inst.op = CMDQ_CODE_WRITE_S;
> > +   }
> > +
> > +   inst.sop = high_addr_reg_idx;
> 
> Writing u16 value in a 5 bit wide variable?

We need only 5 bits in this case. I'll change high_addr_reg_idx
parameter to u8.

> 
> > +   inst.offset = addr_low;
> > +   inst.value = value;
> > +
> > +   return cmdq_pkt_append_command(pkt, inst);
> > +}
> > +EXPORT_SYMBOL(cmdq_pkt_write_s_value);
> > +
> >  int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
> >  {
> > struct cmdq_instruction inst = { {0} };
> > diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
> > b/include/linux/soc/mediatek/mtk-cmdq.h
> > index 01b4184af310..fec292aac83c 100644
> > --- a/include/linux/soc/mediatek/mtk-cmdq.h
> > +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> > @@ -135,6 +135,20 @@ int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 
> > high_addr_reg_idx, u16 addr_low,
> >  int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> >  u16 addr_low, u16 src_reg_idx, u32 mask);
> >  
> > +/**
> > + * cmdq_pkt_write_s_value() - append write_s command with mask to the CMDQ
> > + *   packet which write value to a physical address
> > + * @pkt:   the CMDQ packet
> > + * @high_addr_reg_idx: internal regisger ID which contains high 
> > address of pa
> 
> register

will fix


Regards,
Dennis

> 
> > + * @addr_low:  low address of pa
> > + * @value: the specified target value
> > + * @mask:  the specified target mask
> > + *
> > + * Return: 0 for success; else the error code is returned
> > + */
> > +int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> > +  u16 addr_low, u32 value, u32 mask);
> > +
> >  /**
> >   * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
> >   * @pkt:   the CMDQ packet
> > 



Re: [PATCH v5 10/13] soc: mediatek: cmdq: export finalize function

2020-05-24 Thread Dennis-YC Hsieh
Hi Matthias,

Thanks for your comment.

On Sat, 2020-05-16 at 20:22 +0200, Matthias Brugger wrote:
> 
> On 08/03/2020 11:52, Dennis YC Hsieh wrote:
> > Export finalize function to client which helps append eoc and jump
> > command to pkt. Let client decide call finalize or not.
> > 
> > Signed-off-by: Dennis YC Hsieh 
> > Reviewed-by: CK Hu 
> > ---
> >  drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 1 +
> >  drivers/soc/mediatek/mtk-cmdq-helper.c  | 7 ++-
> >  include/linux/soc/mediatek/mtk-cmdq.h   | 8 
> >  3 files changed, 11 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> > b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > index 0dfcd1787e65..7daaabc26eb1 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > @@ -490,6 +490,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
> > *mtk_crtc)
> > cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
> > cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event);
> > mtk_crtc_ddp_config(crtc, cmdq_handle);
> > +   cmdq_pkt_finalize(cmdq_handle);
> > cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
> > }
> >  #endif
> 
> This should be a independent patch.
> Other then that patch looks good.

ok, I'll separate this part.


Regards,
Dennis

> 
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index a9ebbabb7439..59bc1164b411 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -372,7 +372,7 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, 
> > u32 value)
> >  }
> >  EXPORT_SYMBOL(cmdq_pkt_assign);
> >  
> > -static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
> > +int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
> >  {
> > struct cmdq_instruction inst = { {0} };
> > int err;
> > @@ -392,6 +392,7 @@ static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
> >  
> > return err;
> >  }
> > +EXPORT_SYMBOL(cmdq_pkt_finalize);
> >  
> >  static void cmdq_pkt_flush_async_cb(struct cmdq_cb_data data)
> >  {
> > @@ -426,10 +427,6 @@ int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, 
> > cmdq_async_flush_cb cb,
> > unsigned long flags = 0;
> > struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
> >  
> > -   err = cmdq_pkt_finalize(pkt);
> > -   if (err < 0)
> > -   return err;
> > -
> > pkt->cb.cb = cb;
> > pkt->cb.data = data;
> > pkt->async_cb.cb = cmdq_pkt_flush_async_cb;
> > diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
> > b/include/linux/soc/mediatek/mtk-cmdq.h
> > index fec292aac83c..99e77155f967 100644
> > --- a/include/linux/soc/mediatek/mtk-cmdq.h
> > +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> > @@ -213,6 +213,14 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
> >   */
> >  int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
> >  
> > +/**
> > + * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
> > + * @pkt:   the CMDQ packet
> > + *
> > + * Return: 0 for success; else the error code is returned
> > + */
> > +int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
> > +
> >  /**
> >   * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
> >   *  packet and call back at the end of done packet
> > 



Re: [PATCH v5 12/13] soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api

2020-05-24 Thread Dennis-YC Hsieh
Hi Matthias,

Thanks for your comment.


On Sat, 2020-05-16 at 20:30 +0200, Matthias Brugger wrote:
> 
> On 08/03/2020 11:52, Dennis YC Hsieh wrote:
> > Add clear parameter to let client decide if
> > event should be clear to 0 after GCE receive it.
> > 
> > Signed-off-by: Dennis YC Hsieh 
> > ---
> >  drivers/gpu/drm/mediatek/mtk_drm_crtc.c  | 2 +-
> >  drivers/soc/mediatek/mtk-cmdq-helper.c   | 5 +++--
> >  include/linux/mailbox/mtk-cmdq-mailbox.h | 3 +--
> >  include/linux/soc/mediatek/mtk-cmdq.h| 5 +++--
> >  4 files changed, 8 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> > b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > index 7daaabc26eb1..a065b3a412cf 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > @@ -488,7 +488,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
> > *mtk_crtc)
> > if (mtk_crtc->cmdq_client) {
> > cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE);
> > cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
> > -   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event);
> > +   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
> > mtk_crtc_ddp_config(crtc, cmdq_handle);
> > cmdq_pkt_finalize(cmdq_handle);
> > cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
> 
> This should be an independent patch

ok, I'll separate this part.


Regards,
Dennis

> 
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index bb5be20fc70a..ec5637d43254 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -296,15 +296,16 @@ int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u16 
> > high_addr_reg_idx,
> >  }
> >  EXPORT_SYMBOL(cmdq_pkt_write_s_value);
> >  
> > -int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
> > +int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear)
> >  {
> > struct cmdq_instruction inst = { {0} };
> > +   u32 clear_option = clear ? CMDQ_WFE_UPDATE : 0;
> >  
> > if (event >= CMDQ_MAX_EVENT)
> > return -EINVAL;
> >  
> > inst.op = CMDQ_CODE_WFE;
> > -   inst.value = CMDQ_WFE_OPTION;
> > +   inst.value = CMDQ_WFE_OPTION | clear_option;
> > inst.event = event;
> >  
> > return cmdq_pkt_append_command(pkt, inst);
> > diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
> > b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > index 3f6bc0dfd5da..42d2a30e6a70 100644
> > --- a/include/linux/mailbox/mtk-cmdq-mailbox.h
> > +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > @@ -27,8 +27,7 @@
> >   * bit 16-27: update value
> >   * bit 31: 1 - update, 0 - no update
> >   */
> > -#define CMDQ_WFE_OPTION(CMDQ_WFE_UPDATE | 
> > CMDQ_WFE_WAIT | \
> > -   CMDQ_WFE_WAIT_VALUE)
> > +#define CMDQ_WFE_OPTION(CMDQ_WFE_WAIT | 
> > CMDQ_WFE_WAIT_VALUE)
> >  
> >  /** cmdq event maximum */
> >  #define CMDQ_MAX_EVENT 0x3ff
> > diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
> > b/include/linux/soc/mediatek/mtk-cmdq.h
> > index 1a6c56f3bec1..d63749440697 100644
> > --- a/include/linux/soc/mediatek/mtk-cmdq.h
> > +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> > @@ -152,11 +152,12 @@ int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u16 
> > high_addr_reg_idx,
> >  /**
> >   * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
> >   * @pkt:   the CMDQ packet
> > - * @event: the desired event type to "wait and CLEAR"
> > + * @event: the desired event type to wait
> > + * @clear: clear event or not after event arrive
> >   *
> >   * Return: 0 for success; else the error code is returned
> >   */
> > -int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event);
> > +int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear);
> >  
> >  /**
> >   * cmdq_pkt_clear_event() - append clear event command to the CMDQ packet
> > 



Re: [PATCH v5 13/13] soc: mediatek: cmdq: add set event function

2020-05-24 Thread Dennis-YC Hsieh
Hi Matthias,

Thanks for your comment.


On Sat, 2020-05-16 at 20:32 +0200, Matthias Brugger wrote:
> 
> On 08/03/2020 11:52, Dennis YC Hsieh wrote:
> > Add set event function in cmdq helper functions to set specific event.
> > 
> > Signed-off-by: Dennis YC Hsieh 
> > Reviewed-by: CK Hu 
> > ---
> >  drivers/soc/mediatek/mtk-cmdq-helper.c   | 15 +++
> >  include/linux/mailbox/mtk-cmdq-mailbox.h |  1 +
> >  include/linux/soc/mediatek/mtk-cmdq.h|  9 +
> >  3 files changed, 25 insertions(+)
> > 
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index ec5637d43254..3294c9285994 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -327,6 +327,21 @@ int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 
> > event)
> >  }
> >  EXPORT_SYMBOL(cmdq_pkt_clear_event);
> >  
> > +int cmdq_pkt_set_event(struct cmdq_pkt *pkt, u16 event)
> > +{
> > +   struct cmdq_instruction inst = { {0} };
> > +
> > +   if (event >= CMDQ_MAX_EVENT)
> > +   return -EINVAL;
> > +
> > +   inst.op = CMDQ_CODE_WFE;
> > +   inst.value = CMDQ_WFE_UPDATE | CMDQ_WFE_UPDATE_VALUE;
> > +   inst.event = event;
> > +
> > +   return cmdq_pkt_append_command(pkt, inst);
> > +}
> > +EXPORT_SYMBOL(cmdq_pkt_set_event);
> > +
> >  int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys,
> >   u16 offset, u32 value)
> >  {
> > diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
> > b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > index 42d2a30e6a70..ba2d811183a9 100644
> > --- a/include/linux/mailbox/mtk-cmdq-mailbox.h
> > +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > @@ -17,6 +17,7 @@
> >  #define CMDQ_JUMP_PASS CMDQ_INST_SIZE
> >  
> >  #define CMDQ_WFE_UPDATEBIT(31)
> > +#define CMDQ_WFE_UPDATE_VALUE  BIT(16)
> >  #define CMDQ_WFE_WAIT  BIT(15)
> >  #define CMDQ_WFE_WAIT_VALUE0x1
> >  
> > diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
> > b/include/linux/soc/mediatek/mtk-cmdq.h
> > index d63749440697..ca70296ae120 100644
> > --- a/include/linux/soc/mediatek/mtk-cmdq.h
> > +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> > @@ -168,6 +168,15 @@ int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool 
> > clear);
> >   */
> >  int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event);
> >  
> > +/**
> > + * cmdq_pkt_set_event() - append set event command to the CMDQ packet
> > + * @pkt:   the CMDQ packet
> > + * @event: the desired event to be set
> 
> Can we add the events and their code, so that later on, when a consumer calls
> cmdq_pkt_set_event() we don't have any magic values that are hard to 
> understand?

Please see patch 02/13:
http://lists.infradead.org/pipermail/linux-mediatek/2020-March/027801.html

Definitions begin with CMDQ_EVENT_ is the event id to this function.
Since the event id is different between platform, client must parse it
from device tree. So no magic values require when call this function.


Regard,
Dennis


> 
> Regards,
> Matthias
> 
> > + *
> > + * Return: 0 for success; else the error code is returned
> > + */
> > +int cmdq_pkt_set_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
> > 



Re: [PATCH v5 09/13] soc: mediatek: cmdq: add write_s value function

2020-05-24 Thread Dennis-YC Hsieh

On Sun, 2020-05-24 at 20:13 +0200, Matthias Brugger wrote:
> 
> On 24/05/2020 19:31, Dennis-YC Hsieh wrote:
> > Hi Matthias,
> > 
> > Thanks for your comment.
> > 
> > On Sat, 2020-05-16 at 20:20 +0200, Matthias Brugger wrote:
> >>
> >> On 08/03/2020 11:52, Dennis YC Hsieh wrote:
> >>> add write_s function in cmdq helper functions which
> >>> writes a constant value to address with large dma
> >>> access support.
> >>>
> >>> Signed-off-by: Dennis YC Hsieh 
> >>> Reviewed-by: CK Hu 
> >>> ---
> >>>  drivers/soc/mediatek/mtk-cmdq-helper.c | 26 ++
> >>>  include/linux/soc/mediatek/mtk-cmdq.h  | 14 ++
> >>>  2 files changed, 40 insertions(+)
> >>>
> >>> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> >>> b/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>> index 03c129230cd7..a9ebbabb7439 100644
> >>> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>> @@ -269,6 +269,32 @@ int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 
> >>> high_addr_reg_idx,
> >>>  }
> >>>  EXPORT_SYMBOL(cmdq_pkt_write_s);
> >>>  
> >>> +int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> >>> +u16 addr_low, u32 value, u32 mask)
> >>> +{
> >>> + struct cmdq_instruction inst = { {0} };
> >>> + int err;
> >>> +
> >>> + if (mask != U32_MAX) {
> >>> + inst.op = CMDQ_CODE_MASK;
> >>> + inst.mask = ~mask;
> >>> + err = cmdq_pkt_append_command(pkt, inst);
> >>> + if (err < 0)
> >>> + return err;
> >>> +
> >>> + inst.op = CMDQ_CODE_WRITE_S_MASK;
> >>> + } else {
> >>> + inst.op = CMDQ_CODE_WRITE_S;
> >>> + }
> >>> +
> >>> + inst.sop = high_addr_reg_idx;
> >>
> >> Writing u16 value in a 5 bit wide variable?
> > 
> > We need only 5 bits in this case. I'll change high_addr_reg_idx
> > parameter to u8.
> > 
> 
> Ok, please make sure to mask the value, so that it's explicit in the code that
> we only use the lowest 5 bits of high_addr_reg_idx.

Is it necessary to mask the value?
Since sop already defined as "u8 sop:5;", I thought it is explicit that
only use 5 bits and compiler should do the rest jobs.


Regards,
Dennis

> 
> Regards,
> Matthias
> 
> >>
> >>> + inst.offset = addr_low;
> >>> + inst.value = value;
> >>> +
> >>> + return cmdq_pkt_append_command(pkt, inst);
> >>> +}
> >>> +EXPORT_SYMBOL(cmdq_pkt_write_s_value);
> >>> +
> >>>  int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
> >>>  {
> >>>   struct cmdq_instruction inst = { {0} };
> >>> diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
> >>> b/include/linux/soc/mediatek/mtk-cmdq.h
> >>> index 01b4184af310..fec292aac83c 100644
> >>> --- a/include/linux/soc/mediatek/mtk-cmdq.h
> >>> +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> >>> @@ -135,6 +135,20 @@ int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 
> >>> high_addr_reg_idx, u16 addr_low,
> >>>  int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> >>>u16 addr_low, u16 src_reg_idx, u32 mask);
> >>>  
> >>> +/**
> >>> + * cmdq_pkt_write_s_value() - append write_s command with mask to the 
> >>> CMDQ
> >>> + * packet which write value to a physical 
> >>> address
> >>> + * @pkt: the CMDQ packet
> >>> + * @high_addr_reg_idx:   internal regisger ID which contains high 
> >>> address of pa
> >>
> >> register
> > 
> > will fix
> > 
> > 
> > Regards,
> > Dennis
> > 
> >>
> >>> + * @addr_low:low address of pa
> >>> + * @value:   the specified target value
> >>> + * @mask:the specified target mask
> >>> + *
> >>> + * Return: 0 for success; else the error code is returned
> >>> + */
> >>> +int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> >>> +u16 addr_low, u32 value, u32 mask);
> >>> +
> >>>  /**
> >>>   * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
> >>>   * @pkt: the CMDQ packet
> >>>
> > 



[PATCH v8 2/4] mailbox: cmdq: variablize address shift in platform

2020-07-04 Thread Dennis YC Hsieh
Some gce hardware shift pc and end address in register to support
large dram addressing.
Implement gce address shift when write or read pc and end register.
And add shift bit in platform definition.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/mailbox/mtk-cmdq-mailbox.c   |   57 +++---
 include/linux/mailbox/mtk-cmdq-mailbox.h |2 ++
 2 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
b/drivers/mailbox/mtk-cmdq-mailbox.c
index b24822ad8409..49d9264145aa 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -75,8 +75,22 @@ struct cmdq {
struct cmdq_thread  *thread;
struct clk  *clock;
boolsuspended;
+   u8  shift_pa;
 };
 
+struct gce_plat {
+   u32 thread_nr;
+   u8 shift;
+};
+
+u8 cmdq_get_shift_pa(struct mbox_chan *chan)
+{
+   struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox);
+
+   return cmdq->shift_pa;
+}
+EXPORT_SYMBOL(cmdq_get_shift_pa);
+
 static int cmdq_thread_suspend(struct cmdq *cmdq, struct cmdq_thread *thread)
 {
u32 status;
@@ -183,13 +197,15 @@ static void cmdq_task_handle_error(struct cmdq_task *task)
 {
struct cmdq_thread *thread = task->thread;
struct cmdq_task *next_task;
+   struct cmdq *cmdq = task->cmdq;
 
-   dev_err(task->cmdq->mbox.dev, "task 0x%p error\n", task);
-   WARN_ON(cmdq_thread_suspend(task->cmdq, thread) < 0);
+   dev_err(cmdq->mbox.dev, "task 0x%p error\n", task);
+   WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
next_task = list_first_entry_or_null(&thread->task_busy_list,
struct cmdq_task, list_entry);
if (next_task)
-   writel(next_task->pa_base, thread->base + CMDQ_THR_CURR_ADDR);
+   writel(next_task->pa_base >> cmdq->shift_pa,
+  thread->base + CMDQ_THR_CURR_ADDR);
cmdq_thread_resume(thread);
 }
 
@@ -219,7 +235,7 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
else
return;
 
-   curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR);
+   curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) << cmdq->shift_pa;
 
list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
 list_entry) {
@@ -335,27 +351,31 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, 
void *data)
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,
+   writel(task->pa_base >> cmdq->shift_pa,
+  thread->base + CMDQ_THR_CURR_ADDR);
+   writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->shift_pa,
   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);
} 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);
+   curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) <<
+   cmdq->shift_pa;
+   end_pa = readl(thread->base + CMDQ_THR_END_ADDR) <<
+   cmdq->shift_pa;
/* check boundary */
if (curr_pa == end_pa - CMDQ_INST_SIZE ||
curr_pa == end_pa) {
/* set to this task directly */
-   writel(task->pa_base,
+   writel(task->pa_base >> cmdq->shift_pa,
   thread->base + CMDQ_THR_CURR_ADDR);
} else {
cmdq_task_insert_into_thread(task);
smp_mb(); /* modify jump before enable thread */
}
-   writel(task->pa_base + pkt->cmd_buf_size,
+   writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->shift_pa,
   thread->base + CMDQ_THR_END_ADDR);
cmdq_thread_resume(thread);
}
@@ -453,6 +473,7 @@ static int cmdq_probe(struct platform_device *pdev)
struct resource *res;
struct cmdq *cmdq;
int err, i;
+   struct gce_plat *plat_data;
 
cmdq = devm_kzalloc(dev, sizeof(*cmdq), GFP_KERNEL);
if (!cmdq)
@@ -471,7 +492,14 @@

[PATCH v8 0/4] support gce on mt6779 platform

2020-07-04 Thread Dennis YC Hsieh
This patch support gce on mt6779 platform.

Change since v7:
- Rename cmdq_mbox_shift() to cmdq_get_shift_pa().

Change since v6:
- Separate all helper function to another patchset.

Change since v5:
- spearate address shift code in client helper and mailbox controller
- separate write_s/write_s_mask and write_s_value/write_s_mask_value so that
  client can decide use mask or not
- fix typo in header

[... snip ...]


Dennis YC Hsieh (4):
  dt-binding: gce: add gce header file for mt6779
  mailbox: cmdq: variablize address shift in platform
  mailbox: cmdq: support mt6779 gce platform definition
  mailbox: mediatek: cmdq: clear task in channel before shutdown

 .../devicetree/bindings/mailbox/mtk-gce.txt   |   8 +-
 drivers/mailbox/mtk-cmdq-mailbox.c|  97 +++-
 include/dt-bindings/gce/mt6779-gce.h  | 222 ++
 include/linux/mailbox/mtk-cmdq-mailbox.h  |   2 +
 4 files changed, 313 insertions(+), 16 deletions(-)
 create mode 100644 include/dt-bindings/gce/mt6779-gce.h

-- 
2.18.0

[PATCH v8 3/4] mailbox: cmdq: support mt6779 gce platform definition

2020-07-04 Thread Dennis YC Hsieh
Add gce v4 hardware support with different thread number and shift.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
Reviewed-by: Matthias Brugger 
Reviewed-by: Bibby Hsieh 
---
 drivers/mailbox/mtk-cmdq-mailbox.c |2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
b/drivers/mailbox/mtk-cmdq-mailbox.c
index 49d9264145aa..08bd4f1eb469 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -564,10 +564,12 @@ static int cmdq_probe(struct platform_device *pdev)
 
 static const struct gce_plat gce_plat_v2 = {.thread_nr = 16};
 static const struct gce_plat gce_plat_v3 = {.thread_nr = 24};
+static const struct gce_plat gce_plat_v4 = {.thread_nr = 24, .shift = 3};
 
 static const struct of_device_id cmdq_of_ids[] = {
{.compatible = "mediatek,mt8173-gce", .data = (void *)&gce_plat_v2},
{.compatible = "mediatek,mt8183-gce", .data = (void *)&gce_plat_v3},
+   {.compatible = "mediatek,mt6779-gce", .data = (void *)&gce_plat_v4},
{}
 };
 
-- 
1.7.9.5


[PATCH v8 1/4] dt-binding: gce: add gce header file for mt6779

2020-07-04 Thread Dennis YC Hsieh
Add documentation for the mt6779 gce.

Add gce header file defined the gce hardware event,
subsys number and constant for mt6779.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: Rob Herring 
Reviewed-by: CK Hu 
Reviewed-by: Bibby Hsieh 
---
 .../devicetree/bindings/mailbox/mtk-gce.txt|8 +-
 include/dt-bindings/gce/mt6779-gce.h   |  222 
 2 files changed, 227 insertions(+), 3 deletions(-)
 create mode 100644 include/dt-bindings/gce/mt6779-gce.h

diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt 
b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
index 0b5b2a6bcc48..cf48cd806e00 100644
--- a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
+++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
@@ -9,7 +9,8 @@ CMDQ driver uses mailbox framework for communication. Please 
refer to
 mailbox.txt for generic information about mailbox device-tree bindings.
 
 Required properties:
-- compatible: can be "mediatek,mt8173-gce" or "mediatek,mt8183-gce"
+- compatible: can be "mediatek,mt8173-gce", "mediatek,mt8183-gce" or
+  "mediatek,mt6779-gce".
 - reg: Address range of the GCE unit
 - interrupts: The interrupt signal from the GCE block
 - clock: Clocks according to the common clock binding
@@ -34,8 +35,9 @@ Optional properties for a client device:
   start_offset: the start offset of register address that GCE can access.
   size: the total size of register address that GCE can access.
 
-Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h'
-or 'dt-binding/gce/mt8183-gce.h'. Such as sub-system ids, thread priority, 
event ids.
+Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h',
+'dt-binding/gce/mt8183-gce.h' or 'dt-bindings/gce/mt6779-gce.h'. Such as
+sub-system ids, thread priority, event ids.
 
 Example:
 
diff --git a/include/dt-bindings/gce/mt6779-gce.h 
b/include/dt-bindings/gce/mt6779-gce.h
new file mode 100644
index ..06101316ace4
--- /dev/null
+++ b/include/dt-bindings/gce/mt6779-gce.h
@@ -0,0 +1,222 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Dennis-YC Hsieh 
+ */
+
+#ifndef _DT_BINDINGS_GCE_MT6779_H
+#define _DT_BINDINGS_GCE_MT6779_H
+
+#define CMDQ_NO_TIMEOUT0x
+
+/* GCE HW thread priority */
+#define CMDQ_THR_PRIO_LOWEST   0
+#define CMDQ_THR_PRIO_11
+#define CMDQ_THR_PRIO_22
+#define CMDQ_THR_PRIO_33
+#define CMDQ_THR_PRIO_44
+#define CMDQ_THR_PRIO_55
+#define CMDQ_THR_PRIO_66
+#define CMDQ_THR_PRIO_HIGHEST  7
+
+/* GCE subsys table */
+#define SUBSYS_13000
+#define SUBSYS_14001
+#define SUBSYS_14012
+#define SUBSYS_14023
+#define SUBSYS_15024
+#define SUBSYS_18805
+#define SUBSYS_18816
+#define SUBSYS_18827
+#define SUBSYS_18838
+#define SUBSYS_18849
+#define SUBSYS_100010
+#define SUBSYS_100111
+#define SUBSYS_100212
+#define SUBSYS_100313
+#define SUBSYS_100414
+#define SUBSYS_100515
+#define SUBSYS_102016
+#define SUBSYS_102817
+#define SUBSYS_170018
+#define SUBSYS_170119
+#define SUBSYS_170220
+#define SUBSYS_170321
+#define SUBSYS_180022
+#define SUBSYS_180123
+#define SUBSYS_180224
+#define SUBSYS_180425
+#define SUBSYS_180526
+#define SUBSYS_180827
+#define SUBSYS_180a28
+#define SUBSYS_180b29
+#define CMDQ_SUBSYS_OFF32
+
+/* GCE hardware events */
+#define CMDQ_EVENT_DISP_RDMA0_SOF  0
+#define CMDQ_EVENT_DISP_RDMA1_SOF  1
+#define CMDQ_EVENT_MDP_RDMA0_SOF   2
+#define CMDQ_EVENT_MDP_RDMA1_SOF   3
+#define CMDQ_EVENT_MDP_RSZ0_SOF4
+#define CMDQ_EVENT_MDP_RSZ1_SOF5
+#define CMDQ_EVENT_MDP_TDSHP_SOF   6
+#define CMDQ_EVENT_MDP_WROT0_SOF   7
+#define CMDQ_EVENT_MDP_WROT1_SOF   8
+#define CMDQ_EVENT_DISP_OVL0_SOF   9
+#define CMDQ_EVENT_DISP_2L_OVL0_SOF10
+#define CMDQ_EVENT_DISP_2L_OVL1_SOF11
+#define CMDQ_EVENT_DISP_WDMA0_SOF  12
+#define CMDQ_EVENT_DISP_COLOR0_SOF 13
+#define CMDQ_EVENT_DISP_CCORR0_SOF 14
+#define CMDQ_EVENT_DISP_AAL0_SOF   15
+#define CMDQ_EVENT_DISP_GAMMA0_SOF

[PATCH v8 4/4] mailbox: mediatek: cmdq: clear task in channel before shutdown

2020-07-04 Thread Dennis YC Hsieh
Do success callback in channel when shutdown. For those task not finish,
callback with error code thus client has chance to cleanup or reset.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
Reviewed-by: Bibby Hsieh 
---
 drivers/mailbox/mtk-cmdq-mailbox.c |   38 
 1 file changed, 38 insertions(+)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
b/drivers/mailbox/mtk-cmdq-mailbox.c
index 08bd4f1eb469..484d4438cd83 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -349,6 +349,12 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, 
void *data)
 
if (list_empty(&thread->task_busy_list)) {
WARN_ON(clk_enable(cmdq->clock) < 0);
+   /*
+* The thread reset will clear thread related register to 0,
+* including pc, end, priority, irq, suspend and enable. Thus
+* set CMDQ_THR_ENABLED to CMDQ_THR_ENABLE_TASK will enable
+* thread and make it running.
+*/
WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
 
writel(task->pa_base >> cmdq->shift_pa,
@@ -391,6 +397,38 @@ static int cmdq_mbox_startup(struct mbox_chan *chan)
 
 static void cmdq_mbox_shutdown(struct mbox_chan *chan)
 {
+   struct cmdq_thread *thread = (struct cmdq_thread *)chan->con_priv;
+   struct cmdq *cmdq = dev_get_drvdata(chan->mbox->dev);
+   struct cmdq_task *task, *tmp;
+   unsigned long flags;
+
+   spin_lock_irqsave(&thread->chan->lock, flags);
+   if (list_empty(&thread->task_busy_list))
+   goto done;
+
+   WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
+
+   /* make sure executed tasks have success callback */
+   cmdq_thread_irq_handler(cmdq, thread);
+   if (list_empty(&thread->task_busy_list))
+   goto done;
+
+   list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
+list_entry) {
+   cmdq_task_exec_done(task, CMDQ_CB_ERROR);
+   kfree(task);
+   }
+
+   cmdq_thread_disable(cmdq, thread);
+   clk_disable(cmdq->clock);
+done:
+   /*
+* The thread->task_busy_list empty means thread already disable. The
+* cmdq_mbox_send_data() always reset thread which clear disable and
+* suspend statue when first pkt send to channel, so there is no need
+* to do any operation here, only unlock and leave.
+*/
+   spin_unlock_irqrestore(&thread->chan->lock, flags);
 }
 
 static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout)
-- 
1.7.9.5


[PATCH v2 6/8] soc: mediatek: cmdq: add write_s_mask value function

2020-07-04 Thread Dennis YC Hsieh
add write_s_mask_value function in cmdq helper functions which
writes a constant value to address with mask and large dma
access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |   21 +
 include/linux/soc/mediatek/mtk-cmdq.h  |   15 +++
 2 files changed, 36 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 4e86b65815fc..b6e25f216605 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -294,6 +294,27 @@ int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_value);
 
+int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+   u16 addr_low, u32 value, u32 mask)
+{
+   struct cmdq_instruction inst = {};
+   int err;
+
+   inst.op = CMDQ_CODE_MASK;
+   inst.mask = ~mask;
+   err = cmdq_pkt_append_command(pkt, inst);
+   if (err < 0)
+   return err;
+
+   inst.op = CMDQ_CODE_WRITE_S_MASK;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.value = value;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index ae73e10da274..d9390d76ee14 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -165,6 +165,21 @@ int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
   u16 addr_low, u32 value);
 
 /**
+ * cmdq_pkt_write_s_mask_value() - append write_s command with mask to the CMDQ
+ *packet which write value to a physical
+ *address
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @value: the specified target value
+ * @mask:  the specified target mask
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+   u16 addr_low, u32 value, u32 mask);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v2 8/8] soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api

2020-07-04 Thread Dennis YC Hsieh
Add clear parameter to let client decide if
event should be clear to 0 after GCE receive it.

Fixes: 2f965be7f9008 ("drm/mediatek: apply CMDQ control flow")
Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |2 +-
 drivers/soc/mediatek/mtk-cmdq-helper.c   |5 +++--
 include/linux/mailbox/mtk-cmdq-mailbox.h |3 +--
 include/linux/soc/mediatek/mtk-cmdq.h|5 +++--
 4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index ec6c9ffbf35e..ba6cf956b239 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -490,7 +490,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
*mtk_crtc)
mbox_flush(mtk_crtc->cmdq_client->chan, 2000);
cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE);
cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
-   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event);
+   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
mtk_crtc_ddp_config(crtc, cmdq_handle);
cmdq_pkt_finalize(cmdq_handle);
cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index d55dc3296105..505651b0d715 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -316,15 +316,16 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
 
-int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear)
 {
struct cmdq_instruction inst = { {0} };
+   u32 clear_option = clear ? CMDQ_WFE_UPDATE : 0;
 
if (event >= CMDQ_MAX_EVENT)
return -EINVAL;
 
inst.op = CMDQ_CODE_WFE;
-   inst.value = CMDQ_WFE_OPTION;
+   inst.value = CMDQ_WFE_OPTION | clear_option;
inst.event = event;
 
return cmdq_pkt_append_command(pkt, inst);
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index efbd8a9eb2d1..d5a983d65f05 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -28,8 +28,7 @@
  * bit 16-27: update value
  * bit 31: 1 - update, 0 - no update
  */
-#define CMDQ_WFE_OPTION(CMDQ_WFE_UPDATE | 
CMDQ_WFE_WAIT | \
-   CMDQ_WFE_WAIT_VALUE)
+#define CMDQ_WFE_OPTION(CMDQ_WFE_WAIT | 
CMDQ_WFE_WAIT_VALUE)
 
 /** cmdq event maximum */
 #define CMDQ_MAX_EVENT 0x3ff
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 34354e952f60..960704d75994 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -182,11 +182,12 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 /**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
- * @event: the desired event type to "wait and CLEAR"
+ * @event: the desired event type to wait
+ * @clear: clear event or not after event arrive
  *
  * Return: 0 for success; else the error code is returned
  */
-int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event);
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear);
 
 /**
  * cmdq_pkt_clear_event() - append clear event command to the CMDQ packet
-- 
1.7.9.5


[PATCH v2 3/8] soc: mediatek: cmdq: add write_s_mask function

2020-07-04 Thread Dennis YC Hsieh
add write_s_mask function in cmdq helper functions which
writes value contains in internal register to address
with mask and large dma access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   23 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|   18 ++
 3 files changed, 42 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 880349b3f16c..550e9e7e3ff2 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -242,6 +242,29 @@ int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s);
 
+int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+ u16 addr_low, u16 src_reg_idx, u32 mask)
+{
+   struct cmdq_instruction inst = {};
+   int err;
+
+   inst.op = CMDQ_CODE_MASK;
+   inst.mask = ~mask;
+   err = cmdq_pkt_append_command(pkt, inst);
+   if (err < 0)
+   return err;
+
+   inst.mask = 0;
+   inst.op = CMDQ_CODE_WRITE_S_MASK;
+   inst.src_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.src_reg = src_reg_idx;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_mask);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 1f76cfedb16d..90d1d8e64412 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -61,6 +61,7 @@ enum cmdq_code {
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
CMDQ_CODE_WRITE_S = 0x90,
+   CMDQ_CODE_WRITE_S_MASK = 0x91,
CMDQ_CODE_LOGIC = 0xa0,
 };
 
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 9b0c57a0063d..53230341bf94 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -122,6 +122,24 @@ int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 u16 addr_low, u16 src_reg_idx);
 
 /**
+ * cmdq_pkt_write_s_mask() - append write_s with mask command to the CMDQ 
packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @src_reg_idx:   the CMDQ internal register ID which cache source value
+ * @mask:  the specified target address mask, use U32_MAX if no need
+ *
+ * Return: 0 for success; else the error code is returned
+ *
+ * Support write value to physical address without subsys. Use CMDQ_ADDR_HIGH()
+ * to get high address and call cmdq_pkt_assign() to assign value into internal
+ * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter when
+ * call to this function.
+ */
+int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+ u16 addr_low, u16 src_reg_idx, u32 mask);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v2 5/8] soc: mediatek: cmdq: add write_s value function

2020-07-04 Thread Dennis YC Hsieh
add write_s function in cmdq helper functions which
writes a constant value to address with large dma
access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |   14 ++
 include/linux/soc/mediatek/mtk-cmdq.h  |   13 +
 2 files changed, 27 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index ed9f5e63c195..4e86b65815fc 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -280,6 +280,20 @@ int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_mask);
 
+int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+  u16 addr_low, u32 value)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_WRITE_S;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.value = value;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_value);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index cd7ec714344e..ae73e10da274 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -152,6 +152,19 @@ int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
  u16 addr_low, u16 src_reg_idx, u32 mask);
 
 /**
+ * cmdq_pkt_write_s_value() - append write_s command to the CMDQ packet which
+ *   write value to a physical address
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @value: the specified target value
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+  u16 addr_low, u32 value);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v2 1/8] soc: mediatek: cmdq: add address shift in jump

2020-07-04 Thread Dennis YC Hsieh
Add address shift when compose jump instruction
to compatible with 35bit format.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index dc644cfb6419..9faf78fbed3a 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -329,7 +329,8 @@ int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 
/* JUMP to end */
inst.op = CMDQ_CODE_JUMP;
-   inst.value = CMDQ_JUMP_PASS;
+   inst.value = CMDQ_JUMP_PASS >>
+   cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan);
err = cmdq_pkt_append_command(pkt, inst);
 
return err;
-- 
1.7.9.5


[PATCH v2 4/8] soc: mediatek: cmdq: add read_s function

2020-07-04 Thread Dennis YC Hsieh
Add read_s function in cmdq helper functions which support read value from
register or dma physical address into gce internal register.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   15 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|   12 
 3 files changed, 28 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 550e9e7e3ff2..ed9f5e63c195 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -227,6 +227,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_mask);
 
+int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, u16 addr_low,
+   u16 reg_idx)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_READ_S;
+   inst.dst_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.reg_dst = reg_idx;
+   inst.src_reg = addr_low;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_read_s);
+
 int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
 u16 addr_low, u16 src_reg_idx)
 {
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 90d1d8e64412..efbd8a9eb2d1 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -60,6 +60,7 @@ enum cmdq_code {
CMDQ_CODE_JUMP = 0x10,
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
+   CMDQ_CODE_READ_S = 0x80,
CMDQ_CODE_WRITE_S = 0x90,
CMDQ_CODE_WRITE_S_MASK = 0x91,
CMDQ_CODE_LOGIC = 0xa0,
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 53230341bf94..cd7ec714344e 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -104,6 +104,18 @@ struct cmdq_client *cmdq_mbox_create(struct device *dev, 
int index,
 int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
u16 offset, u32 value, u32 mask);
 
+/*
+ * cmdq_pkt_read_s() - append read_s command to the CMDQ packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @reg_idx:   the CMDQ internal register ID to cache read data
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, u16 addr_low,
+   u16 reg_idx);
+
 /**
  * cmdq_pkt_write_s() - append write_s command to the CMDQ packet
  * @pkt:   the CMDQ packet
-- 
1.7.9.5


[PATCH v2 7/8] soc: mediatek: cmdq: add jump function

2020-07-04 Thread Dennis YC Hsieh
Add jump function so that client can jump to any address which
contains instruction.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |   13 +
 include/linux/soc/mediatek/mtk-cmdq.h  |   11 +++
 2 files changed, 24 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index b6e25f216605..d55dc3296105 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -13,6 +13,7 @@
 #define CMDQ_POLL_ENABLE_MASK  BIT(0)
 #define CMDQ_EOC_IRQ_ENBIT(0)
 #define CMDQ_REG_TYPE  1
+#define CMDQ_JUMP_RELATIVE 1
 
 struct cmdq_instruction {
union {
@@ -407,6 +408,18 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 
value)
 }
 EXPORT_SYMBOL(cmdq_pkt_assign);
 
+int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_JUMP;
+   inst.offset = CMDQ_JUMP_RELATIVE;
+   inst.value = addr >>
+   cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan);
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_jump);
+
 int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index d9390d76ee14..34354e952f60 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -253,6 +253,17 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
 int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
 
 /**
+ * cmdq_pkt_jump() - Append jump command to the CMDQ packet, ask GCE
+ *  to execute an instruction that change current thread PC to
+ *  a physical address which should contains more instruction.
+ * @pkt:the CMDQ packet
+ * @addr:   physical address of target instruction buffer
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr);
+
+/**
  * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
  * @pkt:   the CMDQ packet
  *
-- 
1.7.9.5


Subject: [PATCH v1 0/8] support cmdq helper function on mt6779 platform

2020-07-04 Thread Dennis YC Hsieh
This patch support more gce helper function on mt6779 platform.

depends on patch: support gce on mt6779 platform

and depends on following applied patches
soc: mediatek: cmdq: add set event function
soc: mediatek: cmdq: export finalize function
soc: mediatek: cmdq: add assign function

Change since v1:
- Rename cmdq_mbox_shift() to cmdq_get_shift_pa().


Dennis YC Hsieh (8):
  soc: mediatek: cmdq: add address shift in jump
  soc: mediatek: cmdq: add write_s function
  soc: mediatek: cmdq: add write_s_mask function
  soc: mediatek: cmdq: add read_s function
  soc: mediatek: cmdq: add write_s value function
  soc: mediatek: cmdq: add write_s_mask value function
  soc: mediatek: cmdq: add jump function
  soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api

 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |   2 +-
 drivers/soc/mediatek/mtk-cmdq-helper.c   | 113 ++-
 include/linux/mailbox/mtk-cmdq-mailbox.h |   6 +-
 include/linux/soc/mediatek/mtk-cmdq.h|  93 ++-
 4 files changed, 206 insertions(+), 8 deletions(-)

-- 
2.18.0

[PATCH v2 2/8] soc: mediatek: cmdq: add write_s function

2020-07-04 Thread Dennis YC Hsieh
add write_s function in cmdq helper functions which
writes value contains in internal register to address
with large dma access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   19 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|   19 +++
 3 files changed, 39 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 9faf78fbed3a..880349b3f16c 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -18,6 +18,10 @@ struct cmdq_instruction {
union {
u32 value;
u32 mask;
+   struct {
+   u16 arg_c;
+   u16 src_reg;
+   };
};
union {
u16 offset;
@@ -223,6 +227,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_mask);
 
+int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+u16 addr_low, u16 src_reg_idx)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_WRITE_S;
+   inst.src_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.src_reg = src_reg_idx;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 05eea1aef5aa..1f76cfedb16d 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -60,6 +60,7 @@ enum cmdq_code {
CMDQ_CODE_JUMP = 0x10,
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
+   CMDQ_CODE_WRITE_S = 0x90,
CMDQ_CODE_LOGIC = 0xa0,
 };
 
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 2249ecaf77e4..9b0c57a0063d 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -12,6 +12,8 @@
 #include 
 
 #define CMDQ_NO_TIMEOUT0xu
+#define CMDQ_ADDR_HIGH(addr)   ((u32)(((addr) >> 16) & GENMASK(31, 0)))
+#define CMDQ_ADDR_LOW(addr)((u16)(addr) | BIT(1))
 
 struct cmdq_pkt;
 
@@ -103,6 +105,23 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
u16 offset, u32 value, u32 mask);
 
 /**
+ * cmdq_pkt_write_s() - append write_s command to the CMDQ packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @src_reg_idx:   the CMDQ internal register ID which cache source value
+ *
+ * Return: 0 for success; else the error code is returned
+ *
+ * Support write value to physical address without subsys. Use CMDQ_ADDR_HIGH()
+ * to get high address and call cmdq_pkt_assign() to assign value into internal
+ * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter when
+ * call to this function.
+ */
+int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+u16 addr_low, u16 src_reg_idx);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


Re: [PATCH v2 1/8] soc: mediatek: cmdq: add address shift in jump

2020-07-06 Thread Dennis-YC Hsieh
Hi Matthias,

thanks for your comment

On Mon, 2020-07-06 at 16:03 +0200, Matthias Brugger wrote:
> 
> On 05/07/2020 08:48, Dennis YC Hsieh wrote:
> > Add address shift when compose jump instruction
> > to compatible with 35bit format.
> > 
> > Signed-off-by: Dennis YC Hsieh 
> 
> You are missing Bibby's Reviewed-by. Please honour the effort reviewers do by
> adding the appropriate tags.
> 
> Please double check the series and resend with all tags added.
> 
> Also, it would be good if you could provide a change log. That makes it easier
> for the maintainer to see which statements you addressed.

this patch changed since cmdq_mbox_shift() rename to cmdq_get_shift_pa()
by Bibby's comment [1], so I removed reviewed tags from this patch.

I'll provide change log to this patch and resend later, thanks.

[1]
http://lists.infradead.org/pipermail/linux-mediatek/2020-June/013387.html


Regards,
Dennis

> 
> Thanks,
> Matthias
> 
> > ---
> >  drivers/soc/mediatek/mtk-cmdq-helper.c |3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index dc644cfb6419..9faf78fbed3a 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -329,7 +329,8 @@ int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
> >  
> > /* JUMP to end */
> > inst.op = CMDQ_CODE_JUMP;
> > -   inst.value = CMDQ_JUMP_PASS;
> > +   inst.value = CMDQ_JUMP_PASS >>
> > +   cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan);
> > err = cmdq_pkt_append_command(pkt, inst);
> >  
> > return err;
> > 



Re: [PATCH v2 8/8] soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api

2020-07-06 Thread Dennis-YC Hsieh
Hi CK,

Thanks for your comment.

On Tue, 2020-07-07 at 07:46 +0800, Chun-Kuang Hu wrote:
> Hi, Dennis:
> 
> Dennis YC Hsieh  於 2020年7月6日 週一 下午3:20寫道:
> >
> > Add clear parameter to let client decide if
> > event should be clear to 0 after GCE receive it.
> >
> > Fixes: 2f965be7f9008 ("drm/mediatek: apply CMDQ control flow")
> 
> I think this patch include two things, one is bug fix, another is
> changing interface.
> below is the bug fix part.
> 
> -#define CMDQ_WFE_OPTION(CMDQ_WFE_UPDATE |
> CMDQ_WFE_WAIT | \
> -   CMDQ_WFE_WAIT_VALUE)
> +#define CMDQ_WFE_OPTION(CMDQ_WFE_WAIT |
> CMDQ_WFE_WAIT_VALUE)
> 
> the other is changing interface part. So this patch should be broken
> into two patches.

ok I'll break into two patches


Regards,
Dennis

> 
> Regards,
> Chun-Kuang.
> 
> > Signed-off-by: Dennis YC Hsieh 
> > Reviewed-by: CK Hu 
> > ---
> >  drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |2 +-
> >  drivers/soc/mediatek/mtk-cmdq-helper.c   |5 +++--
> >  include/linux/mailbox/mtk-cmdq-mailbox.h |3 +--
> >  include/linux/soc/mediatek/mtk-cmdq.h|5 +++--
> >  4 files changed, 8 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> > b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > index ec6c9ffbf35e..ba6cf956b239 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > @@ -490,7 +490,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
> > *mtk_crtc)
> > mbox_flush(mtk_crtc->cmdq_client->chan, 2000);
> > cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, 
> > PAGE_SIZE);
> > cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
> > -   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event);
> > +   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
> > mtk_crtc_ddp_config(crtc, cmdq_handle);
> > cmdq_pkt_finalize(cmdq_handle);
> > cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index d55dc3296105..505651b0d715 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -316,15 +316,16 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, 
> > u8 high_addr_reg_idx,
> >  }
> >  EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
> >
> > -int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
> > +int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear)
> >  {
> > struct cmdq_instruction inst = { {0} };
> > +   u32 clear_option = clear ? CMDQ_WFE_UPDATE : 0;
> >
> > if (event >= CMDQ_MAX_EVENT)
> > return -EINVAL;
> >
> > inst.op = CMDQ_CODE_WFE;
> > -   inst.value = CMDQ_WFE_OPTION;
> > +   inst.value = CMDQ_WFE_OPTION | clear_option;
> > inst.event = event;
> >
> > return cmdq_pkt_append_command(pkt, inst);
> > diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
> > b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > index efbd8a9eb2d1..d5a983d65f05 100644
> > --- a/include/linux/mailbox/mtk-cmdq-mailbox.h
> > +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > @@ -28,8 +28,7 @@
> >   * bit 16-27: update value
> >   * bit 31: 1 - update, 0 - no update
> >   */
> > -#define CMDQ_WFE_OPTION(CMDQ_WFE_UPDATE | 
> > CMDQ_WFE_WAIT | \
> > -   CMDQ_WFE_WAIT_VALUE)
> > +#define CMDQ_WFE_OPTION(CMDQ_WFE_WAIT | 
> > CMDQ_WFE_WAIT_VALUE)
> >
> >  /** cmdq event maximum */
> >  #define CMDQ_MAX_EVENT 0x3ff
> > diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
> > b/include/linux/soc/mediatek/mtk-cmdq.h
> > index 34354e952f60..960704d75994 100644
> > --- a/include/linux/soc/mediatek/mtk-cmdq.h
> > +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> > @@ -182,11 +182,12 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, 
> > u8 high_addr_reg_idx,
> >  /**
> >   * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
> >   * @pkt:   the CMDQ packet
> > - * @event: the desired event type to "wait and CLEAR"
> > + * @event: the desired event

Re: [PATCH v3 8/9] soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api

2020-09-21 Thread Dennis-YC Hsieh
Hi Matthias,


On Mon, 2020-09-21 at 18:19 +0200, Matthias Brugger wrote:
> 
> On 07/07/2020 17:45, Dennis YC Hsieh wrote:
> > Add clear parameter to let client decide if
> > event should be clear to 0 after GCE receive it.
> > 
> > Change since v2:
> > - Keep behavior in drm crtc driver and
> >separate bug fix code into another patch.
> 
> This, should go...
> 
> > 
> > Signed-off-by: Dennis YC Hsieh 
> > ---
> 
> ...here :)
> 
> I fixed to commit message and pushed the patch to v5.9-next/soc

got it, thanks a lot


Regards,
Dennis

> 
> Thanks!
> 
> >   drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |2 +-
> >   drivers/soc/mediatek/mtk-cmdq-helper.c   |5 +++--
> >   include/linux/mailbox/mtk-cmdq-mailbox.h |3 +--
> >   include/linux/soc/mediatek/mtk-cmdq.h|5 +++--
> >   4 files changed, 8 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> > b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > index ec6c9ffbf35e..c84e7a14d4a8 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > @@ -490,7 +490,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
> > *mtk_crtc)
> > mbox_flush(mtk_crtc->cmdq_client->chan, 2000);
> > cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE);
> > cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
> > -   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event);
> > +   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, true);
> > mtk_crtc_ddp_config(crtc, cmdq_handle);
> > cmdq_pkt_finalize(cmdq_handle);
> > cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index d55dc3296105..505651b0d715 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -316,15 +316,16 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, 
> > u8 high_addr_reg_idx,
> >   }
> >   EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
> >   
> > -int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
> > +int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear)
> >   {
> > struct cmdq_instruction inst = { {0} };
> > +   u32 clear_option = clear ? CMDQ_WFE_UPDATE : 0;
> >   
> > if (event >= CMDQ_MAX_EVENT)
> > return -EINVAL;
> >   
> > inst.op = CMDQ_CODE_WFE;
> > -   inst.value = CMDQ_WFE_OPTION;
> > +   inst.value = CMDQ_WFE_OPTION | clear_option;
> > inst.event = event;
> >   
> > return cmdq_pkt_append_command(pkt, inst);
> > diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
> > b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > index efbd8a9eb2d1..d5a983d65f05 100644
> > --- a/include/linux/mailbox/mtk-cmdq-mailbox.h
> > +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > @@ -28,8 +28,7 @@
> >* bit 16-27: update value
> >* bit 31: 1 - update, 0 - no update
> >*/
> > -#define CMDQ_WFE_OPTION(CMDQ_WFE_UPDATE | 
> > CMDQ_WFE_WAIT | \
> > -   CMDQ_WFE_WAIT_VALUE)
> > +#define CMDQ_WFE_OPTION(CMDQ_WFE_WAIT | 
> > CMDQ_WFE_WAIT_VALUE)
> >   
> >   /** cmdq event maximum */
> >   #define CMDQ_MAX_EVENT0x3ff
> > diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
> > b/include/linux/soc/mediatek/mtk-cmdq.h
> > index 34354e952f60..960704d75994 100644
> > --- a/include/linux/soc/mediatek/mtk-cmdq.h
> > +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> > @@ -182,11 +182,12 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, 
> > u8 high_addr_reg_idx,
> >   /**
> >* cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
> >* @pkt:  the CMDQ packet
> > - * @event: the desired event type to "wait and CLEAR"
> > + * @event: the desired event type to wait
> > + * @clear: clear event or not after event arrive
> >*
> >* Return: 0 for success; else the error code is returned
> >*/
> > -int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event);
> > +int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear);
> >   
> >   /**
> >* cmdq_pkt_clear_event() - append clear event command to the CMDQ packet
> > 



[PATCH v7 1/4] dt-binding: gce: add gce header file for mt6779

2020-06-21 Thread Dennis YC Hsieh
Add documentation for the mt6779 gce.

Add gce header file defined the gce hardware event,
subsys number and constant for mt6779.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: Rob Herring 
Reviewed-by: CK Hu 
---
 .../devicetree/bindings/mailbox/mtk-gce.txt|8 +-
 include/dt-bindings/gce/mt6779-gce.h   |  222 
 2 files changed, 227 insertions(+), 3 deletions(-)
 create mode 100644 include/dt-bindings/gce/mt6779-gce.h

diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt 
b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
index 7b13787ab13d..82c0a83fed09 100644
--- a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
+++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
@@ -9,7 +9,8 @@ CMDQ driver uses mailbox framework for communication. Please 
refer to
 mailbox.txt for generic information about mailbox device-tree bindings.
 
 Required properties:
-- compatible: can be "mediatek,mt8173-gce" or "mediatek,mt8183-gce"
+- compatible: can be "mediatek,mt8173-gce", "mediatek,mt8183-gce" or
+  "mediatek,mt6779-gce".
 - reg: Address range of the GCE unit
 - interrupts: The interrupt signal from the GCE block
 - clock: Clocks according to the common clock binding
@@ -36,8 +37,9 @@ Optional properties for a client device:
   start_offset: the start offset of register address that GCE can access.
   size: the total size of register address that GCE can access.
 
-Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h'
-or 'dt-binding/gce/mt8183-gce.h'. Such as sub-system ids, thread priority, 
event ids.
+Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h',
+'dt-binding/gce/mt8183-gce.h' or 'dt-bindings/gce/mt6779-gce.h'. Such as
+sub-system ids, thread priority, event ids.
 
 Example:
 
diff --git a/include/dt-bindings/gce/mt6779-gce.h 
b/include/dt-bindings/gce/mt6779-gce.h
new file mode 100644
index ..06101316ace4
--- /dev/null
+++ b/include/dt-bindings/gce/mt6779-gce.h
@@ -0,0 +1,222 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Dennis-YC Hsieh 
+ */
+
+#ifndef _DT_BINDINGS_GCE_MT6779_H
+#define _DT_BINDINGS_GCE_MT6779_H
+
+#define CMDQ_NO_TIMEOUT0x
+
+/* GCE HW thread priority */
+#define CMDQ_THR_PRIO_LOWEST   0
+#define CMDQ_THR_PRIO_11
+#define CMDQ_THR_PRIO_22
+#define CMDQ_THR_PRIO_33
+#define CMDQ_THR_PRIO_44
+#define CMDQ_THR_PRIO_55
+#define CMDQ_THR_PRIO_66
+#define CMDQ_THR_PRIO_HIGHEST  7
+
+/* GCE subsys table */
+#define SUBSYS_13000
+#define SUBSYS_14001
+#define SUBSYS_14012
+#define SUBSYS_14023
+#define SUBSYS_15024
+#define SUBSYS_18805
+#define SUBSYS_18816
+#define SUBSYS_18827
+#define SUBSYS_18838
+#define SUBSYS_18849
+#define SUBSYS_100010
+#define SUBSYS_100111
+#define SUBSYS_100212
+#define SUBSYS_100313
+#define SUBSYS_100414
+#define SUBSYS_100515
+#define SUBSYS_102016
+#define SUBSYS_102817
+#define SUBSYS_170018
+#define SUBSYS_170119
+#define SUBSYS_170220
+#define SUBSYS_170321
+#define SUBSYS_180022
+#define SUBSYS_180123
+#define SUBSYS_180224
+#define SUBSYS_180425
+#define SUBSYS_180526
+#define SUBSYS_180827
+#define SUBSYS_180a28
+#define SUBSYS_180b29
+#define CMDQ_SUBSYS_OFF32
+
+/* GCE hardware events */
+#define CMDQ_EVENT_DISP_RDMA0_SOF  0
+#define CMDQ_EVENT_DISP_RDMA1_SOF  1
+#define CMDQ_EVENT_MDP_RDMA0_SOF   2
+#define CMDQ_EVENT_MDP_RDMA1_SOF   3
+#define CMDQ_EVENT_MDP_RSZ0_SOF4
+#define CMDQ_EVENT_MDP_RSZ1_SOF5
+#define CMDQ_EVENT_MDP_TDSHP_SOF   6
+#define CMDQ_EVENT_MDP_WROT0_SOF   7
+#define CMDQ_EVENT_MDP_WROT1_SOF   8
+#define CMDQ_EVENT_DISP_OVL0_SOF   9
+#define CMDQ_EVENT_DISP_2L_OVL0_SOF10
+#define CMDQ_EVENT_DISP_2L_OVL1_SOF11
+#define CMDQ_EVENT_DISP_WDMA0_SOF  12
+#define CMDQ_EVENT_DISP_COLOR0_SOF 13
+#define CMDQ_EVENT_DISP_CCORR0_SOF 14
+#define CMDQ_EVENT_DISP_AAL0_SOF   15
+#define CMDQ_EVENT_DISP_GAMMA0_SOF 16
+#define C

[PATCH v7 2/4] mailbox: cmdq: variablize address shift in platform

2020-06-21 Thread Dennis YC Hsieh
Some gce hardware shift pc and end address in register to support
large dram addressing.
Implement gce address shift when write or read pc and end register.
And add shift bit in platform definition.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/mailbox/mtk-cmdq-mailbox.c   |   61 ++
 include/linux/mailbox/mtk-cmdq-mailbox.h |2 +
 2 files changed, 48 insertions(+), 15 deletions(-)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
b/drivers/mailbox/mtk-cmdq-mailbox.c
index 9a6ce9f5a7db..4dbee9258127 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -76,8 +76,22 @@ struct cmdq {
struct cmdq_thread  *thread;
struct clk  *clock;
boolsuspended;
+   u8  shift_pa;
 };
 
+struct gce_plat {
+   u32 thread_nr;
+   u8 shift;
+};
+
+u8 cmdq_mbox_shift(struct mbox_chan *chan)
+{
+   struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox);
+
+   return cmdq->shift_pa;
+}
+EXPORT_SYMBOL(cmdq_mbox_shift);
+
 static int cmdq_thread_suspend(struct cmdq *cmdq, struct cmdq_thread *thread)
 {
u32 status;
@@ -183,7 +197,7 @@ static void cmdq_task_remove_wfe(struct cmdq_task *task)
for (i = 0; i < CMDQ_NUM_CMD(task->pkt); i++)
if (cmdq_command_is_wfe(base[i]))
base[i] = (u64)CMDQ_JUMP_BY_OFFSET << 32 |
- CMDQ_JUMP_PASS;
+ CMDQ_JUMP_PASS >> task->cmdq->shift_pa;
dma_sync_single_for_device(dev, task->pa_base, task->pkt->cmd_buf_size,
   DMA_TO_DEVICE);
 }
@@ -221,13 +235,15 @@ static void cmdq_task_handle_error(struct cmdq_task *task)
 {
struct cmdq_thread *thread = task->thread;
struct cmdq_task *next_task;
+   struct cmdq *cmdq = task->cmdq;
 
-   dev_err(task->cmdq->mbox.dev, "task 0x%p error\n", task);
-   WARN_ON(cmdq_thread_suspend(task->cmdq, thread) < 0);
+   dev_err(cmdq->mbox.dev, "task 0x%p error\n", task);
+   WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
next_task = list_first_entry_or_null(&thread->task_busy_list,
struct cmdq_task, list_entry);
if (next_task)
-   writel(next_task->pa_base, thread->base + CMDQ_THR_CURR_ADDR);
+   writel(next_task->pa_base >> cmdq->shift_pa,
+  thread->base + CMDQ_THR_CURR_ADDR);
cmdq_thread_resume(thread);
 }
 
@@ -257,7 +273,7 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
else
return;
 
-   curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR);
+   curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) << cmdq->shift_pa;
 
list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
 list_entry) {
@@ -373,16 +389,20 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, 
void *data)
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,
+   writel(task->pa_base >> cmdq->shift_pa,
+  thread->base + CMDQ_THR_CURR_ADDR);
+   writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->shift_pa,
   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);
} 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);
+   curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) <<
+   cmdq->shift_pa;
+   end_pa = readl(thread->base + CMDQ_THR_END_ADDR) <<
+   cmdq->shift_pa;
 
/*
 * Atomic execution should remove the following wfe, i.e. only
@@ -395,7 +415,7 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void 
*data)
cmdq_thread_wait_end(thread, end_pa);
WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
/* set to this task directly */
-   writel(task->pa_base,
+   writel(task->pa_base >> cmdq->shift_pa,
   thr

[PATCH v7 3/4] mailbox: cmdq: support mt6779 gce platform definition

2020-06-21 Thread Dennis YC Hsieh
Add gce v4 hardware support with different thread number and shift.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
Reviewed-by: Matthias Brugger 
---
 drivers/mailbox/mtk-cmdq-mailbox.c |2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
b/drivers/mailbox/mtk-cmdq-mailbox.c
index 4dbee9258127..9994ac9426d6 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -572,10 +572,12 @@ static int cmdq_probe(struct platform_device *pdev)
 
 static const struct gce_plat gce_plat_v2 = {.thread_nr = 16};
 static const struct gce_plat gce_plat_v3 = {.thread_nr = 24};
+static const struct gce_plat gce_plat_v4 = {.thread_nr = 24, .shift = 3};
 
 static const struct of_device_id cmdq_of_ids[] = {
{.compatible = "mediatek,mt8173-gce", .data = (void *)&gce_plat_v2},
{.compatible = "mediatek,mt8183-gce", .data = (void *)&gce_plat_v3},
+   {.compatible = "mediatek,mt6779-gce", .data = (void *)&gce_plat_v4},
{}
 };
 
-- 
1.7.9.5


[PATCH v7 0/4] support gce on mt6779 platform

2020-06-21 Thread Dennis YC Hsieh
This patch support gce on mt6779 platform.

Change since v6:
- Separate all helper function to another patchset.

Change since v5:
- spearate address shift code in client helper and mailbox controller
- separate write_s/write_s_mask and write_s_value/write_s_mask_value so that
  client can decide use mask or not
- fix typo in header

Change since v4:
- do not clear disp event again in drm driver
- symbolize value 1 to jump relative

[... snip ...]


Dennis YC Hsieh (4):
  dt-binding: gce: add gce header file for mt6779
  mailbox: cmdq: variablize address shift in platform
  mailbox: cmdq: support mt6779 gce platform definition
  mailbox: mediatek: cmdq: clear task in channel before shutdown

 .../devicetree/bindings/mailbox/mtk-gce.txt   |   8 +-
 drivers/mailbox/mtk-cmdq-mailbox.c| 101 ++--
 include/dt-bindings/gce/mt6779-gce.h  | 222 ++
 include/linux/mailbox/mtk-cmdq-mailbox.h  |   2 +
 4 files changed, 315 insertions(+), 18 deletions(-)
 create mode 100644 include/dt-bindings/gce/mt6779-gce.h

-- 
2.18.0

[PATCH v7 4/4] mailbox: mediatek: cmdq: clear task in channel before shutdown

2020-06-21 Thread Dennis YC Hsieh
Do success callback in channel when shutdown. For those task not finish,
callback with error code thus client has chance to cleanup or reset.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
---
 drivers/mailbox/mtk-cmdq-mailbox.c |   38 
 1 file changed, 38 insertions(+)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
b/drivers/mailbox/mtk-cmdq-mailbox.c
index 9994ac9426d6..b56d340c8982 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -387,6 +387,12 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, 
void *data)
 
if (list_empty(&thread->task_busy_list)) {
WARN_ON(clk_enable(cmdq->clock) < 0);
+   /*
+* The thread reset will clear thread related register to 0,
+* including pc, end, priority, irq, suspend and enable. Thus
+* set CMDQ_THR_ENABLED to CMDQ_THR_ENABLE_TASK will enable
+* thread and make it running.
+*/
WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
 
writel(task->pa_base >> cmdq->shift_pa,
@@ -450,6 +456,38 @@ static int cmdq_mbox_startup(struct mbox_chan *chan)
 
 static void cmdq_mbox_shutdown(struct mbox_chan *chan)
 {
+   struct cmdq_thread *thread = (struct cmdq_thread *)chan->con_priv;
+   struct cmdq *cmdq = dev_get_drvdata(chan->mbox->dev);
+   struct cmdq_task *task, *tmp;
+   unsigned long flags;
+
+   spin_lock_irqsave(&thread->chan->lock, flags);
+   if (list_empty(&thread->task_busy_list))
+   goto done;
+
+   WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
+
+   /* make sure executed tasks have success callback */
+   cmdq_thread_irq_handler(cmdq, thread);
+   if (list_empty(&thread->task_busy_list))
+   goto done;
+
+   list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
+list_entry) {
+   cmdq_task_exec_done(task, CMDQ_CB_ERROR);
+   kfree(task);
+   }
+
+   cmdq_thread_disable(cmdq, thread);
+   clk_disable(cmdq->clock);
+done:
+   /*
+* The thread->task_busy_list empty means thread already disable. The
+* cmdq_mbox_send_data() always reset thread which clear disable and
+* suspend statue when first pkt send to channel, so there is no need
+* to do any operation here, only unlock and leave.
+*/
+   spin_unlock_irqrestore(&thread->chan->lock, flags);
 }
 
 static const struct mbox_chan_ops cmdq_mbox_chan_ops = {
-- 
1.7.9.5


[PATCH v1 09/11] soc: mediatek: cmdq: add jump function

2020-06-21 Thread Dennis YC Hsieh
Add jump function so that client can jump to any address which
contains instruction.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |   13 +
 include/linux/soc/mediatek/mtk-cmdq.h  |   11 +++
 2 files changed, 24 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 248945108a36..009f86ae72c6 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -13,6 +13,7 @@
 #define CMDQ_POLL_ENABLE_MASK  BIT(0)
 #define CMDQ_EOC_IRQ_ENBIT(0)
 #define CMDQ_REG_TYPE  1
+#define CMDQ_JUMP_RELATIVE 1
 
 struct cmdq_instruction {
union {
@@ -391,6 +392,18 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 
value)
 }
 EXPORT_SYMBOL(cmdq_pkt_assign);
 
+int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_JUMP;
+   inst.offset = CMDQ_JUMP_RELATIVE;
+   inst.value = addr >>
+   cmdq_mbox_shift(((struct cmdq_client *)pkt->cl)->chan);
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_jump);
+
 int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index eac1405e4872..18364d81e8f7 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -244,6 +244,17 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
 int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
 
 /**
+ * cmdq_pkt_jump() - Append jump command to the CMDQ packet, ask GCE
+ *  to execute an instruction that change current thread PC to
+ *  a physical address which should contains more instruction.
+ * @pkt:the CMDQ packet
+ * @addr:   physical address of target instruction buffer
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr);
+
+/**
  * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
  * @pkt:   the CMDQ packet
  *
-- 
1.7.9.5


[PATCH v1 06/11] soc: mediatek: cmdq: add write_s value function

2020-06-21 Thread Dennis YC Hsieh
add write_s function in cmdq helper functions which
writes a constant value to address with large dma
access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |   14 ++
 include/linux/soc/mediatek/mtk-cmdq.h  |   13 +
 2 files changed, 27 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 58075589509b..2ad78df46636 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -279,6 +279,20 @@ int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_mask);
 
+int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+  u16 addr_low, u32 value)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_WRITE_S;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.value = value;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_value);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 40fe1eb52190..7f1c115a66b8 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -152,6 +152,19 @@ int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
  u16 addr_low, u16 src_reg_idx, u32 mask);
 
 /**
+ * cmdq_pkt_write_s_value() - append write_s command to the CMDQ packet which
+ *   write value to a physical address
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @value: the specified target value
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+  u16 addr_low, u32 value);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v1 08/11] soc: mediatek: cmdq: export finalize function

2020-06-21 Thread Dennis YC Hsieh
Export finalize function to client which helps append eoc and jump
command to pkt. Let client decide call finalize or not.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
Acked-by: Chun-Kuang Hu 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c  |7 ++-
 include/linux/soc/mediatek/mtk-cmdq.h   |8 
 3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 0dfcd1787e65..7daaabc26eb1 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -490,6 +490,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
*mtk_crtc)
cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event);
mtk_crtc_ddp_config(crtc, cmdq_handle);
+   cmdq_pkt_finalize(cmdq_handle);
cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
}
 #endif
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index e372ae065240..248945108a36 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -391,7 +391,7 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 
value)
 }
 EXPORT_SYMBOL(cmdq_pkt_assign);
 
-static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
+int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
struct cmdq_instruction inst = { {0} };
int err;
@@ -411,6 +411,7 @@ static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 
return err;
 }
+EXPORT_SYMBOL(cmdq_pkt_finalize);
 
 static void cmdq_pkt_flush_async_cb(struct cmdq_cb_data data)
 {
@@ -445,10 +446,6 @@ int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, 
cmdq_async_flush_cb cb,
unsigned long flags = 0;
struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
 
-   err = cmdq_pkt_finalize(pkt);
-   if (err < 0)
-   return err;
-
pkt->cb.cb = cb;
pkt->cb.data = data;
pkt->async_cb.cb = cmdq_pkt_flush_async_cb;
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 6e8caacedc80..eac1405e4872 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -244,6 +244,14 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
 int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
 
 /**
+ * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
+ * @pkt:   the CMDQ packet
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
+
+/**
  * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
  *  packet and call back at the end of done packet
  * @pkt:   the CMDQ packet
-- 
1.7.9.5


[PATCH v1 0/11] support cmdq helper function on mt6779 platform

2020-06-21 Thread Dennis YC Hsieh
This patch support cmdq helper function on mt6779 platform,
based on "support gce on mt6779 platform" patchset.


Dennis YC Hsieh (11):
  soc: mediatek: cmdq: add address shift in jump
  soc: mediatek: cmdq: add assign function
  soc: mediatek: cmdq: add write_s function
  soc: mediatek: cmdq: add write_s_mask function
  soc: mediatek: cmdq: add read_s function
  soc: mediatek: cmdq: add write_s value function
  soc: mediatek: cmdq: add write_s_mask value function
  soc: mediatek: cmdq: export finalize function
  soc: mediatek: cmdq: add jump function
  soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api
  soc: mediatek: cmdq: add set event function

 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |   3 +-
 drivers/soc/mediatek/mtk-cmdq-helper.c   | 159 +--
 include/linux/mailbox/mtk-cmdq-mailbox.h |   8 +-
 include/linux/soc/mediatek/mtk-cmdq.h| 124 +-
 4 files changed, 280 insertions(+), 14 deletions(-)

-- 
2.18.0

[PATCH v1 01/11] soc: mediatek: cmdq: add address shift in jump

2020-06-21 Thread Dennis YC Hsieh
Add address shift when compose jump instruction
to compatible with 35bit format.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index c67081759728..98f23ba3ba47 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -291,7 +291,8 @@ static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 
/* JUMP to end */
inst.op = CMDQ_CODE_JUMP;
-   inst.value = CMDQ_JUMP_PASS;
+   inst.value = CMDQ_JUMP_PASS >>
+   cmdq_mbox_shift(((struct cmdq_client *)pkt->cl)->chan);
err = cmdq_pkt_append_command(pkt, inst);
 
return err;
-- 
1.7.9.5


[PATCH v1 02/11] soc: mediatek: cmdq: add assign function

2020-06-21 Thread Dennis YC Hsieh
Add assign function in cmdq helper which assign constant value into
internal register by index.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   24 +++-
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|   14 ++
 3 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 98f23ba3ba47..bf32e3b2ca6c 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -12,6 +12,7 @@
 #define CMDQ_WRITE_ENABLE_MASK BIT(0)
 #define CMDQ_POLL_ENABLE_MASK  BIT(0)
 #define CMDQ_EOC_IRQ_ENBIT(0)
+#define CMDQ_REG_TYPE  1
 
 struct cmdq_instruction {
union {
@@ -21,8 +22,17 @@ struct cmdq_instruction {
union {
u16 offset;
u16 event;
+   u16 reg_dst;
+   };
+   union {
+   u8 subsys;
+   struct {
+   u8 sop:5;
+   u8 arg_c_t:1;
+   u8 src_t:1;
+   u8 dst_t:1;
+   };
};
-   u8 subsys;
u8 op;
 };
 
@@ -277,6 +287,18 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
 }
 EXPORT_SYMBOL(cmdq_pkt_poll_mask);
 
+int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_LOGIC;
+   inst.dst_t = CMDQ_REG_TYPE;
+   inst.reg_dst = reg_idx;
+   inst.value = value;
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_assign);
+
 static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index dfe5b2eb85cc..121c3bb6d3de 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -59,6 +59,7 @@ enum cmdq_code {
CMDQ_CODE_JUMP = 0x10,
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
+   CMDQ_CODE_LOGIC = 0xa0,
 };
 
 enum cmdq_cb_status {
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index a74c1d5acdf3..83340211e1d3 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -152,6 +152,20 @@ int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys,
  */
 int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
   u16 offset, u32 value, u32 mask);
+
+/**
+ * cmdq_pkt_assign() - Append logic assign command to the CMDQ packet, ask GCE
+ *to execute an instruction that set a constant value into
+ *internal register and use as value, mask or address in
+ *read/write instruction.
+ * @pkt:   the CMDQ packet
+ * @reg_idx:   the CMDQ internal register ID
+ * @value: the specified value
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
+
 /**
  * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
  *  packet and call back at the end of done packet
-- 
1.7.9.5


[PATCH v1 04/11] soc: mediatek: cmdq: add write_s_mask function

2020-06-21 Thread Dennis YC Hsieh
add write_s_mask function in cmdq helper functions which
writes value contains in internal register to address
with mask and large dma access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   23 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|   18 ++
 3 files changed, 42 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 817a5a97dbe5..13b888779093 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -241,6 +241,29 @@ int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s);
 
+int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+ u16 addr_low, u16 src_reg_idx, u32 mask)
+{
+   struct cmdq_instruction inst = {};
+   int err;
+
+   inst.op = CMDQ_CODE_MASK;
+   inst.mask = ~mask;
+   err = cmdq_pkt_append_command(pkt, inst);
+   if (err < 0)
+   return err;
+
+   inst.mask = 0;
+   inst.op = CMDQ_CODE_WRITE_S_MASK;
+   inst.src_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.src_reg = src_reg_idx;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_mask);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index ee67dd3b86f5..8ef87e1bd03b 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -60,6 +60,7 @@ enum cmdq_code {
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
CMDQ_CODE_WRITE_S = 0x90,
+   CMDQ_CODE_WRITE_S_MASK = 0x91,
CMDQ_CODE_LOGIC = 0xa0,
 };
 
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index e1c5a7549b4f..ca9c75fd8125 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -122,6 +122,24 @@ int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 u16 addr_low, u16 src_reg_idx);
 
 /**
+ * cmdq_pkt_write_s_mask() - append write_s with mask command to the CMDQ 
packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @src_reg_idx:   the CMDQ internal register ID which cache source value
+ * @mask:  the specified target address mask, use U32_MAX if no need
+ *
+ * Return: 0 for success; else the error code is returned
+ *
+ * Support write value to physical address without subsys. Use CMDQ_ADDR_HIGH()
+ * to get high address and call cmdq_pkt_assign() to assign value into internal
+ * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter when
+ * call to this function.
+ */
+int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+ u16 addr_low, u16 src_reg_idx, u32 mask);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v1 11/11] soc: mediatek: cmdq: add set event function

2020-06-21 Thread Dennis YC Hsieh
Add set event function in cmdq helper functions to set specific event.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   15 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|9 +
 3 files changed, 25 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 13f78c9b5901..e6133a42d229 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -346,6 +346,21 @@ int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event)
 }
 EXPORT_SYMBOL(cmdq_pkt_clear_event);
 
+int cmdq_pkt_set_event(struct cmdq_pkt *pkt, u16 event)
+{
+   struct cmdq_instruction inst = {};
+
+   if (event >= CMDQ_MAX_EVENT)
+   return -EINVAL;
+
+   inst.op = CMDQ_CODE_WFE;
+   inst.value = CMDQ_WFE_UPDATE | CMDQ_WFE_UPDATE_VALUE;
+   inst.event = event;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_set_event);
+
 int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys,
  u16 offset, u32 value)
 {
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 42d2a30e6a70..ba2d811183a9 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -17,6 +17,7 @@
 #define CMDQ_JUMP_PASS CMDQ_INST_SIZE
 
 #define CMDQ_WFE_UPDATEBIT(31)
+#define CMDQ_WFE_UPDATE_VALUE  BIT(16)
 #define CMDQ_WFE_WAIT  BIT(15)
 #define CMDQ_WFE_WAIT_VALUE0x1
 
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 4b5f5d154bad..960704d75994 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -199,6 +199,15 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event);
 
 /**
+ * cmdq_pkt_set_event() - append set event command to the CMDQ packet
+ * @pkt:   the CMDQ packet
+ * @event: the desired event to be set
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_set_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 w/o mask.
-- 
1.7.9.5


[PATCH v1 10/11] soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api

2020-06-21 Thread Dennis YC Hsieh
Add clear parameter to let client decide if
event should be clear to 0 after GCE receive it.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |2 +-
 drivers/soc/mediatek/mtk-cmdq-helper.c   |5 +++--
 include/linux/mailbox/mtk-cmdq-mailbox.h |3 +--
 include/linux/soc/mediatek/mtk-cmdq.h|5 +++--
 4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 7daaabc26eb1..a065b3a412cf 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -488,7 +488,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
*mtk_crtc)
if (mtk_crtc->cmdq_client) {
cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE);
cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
-   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event);
+   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
mtk_crtc_ddp_config(crtc, cmdq_handle);
cmdq_pkt_finalize(cmdq_handle);
cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 009f86ae72c6..13f78c9b5901 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -315,15 +315,16 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
 
-int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear)
 {
struct cmdq_instruction inst = { {0} };
+   u32 clear_option = clear ? CMDQ_WFE_UPDATE : 0;
 
if (event >= CMDQ_MAX_EVENT)
return -EINVAL;
 
inst.op = CMDQ_CODE_WFE;
-   inst.value = CMDQ_WFE_OPTION;
+   inst.value = CMDQ_WFE_OPTION | clear_option;
inst.event = event;
 
return cmdq_pkt_append_command(pkt, inst);
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 3f6bc0dfd5da..42d2a30e6a70 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -27,8 +27,7 @@
  * bit 16-27: update value
  * bit 31: 1 - update, 0 - no update
  */
-#define CMDQ_WFE_OPTION(CMDQ_WFE_UPDATE | 
CMDQ_WFE_WAIT | \
-   CMDQ_WFE_WAIT_VALUE)
+#define CMDQ_WFE_OPTION(CMDQ_WFE_WAIT | 
CMDQ_WFE_WAIT_VALUE)
 
 /** cmdq event maximum */
 #define CMDQ_MAX_EVENT 0x3ff
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 18364d81e8f7..4b5f5d154bad 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -182,11 +182,12 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 /**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
- * @event: the desired event type to "wait and CLEAR"
+ * @event: the desired event type to wait
+ * @clear: clear event or not after event arrive
  *
  * Return: 0 for success; else the error code is returned
  */
-int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event);
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear);
 
 /**
  * cmdq_pkt_clear_event() - append clear event command to the CMDQ packet
-- 
1.7.9.5


[PATCH v1 03/11] soc: mediatek: cmdq: add write_s function

2020-06-21 Thread Dennis YC Hsieh
add write_s function in cmdq helper functions which
writes value contains in internal register to address
with large dma access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   19 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|   19 +++
 3 files changed, 39 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index bf32e3b2ca6c..817a5a97dbe5 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -18,6 +18,10 @@ struct cmdq_instruction {
union {
u32 value;
u32 mask;
+   struct {
+   u16 arg_c;
+   u16 src_reg;
+   };
};
union {
u16 offset;
@@ -222,6 +226,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_mask);
 
+int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+u16 addr_low, u16 src_reg_idx)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_WRITE_S;
+   inst.src_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.src_reg = src_reg_idx;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 121c3bb6d3de..ee67dd3b86f5 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -59,6 +59,7 @@ enum cmdq_code {
CMDQ_CODE_JUMP = 0x10,
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
+   CMDQ_CODE_WRITE_S = 0x90,
CMDQ_CODE_LOGIC = 0xa0,
 };
 
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 83340211e1d3..e1c5a7549b4f 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -12,6 +12,8 @@
 #include 
 
 #define CMDQ_NO_TIMEOUT0xu
+#define CMDQ_ADDR_HIGH(addr)   ((u32)(((addr) >> 16) & GENMASK(31, 0)))
+#define CMDQ_ADDR_LOW(addr)((u16)(addr) | BIT(1))
 
 struct cmdq_pkt;
 
@@ -103,6 +105,23 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
u16 offset, u32 value, u32 mask);
 
 /**
+ * cmdq_pkt_write_s() - append write_s command to the CMDQ packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @src_reg_idx:   the CMDQ internal register ID which cache source value
+ *
+ * Return: 0 for success; else the error code is returned
+ *
+ * Support write value to physical address without subsys. Use CMDQ_ADDR_HIGH()
+ * to get high address and call cmdq_pkt_assign() to assign value into internal
+ * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter when
+ * call to this function.
+ */
+int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+u16 addr_low, u16 src_reg_idx);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v1 05/11] soc: mediatek: cmdq: add read_s function

2020-06-21 Thread Dennis YC Hsieh
Add read_s function in cmdq helper functions which support read value from
register or dma physical address into gce internal register.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   15 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|   12 
 3 files changed, 28 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 13b888779093..58075589509b 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -226,6 +226,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_mask);
 
+int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, u16 addr_low,
+   u16 reg_idx)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_READ_S;
+   inst.dst_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.reg_dst = reg_idx;
+   inst.src_reg = addr_low;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_read_s);
+
 int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
 u16 addr_low, u16 src_reg_idx)
 {
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 8ef87e1bd03b..3f6bc0dfd5da 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -59,6 +59,7 @@ enum cmdq_code {
CMDQ_CODE_JUMP = 0x10,
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
+   CMDQ_CODE_READ_S = 0x80,
CMDQ_CODE_WRITE_S = 0x90,
CMDQ_CODE_WRITE_S_MASK = 0x91,
CMDQ_CODE_LOGIC = 0xa0,
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index ca9c75fd8125..40fe1eb52190 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -104,6 +104,18 @@ struct cmdq_client *cmdq_mbox_create(struct device *dev, 
int index,
 int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
u16 offset, u32 value, u32 mask);
 
+/*
+ * cmdq_pkt_read_s() - append read_s command to the CMDQ packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @reg_idx:   the CMDQ internal register ID to cache read data
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, u16 addr_low,
+   u16 reg_idx);
+
 /**
  * cmdq_pkt_write_s() - append write_s command to the CMDQ packet
  * @pkt:   the CMDQ packet
-- 
1.7.9.5


[PATCH v1 07/11] soc: mediatek: cmdq: add write_s_mask value function

2020-06-21 Thread Dennis YC Hsieh
add write_s_mask_value function in cmdq helper functions which
writes a constant value to address with mask and large dma
access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |   21 +
 include/linux/soc/mediatek/mtk-cmdq.h  |   15 +++
 2 files changed, 36 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 2ad78df46636..e372ae065240 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -293,6 +293,27 @@ int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_value);
 
+int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+   u16 addr_low, u32 value, u32 mask)
+{
+   struct cmdq_instruction inst = {};
+   int err;
+
+   inst.op = CMDQ_CODE_MASK;
+   inst.mask = ~mask;
+   err = cmdq_pkt_append_command(pkt, inst);
+   if (err < 0)
+   return err;
+
+   inst.op = CMDQ_CODE_WRITE_S_MASK;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.value = value;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 7f1c115a66b8..6e8caacedc80 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -165,6 +165,21 @@ int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
   u16 addr_low, u32 value);
 
 /**
+ * cmdq_pkt_write_s_mask_value() - append write_s command with mask to the CMDQ
+ *packet which write value to a physical
+ *address
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @value: the specified target value
+ * @mask:  the specified target mask
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+   u16 addr_low, u32 value, u32 mask);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5