All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1, 0/1] fix gce timeout issue
@ 2022-08-15  3:07 ` Yongqiang Niu
  0 siblings, 0 replies; 20+ messages in thread
From: Yongqiang Niu @ 2022-08-15  3:07 UTC (permalink / raw)
  To: Chun-Kuang Hu
  Cc: Jassi Brar, Matthias Brugger, linux-kernel, linux-arm-kernel,
	linux-mediatek, Project_Global_Chrome_Upstream_Group,
	Hsin-Yi Wang, Yongqiang Niu

base linux v5.17-rc1

Yongqiang Niu (1):
  mailbox: mtk-cmdq: fix gce timeout issue

 drivers/mailbox/mtk-cmdq-mailbox.c | 57 ++++++++++++++++++++++++++----
 1 file changed, 51 insertions(+), 6 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v1, 0/1] fix gce timeout issue
@ 2022-08-15  3:07 ` Yongqiang Niu
  0 siblings, 0 replies; 20+ messages in thread
From: Yongqiang Niu @ 2022-08-15  3:07 UTC (permalink / raw)
  To: Chun-Kuang Hu
  Cc: Jassi Brar, Matthias Brugger, linux-kernel, linux-arm-kernel,
	linux-mediatek, Project_Global_Chrome_Upstream_Group,
	Hsin-Yi Wang, Yongqiang Niu

base linux v5.17-rc1

Yongqiang Niu (1):
  mailbox: mtk-cmdq: fix gce timeout issue

 drivers/mailbox/mtk-cmdq-mailbox.c | 57 ++++++++++++++++++++++++++----
 1 file changed, 51 insertions(+), 6 deletions(-)

-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v1, 1/1] mailbox: mtk-cmdq: fix gce timeout issue
  2022-08-15  3:07 ` Yongqiang Niu
@ 2022-08-15  3:07   ` Yongqiang Niu
  -1 siblings, 0 replies; 20+ messages in thread
From: Yongqiang Niu @ 2022-08-15  3:07 UTC (permalink / raw)
  To: Chun-Kuang Hu
  Cc: Jassi Brar, Matthias Brugger, linux-kernel, linux-arm-kernel,
	linux-mediatek, Project_Global_Chrome_Upstream_Group,
	Hsin-Yi Wang, Yongqiang Niu, Allen-kh Cheng

From: Yongqiang Niu <yongqiang.niu@mediatek.corp-partner.google.com>

1. enable gce ddr enable(gce reigster offset 0x48, bit 16 to 18) when gce work,
and disable gce ddr enable when gce work job done
2. split cmdq clk enable/disable api, and control gce ddr enable/disable
in clk enable/disable function to make sure it could protect when cmdq
is multiple used by display and mdp

Signed-off-by: Yongqiang Niu <yongqiang.niu@mediatek.corp-partner.google.com>
Signed-off-by: Allen-kh Cheng <allen-kh.cheng@mediatek.corp-partner.google.com>
---
 drivers/mailbox/mtk-cmdq-mailbox.c | 57 ++++++++++++++++++++++++++----
 1 file changed, 51 insertions(+), 6 deletions(-)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index 2578e5aaa935..64a47470f062 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -81,6 +81,8 @@ struct cmdq {
 	u8			shift_pa;
 	bool			control_by_sw;
 	u32			gce_num;
+	atomic_t		usage;
+	spinlock_t		lock;
 };
 
 struct gce_plat {
@@ -90,6 +92,46 @@ struct gce_plat {
 	u32 gce_num;
 };
 
+static s32 cmdq_clk_enable(struct cmdq *cmdq)
+{
+	s32 usage, ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cmdq->lock, flags);
+
+	usage = atomic_inc_return(&cmdq->usage);
+
+	ret = clk_bulk_enable(cmdq->gce_num, cmdq->clocks);
+	if (usage <=0 || ret < 0) {
+		dev_err(cmdq->mbox.dev, "ref count %d ret %d suspend %d\n",
+			usage, ret, cmdq->suspended);
+	} else if (usage == 1) {
+		if (cmdq->control_by_sw)
+			writel((0x7 << 16) + 0x7, cmdq->base + GCE_GCTL_VALUE);
+	}
+
+	spin_unlock_irqrestore(&cmdq->lock, flags);
+
+	return ret;
+}
+
+static void cmdq_clk_disable(struct cmdq *cmdq)
+{
+	s32 usage;
+
+	usage = atomic_dec_return(&cmdq->usage);
+
+	if (usage < 0) {
+		dev_err(cmdq->mbox.dev, "ref count %d suspend %d\n",
+			usage, cmdq->suspended);
+	} else if (usage == 0) {
+		if (cmdq->control_by_sw)
+			writel(0x7, cmdq->base + GCE_GCTL_VALUE);
+	}
+
+	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
+}
+
 u8 cmdq_get_shift_pa(struct mbox_chan *chan)
 {
 	struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox);
@@ -271,7 +313,8 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
 
 	if (list_empty(&thread->task_busy_list)) {
 		cmdq_thread_disable(cmdq, thread);
-		clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
+
+		cmdq_clk_disable(cmdq);
 	}
 }
 
@@ -360,8 +403,7 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
 	task->pkt = pkt;
 
 	if (list_empty(&thread->task_busy_list)) {
-		WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq->clocks));
-
+		WARN_ON(cmdq_clk_enable(cmdq) < 0);
 		/*
 		 * The thread reset will clear thread related register to 0,
 		 * including pc, end, priority, irq, suspend and enable. Thus
@@ -433,7 +475,7 @@ static void cmdq_mbox_shutdown(struct mbox_chan *chan)
 	}
 
 	cmdq_thread_disable(cmdq, thread);
-	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
+	cmdq_clk_disable(cmdq);
 
 done:
 	/*
@@ -479,7 +521,8 @@ static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout)
 
 	cmdq_thread_resume(thread);
 	cmdq_thread_disable(cmdq, thread);
-	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
+
+	cmdq_clk_disable(cmdq);
 
 out:
 	spin_unlock_irqrestore(&thread->chan->lock, flags);
@@ -490,7 +533,8 @@ static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout)
 	spin_unlock_irqrestore(&thread->chan->lock, flags);
 	if (readl_poll_timeout_atomic(thread->base + CMDQ_THR_ENABLE_TASK,
 				      enable, enable == 0, 1, timeout)) {
-		dev_err(cmdq->mbox.dev, "Fail to wait GCE thread 0x%x done\n",
+		dev_err(cmdq->mbox.dev,
+			"Fail to wait GCE thread 0x%x done\n",
 			(u32)(thread->base - cmdq->base));
 
 		return -EFAULT;
@@ -626,6 +670,7 @@ static int cmdq_probe(struct platform_device *pdev)
 
 	WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
 
+	spin_lock_init(&cmdq->lock);
 	cmdq_init(cmdq);
 
 	return 0;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v1, 1/1] mailbox: mtk-cmdq: fix gce timeout issue
@ 2022-08-15  3:07   ` Yongqiang Niu
  0 siblings, 0 replies; 20+ messages in thread
From: Yongqiang Niu @ 2022-08-15  3:07 UTC (permalink / raw)
  To: Chun-Kuang Hu
  Cc: Jassi Brar, Matthias Brugger, linux-kernel, linux-arm-kernel,
	linux-mediatek, Project_Global_Chrome_Upstream_Group,
	Hsin-Yi Wang, Yongqiang Niu, Allen-kh Cheng

From: Yongqiang Niu <yongqiang.niu@mediatek.corp-partner.google.com>

1. enable gce ddr enable(gce reigster offset 0x48, bit 16 to 18) when gce work,
and disable gce ddr enable when gce work job done
2. split cmdq clk enable/disable api, and control gce ddr enable/disable
in clk enable/disable function to make sure it could protect when cmdq
is multiple used by display and mdp

Signed-off-by: Yongqiang Niu <yongqiang.niu@mediatek.corp-partner.google.com>
Signed-off-by: Allen-kh Cheng <allen-kh.cheng@mediatek.corp-partner.google.com>
---
 drivers/mailbox/mtk-cmdq-mailbox.c | 57 ++++++++++++++++++++++++++----
 1 file changed, 51 insertions(+), 6 deletions(-)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index 2578e5aaa935..64a47470f062 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -81,6 +81,8 @@ struct cmdq {
 	u8			shift_pa;
 	bool			control_by_sw;
 	u32			gce_num;
+	atomic_t		usage;
+	spinlock_t		lock;
 };
 
 struct gce_plat {
@@ -90,6 +92,46 @@ struct gce_plat {
 	u32 gce_num;
 };
 
+static s32 cmdq_clk_enable(struct cmdq *cmdq)
+{
+	s32 usage, ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cmdq->lock, flags);
+
+	usage = atomic_inc_return(&cmdq->usage);
+
+	ret = clk_bulk_enable(cmdq->gce_num, cmdq->clocks);
+	if (usage <=0 || ret < 0) {
+		dev_err(cmdq->mbox.dev, "ref count %d ret %d suspend %d\n",
+			usage, ret, cmdq->suspended);
+	} else if (usage == 1) {
+		if (cmdq->control_by_sw)
+			writel((0x7 << 16) + 0x7, cmdq->base + GCE_GCTL_VALUE);
+	}
+
+	spin_unlock_irqrestore(&cmdq->lock, flags);
+
+	return ret;
+}
+
+static void cmdq_clk_disable(struct cmdq *cmdq)
+{
+	s32 usage;
+
+	usage = atomic_dec_return(&cmdq->usage);
+
+	if (usage < 0) {
+		dev_err(cmdq->mbox.dev, "ref count %d suspend %d\n",
+			usage, cmdq->suspended);
+	} else if (usage == 0) {
+		if (cmdq->control_by_sw)
+			writel(0x7, cmdq->base + GCE_GCTL_VALUE);
+	}
+
+	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
+}
+
 u8 cmdq_get_shift_pa(struct mbox_chan *chan)
 {
 	struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox);
@@ -271,7 +313,8 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
 
 	if (list_empty(&thread->task_busy_list)) {
 		cmdq_thread_disable(cmdq, thread);
-		clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
+
+		cmdq_clk_disable(cmdq);
 	}
 }
 
@@ -360,8 +403,7 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
 	task->pkt = pkt;
 
 	if (list_empty(&thread->task_busy_list)) {
-		WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq->clocks));
-
+		WARN_ON(cmdq_clk_enable(cmdq) < 0);
 		/*
 		 * The thread reset will clear thread related register to 0,
 		 * including pc, end, priority, irq, suspend and enable. Thus
@@ -433,7 +475,7 @@ static void cmdq_mbox_shutdown(struct mbox_chan *chan)
 	}
 
 	cmdq_thread_disable(cmdq, thread);
-	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
+	cmdq_clk_disable(cmdq);
 
 done:
 	/*
@@ -479,7 +521,8 @@ static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout)
 
 	cmdq_thread_resume(thread);
 	cmdq_thread_disable(cmdq, thread);
-	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
+
+	cmdq_clk_disable(cmdq);
 
 out:
 	spin_unlock_irqrestore(&thread->chan->lock, flags);
@@ -490,7 +533,8 @@ static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout)
 	spin_unlock_irqrestore(&thread->chan->lock, flags);
 	if (readl_poll_timeout_atomic(thread->base + CMDQ_THR_ENABLE_TASK,
 				      enable, enable == 0, 1, timeout)) {
-		dev_err(cmdq->mbox.dev, "Fail to wait GCE thread 0x%x done\n",
+		dev_err(cmdq->mbox.dev,
+			"Fail to wait GCE thread 0x%x done\n",
 			(u32)(thread->base - cmdq->base));
 
 		return -EFAULT;
@@ -626,6 +670,7 @@ static int cmdq_probe(struct platform_device *pdev)
 
 	WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
 
+	spin_lock_init(&cmdq->lock);
 	cmdq_init(cmdq);
 
 	return 0;
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH v1, 0/1] fix gce timeout issue
  2022-08-15  3:07 ` Yongqiang Niu
@ 2022-08-15  3:24   ` Allen-KH Cheng
  -1 siblings, 0 replies; 20+ messages in thread
From: Allen-KH Cheng @ 2022-08-15  3:24 UTC (permalink / raw)
  To: Yongqiang Niu, Chun-Kuang Hu
  Cc: Jassi Brar, Matthias Brugger, linux-kernel, linux-arm-kernel,
	linux-mediatek, Project_Global_Chrome_Upstream_Group,
	Hsin-Yi Wang

Hi Yongqiang,

Please don't send cover letters for single patches, thanks.

https://lore.kernel.org/all/YuJsDI8rqkHuysIT@sirena.org.uk/

BRs,
Allen

On Mon, 2022-08-15 at 11:07 +0800, Yongqiang Niu wrote:
> base linux v5.17-rc1
> 
> Yongqiang Niu (1):
>   mailbox: mtk-cmdq: fix gce timeout issue
> 
>  drivers/mailbox/mtk-cmdq-mailbox.c | 57 ++++++++++++++++++++++++++
> ----
>  1 file changed, 51 insertions(+), 6 deletions(-)
> 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1, 0/1] fix gce timeout issue
@ 2022-08-15  3:24   ` Allen-KH Cheng
  0 siblings, 0 replies; 20+ messages in thread
From: Allen-KH Cheng @ 2022-08-15  3:24 UTC (permalink / raw)
  To: Yongqiang Niu, Chun-Kuang Hu
  Cc: Jassi Brar, Matthias Brugger, linux-kernel, linux-arm-kernel,
	linux-mediatek, Project_Global_Chrome_Upstream_Group,
	Hsin-Yi Wang

Hi Yongqiang,

Please don't send cover letters for single patches, thanks.

https://lore.kernel.org/all/YuJsDI8rqkHuysIT@sirena.org.uk/

BRs,
Allen

On Mon, 2022-08-15 at 11:07 +0800, Yongqiang Niu wrote:
> base linux v5.17-rc1
> 
> Yongqiang Niu (1):
>   mailbox: mtk-cmdq: fix gce timeout issue
> 
>  drivers/mailbox/mtk-cmdq-mailbox.c | 57 ++++++++++++++++++++++++++
> ----
>  1 file changed, 51 insertions(+), 6 deletions(-)
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1, 0/1] fix gce timeout issue
  2022-08-15  3:07 ` Yongqiang Niu
@ 2022-08-15  4:30   ` Hsin-Yi Wang
  -1 siblings, 0 replies; 20+ messages in thread
From: Hsin-Yi Wang @ 2022-08-15  4:30 UTC (permalink / raw)
  To: Yongqiang Niu
  Cc: Chun-Kuang Hu, Jassi Brar, Matthias Brugger, linux-kernel,
	linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

On Mon, Aug 15, 2022 at 11:07 AM Yongqiang Niu
<yongqiang.niu@mediatek.com> wrote:
>
> base linux v5.17-rc1
Can you base it on newer version?

>
> Yongqiang Niu (1):
>   mailbox: mtk-cmdq: fix gce timeout issue
>
>  drivers/mailbox/mtk-cmdq-mailbox.c | 57 ++++++++++++++++++++++++++----
>  1 file changed, 51 insertions(+), 6 deletions(-)
>
> --
> 2.25.1
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1, 0/1] fix gce timeout issue
@ 2022-08-15  4:30   ` Hsin-Yi Wang
  0 siblings, 0 replies; 20+ messages in thread
From: Hsin-Yi Wang @ 2022-08-15  4:30 UTC (permalink / raw)
  To: Yongqiang Niu
  Cc: Chun-Kuang Hu, Jassi Brar, Matthias Brugger, linux-kernel,
	linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group

On Mon, Aug 15, 2022 at 11:07 AM Yongqiang Niu
<yongqiang.niu@mediatek.com> wrote:
>
> base linux v5.17-rc1
Can you base it on newer version?

>
> Yongqiang Niu (1):
>   mailbox: mtk-cmdq: fix gce timeout issue
>
>  drivers/mailbox/mtk-cmdq-mailbox.c | 57 ++++++++++++++++++++++++++----
>  1 file changed, 51 insertions(+), 6 deletions(-)
>
> --
> 2.25.1
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1, 1/1] mailbox: mtk-cmdq: fix gce timeout issue
  2022-08-15  3:07   ` Yongqiang Niu
@ 2022-08-15  5:24     ` CK Hu
  -1 siblings, 0 replies; 20+ messages in thread
From: CK Hu @ 2022-08-15  5:24 UTC (permalink / raw)
  To: Yongqiang Niu, Chun-Kuang Hu
  Cc: Jassi Brar, Matthias Brugger, linux-kernel, linux-arm-kernel,
	linux-mediatek, Project_Global_Chrome_Upstream_Group,
	Hsin-Yi Wang, Yongqiang Niu, Allen-kh Cheng

Hi, Yongqiang:


On Mon, 2022-08-15 at 11:07 +0800, Yongqiang Niu wrote:
> From: Yongqiang Niu <yongqiang.niu@mediatek.corp-partner.google.com>
> 
> 1. enable gce ddr enable(gce reigster offset 0x48, bit 16 to 18) when
> gce work,
> and disable gce ddr enable when gce work job done

Why need gce ddr enable? I think gce works fine without this. Describe
more about this.

Regards,
CK

> 2. split cmdq clk enable/disable api, and control gce ddr
> enable/disable
> in clk enable/disable function to make sure it could protect when
> cmdq
> is multiple used by display and mdp
> 
> Signed-off-by: Yongqiang Niu <
> yongqiang.niu@mediatek.corp-partner.google.com>
> Signed-off-by: Allen-kh Cheng <
> allen-kh.cheng@mediatek.corp-partner.google.com>
> ---
>  drivers/mailbox/mtk-cmdq-mailbox.c | 57 ++++++++++++++++++++++++++
> ----
>  1 file changed, 51 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c
> b/drivers/mailbox/mtk-cmdq-mailbox.c
> index 2578e5aaa935..64a47470f062 100644
> --- a/drivers/mailbox/mtk-cmdq-mailbox.c
> +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> @@ -81,6 +81,8 @@ struct cmdq {
>  	u8			shift_pa;
>  	bool			control_by_sw;
>  	u32			gce_num;
> +	atomic_t		usage;
> +	spinlock_t		lock;
>  };
>  
>  struct gce_plat {
> @@ -90,6 +92,46 @@ struct gce_plat {
>  	u32 gce_num;
>  };
>  
> +static s32 cmdq_clk_enable(struct cmdq *cmdq)
> +{
> +	s32 usage, ret;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&cmdq->lock, flags);
> +
> +	usage = atomic_inc_return(&cmdq->usage);
> +
> +	ret = clk_bulk_enable(cmdq->gce_num, cmdq->clocks);
> +	if (usage <=0 || ret < 0) {
> +		dev_err(cmdq->mbox.dev, "ref count %d ret %d suspend
> %d\n",
> +			usage, ret, cmdq->suspended);
> +	} else if (usage == 1) {
> +		if (cmdq->control_by_sw)
> +			writel((0x7 << 16) + 0x7, cmdq->base +
> GCE_GCTL_VALUE);
> +	}
> +
> +	spin_unlock_irqrestore(&cmdq->lock, flags);
> +
> +	return ret;
> +}
> +
> +static void cmdq_clk_disable(struct cmdq *cmdq)
> +{
> +	s32 usage;
> +
> +	usage = atomic_dec_return(&cmdq->usage);
> +
> +	if (usage < 0) {
> +		dev_err(cmdq->mbox.dev, "ref count %d suspend %d\n",
> +			usage, cmdq->suspended);
> +	} else if (usage == 0) {
> +		if (cmdq->control_by_sw)
> +			writel(0x7, cmdq->base + GCE_GCTL_VALUE);
> +	}
> +
> +	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> +}
> +
>  u8 cmdq_get_shift_pa(struct mbox_chan *chan)
>  {
>  	struct cmdq *cmdq = container_of(chan->mbox, struct cmdq,
> mbox);
> @@ -271,7 +313,8 @@ static void cmdq_thread_irq_handler(struct cmdq
> *cmdq,
>  
>  	if (list_empty(&thread->task_busy_list)) {
>  		cmdq_thread_disable(cmdq, thread);
> -		clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> +
> +		cmdq_clk_disable(cmdq);
>  	}
>  }
>  
> @@ -360,8 +403,7 @@ static int cmdq_mbox_send_data(struct mbox_chan
> *chan, void *data)
>  	task->pkt = pkt;
>  
>  	if (list_empty(&thread->task_busy_list)) {
> -		WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq->clocks));
> -
> +		WARN_ON(cmdq_clk_enable(cmdq) < 0);
>  		/*
>  		 * The thread reset will clear thread related register
> to 0,
>  		 * including pc, end, priority, irq, suspend and
> enable. Thus
> @@ -433,7 +475,7 @@ static void cmdq_mbox_shutdown(struct mbox_chan
> *chan)
>  	}
>  
>  	cmdq_thread_disable(cmdq, thread);
> -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> +	cmdq_clk_disable(cmdq);
>  
>  done:
>  	/*
> @@ -479,7 +521,8 @@ static int cmdq_mbox_flush(struct mbox_chan
> *chan, unsigned long timeout)
>  
>  	cmdq_thread_resume(thread);
>  	cmdq_thread_disable(cmdq, thread);
> -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> +
> +	cmdq_clk_disable(cmdq);
>  
>  out:
>  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> @@ -490,7 +533,8 @@ static int cmdq_mbox_flush(struct mbox_chan
> *chan, unsigned long timeout)
>  	spin_unlock_irqrestore(&thread->chan->lock, flags);
>  	if (readl_poll_timeout_atomic(thread->base +
> CMDQ_THR_ENABLE_TASK,
>  				      enable, enable == 0, 1, timeout))
> {
> -		dev_err(cmdq->mbox.dev, "Fail to wait GCE thread 0x%x
> done\n",
> +		dev_err(cmdq->mbox.dev,
> +			"Fail to wait GCE thread 0x%x done\n",
>  			(u32)(thread->base - cmdq->base));
>  
>  		return -EFAULT;
> @@ -626,6 +670,7 @@ static int cmdq_probe(struct platform_device
> *pdev)
>  
>  	WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
>  
> +	spin_lock_init(&cmdq->lock);
>  	cmdq_init(cmdq);
>  
>  	return 0;


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1, 1/1] mailbox: mtk-cmdq: fix gce timeout issue
@ 2022-08-15  5:24     ` CK Hu
  0 siblings, 0 replies; 20+ messages in thread
From: CK Hu @ 2022-08-15  5:24 UTC (permalink / raw)
  To: Yongqiang Niu, Chun-Kuang Hu
  Cc: Jassi Brar, Matthias Brugger, linux-kernel, linux-arm-kernel,
	linux-mediatek, Project_Global_Chrome_Upstream_Group,
	Hsin-Yi Wang, Yongqiang Niu, Allen-kh Cheng

Hi, Yongqiang:


On Mon, 2022-08-15 at 11:07 +0800, Yongqiang Niu wrote:
> From: Yongqiang Niu <yongqiang.niu@mediatek.corp-partner.google.com>
> 
> 1. enable gce ddr enable(gce reigster offset 0x48, bit 16 to 18) when
> gce work,
> and disable gce ddr enable when gce work job done

Why need gce ddr enable? I think gce works fine without this. Describe
more about this.

Regards,
CK

> 2. split cmdq clk enable/disable api, and control gce ddr
> enable/disable
> in clk enable/disable function to make sure it could protect when
> cmdq
> is multiple used by display and mdp
> 
> Signed-off-by: Yongqiang Niu <
> yongqiang.niu@mediatek.corp-partner.google.com>
> Signed-off-by: Allen-kh Cheng <
> allen-kh.cheng@mediatek.corp-partner.google.com>
> ---
>  drivers/mailbox/mtk-cmdq-mailbox.c | 57 ++++++++++++++++++++++++++
> ----
>  1 file changed, 51 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c
> b/drivers/mailbox/mtk-cmdq-mailbox.c
> index 2578e5aaa935..64a47470f062 100644
> --- a/drivers/mailbox/mtk-cmdq-mailbox.c
> +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> @@ -81,6 +81,8 @@ struct cmdq {
>  	u8			shift_pa;
>  	bool			control_by_sw;
>  	u32			gce_num;
> +	atomic_t		usage;
> +	spinlock_t		lock;
>  };
>  
>  struct gce_plat {
> @@ -90,6 +92,46 @@ struct gce_plat {
>  	u32 gce_num;
>  };
>  
> +static s32 cmdq_clk_enable(struct cmdq *cmdq)
> +{
> +	s32 usage, ret;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&cmdq->lock, flags);
> +
> +	usage = atomic_inc_return(&cmdq->usage);
> +
> +	ret = clk_bulk_enable(cmdq->gce_num, cmdq->clocks);
> +	if (usage <=0 || ret < 0) {
> +		dev_err(cmdq->mbox.dev, "ref count %d ret %d suspend
> %d\n",
> +			usage, ret, cmdq->suspended);
> +	} else if (usage == 1) {
> +		if (cmdq->control_by_sw)
> +			writel((0x7 << 16) + 0x7, cmdq->base +
> GCE_GCTL_VALUE);
> +	}
> +
> +	spin_unlock_irqrestore(&cmdq->lock, flags);
> +
> +	return ret;
> +}
> +
> +static void cmdq_clk_disable(struct cmdq *cmdq)
> +{
> +	s32 usage;
> +
> +	usage = atomic_dec_return(&cmdq->usage);
> +
> +	if (usage < 0) {
> +		dev_err(cmdq->mbox.dev, "ref count %d suspend %d\n",
> +			usage, cmdq->suspended);
> +	} else if (usage == 0) {
> +		if (cmdq->control_by_sw)
> +			writel(0x7, cmdq->base + GCE_GCTL_VALUE);
> +	}
> +
> +	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> +}
> +
>  u8 cmdq_get_shift_pa(struct mbox_chan *chan)
>  {
>  	struct cmdq *cmdq = container_of(chan->mbox, struct cmdq,
> mbox);
> @@ -271,7 +313,8 @@ static void cmdq_thread_irq_handler(struct cmdq
> *cmdq,
>  
>  	if (list_empty(&thread->task_busy_list)) {
>  		cmdq_thread_disable(cmdq, thread);
> -		clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> +
> +		cmdq_clk_disable(cmdq);
>  	}
>  }
>  
> @@ -360,8 +403,7 @@ static int cmdq_mbox_send_data(struct mbox_chan
> *chan, void *data)
>  	task->pkt = pkt;
>  
>  	if (list_empty(&thread->task_busy_list)) {
> -		WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq->clocks));
> -
> +		WARN_ON(cmdq_clk_enable(cmdq) < 0);
>  		/*
>  		 * The thread reset will clear thread related register
> to 0,
>  		 * including pc, end, priority, irq, suspend and
> enable. Thus
> @@ -433,7 +475,7 @@ static void cmdq_mbox_shutdown(struct mbox_chan
> *chan)
>  	}
>  
>  	cmdq_thread_disable(cmdq, thread);
> -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> +	cmdq_clk_disable(cmdq);
>  
>  done:
>  	/*
> @@ -479,7 +521,8 @@ static int cmdq_mbox_flush(struct mbox_chan
> *chan, unsigned long timeout)
>  
>  	cmdq_thread_resume(thread);
>  	cmdq_thread_disable(cmdq, thread);
> -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> +
> +	cmdq_clk_disable(cmdq);
>  
>  out:
>  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> @@ -490,7 +533,8 @@ static int cmdq_mbox_flush(struct mbox_chan
> *chan, unsigned long timeout)
>  	spin_unlock_irqrestore(&thread->chan->lock, flags);
>  	if (readl_poll_timeout_atomic(thread->base +
> CMDQ_THR_ENABLE_TASK,
>  				      enable, enable == 0, 1, timeout))
> {
> -		dev_err(cmdq->mbox.dev, "Fail to wait GCE thread 0x%x
> done\n",
> +		dev_err(cmdq->mbox.dev,
> +			"Fail to wait GCE thread 0x%x done\n",
>  			(u32)(thread->base - cmdq->base));
>  
>  		return -EFAULT;
> @@ -626,6 +670,7 @@ static int cmdq_probe(struct platform_device
> *pdev)
>  
>  	WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
>  
> +	spin_lock_init(&cmdq->lock);
>  	cmdq_init(cmdq);
>  
>  	return 0;


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1, 1/1] mailbox: mtk-cmdq: fix gce timeout issue
  2022-08-15  5:24     ` CK Hu
@ 2022-08-15  5:51       ` yongqiang.niu
  -1 siblings, 0 replies; 20+ messages in thread
From: yongqiang.niu @ 2022-08-15  5:51 UTC (permalink / raw)
  To: CK Hu, Chun-Kuang Hu
  Cc: Jassi Brar, Matthias Brugger, linux-kernel, linux-arm-kernel,
	linux-mediatek, Project_Global_Chrome_Upstream_Group,
	Hsin-Yi Wang, Yongqiang Niu, Allen-kh Cheng

On Mon, 2022-08-15 at 13:24 +0800, CK Hu wrote:
> Hi, Yongqiang:
> 
> 
> On Mon, 2022-08-15 at 11:07 +0800, Yongqiang Niu wrote:
> > From: Yongqiang Niu <yongqiang.niu@mediatek.corp-partner.google.com
> > >
> > 
> > 1. enable gce ddr enable(gce reigster offset 0x48, bit 16 to 18)
> > when
> > gce work,
> > and disable gce ddr enable when gce work job done
> 
> Why need gce ddr enable? I think gce works fine without this.
> Describe
> more about this.
> 
> Regards,
> CK

this is only for some SOC which has flag "control_by_sw".
for this kind of gce, there is a handshake flow between gce and ddr
hardware,
if not set ddr enable flag of gce, ddr will fall into idle mode, 
then gce instructions will not process done.
we need set this flag of gce to tell ddr when gce is idle or busy
controlled by software flow.

> 
> > 2. split cmdq clk enable/disable api, and control gce ddr
> > enable/disable
> > in clk enable/disable function to make sure it could protect when
> > cmdq
> > is multiple used by display and mdp
> > 
> > Signed-off-by: Yongqiang Niu <
> > yongqiang.niu@mediatek.corp-partner.google.com>
> > Signed-off-by: Allen-kh Cheng <
> > allen-kh.cheng@mediatek.corp-partner.google.com>
> > ---
> >  drivers/mailbox/mtk-cmdq-mailbox.c | 57 ++++++++++++++++++++++++++
> > ----
> >  1 file changed, 51 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c
> > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > index 2578e5aaa935..64a47470f062 100644
> > --- a/drivers/mailbox/mtk-cmdq-mailbox.c
> > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > @@ -81,6 +81,8 @@ struct cmdq {
> >  	u8			shift_pa;
> >  	bool			control_by_sw;
> >  	u32			gce_num;
> > +	atomic_t		usage;
> > +	spinlock_t		lock;
> >  };
> >  
> >  struct gce_plat {
> > @@ -90,6 +92,46 @@ struct gce_plat {
> >  	u32 gce_num;
> >  };
> >  
> > +static s32 cmdq_clk_enable(struct cmdq *cmdq)
> > +{
> > +	s32 usage, ret;
> > +	unsigned long flags;
> > +
> > +	spin_lock_irqsave(&cmdq->lock, flags);
> > +
> > +	usage = atomic_inc_return(&cmdq->usage);
> > +
> > +	ret = clk_bulk_enable(cmdq->gce_num, cmdq->clocks);
> > +	if (usage <=0 || ret < 0) {
> > +		dev_err(cmdq->mbox.dev, "ref count %d ret %d suspend
> > %d\n",
> > +			usage, ret, cmdq->suspended);
> > +	} else if (usage == 1) {
> > +		if (cmdq->control_by_sw)
> > +			writel((0x7 << 16) + 0x7, cmdq->base +
> > GCE_GCTL_VALUE);
> > +	}
> > +
> > +	spin_unlock_irqrestore(&cmdq->lock, flags);
> > +
> > +	return ret;
> > +}
> > +
> > +static void cmdq_clk_disable(struct cmdq *cmdq)
> > +{
> > +	s32 usage;
> > +
> > +	usage = atomic_dec_return(&cmdq->usage);
> > +
> > +	if (usage < 0) {
> > +		dev_err(cmdq->mbox.dev, "ref count %d suspend %d\n",
> > +			usage, cmdq->suspended);
> > +	} else if (usage == 0) {
> > +		if (cmdq->control_by_sw)
> > +			writel(0x7, cmdq->base + GCE_GCTL_VALUE);
> > +	}
> > +
> > +	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > +}
> > +
> >  u8 cmdq_get_shift_pa(struct mbox_chan *chan)
> >  {
> >  	struct cmdq *cmdq = container_of(chan->mbox, struct cmdq,
> > mbox);
> > @@ -271,7 +313,8 @@ static void cmdq_thread_irq_handler(struct cmdq
> > *cmdq,
> >  
> >  	if (list_empty(&thread->task_busy_list)) {
> >  		cmdq_thread_disable(cmdq, thread);
> > -		clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > +
> > +		cmdq_clk_disable(cmdq);
> >  	}
> >  }
> >  
> > @@ -360,8 +403,7 @@ static int cmdq_mbox_send_data(struct mbox_chan
> > *chan, void *data)
> >  	task->pkt = pkt;
> >  
> >  	if (list_empty(&thread->task_busy_list)) {
> > -		WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq->clocks));
> > -
> > +		WARN_ON(cmdq_clk_enable(cmdq) < 0);
> >  		/*
> >  		 * The thread reset will clear thread related register
> > to 0,
> >  		 * including pc, end, priority, irq, suspend and
> > enable. Thus
> > @@ -433,7 +475,7 @@ static void cmdq_mbox_shutdown(struct mbox_chan
> > *chan)
> >  	}
> >  
> >  	cmdq_thread_disable(cmdq, thread);
> > -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > +	cmdq_clk_disable(cmdq);
> >  
> >  done:
> >  	/*
> > @@ -479,7 +521,8 @@ static int cmdq_mbox_flush(struct mbox_chan
> > *chan, unsigned long timeout)
> >  
> >  	cmdq_thread_resume(thread);
> >  	cmdq_thread_disable(cmdq, thread);
> > -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > +
> > +	cmdq_clk_disable(cmdq);
> >  
> >  out:
> >  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> > @@ -490,7 +533,8 @@ static int cmdq_mbox_flush(struct mbox_chan
> > *chan, unsigned long timeout)
> >  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> >  	if (readl_poll_timeout_atomic(thread->base +
> > CMDQ_THR_ENABLE_TASK,
> >  				      enable, enable == 0, 1, timeout))
> > {
> > -		dev_err(cmdq->mbox.dev, "Fail to wait GCE thread 0x%x
> > done\n",
> > +		dev_err(cmdq->mbox.dev,
> > +			"Fail to wait GCE thread 0x%x done\n",
> >  			(u32)(thread->base - cmdq->base));
> >  
> >  		return -EFAULT;
> > @@ -626,6 +670,7 @@ static int cmdq_probe(struct platform_device
> > *pdev)
> >  
> >  	WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
> >  
> > +	spin_lock_init(&cmdq->lock);
> >  	cmdq_init(cmdq);
> >  
> >  	return 0;
> 
> 



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1, 1/1] mailbox: mtk-cmdq: fix gce timeout issue
@ 2022-08-15  5:51       ` yongqiang.niu
  0 siblings, 0 replies; 20+ messages in thread
From: yongqiang.niu @ 2022-08-15  5:51 UTC (permalink / raw)
  To: CK Hu, Chun-Kuang Hu
  Cc: Jassi Brar, Matthias Brugger, linux-kernel, linux-arm-kernel,
	linux-mediatek, Project_Global_Chrome_Upstream_Group,
	Hsin-Yi Wang, Yongqiang Niu, Allen-kh Cheng

On Mon, 2022-08-15 at 13:24 +0800, CK Hu wrote:
> Hi, Yongqiang:
> 
> 
> On Mon, 2022-08-15 at 11:07 +0800, Yongqiang Niu wrote:
> > From: Yongqiang Niu <yongqiang.niu@mediatek.corp-partner.google.com
> > >
> > 
> > 1. enable gce ddr enable(gce reigster offset 0x48, bit 16 to 18)
> > when
> > gce work,
> > and disable gce ddr enable when gce work job done
> 
> Why need gce ddr enable? I think gce works fine without this.
> Describe
> more about this.
> 
> Regards,
> CK

this is only for some SOC which has flag "control_by_sw".
for this kind of gce, there is a handshake flow between gce and ddr
hardware,
if not set ddr enable flag of gce, ddr will fall into idle mode, 
then gce instructions will not process done.
we need set this flag of gce to tell ddr when gce is idle or busy
controlled by software flow.

> 
> > 2. split cmdq clk enable/disable api, and control gce ddr
> > enable/disable
> > in clk enable/disable function to make sure it could protect when
> > cmdq
> > is multiple used by display and mdp
> > 
> > Signed-off-by: Yongqiang Niu <
> > yongqiang.niu@mediatek.corp-partner.google.com>
> > Signed-off-by: Allen-kh Cheng <
> > allen-kh.cheng@mediatek.corp-partner.google.com>
> > ---
> >  drivers/mailbox/mtk-cmdq-mailbox.c | 57 ++++++++++++++++++++++++++
> > ----
> >  1 file changed, 51 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c
> > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > index 2578e5aaa935..64a47470f062 100644
> > --- a/drivers/mailbox/mtk-cmdq-mailbox.c
> > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > @@ -81,6 +81,8 @@ struct cmdq {
> >  	u8			shift_pa;
> >  	bool			control_by_sw;
> >  	u32			gce_num;
> > +	atomic_t		usage;
> > +	spinlock_t		lock;
> >  };
> >  
> >  struct gce_plat {
> > @@ -90,6 +92,46 @@ struct gce_plat {
> >  	u32 gce_num;
> >  };
> >  
> > +static s32 cmdq_clk_enable(struct cmdq *cmdq)
> > +{
> > +	s32 usage, ret;
> > +	unsigned long flags;
> > +
> > +	spin_lock_irqsave(&cmdq->lock, flags);
> > +
> > +	usage = atomic_inc_return(&cmdq->usage);
> > +
> > +	ret = clk_bulk_enable(cmdq->gce_num, cmdq->clocks);
> > +	if (usage <=0 || ret < 0) {
> > +		dev_err(cmdq->mbox.dev, "ref count %d ret %d suspend
> > %d\n",
> > +			usage, ret, cmdq->suspended);
> > +	} else if (usage == 1) {
> > +		if (cmdq->control_by_sw)
> > +			writel((0x7 << 16) + 0x7, cmdq->base +
> > GCE_GCTL_VALUE);
> > +	}
> > +
> > +	spin_unlock_irqrestore(&cmdq->lock, flags);
> > +
> > +	return ret;
> > +}
> > +
> > +static void cmdq_clk_disable(struct cmdq *cmdq)
> > +{
> > +	s32 usage;
> > +
> > +	usage = atomic_dec_return(&cmdq->usage);
> > +
> > +	if (usage < 0) {
> > +		dev_err(cmdq->mbox.dev, "ref count %d suspend %d\n",
> > +			usage, cmdq->suspended);
> > +	} else if (usage == 0) {
> > +		if (cmdq->control_by_sw)
> > +			writel(0x7, cmdq->base + GCE_GCTL_VALUE);
> > +	}
> > +
> > +	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > +}
> > +
> >  u8 cmdq_get_shift_pa(struct mbox_chan *chan)
> >  {
> >  	struct cmdq *cmdq = container_of(chan->mbox, struct cmdq,
> > mbox);
> > @@ -271,7 +313,8 @@ static void cmdq_thread_irq_handler(struct cmdq
> > *cmdq,
> >  
> >  	if (list_empty(&thread->task_busy_list)) {
> >  		cmdq_thread_disable(cmdq, thread);
> > -		clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > +
> > +		cmdq_clk_disable(cmdq);
> >  	}
> >  }
> >  
> > @@ -360,8 +403,7 @@ static int cmdq_mbox_send_data(struct mbox_chan
> > *chan, void *data)
> >  	task->pkt = pkt;
> >  
> >  	if (list_empty(&thread->task_busy_list)) {
> > -		WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq->clocks));
> > -
> > +		WARN_ON(cmdq_clk_enable(cmdq) < 0);
> >  		/*
> >  		 * The thread reset will clear thread related register
> > to 0,
> >  		 * including pc, end, priority, irq, suspend and
> > enable. Thus
> > @@ -433,7 +475,7 @@ static void cmdq_mbox_shutdown(struct mbox_chan
> > *chan)
> >  	}
> >  
> >  	cmdq_thread_disable(cmdq, thread);
> > -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > +	cmdq_clk_disable(cmdq);
> >  
> >  done:
> >  	/*
> > @@ -479,7 +521,8 @@ static int cmdq_mbox_flush(struct mbox_chan
> > *chan, unsigned long timeout)
> >  
> >  	cmdq_thread_resume(thread);
> >  	cmdq_thread_disable(cmdq, thread);
> > -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > +
> > +	cmdq_clk_disable(cmdq);
> >  
> >  out:
> >  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> > @@ -490,7 +533,8 @@ static int cmdq_mbox_flush(struct mbox_chan
> > *chan, unsigned long timeout)
> >  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> >  	if (readl_poll_timeout_atomic(thread->base +
> > CMDQ_THR_ENABLE_TASK,
> >  				      enable, enable == 0, 1, timeout))
> > {
> > -		dev_err(cmdq->mbox.dev, "Fail to wait GCE thread 0x%x
> > done\n",
> > +		dev_err(cmdq->mbox.dev,
> > +			"Fail to wait GCE thread 0x%x done\n",
> >  			(u32)(thread->base - cmdq->base));
> >  
> >  		return -EFAULT;
> > @@ -626,6 +670,7 @@ static int cmdq_probe(struct platform_device
> > *pdev)
> >  
> >  	WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
> >  
> > +	spin_lock_init(&cmdq->lock);
> >  	cmdq_init(cmdq);
> >  
> >  	return 0;
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1, 1/1] mailbox: mtk-cmdq: fix gce timeout issue
  2022-08-15  5:51       ` yongqiang.niu
@ 2022-08-15  6:23         ` CK Hu
  -1 siblings, 0 replies; 20+ messages in thread
From: CK Hu @ 2022-08-15  6:23 UTC (permalink / raw)
  To: yongqiang.niu, Chun-Kuang Hu
  Cc: Jassi Brar, Matthias Brugger, linux-kernel, linux-arm-kernel,
	linux-mediatek, Project_Global_Chrome_Upstream_Group,
	Hsin-Yi Wang, Yongqiang Niu, Allen-kh Cheng

Hi, Yongqiang:

On Mon, 2022-08-15 at 13:51 +0800, yongqiang.niu wrote:
> On Mon, 2022-08-15 at 13:24 +0800, CK Hu wrote:
> > Hi, Yongqiang:
> > 
> > 
> > On Mon, 2022-08-15 at 11:07 +0800, Yongqiang Niu wrote:
> > > From: Yongqiang Niu <
> > > yongqiang.niu@mediatek.corp-partner.google.com
> > > > 
> > > 
> > > 1. enable gce ddr enable(gce reigster offset 0x48, bit 16 to 18)
> > > when
> > > gce work,
> > > and disable gce ddr enable when gce work job done
> > 
> > Why need gce ddr enable? I think gce works fine without this.
> > Describe
> > more about this.
> > 
> > Regards,
> > CK
> 
> this is only for some SOC which has flag "control_by_sw".
> for this kind of gce, there is a handshake flow between gce and ddr
> hardware,
> if not set ddr enable flag of gce, ddr will fall into idle mode, 
> then gce instructions will not process done.
> we need set this flag of gce to tell ddr when gce is idle or busy
> controlled by software flow.

You [1] and Jason [2] has already enable control_by_sw and I believe
you two have test your patch in general. Is the ddr problem a special
case? How to operate to trigger this bug? Describe more in commit
message to let us know why need this patch.

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/mailbox/mtk-cmdq-mailbox.c?h=v6.0-rc1&id=84fd4201b78b96f8d31f6a2624be27ad6306a9bc
[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/mailbox/mtk-cmdq-mailbox.c?h=v6.0-rc1&id=9388501fbb99a1b6a23f28634d125567a3b45a3d


> 
> > 
> > > 2. split cmdq clk enable/disable api, and control gce ddr
> > > enable/disable
> > > in clk enable/disable function to make sure it could protect when
> > > cmdq
> > > is multiple used by display and mdp
> > > 
> > > Signed-off-by: Yongqiang Niu <
> > > yongqiang.niu@mediatek.corp-partner.google.com>
> > > Signed-off-by: Allen-kh Cheng <
> > > allen-kh.cheng@mediatek.corp-partner.google.com>
> > > ---
> > >  drivers/mailbox/mtk-cmdq-mailbox.c | 57
> > > ++++++++++++++++++++++++++
> > > ----
> > >  1 file changed, 51 insertions(+), 6 deletions(-)
> > > 
> > > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c
> > > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > index 2578e5aaa935..64a47470f062 100644
> > > --- a/drivers/mailbox/mtk-cmdq-mailbox.c
> > > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > @@ -81,6 +81,8 @@ struct cmdq {
> > >  	u8			shift_pa;
> > >  	bool			control_by_sw;
> > >  	u32			gce_num;
> > > +	atomic_t		usage;
> > > +	spinlock_t		lock;
> > >  };
> > >  
> > >  struct gce_plat {
> > > @@ -90,6 +92,46 @@ struct gce_plat {
> > >  	u32 gce_num;
> > >  };
> > >  
> > > +static s32 cmdq_clk_enable(struct cmdq *cmdq)
> > > +{
> > > +	s32 usage, ret;
> > > +	unsigned long flags;
> > > +
> > > +	spin_lock_irqsave(&cmdq->lock, flags);
> > > +
> > > +	usage = atomic_inc_return(&cmdq->usage);
> > > +
> > > +	ret = clk_bulk_enable(cmdq->gce_num, cmdq->clocks);
> > > +	if (usage <=0 || ret < 0) {
> > > +		dev_err(cmdq->mbox.dev, "ref count %d ret %d suspend
> > > %d\n",
> > > +			usage, ret, cmdq->suspended);
> > > +	} else if (usage == 1) {
> > > +		if (cmdq->control_by_sw)
> > > +			writel((0x7 << 16) + 0x7, cmdq->base +
> > > GCE_GCTL_VALUE);
> > > +	}
> > > +
> > > +	spin_unlock_irqrestore(&cmdq->lock, flags);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > > +static void cmdq_clk_disable(struct cmdq *cmdq)
> > > +{
> > > +	s32 usage;
> > > +
> > > +	usage = atomic_dec_return(&cmdq->usage);
> > > +
> > > +	if (usage < 0) {
> > > +		dev_err(cmdq->mbox.dev, "ref count %d suspend %d\n",
> > > +			usage, cmdq->suspended);
> > > +	} else if (usage == 0) {
> > > +		if (cmdq->control_by_sw)
> > > +			writel(0x7, cmdq->base + GCE_GCTL_VALUE);
> > > +	}
> > > +
> > > +	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > +}
> > > +
> > >  u8 cmdq_get_shift_pa(struct mbox_chan *chan)
> > >  {
> > >  	struct cmdq *cmdq = container_of(chan->mbox, struct cmdq,
> > > mbox);
> > > @@ -271,7 +313,8 @@ static void cmdq_thread_irq_handler(struct
> > > cmdq
> > > *cmdq,
> > >  
> > >  	if (list_empty(&thread->task_busy_list)) {
> > >  		cmdq_thread_disable(cmdq, thread);
> > > -		clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > +
> > > +		cmdq_clk_disable(cmdq);
> > >  	}
> > >  }
> > >  
> > > @@ -360,8 +403,7 @@ static int cmdq_mbox_send_data(struct
> > > mbox_chan
> > > *chan, void *data)
> > >  	task->pkt = pkt;
> > >  
> > >  	if (list_empty(&thread->task_busy_list)) {
> > > -		WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq->clocks));
> > > -
> > > +		WARN_ON(cmdq_clk_enable(cmdq) < 0);
> > >  		/*
> > >  		 * The thread reset will clear thread related register
> > > to 0,
> > >  		 * including pc, end, priority, irq, suspend and
> > > enable. Thus
> > > @@ -433,7 +475,7 @@ static void cmdq_mbox_shutdown(struct
> > > mbox_chan
> > > *chan)
> > >  	}
> > >  
> > >  	cmdq_thread_disable(cmdq, thread);
> > > -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > +	cmdq_clk_disable(cmdq);
> > >  
> > >  done:
> > >  	/*
> > > @@ -479,7 +521,8 @@ static int cmdq_mbox_flush(struct mbox_chan
> > > *chan, unsigned long timeout)
> > >  
> > >  	cmdq_thread_resume(thread);
> > >  	cmdq_thread_disable(cmdq, thread);
> > > -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > +
> > > +	cmdq_clk_disable(cmdq);
> > >  
> > >  out:
> > >  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> > > @@ -490,7 +533,8 @@ static int cmdq_mbox_flush(struct mbox_chan
> > > *chan, unsigned long timeout)
> > >  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> > >  	if (readl_poll_timeout_atomic(thread->base +
> > > CMDQ_THR_ENABLE_TASK,
> > >  				      enable, enable == 0, 1, timeout))
> > > {
> > > -		dev_err(cmdq->mbox.dev, "Fail to wait GCE thread 0x%x
> > > done\n",
> > > +		dev_err(cmdq->mbox.dev,
> > > +			"Fail to wait GCE thread 0x%x done\n",
> > >  			(u32)(thread->base - cmdq->base));
> > >  
> > >  		return -EFAULT;
> > > @@ -626,6 +670,7 @@ static int cmdq_probe(struct platform_device
> > > *pdev)
> > >  
> > >  	WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
> > >  
> > > +	spin_lock_init(&cmdq->lock);
> > >  	cmdq_init(cmdq);
> > >  
> > >  	return 0;
> > 
> > 
> 
> 



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1, 1/1] mailbox: mtk-cmdq: fix gce timeout issue
@ 2022-08-15  6:23         ` CK Hu
  0 siblings, 0 replies; 20+ messages in thread
From: CK Hu @ 2022-08-15  6:23 UTC (permalink / raw)
  To: yongqiang.niu, Chun-Kuang Hu
  Cc: Jassi Brar, Matthias Brugger, linux-kernel, linux-arm-kernel,
	linux-mediatek, Project_Global_Chrome_Upstream_Group,
	Hsin-Yi Wang, Yongqiang Niu, Allen-kh Cheng

Hi, Yongqiang:

On Mon, 2022-08-15 at 13:51 +0800, yongqiang.niu wrote:
> On Mon, 2022-08-15 at 13:24 +0800, CK Hu wrote:
> > Hi, Yongqiang:
> > 
> > 
> > On Mon, 2022-08-15 at 11:07 +0800, Yongqiang Niu wrote:
> > > From: Yongqiang Niu <
> > > yongqiang.niu@mediatek.corp-partner.google.com
> > > > 
> > > 
> > > 1. enable gce ddr enable(gce reigster offset 0x48, bit 16 to 18)
> > > when
> > > gce work,
> > > and disable gce ddr enable when gce work job done
> > 
> > Why need gce ddr enable? I think gce works fine without this.
> > Describe
> > more about this.
> > 
> > Regards,
> > CK
> 
> this is only for some SOC which has flag "control_by_sw".
> for this kind of gce, there is a handshake flow between gce and ddr
> hardware,
> if not set ddr enable flag of gce, ddr will fall into idle mode, 
> then gce instructions will not process done.
> we need set this flag of gce to tell ddr when gce is idle or busy
> controlled by software flow.

You [1] and Jason [2] has already enable control_by_sw and I believe
you two have test your patch in general. Is the ddr problem a special
case? How to operate to trigger this bug? Describe more in commit
message to let us know why need this patch.

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/mailbox/mtk-cmdq-mailbox.c?h=v6.0-rc1&id=84fd4201b78b96f8d31f6a2624be27ad6306a9bc
[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/mailbox/mtk-cmdq-mailbox.c?h=v6.0-rc1&id=9388501fbb99a1b6a23f28634d125567a3b45a3d


> 
> > 
> > > 2. split cmdq clk enable/disable api, and control gce ddr
> > > enable/disable
> > > in clk enable/disable function to make sure it could protect when
> > > cmdq
> > > is multiple used by display and mdp
> > > 
> > > Signed-off-by: Yongqiang Niu <
> > > yongqiang.niu@mediatek.corp-partner.google.com>
> > > Signed-off-by: Allen-kh Cheng <
> > > allen-kh.cheng@mediatek.corp-partner.google.com>
> > > ---
> > >  drivers/mailbox/mtk-cmdq-mailbox.c | 57
> > > ++++++++++++++++++++++++++
> > > ----
> > >  1 file changed, 51 insertions(+), 6 deletions(-)
> > > 
> > > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c
> > > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > index 2578e5aaa935..64a47470f062 100644
> > > --- a/drivers/mailbox/mtk-cmdq-mailbox.c
> > > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > @@ -81,6 +81,8 @@ struct cmdq {
> > >  	u8			shift_pa;
> > >  	bool			control_by_sw;
> > >  	u32			gce_num;
> > > +	atomic_t		usage;
> > > +	spinlock_t		lock;
> > >  };
> > >  
> > >  struct gce_plat {
> > > @@ -90,6 +92,46 @@ struct gce_plat {
> > >  	u32 gce_num;
> > >  };
> > >  
> > > +static s32 cmdq_clk_enable(struct cmdq *cmdq)
> > > +{
> > > +	s32 usage, ret;
> > > +	unsigned long flags;
> > > +
> > > +	spin_lock_irqsave(&cmdq->lock, flags);
> > > +
> > > +	usage = atomic_inc_return(&cmdq->usage);
> > > +
> > > +	ret = clk_bulk_enable(cmdq->gce_num, cmdq->clocks);
> > > +	if (usage <=0 || ret < 0) {
> > > +		dev_err(cmdq->mbox.dev, "ref count %d ret %d suspend
> > > %d\n",
> > > +			usage, ret, cmdq->suspended);
> > > +	} else if (usage == 1) {
> > > +		if (cmdq->control_by_sw)
> > > +			writel((0x7 << 16) + 0x7, cmdq->base +
> > > GCE_GCTL_VALUE);
> > > +	}
> > > +
> > > +	spin_unlock_irqrestore(&cmdq->lock, flags);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > > +static void cmdq_clk_disable(struct cmdq *cmdq)
> > > +{
> > > +	s32 usage;
> > > +
> > > +	usage = atomic_dec_return(&cmdq->usage);
> > > +
> > > +	if (usage < 0) {
> > > +		dev_err(cmdq->mbox.dev, "ref count %d suspend %d\n",
> > > +			usage, cmdq->suspended);
> > > +	} else if (usage == 0) {
> > > +		if (cmdq->control_by_sw)
> > > +			writel(0x7, cmdq->base + GCE_GCTL_VALUE);
> > > +	}
> > > +
> > > +	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > +}
> > > +
> > >  u8 cmdq_get_shift_pa(struct mbox_chan *chan)
> > >  {
> > >  	struct cmdq *cmdq = container_of(chan->mbox, struct cmdq,
> > > mbox);
> > > @@ -271,7 +313,8 @@ static void cmdq_thread_irq_handler(struct
> > > cmdq
> > > *cmdq,
> > >  
> > >  	if (list_empty(&thread->task_busy_list)) {
> > >  		cmdq_thread_disable(cmdq, thread);
> > > -		clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > +
> > > +		cmdq_clk_disable(cmdq);
> > >  	}
> > >  }
> > >  
> > > @@ -360,8 +403,7 @@ static int cmdq_mbox_send_data(struct
> > > mbox_chan
> > > *chan, void *data)
> > >  	task->pkt = pkt;
> > >  
> > >  	if (list_empty(&thread->task_busy_list)) {
> > > -		WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq->clocks));
> > > -
> > > +		WARN_ON(cmdq_clk_enable(cmdq) < 0);
> > >  		/*
> > >  		 * The thread reset will clear thread related register
> > > to 0,
> > >  		 * including pc, end, priority, irq, suspend and
> > > enable. Thus
> > > @@ -433,7 +475,7 @@ static void cmdq_mbox_shutdown(struct
> > > mbox_chan
> > > *chan)
> > >  	}
> > >  
> > >  	cmdq_thread_disable(cmdq, thread);
> > > -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > +	cmdq_clk_disable(cmdq);
> > >  
> > >  done:
> > >  	/*
> > > @@ -479,7 +521,8 @@ static int cmdq_mbox_flush(struct mbox_chan
> > > *chan, unsigned long timeout)
> > >  
> > >  	cmdq_thread_resume(thread);
> > >  	cmdq_thread_disable(cmdq, thread);
> > > -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > +
> > > +	cmdq_clk_disable(cmdq);
> > >  
> > >  out:
> > >  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> > > @@ -490,7 +533,8 @@ static int cmdq_mbox_flush(struct mbox_chan
> > > *chan, unsigned long timeout)
> > >  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> > >  	if (readl_poll_timeout_atomic(thread->base +
> > > CMDQ_THR_ENABLE_TASK,
> > >  				      enable, enable == 0, 1, timeout))
> > > {
> > > -		dev_err(cmdq->mbox.dev, "Fail to wait GCE thread 0x%x
> > > done\n",
> > > +		dev_err(cmdq->mbox.dev,
> > > +			"Fail to wait GCE thread 0x%x done\n",
> > >  			(u32)(thread->base - cmdq->base));
> > >  
> > >  		return -EFAULT;
> > > @@ -626,6 +670,7 @@ static int cmdq_probe(struct platform_device
> > > *pdev)
> > >  
> > >  	WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
> > >  
> > > +	spin_lock_init(&cmdq->lock);
> > >  	cmdq_init(cmdq);
> > >  
> > >  	return 0;
> > 
> > 
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1, 1/1] mailbox: mtk-cmdq: fix gce timeout issue
  2022-08-15  6:23         ` CK Hu
@ 2022-08-15  9:51           ` yongqiang.niu
  -1 siblings, 0 replies; 20+ messages in thread
From: yongqiang.niu @ 2022-08-15  9:51 UTC (permalink / raw)
  To: CK Hu, Chun-Kuang Hu
  Cc: Jassi Brar, Matthias Brugger, linux-kernel, linux-arm-kernel,
	linux-mediatek, Project_Global_Chrome_Upstream_Group,
	Hsin-Yi Wang, Yongqiang Niu, Allen-kh Cheng

On Mon, 2022-08-15 at 14:23 +0800, CK Hu wrote:
> Hi, Yongqiang:
> 
> On Mon, 2022-08-15 at 13:51 +0800, yongqiang.niu wrote:
> > On Mon, 2022-08-15 at 13:24 +0800, CK Hu wrote:
> > > Hi, Yongqiang:
> > > 
> > > 
> > > On Mon, 2022-08-15 at 11:07 +0800, Yongqiang Niu wrote:
> > > > From: Yongqiang Niu <
> > > > yongqiang.niu@mediatek.corp-partner.google.com
> > > > > 
> > > > 
> > > > 1. enable gce ddr enable(gce reigster offset 0x48, bit 16 to
> > > > 18)
> > > > when
> > > > gce work,
> > > > and disable gce ddr enable when gce work job done
> > > 
> > > Why need gce ddr enable? I think gce works fine without this.
> > > Describe
> > > more about this.
> > > 
> > > Regards,
> > > CK
> > 
> > this is only for some SOC which has flag "control_by_sw".
> > for this kind of gce, there is a handshake flow between gce and ddr
> > hardware,
> > if not set ddr enable flag of gce, ddr will fall into idle mode, 
> > then gce instructions will not process done.
> > we need set this flag of gce to tell ddr when gce is idle or busy
> > controlled by software flow.
> 
> You [1] and Jason [2] has already enable control_by_sw and I believe
> you two have test your patch in general. Is the ddr problem a special
> case? How to operate to trigger this bug? Describe more in commit
> message to let us know why need this patch.
> 
> [1] 
> 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/mailbox/mtk-cmdq-mailbox.c?h=v6.0-rc1&id=84fd4201b78b96f8d31f6a2624be27ad6306a9bc
> [2] 
> 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/mailbox/mtk-cmdq-mailbox.c?h=v6.0-rc1&id=9388501fbb99a1b6a23f28634d125567a3b45a3d
> 

ddr problem is a special case.
when test suspend/resume case, gce sometimes will pull ddr, and ddr can
not go to suspend.
if we set gce register 0x48 to 0x7, will fix this gce pull ddr issue,
as you have referred [1] and [2] (8192 and 8195)

but for mt8186, the gce is more special, except setting of [1] and [2],
we need add more setting set gce register 0x48 to (0x7 << 16 | 0x7)
when gce working to make sure gce could process all instructions ok.
this case just need normal bootup, if we not set this, display cmdq
task will timeout, and chrome homescreen will always black screen.

and for this patch, we have done these test on mt8186:
1.suspend/resume
2.boot up to home screen
3.playback video with youtube.

mt8195 is under testing

> 
> > 
> > > 
> > > > 2. split cmdq clk enable/disable api, and control gce ddr
> > > > enable/disable
> > > > in clk enable/disable function to make sure it could protect
> > > > when
> > > > cmdq
> > > > is multiple used by display and mdp
> > > > 
> > > > Signed-off-by: Yongqiang Niu <
> > > > yongqiang.niu@mediatek.corp-partner.google.com>
> > > > Signed-off-by: Allen-kh Cheng <
> > > > allen-kh.cheng@mediatek.corp-partner.google.com>
> > > > ---
> > > >  drivers/mailbox/mtk-cmdq-mailbox.c | 57
> > > > ++++++++++++++++++++++++++
> > > > ----
> > > >  1 file changed, 51 insertions(+), 6 deletions(-)
> > > > 
> > > > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > index 2578e5aaa935..64a47470f062 100644
> > > > --- a/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > @@ -81,6 +81,8 @@ struct cmdq {
> > > >  	u8			shift_pa;
> > > >  	bool			control_by_sw;
> > > >  	u32			gce_num;
> > > > +	atomic_t		usage;
> > > > +	spinlock_t		lock;
> > > >  };
> > > >  
> > > >  struct gce_plat {
> > > > @@ -90,6 +92,46 @@ struct gce_plat {
> > > >  	u32 gce_num;
> > > >  };
> > > >  
> > > > +static s32 cmdq_clk_enable(struct cmdq *cmdq)
> > > > +{
> > > > +	s32 usage, ret;
> > > > +	unsigned long flags;
> > > > +
> > > > +	spin_lock_irqsave(&cmdq->lock, flags);
> > > > +
> > > > +	usage = atomic_inc_return(&cmdq->usage);
> > > > +
> > > > +	ret = clk_bulk_enable(cmdq->gce_num, cmdq->clocks);
> > > > +	if (usage <=0 || ret < 0) {
> > > > +		dev_err(cmdq->mbox.dev, "ref count %d ret %d
> > > > suspend
> > > > %d\n",
> > > > +			usage, ret, cmdq->suspended);
> > > > +	} else if (usage == 1) {
> > > > +		if (cmdq->control_by_sw)
> > > > +			writel((0x7 << 16) + 0x7, cmdq->base +
> > > > GCE_GCTL_VALUE);
> > > > +	}
> > > > +
> > > > +	spin_unlock_irqrestore(&cmdq->lock, flags);
> > > > +
> > > > +	return ret;
> > > > +}
> > > > +
> > > > +static void cmdq_clk_disable(struct cmdq *cmdq)
> > > > +{
> > > > +	s32 usage;
> > > > +
> > > > +	usage = atomic_dec_return(&cmdq->usage);
> > > > +
> > > > +	if (usage < 0) {
> > > > +		dev_err(cmdq->mbox.dev, "ref count %d suspend
> > > > %d\n",
> > > > +			usage, cmdq->suspended);
> > > > +	} else if (usage == 0) {
> > > > +		if (cmdq->control_by_sw)
> > > > +			writel(0x7, cmdq->base +
> > > > GCE_GCTL_VALUE);
> > > > +	}
> > > > +
> > > > +	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > +}
> > > > +
> > > >  u8 cmdq_get_shift_pa(struct mbox_chan *chan)
> > > >  {
> > > >  	struct cmdq *cmdq = container_of(chan->mbox, struct
> > > > cmdq,
> > > > mbox);
> > > > @@ -271,7 +313,8 @@ static void cmdq_thread_irq_handler(struct
> > > > cmdq
> > > > *cmdq,
> > > >  
> > > >  	if (list_empty(&thread->task_busy_list)) {
> > > >  		cmdq_thread_disable(cmdq, thread);
> > > > -		clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > +
> > > > +		cmdq_clk_disable(cmdq);
> > > >  	}
> > > >  }
> > > >  
> > > > @@ -360,8 +403,7 @@ static int cmdq_mbox_send_data(struct
> > > > mbox_chan
> > > > *chan, void *data)
> > > >  	task->pkt = pkt;
> > > >  
> > > >  	if (list_empty(&thread->task_busy_list)) {
> > > > -		WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq-
> > > > >clocks));
> > > > -
> > > > +		WARN_ON(cmdq_clk_enable(cmdq) < 0);
> > > >  		/*
> > > >  		 * The thread reset will clear thread related
> > > > register
> > > > to 0,
> > > >  		 * including pc, end, priority, irq, suspend
> > > > and
> > > > enable. Thus
> > > > @@ -433,7 +475,7 @@ static void cmdq_mbox_shutdown(struct
> > > > mbox_chan
> > > > *chan)
> > > >  	}
> > > >  
> > > >  	cmdq_thread_disable(cmdq, thread);
> > > > -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > +	cmdq_clk_disable(cmdq);
> > > >  
> > > >  done:
> > > >  	/*
> > > > @@ -479,7 +521,8 @@ static int cmdq_mbox_flush(struct mbox_chan
> > > > *chan, unsigned long timeout)
> > > >  
> > > >  	cmdq_thread_resume(thread);
> > > >  	cmdq_thread_disable(cmdq, thread);
> > > > -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > +
> > > > +	cmdq_clk_disable(cmdq);
> > > >  
> > > >  out:
> > > >  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> > > > @@ -490,7 +533,8 @@ static int cmdq_mbox_flush(struct mbox_chan
> > > > *chan, unsigned long timeout)
> > > >  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> > > >  	if (readl_poll_timeout_atomic(thread->base +
> > > > CMDQ_THR_ENABLE_TASK,
> > > >  				      enable, enable == 0, 1,
> > > > timeout))
> > > > {
> > > > -		dev_err(cmdq->mbox.dev, "Fail to wait GCE
> > > > thread 0x%x
> > > > done\n",
> > > > +		dev_err(cmdq->mbox.dev,
> > > > +			"Fail to wait GCE thread 0x%x done\n",
> > > >  			(u32)(thread->base - cmdq->base));
> > > >  
> > > >  		return -EFAULT;
> > > > @@ -626,6 +670,7 @@ static int cmdq_probe(struct
> > > > platform_device
> > > > *pdev)
> > > >  
> > > >  	WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
> > > >  
> > > > +	spin_lock_init(&cmdq->lock);
> > > >  	cmdq_init(cmdq);
> > > >  
> > > >  	return 0;
> > > 
> > > 
> > 
> > 
> 
> 



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1, 1/1] mailbox: mtk-cmdq: fix gce timeout issue
@ 2022-08-15  9:51           ` yongqiang.niu
  0 siblings, 0 replies; 20+ messages in thread
From: yongqiang.niu @ 2022-08-15  9:51 UTC (permalink / raw)
  To: CK Hu, Chun-Kuang Hu
  Cc: Jassi Brar, Matthias Brugger, linux-kernel, linux-arm-kernel,
	linux-mediatek, Project_Global_Chrome_Upstream_Group,
	Hsin-Yi Wang, Yongqiang Niu, Allen-kh Cheng

On Mon, 2022-08-15 at 14:23 +0800, CK Hu wrote:
> Hi, Yongqiang:
> 
> On Mon, 2022-08-15 at 13:51 +0800, yongqiang.niu wrote:
> > On Mon, 2022-08-15 at 13:24 +0800, CK Hu wrote:
> > > Hi, Yongqiang:
> > > 
> > > 
> > > On Mon, 2022-08-15 at 11:07 +0800, Yongqiang Niu wrote:
> > > > From: Yongqiang Niu <
> > > > yongqiang.niu@mediatek.corp-partner.google.com
> > > > > 
> > > > 
> > > > 1. enable gce ddr enable(gce reigster offset 0x48, bit 16 to
> > > > 18)
> > > > when
> > > > gce work,
> > > > and disable gce ddr enable when gce work job done
> > > 
> > > Why need gce ddr enable? I think gce works fine without this.
> > > Describe
> > > more about this.
> > > 
> > > Regards,
> > > CK
> > 
> > this is only for some SOC which has flag "control_by_sw".
> > for this kind of gce, there is a handshake flow between gce and ddr
> > hardware,
> > if not set ddr enable flag of gce, ddr will fall into idle mode, 
> > then gce instructions will not process done.
> > we need set this flag of gce to tell ddr when gce is idle or busy
> > controlled by software flow.
> 
> You [1] and Jason [2] has already enable control_by_sw and I believe
> you two have test your patch in general. Is the ddr problem a special
> case? How to operate to trigger this bug? Describe more in commit
> message to let us know why need this patch.
> 
> [1] 
> 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/mailbox/mtk-cmdq-mailbox.c?h=v6.0-rc1&id=84fd4201b78b96f8d31f6a2624be27ad6306a9bc
> [2] 
> 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/mailbox/mtk-cmdq-mailbox.c?h=v6.0-rc1&id=9388501fbb99a1b6a23f28634d125567a3b45a3d
> 

ddr problem is a special case.
when test suspend/resume case, gce sometimes will pull ddr, and ddr can
not go to suspend.
if we set gce register 0x48 to 0x7, will fix this gce pull ddr issue,
as you have referred [1] and [2] (8192 and 8195)

but for mt8186, the gce is more special, except setting of [1] and [2],
we need add more setting set gce register 0x48 to (0x7 << 16 | 0x7)
when gce working to make sure gce could process all instructions ok.
this case just need normal bootup, if we not set this, display cmdq
task will timeout, and chrome homescreen will always black screen.

and for this patch, we have done these test on mt8186:
1.suspend/resume
2.boot up to home screen
3.playback video with youtube.

mt8195 is under testing

> 
> > 
> > > 
> > > > 2. split cmdq clk enable/disable api, and control gce ddr
> > > > enable/disable
> > > > in clk enable/disable function to make sure it could protect
> > > > when
> > > > cmdq
> > > > is multiple used by display and mdp
> > > > 
> > > > Signed-off-by: Yongqiang Niu <
> > > > yongqiang.niu@mediatek.corp-partner.google.com>
> > > > Signed-off-by: Allen-kh Cheng <
> > > > allen-kh.cheng@mediatek.corp-partner.google.com>
> > > > ---
> > > >  drivers/mailbox/mtk-cmdq-mailbox.c | 57
> > > > ++++++++++++++++++++++++++
> > > > ----
> > > >  1 file changed, 51 insertions(+), 6 deletions(-)
> > > > 
> > > > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > index 2578e5aaa935..64a47470f062 100644
> > > > --- a/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > @@ -81,6 +81,8 @@ struct cmdq {
> > > >  	u8			shift_pa;
> > > >  	bool			control_by_sw;
> > > >  	u32			gce_num;
> > > > +	atomic_t		usage;
> > > > +	spinlock_t		lock;
> > > >  };
> > > >  
> > > >  struct gce_plat {
> > > > @@ -90,6 +92,46 @@ struct gce_plat {
> > > >  	u32 gce_num;
> > > >  };
> > > >  
> > > > +static s32 cmdq_clk_enable(struct cmdq *cmdq)
> > > > +{
> > > > +	s32 usage, ret;
> > > > +	unsigned long flags;
> > > > +
> > > > +	spin_lock_irqsave(&cmdq->lock, flags);
> > > > +
> > > > +	usage = atomic_inc_return(&cmdq->usage);
> > > > +
> > > > +	ret = clk_bulk_enable(cmdq->gce_num, cmdq->clocks);
> > > > +	if (usage <=0 || ret < 0) {
> > > > +		dev_err(cmdq->mbox.dev, "ref count %d ret %d
> > > > suspend
> > > > %d\n",
> > > > +			usage, ret, cmdq->suspended);
> > > > +	} else if (usage == 1) {
> > > > +		if (cmdq->control_by_sw)
> > > > +			writel((0x7 << 16) + 0x7, cmdq->base +
> > > > GCE_GCTL_VALUE);
> > > > +	}
> > > > +
> > > > +	spin_unlock_irqrestore(&cmdq->lock, flags);
> > > > +
> > > > +	return ret;
> > > > +}
> > > > +
> > > > +static void cmdq_clk_disable(struct cmdq *cmdq)
> > > > +{
> > > > +	s32 usage;
> > > > +
> > > > +	usage = atomic_dec_return(&cmdq->usage);
> > > > +
> > > > +	if (usage < 0) {
> > > > +		dev_err(cmdq->mbox.dev, "ref count %d suspend
> > > > %d\n",
> > > > +			usage, cmdq->suspended);
> > > > +	} else if (usage == 0) {
> > > > +		if (cmdq->control_by_sw)
> > > > +			writel(0x7, cmdq->base +
> > > > GCE_GCTL_VALUE);
> > > > +	}
> > > > +
> > > > +	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > +}
> > > > +
> > > >  u8 cmdq_get_shift_pa(struct mbox_chan *chan)
> > > >  {
> > > >  	struct cmdq *cmdq = container_of(chan->mbox, struct
> > > > cmdq,
> > > > mbox);
> > > > @@ -271,7 +313,8 @@ static void cmdq_thread_irq_handler(struct
> > > > cmdq
> > > > *cmdq,
> > > >  
> > > >  	if (list_empty(&thread->task_busy_list)) {
> > > >  		cmdq_thread_disable(cmdq, thread);
> > > > -		clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > +
> > > > +		cmdq_clk_disable(cmdq);
> > > >  	}
> > > >  }
> > > >  
> > > > @@ -360,8 +403,7 @@ static int cmdq_mbox_send_data(struct
> > > > mbox_chan
> > > > *chan, void *data)
> > > >  	task->pkt = pkt;
> > > >  
> > > >  	if (list_empty(&thread->task_busy_list)) {
> > > > -		WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq-
> > > > >clocks));
> > > > -
> > > > +		WARN_ON(cmdq_clk_enable(cmdq) < 0);
> > > >  		/*
> > > >  		 * The thread reset will clear thread related
> > > > register
> > > > to 0,
> > > >  		 * including pc, end, priority, irq, suspend
> > > > and
> > > > enable. Thus
> > > > @@ -433,7 +475,7 @@ static void cmdq_mbox_shutdown(struct
> > > > mbox_chan
> > > > *chan)
> > > >  	}
> > > >  
> > > >  	cmdq_thread_disable(cmdq, thread);
> > > > -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > +	cmdq_clk_disable(cmdq);
> > > >  
> > > >  done:
> > > >  	/*
> > > > @@ -479,7 +521,8 @@ static int cmdq_mbox_flush(struct mbox_chan
> > > > *chan, unsigned long timeout)
> > > >  
> > > >  	cmdq_thread_resume(thread);
> > > >  	cmdq_thread_disable(cmdq, thread);
> > > > -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > +
> > > > +	cmdq_clk_disable(cmdq);
> > > >  
> > > >  out:
> > > >  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> > > > @@ -490,7 +533,8 @@ static int cmdq_mbox_flush(struct mbox_chan
> > > > *chan, unsigned long timeout)
> > > >  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> > > >  	if (readl_poll_timeout_atomic(thread->base +
> > > > CMDQ_THR_ENABLE_TASK,
> > > >  				      enable, enable == 0, 1,
> > > > timeout))
> > > > {
> > > > -		dev_err(cmdq->mbox.dev, "Fail to wait GCE
> > > > thread 0x%x
> > > > done\n",
> > > > +		dev_err(cmdq->mbox.dev,
> > > > +			"Fail to wait GCE thread 0x%x done\n",
> > > >  			(u32)(thread->base - cmdq->base));
> > > >  
> > > >  		return -EFAULT;
> > > > @@ -626,6 +670,7 @@ static int cmdq_probe(struct
> > > > platform_device
> > > > *pdev)
> > > >  
> > > >  	WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
> > > >  
> > > > +	spin_lock_init(&cmdq->lock);
> > > >  	cmdq_init(cmdq);
> > > >  
> > > >  	return 0;
> > > 
> > > 
> > 
> > 
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1, 1/1] mailbox: mtk-cmdq: fix gce timeout issue
  2022-08-15  9:51           ` yongqiang.niu
@ 2022-08-16  1:49             ` CK Hu
  -1 siblings, 0 replies; 20+ messages in thread
From: CK Hu @ 2022-08-16  1:49 UTC (permalink / raw)
  To: yongqiang.niu, Chun-Kuang Hu
  Cc: Jassi Brar, Matthias Brugger, linux-kernel, linux-arm-kernel,
	linux-mediatek, Project_Global_Chrome_Upstream_Group,
	Hsin-Yi Wang, Yongqiang Niu, Allen-kh Cheng

Hi, Yongqiang:

On Mon, 2022-08-15 at 17:51 +0800, yongqiang.niu wrote:
> On Mon, 2022-08-15 at 14:23 +0800, CK Hu wrote:
> > Hi, Yongqiang:
> > 
> > On Mon, 2022-08-15 at 13:51 +0800, yongqiang.niu wrote:
> > > On Mon, 2022-08-15 at 13:24 +0800, CK Hu wrote:
> > > > Hi, Yongqiang:
> > > > 
> > > > 
> > > > On Mon, 2022-08-15 at 11:07 +0800, Yongqiang Niu wrote:
> > > > > From: Yongqiang Niu <
> > > > > yongqiang.niu@mediatek.corp-partner.google.com
> > > > > > 
> > > > > 
> > > > > 1. enable gce ddr enable(gce reigster offset 0x48, bit 16 to
> > > > > 18)
> > > > > when
> > > > > gce work,
> > > > > and disable gce ddr enable when gce work job done
> > > > 
> > > > Why need gce ddr enable? I think gce works fine without this.
> > > > Describe
> > > > more about this.
> > > > 
> > > > Regards,
> > > > CK
> > > 
> > > this is only for some SOC which has flag "control_by_sw".
> > > for this kind of gce, there is a handshake flow between gce and
> > > ddr
> > > hardware,
> > > if not set ddr enable flag of gce, ddr will fall into idle mode, 
> > > then gce instructions will not process done.
> > > we need set this flag of gce to tell ddr when gce is idle or busy
> > > controlled by software flow.
> > 
> > You [1] and Jason [2] has already enable control_by_sw and I
> > believe
> > you two have test your patch in general. Is the ddr problem a
> > special
> > case? How to operate to trigger this bug? Describe more in commit
> > message to let us know why need this patch.
> > 
> > [1] 
> > 
> 
> 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/mailbox/mtk-cmdq-mailbox.c?h=v6.0-rc1&id=84fd4201b78b96f8d31f6a2624be27ad6306a9bc
> > [2] 
> > 
> 
> 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/mailbox/mtk-cmdq-mailbox.c?h=v6.0-rc1&id=9388501fbb99a1b6a23f28634d125567a3b45a3d
> > 
> 
> ddr problem is a special case.
> when test suspend/resume case, gce sometimes will pull ddr, and ddr
> can
> not go to suspend.
> if we set gce register 0x48 to 0x7, will fix this gce pull ddr issue,
> as you have referred [1] and [2] (8192 and 8195)
> 
> but for mt8186, the gce is more special, except setting of [1] and
> [2],
> we need add more setting set gce register 0x48 to (0x7 << 16 | 0x7)
> when gce working to make sure gce could process all instructions ok.
> this case just need normal bootup, if we not set this, display cmdq
> task will timeout, and chrome homescreen will always black screen.
> 
> and for this patch, we have done these test on mt8186:
> 1.suspend/resume
> 2.boot up to home screen
> 3.playback video with youtube.
> 
> mt8195 is under testing

I seems there are two problem. The first is suspend problem which is
fixed by [1] and [2]. The second is boot problem which only happen in
MT8186. So add a new driver private data for the boot problem.

For the suspend problem, I think the correct suspend flow is:

1. Client driver suspend: flush all command in mailbox channel.
2. gce driver suspend: Do nothing to gce hardware because all gce
thread is empty.
3. System suspend: suspend the ddr.

If you find that gce pull the ddr when ddr suspend, that means client
driver does not flush all command when suspend, so fix the client
driver and gce would not pull ddr when ddr suspend. 

Regards,
CK

> 
> > 
> > > 
> > > > 
> > > > > 2. split cmdq clk enable/disable api, and control gce ddr
> > > > > enable/disable
> > > > > in clk enable/disable function to make sure it could protect
> > > > > when
> > > > > cmdq
> > > > > is multiple used by display and mdp
> > > > > 
> > > > > Signed-off-by: Yongqiang Niu <
> > > > > yongqiang.niu@mediatek.corp-partner.google.com>
> > > > > Signed-off-by: Allen-kh Cheng <
> > > > > allen-kh.cheng@mediatek.corp-partner.google.com>
> > > > > ---
> > > > >  drivers/mailbox/mtk-cmdq-mailbox.c | 57
> > > > > ++++++++++++++++++++++++++
> > > > > ----
> > > > >  1 file changed, 51 insertions(+), 6 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > > index 2578e5aaa935..64a47470f062 100644
> > > > > --- a/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > > @@ -81,6 +81,8 @@ struct cmdq {
> > > > >  	u8			shift_pa;
> > > > >  	bool			control_by_sw;
> > > > >  	u32			gce_num;
> > > > > +	atomic_t		usage;
> > > > > +	spinlock_t		lock;
> > > > >  };
> > > > >  
> > > > >  struct gce_plat {
> > > > > @@ -90,6 +92,46 @@ struct gce_plat {
> > > > >  	u32 gce_num;
> > > > >  };
> > > > >  
> > > > > +static s32 cmdq_clk_enable(struct cmdq *cmdq)
> > > > > +{
> > > > > +	s32 usage, ret;
> > > > > +	unsigned long flags;
> > > > > +
> > > > > +	spin_lock_irqsave(&cmdq->lock, flags);
> > > > > +
> > > > > +	usage = atomic_inc_return(&cmdq->usage);
> > > > > +
> > > > > +	ret = clk_bulk_enable(cmdq->gce_num, cmdq->clocks);
> > > > > +	if (usage <=0 || ret < 0) {
> > > > > +		dev_err(cmdq->mbox.dev, "ref count %d ret %d
> > > > > suspend
> > > > > %d\n",
> > > > > +			usage, ret, cmdq->suspended);
> > > > > +	} else if (usage == 1) {
> > > > > +		if (cmdq->control_by_sw)
> > > > > +			writel((0x7 << 16) + 0x7, cmdq->base +
> > > > > GCE_GCTL_VALUE);
> > > > > +	}
> > > > > +
> > > > > +	spin_unlock_irqrestore(&cmdq->lock, flags);
> > > > > +
> > > > > +	return ret;
> > > > > +}
> > > > > +
> > > > > +static void cmdq_clk_disable(struct cmdq *cmdq)
> > > > > +{
> > > > > +	s32 usage;
> > > > > +
> > > > > +	usage = atomic_dec_return(&cmdq->usage);
> > > > > +
> > > > > +	if (usage < 0) {
> > > > > +		dev_err(cmdq->mbox.dev, "ref count %d suspend
> > > > > %d\n",
> > > > > +			usage, cmdq->suspended);
> > > > > +	} else if (usage == 0) {
> > > > > +		if (cmdq->control_by_sw)
> > > > > +			writel(0x7, cmdq->base +
> > > > > GCE_GCTL_VALUE);
> > > > > +	}
> > > > > +
> > > > > +	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > > +}
> > > > > +
> > > > >  u8 cmdq_get_shift_pa(struct mbox_chan *chan)
> > > > >  {
> > > > >  	struct cmdq *cmdq = container_of(chan->mbox, struct
> > > > > cmdq,
> > > > > mbox);
> > > > > @@ -271,7 +313,8 @@ static void
> > > > > cmdq_thread_irq_handler(struct
> > > > > cmdq
> > > > > *cmdq,
> > > > >  
> > > > >  	if (list_empty(&thread->task_busy_list)) {
> > > > >  		cmdq_thread_disable(cmdq, thread);
> > > > > -		clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > > +
> > > > > +		cmdq_clk_disable(cmdq);
> > > > >  	}
> > > > >  }
> > > > >  
> > > > > @@ -360,8 +403,7 @@ static int cmdq_mbox_send_data(struct
> > > > > mbox_chan
> > > > > *chan, void *data)
> > > > >  	task->pkt = pkt;
> > > > >  
> > > > >  	if (list_empty(&thread->task_busy_list)) {
> > > > > -		WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq-
> > > > > > clocks));
> > > > > 
> > > > > -
> > > > > +		WARN_ON(cmdq_clk_enable(cmdq) < 0);
> > > > >  		/*
> > > > >  		 * The thread reset will clear thread related
> > > > > register
> > > > > to 0,
> > > > >  		 * including pc, end, priority, irq, suspend
> > > > > and
> > > > > enable. Thus
> > > > > @@ -433,7 +475,7 @@ static void cmdq_mbox_shutdown(struct
> > > > > mbox_chan
> > > > > *chan)
> > > > >  	}
> > > > >  
> > > > >  	cmdq_thread_disable(cmdq, thread);
> > > > > -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > > +	cmdq_clk_disable(cmdq);
> > > > >  
> > > > >  done:
> > > > >  	/*
> > > > > @@ -479,7 +521,8 @@ static int cmdq_mbox_flush(struct
> > > > > mbox_chan
> > > > > *chan, unsigned long timeout)
> > > > >  
> > > > >  	cmdq_thread_resume(thread);
> > > > >  	cmdq_thread_disable(cmdq, thread);
> > > > > -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > > +
> > > > > +	cmdq_clk_disable(cmdq);
> > > > >  
> > > > >  out:
> > > > >  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> > > > > @@ -490,7 +533,8 @@ static int cmdq_mbox_flush(struct
> > > > > mbox_chan
> > > > > *chan, unsigned long timeout)
> > > > >  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> > > > >  	if (readl_poll_timeout_atomic(thread->base +
> > > > > CMDQ_THR_ENABLE_TASK,
> > > > >  				      enable, enable == 0, 1,
> > > > > timeout))
> > > > > {
> > > > > -		dev_err(cmdq->mbox.dev, "Fail to wait GCE
> > > > > thread 0x%x
> > > > > done\n",
> > > > > +		dev_err(cmdq->mbox.dev,
> > > > > +			"Fail to wait GCE thread 0x%x done\n",
> > > > >  			(u32)(thread->base - cmdq->base));
> > > > >  
> > > > >  		return -EFAULT;
> > > > > @@ -626,6 +670,7 @@ static int cmdq_probe(struct
> > > > > platform_device
> > > > > *pdev)
> > > > >  
> > > > >  	WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
> > > > >  
> > > > > +	spin_lock_init(&cmdq->lock);
> > > > >  	cmdq_init(cmdq);
> > > > >  
> > > > >  	return 0;
> > > > 
> > > > 
> > > 
> > > 
> > 
> > 
> 
> 



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1, 1/1] mailbox: mtk-cmdq: fix gce timeout issue
@ 2022-08-16  1:49             ` CK Hu
  0 siblings, 0 replies; 20+ messages in thread
From: CK Hu @ 2022-08-16  1:49 UTC (permalink / raw)
  To: yongqiang.niu, Chun-Kuang Hu
  Cc: Jassi Brar, Matthias Brugger, linux-kernel, linux-arm-kernel,
	linux-mediatek, Project_Global_Chrome_Upstream_Group,
	Hsin-Yi Wang, Yongqiang Niu, Allen-kh Cheng

Hi, Yongqiang:

On Mon, 2022-08-15 at 17:51 +0800, yongqiang.niu wrote:
> On Mon, 2022-08-15 at 14:23 +0800, CK Hu wrote:
> > Hi, Yongqiang:
> > 
> > On Mon, 2022-08-15 at 13:51 +0800, yongqiang.niu wrote:
> > > On Mon, 2022-08-15 at 13:24 +0800, CK Hu wrote:
> > > > Hi, Yongqiang:
> > > > 
> > > > 
> > > > On Mon, 2022-08-15 at 11:07 +0800, Yongqiang Niu wrote:
> > > > > From: Yongqiang Niu <
> > > > > yongqiang.niu@mediatek.corp-partner.google.com
> > > > > > 
> > > > > 
> > > > > 1. enable gce ddr enable(gce reigster offset 0x48, bit 16 to
> > > > > 18)
> > > > > when
> > > > > gce work,
> > > > > and disable gce ddr enable when gce work job done
> > > > 
> > > > Why need gce ddr enable? I think gce works fine without this.
> > > > Describe
> > > > more about this.
> > > > 
> > > > Regards,
> > > > CK
> > > 
> > > this is only for some SOC which has flag "control_by_sw".
> > > for this kind of gce, there is a handshake flow between gce and
> > > ddr
> > > hardware,
> > > if not set ddr enable flag of gce, ddr will fall into idle mode, 
> > > then gce instructions will not process done.
> > > we need set this flag of gce to tell ddr when gce is idle or busy
> > > controlled by software flow.
> > 
> > You [1] and Jason [2] has already enable control_by_sw and I
> > believe
> > you two have test your patch in general. Is the ddr problem a
> > special
> > case? How to operate to trigger this bug? Describe more in commit
> > message to let us know why need this patch.
> > 
> > [1] 
> > 
> 
> 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/mailbox/mtk-cmdq-mailbox.c?h=v6.0-rc1&id=84fd4201b78b96f8d31f6a2624be27ad6306a9bc
> > [2] 
> > 
> 
> 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/mailbox/mtk-cmdq-mailbox.c?h=v6.0-rc1&id=9388501fbb99a1b6a23f28634d125567a3b45a3d
> > 
> 
> ddr problem is a special case.
> when test suspend/resume case, gce sometimes will pull ddr, and ddr
> can
> not go to suspend.
> if we set gce register 0x48 to 0x7, will fix this gce pull ddr issue,
> as you have referred [1] and [2] (8192 and 8195)
> 
> but for mt8186, the gce is more special, except setting of [1] and
> [2],
> we need add more setting set gce register 0x48 to (0x7 << 16 | 0x7)
> when gce working to make sure gce could process all instructions ok.
> this case just need normal bootup, if we not set this, display cmdq
> task will timeout, and chrome homescreen will always black screen.
> 
> and for this patch, we have done these test on mt8186:
> 1.suspend/resume
> 2.boot up to home screen
> 3.playback video with youtube.
> 
> mt8195 is under testing

I seems there are two problem. The first is suspend problem which is
fixed by [1] and [2]. The second is boot problem which only happen in
MT8186. So add a new driver private data for the boot problem.

For the suspend problem, I think the correct suspend flow is:

1. Client driver suspend: flush all command in mailbox channel.
2. gce driver suspend: Do nothing to gce hardware because all gce
thread is empty.
3. System suspend: suspend the ddr.

If you find that gce pull the ddr when ddr suspend, that means client
driver does not flush all command when suspend, so fix the client
driver and gce would not pull ddr when ddr suspend. 

Regards,
CK

> 
> > 
> > > 
> > > > 
> > > > > 2. split cmdq clk enable/disable api, and control gce ddr
> > > > > enable/disable
> > > > > in clk enable/disable function to make sure it could protect
> > > > > when
> > > > > cmdq
> > > > > is multiple used by display and mdp
> > > > > 
> > > > > Signed-off-by: Yongqiang Niu <
> > > > > yongqiang.niu@mediatek.corp-partner.google.com>
> > > > > Signed-off-by: Allen-kh Cheng <
> > > > > allen-kh.cheng@mediatek.corp-partner.google.com>
> > > > > ---
> > > > >  drivers/mailbox/mtk-cmdq-mailbox.c | 57
> > > > > ++++++++++++++++++++++++++
> > > > > ----
> > > > >  1 file changed, 51 insertions(+), 6 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > > index 2578e5aaa935..64a47470f062 100644
> > > > > --- a/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > > @@ -81,6 +81,8 @@ struct cmdq {
> > > > >  	u8			shift_pa;
> > > > >  	bool			control_by_sw;
> > > > >  	u32			gce_num;
> > > > > +	atomic_t		usage;
> > > > > +	spinlock_t		lock;
> > > > >  };
> > > > >  
> > > > >  struct gce_plat {
> > > > > @@ -90,6 +92,46 @@ struct gce_plat {
> > > > >  	u32 gce_num;
> > > > >  };
> > > > >  
> > > > > +static s32 cmdq_clk_enable(struct cmdq *cmdq)
> > > > > +{
> > > > > +	s32 usage, ret;
> > > > > +	unsigned long flags;
> > > > > +
> > > > > +	spin_lock_irqsave(&cmdq->lock, flags);
> > > > > +
> > > > > +	usage = atomic_inc_return(&cmdq->usage);
> > > > > +
> > > > > +	ret = clk_bulk_enable(cmdq->gce_num, cmdq->clocks);
> > > > > +	if (usage <=0 || ret < 0) {
> > > > > +		dev_err(cmdq->mbox.dev, "ref count %d ret %d
> > > > > suspend
> > > > > %d\n",
> > > > > +			usage, ret, cmdq->suspended);
> > > > > +	} else if (usage == 1) {
> > > > > +		if (cmdq->control_by_sw)
> > > > > +			writel((0x7 << 16) + 0x7, cmdq->base +
> > > > > GCE_GCTL_VALUE);
> > > > > +	}
> > > > > +
> > > > > +	spin_unlock_irqrestore(&cmdq->lock, flags);
> > > > > +
> > > > > +	return ret;
> > > > > +}
> > > > > +
> > > > > +static void cmdq_clk_disable(struct cmdq *cmdq)
> > > > > +{
> > > > > +	s32 usage;
> > > > > +
> > > > > +	usage = atomic_dec_return(&cmdq->usage);
> > > > > +
> > > > > +	if (usage < 0) {
> > > > > +		dev_err(cmdq->mbox.dev, "ref count %d suspend
> > > > > %d\n",
> > > > > +			usage, cmdq->suspended);
> > > > > +	} else if (usage == 0) {
> > > > > +		if (cmdq->control_by_sw)
> > > > > +			writel(0x7, cmdq->base +
> > > > > GCE_GCTL_VALUE);
> > > > > +	}
> > > > > +
> > > > > +	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > > +}
> > > > > +
> > > > >  u8 cmdq_get_shift_pa(struct mbox_chan *chan)
> > > > >  {
> > > > >  	struct cmdq *cmdq = container_of(chan->mbox, struct
> > > > > cmdq,
> > > > > mbox);
> > > > > @@ -271,7 +313,8 @@ static void
> > > > > cmdq_thread_irq_handler(struct
> > > > > cmdq
> > > > > *cmdq,
> > > > >  
> > > > >  	if (list_empty(&thread->task_busy_list)) {
> > > > >  		cmdq_thread_disable(cmdq, thread);
> > > > > -		clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > > +
> > > > > +		cmdq_clk_disable(cmdq);
> > > > >  	}
> > > > >  }
> > > > >  
> > > > > @@ -360,8 +403,7 @@ static int cmdq_mbox_send_data(struct
> > > > > mbox_chan
> > > > > *chan, void *data)
> > > > >  	task->pkt = pkt;
> > > > >  
> > > > >  	if (list_empty(&thread->task_busy_list)) {
> > > > > -		WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq-
> > > > > > clocks));
> > > > > 
> > > > > -
> > > > > +		WARN_ON(cmdq_clk_enable(cmdq) < 0);
> > > > >  		/*
> > > > >  		 * The thread reset will clear thread related
> > > > > register
> > > > > to 0,
> > > > >  		 * including pc, end, priority, irq, suspend
> > > > > and
> > > > > enable. Thus
> > > > > @@ -433,7 +475,7 @@ static void cmdq_mbox_shutdown(struct
> > > > > mbox_chan
> > > > > *chan)
> > > > >  	}
> > > > >  
> > > > >  	cmdq_thread_disable(cmdq, thread);
> > > > > -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > > +	cmdq_clk_disable(cmdq);
> > > > >  
> > > > >  done:
> > > > >  	/*
> > > > > @@ -479,7 +521,8 @@ static int cmdq_mbox_flush(struct
> > > > > mbox_chan
> > > > > *chan, unsigned long timeout)
> > > > >  
> > > > >  	cmdq_thread_resume(thread);
> > > > >  	cmdq_thread_disable(cmdq, thread);
> > > > > -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > > +
> > > > > +	cmdq_clk_disable(cmdq);
> > > > >  
> > > > >  out:
> > > > >  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> > > > > @@ -490,7 +533,8 @@ static int cmdq_mbox_flush(struct
> > > > > mbox_chan
> > > > > *chan, unsigned long timeout)
> > > > >  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> > > > >  	if (readl_poll_timeout_atomic(thread->base +
> > > > > CMDQ_THR_ENABLE_TASK,
> > > > >  				      enable, enable == 0, 1,
> > > > > timeout))
> > > > > {
> > > > > -		dev_err(cmdq->mbox.dev, "Fail to wait GCE
> > > > > thread 0x%x
> > > > > done\n",
> > > > > +		dev_err(cmdq->mbox.dev,
> > > > > +			"Fail to wait GCE thread 0x%x done\n",
> > > > >  			(u32)(thread->base - cmdq->base));
> > > > >  
> > > > >  		return -EFAULT;
> > > > > @@ -626,6 +670,7 @@ static int cmdq_probe(struct
> > > > > platform_device
> > > > > *pdev)
> > > > >  
> > > > >  	WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
> > > > >  
> > > > > +	spin_lock_init(&cmdq->lock);
> > > > >  	cmdq_init(cmdq);
> > > > >  
> > > > >  	return 0;
> > > > 
> > > > 
> > > 
> > > 
> > 
> > 
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1, 1/1] mailbox: mtk-cmdq: fix gce timeout issue
  2022-08-16  1:49             ` CK Hu
@ 2022-08-16  2:14               ` yongqiang.niu
  -1 siblings, 0 replies; 20+ messages in thread
From: yongqiang.niu @ 2022-08-16  2:14 UTC (permalink / raw)
  To: CK Hu, Chun-Kuang Hu
  Cc: Jassi Brar, Matthias Brugger, linux-kernel, linux-arm-kernel,
	linux-mediatek, Project_Global_Chrome_Upstream_Group,
	Hsin-Yi Wang, Yongqiang Niu, Allen-kh Cheng

On Tue, 2022-08-16 at 09:49 +0800, CK Hu wrote:
> Hi, Yongqiang:
> 
> On Mon, 2022-08-15 at 17:51 +0800, yongqiang.niu wrote:
> > On Mon, 2022-08-15 at 14:23 +0800, CK Hu wrote:
> > > Hi, Yongqiang:
> > > 
> > > On Mon, 2022-08-15 at 13:51 +0800, yongqiang.niu wrote:
> > > > On Mon, 2022-08-15 at 13:24 +0800, CK Hu wrote:
> > > > > Hi, Yongqiang:
> > > > > 
> > > > > 
> > > > > On Mon, 2022-08-15 at 11:07 +0800, Yongqiang Niu wrote:
> > > > > > From: Yongqiang Niu <
> > > > > > yongqiang.niu@mediatek.corp-partner.google.com
> > > > > > > 
> > > > > > 
> > > > > > 1. enable gce ddr enable(gce reigster offset 0x48, bit 16
> > > > > > to
> > > > > > 18)
> > > > > > when
> > > > > > gce work,
> > > > > > and disable gce ddr enable when gce work job done
> > > > > 
> > > > > Why need gce ddr enable? I think gce works fine without this.
> > > > > Describe
> > > > > more about this.
> > > > > 
> > > > > Regards,
> > > > > CK
> > > > 
> > > > this is only for some SOC which has flag "control_by_sw".
> > > > for this kind of gce, there is a handshake flow between gce and
> > > > ddr
> > > > hardware,
> > > > if not set ddr enable flag of gce, ddr will fall into idle
> > > > mode, 
> > > > then gce instructions will not process done.
> > > > we need set this flag of gce to tell ddr when gce is idle or
> > > > busy
> > > > controlled by software flow.
> > > 
> > > You [1] and Jason [2] has already enable control_by_sw and I
> > > believe
> > > you two have test your patch in general. Is the ddr problem a
> > > special
> > > case? How to operate to trigger this bug? Describe more in commit
> > > message to let us know why need this patch.
> > > 
> > > [1] 
> > > 
> > 
> > 
> 
> 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/mailbox/mtk-cmdq-mailbox.c?h=v6.0-rc1&id=84fd4201b78b96f8d31f6a2624be27ad6306a9bc
> > > [2] 
> > > 
> > 
> > 
> 
> 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/mailbox/mtk-cmdq-mailbox.c?h=v6.0-rc1&id=9388501fbb99a1b6a23f28634d125567a3b45a3d
> > > 
> > 
> > ddr problem is a special case.
> > when test suspend/resume case, gce sometimes will pull ddr, and ddr
> > can
> > not go to suspend.
> > if we set gce register 0x48 to 0x7, will fix this gce pull ddr
> > issue,
> > as you have referred [1] and [2] (8192 and 8195)
> > 
> > but for mt8186, the gce is more special, except setting of [1] and
> > [2],
> > we need add more setting set gce register 0x48 to (0x7 << 16 | 0x7)
> > when gce working to make sure gce could process all instructions
> > ok.
> > this case just need normal bootup, if we not set this, display cmdq
> > task will timeout, and chrome homescreen will always black screen.
> > 
> > and for this patch, we have done these test on mt8186:
> > 1.suspend/resume
> > 2.boot up to home screen
> > 3.playback video with youtube.
> > 
> > mt8195 is under testing
> 
> I seems there are two problem. The first is suspend problem which is
> fixed by [1] and [2]. The second is boot problem which only happen in
> MT8186. So add a new driver private data for the boot problem.
> 
> For the suspend problem, I think the correct suspend flow is:
> 
> 1. Client driver suspend: flush all command in mailbox channel.
> 2. gce driver suspend: Do nothing to gce hardware because all gce
> thread is empty.
> 3. System suspend: suspend the ddr.
> 
> If you find that gce pull the ddr when ddr suspend, that means client
> driver does not flush all command when suspend, so fix the client
> driver and gce would not pull ddr when ddr suspend. 
> 
> Regards,
> CK
> 

1.suspend issue is special gce hardware issue, gce client  driver
command already process done, but gce still pull ddr.

2. I will add new private data for MT8186 boot up issue in next version


> > 
> > > 
> > > > 
> > > > > 
> > > > > > 2. split cmdq clk enable/disable api, and control gce ddr
> > > > > > enable/disable
> > > > > > in clk enable/disable function to make sure it could
> > > > > > protect
> > > > > > when
> > > > > > cmdq
> > > > > > is multiple used by display and mdp
> > > > > > 
> > > > > > Signed-off-by: Yongqiang Niu <
> > > > > > yongqiang.niu@mediatek.corp-partner.google.com>
> > > > > > Signed-off-by: Allen-kh Cheng <
> > > > > > allen-kh.cheng@mediatek.corp-partner.google.com>
> > > > > > ---
> > > > > >  drivers/mailbox/mtk-cmdq-mailbox.c | 57
> > > > > > ++++++++++++++++++++++++++
> > > > > > ----
> > > > > >  1 file changed, 51 insertions(+), 6 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > > > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > > > index 2578e5aaa935..64a47470f062 100644
> > > > > > --- a/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > > > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > > > @@ -81,6 +81,8 @@ struct cmdq {
> > > > > >  	u8			shift_pa;
> > > > > >  	bool			control_by_sw;
> > > > > >  	u32			gce_num;
> > > > > > +	atomic_t		usage;
> > > > > > +	spinlock_t		lock;
> > > > > >  };
> > > > > >  
> > > > > >  struct gce_plat {
> > > > > > @@ -90,6 +92,46 @@ struct gce_plat {
> > > > > >  	u32 gce_num;
> > > > > >  };
> > > > > >  
> > > > > > +static s32 cmdq_clk_enable(struct cmdq *cmdq)
> > > > > > +{
> > > > > > +	s32 usage, ret;
> > > > > > +	unsigned long flags;
> > > > > > +
> > > > > > +	spin_lock_irqsave(&cmdq->lock, flags);
> > > > > > +
> > > > > > +	usage = atomic_inc_return(&cmdq->usage);
> > > > > > +
> > > > > > +	ret = clk_bulk_enable(cmdq->gce_num, cmdq->clocks);
> > > > > > +	if (usage <=0 || ret < 0) {
> > > > > > +		dev_err(cmdq->mbox.dev, "ref count %d ret %d
> > > > > > suspend
> > > > > > %d\n",
> > > > > > +			usage, ret, cmdq->suspended);
> > > > > > +	} else if (usage == 1) {
> > > > > > +		if (cmdq->control_by_sw)
> > > > > > +			writel((0x7 << 16) + 0x7, cmdq->base +
> > > > > > GCE_GCTL_VALUE);
> > > > > > +	}
> > > > > > +
> > > > > > +	spin_unlock_irqrestore(&cmdq->lock, flags);
> > > > > > +
> > > > > > +	return ret;
> > > > > > +}
> > > > > > +
> > > > > > +static void cmdq_clk_disable(struct cmdq *cmdq)
> > > > > > +{
> > > > > > +	s32 usage;
> > > > > > +
> > > > > > +	usage = atomic_dec_return(&cmdq->usage);
> > > > > > +
> > > > > > +	if (usage < 0) {
> > > > > > +		dev_err(cmdq->mbox.dev, "ref count %d suspend
> > > > > > %d\n",
> > > > > > +			usage, cmdq->suspended);
> > > > > > +	} else if (usage == 0) {
> > > > > > +		if (cmdq->control_by_sw)
> > > > > > +			writel(0x7, cmdq->base +
> > > > > > GCE_GCTL_VALUE);
> > > > > > +	}
> > > > > > +
> > > > > > +	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > > > +}
> > > > > > +
> > > > > >  u8 cmdq_get_shift_pa(struct mbox_chan *chan)
> > > > > >  {
> > > > > >  	struct cmdq *cmdq = container_of(chan->mbox, struct
> > > > > > cmdq,
> > > > > > mbox);
> > > > > > @@ -271,7 +313,8 @@ static void
> > > > > > cmdq_thread_irq_handler(struct
> > > > > > cmdq
> > > > > > *cmdq,
> > > > > >  
> > > > > >  	if (list_empty(&thread->task_busy_list)) {
> > > > > >  		cmdq_thread_disable(cmdq, thread);
> > > > > > -		clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > > > +
> > > > > > +		cmdq_clk_disable(cmdq);
> > > > > >  	}
> > > > > >  }
> > > > > >  
> > > > > > @@ -360,8 +403,7 @@ static int cmdq_mbox_send_data(struct
> > > > > > mbox_chan
> > > > > > *chan, void *data)
> > > > > >  	task->pkt = pkt;
> > > > > >  
> > > > > >  	if (list_empty(&thread->task_busy_list)) {
> > > > > > -		WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq-
> > > > > > > clocks));
> > > > > > 
> > > > > > -
> > > > > > +		WARN_ON(cmdq_clk_enable(cmdq) < 0);
> > > > > >  		/*
> > > > > >  		 * The thread reset will clear thread related
> > > > > > register
> > > > > > to 0,
> > > > > >  		 * including pc, end, priority, irq, suspend
> > > > > > and
> > > > > > enable. Thus
> > > > > > @@ -433,7 +475,7 @@ static void cmdq_mbox_shutdown(struct
> > > > > > mbox_chan
> > > > > > *chan)
> > > > > >  	}
> > > > > >  
> > > > > >  	cmdq_thread_disable(cmdq, thread);
> > > > > > -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > > > +	cmdq_clk_disable(cmdq);
> > > > > >  
> > > > > >  done:
> > > > > >  	/*
> > > > > > @@ -479,7 +521,8 @@ static int cmdq_mbox_flush(struct
> > > > > > mbox_chan
> > > > > > *chan, unsigned long timeout)
> > > > > >  
> > > > > >  	cmdq_thread_resume(thread);
> > > > > >  	cmdq_thread_disable(cmdq, thread);
> > > > > > -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > > > +
> > > > > > +	cmdq_clk_disable(cmdq);
> > > > > >  
> > > > > >  out:
> > > > > >  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> > > > > > @@ -490,7 +533,8 @@ static int cmdq_mbox_flush(struct
> > > > > > mbox_chan
> > > > > > *chan, unsigned long timeout)
> > > > > >  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> > > > > >  	if (readl_poll_timeout_atomic(thread->base +
> > > > > > CMDQ_THR_ENABLE_TASK,
> > > > > >  				      enable, enable == 0, 1,
> > > > > > timeout))
> > > > > > {
> > > > > > -		dev_err(cmdq->mbox.dev, "Fail to wait GCE
> > > > > > thread 0x%x
> > > > > > done\n",
> > > > > > +		dev_err(cmdq->mbox.dev,
> > > > > > +			"Fail to wait GCE thread 0x%x done\n",
> > > > > >  			(u32)(thread->base - cmdq->base));
> > > > > >  
> > > > > >  		return -EFAULT;
> > > > > > @@ -626,6 +670,7 @@ static int cmdq_probe(struct
> > > > > > platform_device
> > > > > > *pdev)
> > > > > >  
> > > > > >  	WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
> > > > > >  
> > > > > > +	spin_lock_init(&cmdq->lock);
> > > > > >  	cmdq_init(cmdq);
> > > > > >  
> > > > > >  	return 0;
> > > > > 
> > > > > 
> > > > 
> > > > 
> > > 
> > > 
> > 
> > 
> 
> 



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1, 1/1] mailbox: mtk-cmdq: fix gce timeout issue
@ 2022-08-16  2:14               ` yongqiang.niu
  0 siblings, 0 replies; 20+ messages in thread
From: yongqiang.niu @ 2022-08-16  2:14 UTC (permalink / raw)
  To: CK Hu, Chun-Kuang Hu
  Cc: Jassi Brar, Matthias Brugger, linux-kernel, linux-arm-kernel,
	linux-mediatek, Project_Global_Chrome_Upstream_Group,
	Hsin-Yi Wang, Yongqiang Niu, Allen-kh Cheng

On Tue, 2022-08-16 at 09:49 +0800, CK Hu wrote:
> Hi, Yongqiang:
> 
> On Mon, 2022-08-15 at 17:51 +0800, yongqiang.niu wrote:
> > On Mon, 2022-08-15 at 14:23 +0800, CK Hu wrote:
> > > Hi, Yongqiang:
> > > 
> > > On Mon, 2022-08-15 at 13:51 +0800, yongqiang.niu wrote:
> > > > On Mon, 2022-08-15 at 13:24 +0800, CK Hu wrote:
> > > > > Hi, Yongqiang:
> > > > > 
> > > > > 
> > > > > On Mon, 2022-08-15 at 11:07 +0800, Yongqiang Niu wrote:
> > > > > > From: Yongqiang Niu <
> > > > > > yongqiang.niu@mediatek.corp-partner.google.com
> > > > > > > 
> > > > > > 
> > > > > > 1. enable gce ddr enable(gce reigster offset 0x48, bit 16
> > > > > > to
> > > > > > 18)
> > > > > > when
> > > > > > gce work,
> > > > > > and disable gce ddr enable when gce work job done
> > > > > 
> > > > > Why need gce ddr enable? I think gce works fine without this.
> > > > > Describe
> > > > > more about this.
> > > > > 
> > > > > Regards,
> > > > > CK
> > > > 
> > > > this is only for some SOC which has flag "control_by_sw".
> > > > for this kind of gce, there is a handshake flow between gce and
> > > > ddr
> > > > hardware,
> > > > if not set ddr enable flag of gce, ddr will fall into idle
> > > > mode, 
> > > > then gce instructions will not process done.
> > > > we need set this flag of gce to tell ddr when gce is idle or
> > > > busy
> > > > controlled by software flow.
> > > 
> > > You [1] and Jason [2] has already enable control_by_sw and I
> > > believe
> > > you two have test your patch in general. Is the ddr problem a
> > > special
> > > case? How to operate to trigger this bug? Describe more in commit
> > > message to let us know why need this patch.
> > > 
> > > [1] 
> > > 
> > 
> > 
> 
> 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/mailbox/mtk-cmdq-mailbox.c?h=v6.0-rc1&id=84fd4201b78b96f8d31f6a2624be27ad6306a9bc
> > > [2] 
> > > 
> > 
> > 
> 
> 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/mailbox/mtk-cmdq-mailbox.c?h=v6.0-rc1&id=9388501fbb99a1b6a23f28634d125567a3b45a3d
> > > 
> > 
> > ddr problem is a special case.
> > when test suspend/resume case, gce sometimes will pull ddr, and ddr
> > can
> > not go to suspend.
> > if we set gce register 0x48 to 0x7, will fix this gce pull ddr
> > issue,
> > as you have referred [1] and [2] (8192 and 8195)
> > 
> > but for mt8186, the gce is more special, except setting of [1] and
> > [2],
> > we need add more setting set gce register 0x48 to (0x7 << 16 | 0x7)
> > when gce working to make sure gce could process all instructions
> > ok.
> > this case just need normal bootup, if we not set this, display cmdq
> > task will timeout, and chrome homescreen will always black screen.
> > 
> > and for this patch, we have done these test on mt8186:
> > 1.suspend/resume
> > 2.boot up to home screen
> > 3.playback video with youtube.
> > 
> > mt8195 is under testing
> 
> I seems there are two problem. The first is suspend problem which is
> fixed by [1] and [2]. The second is boot problem which only happen in
> MT8186. So add a new driver private data for the boot problem.
> 
> For the suspend problem, I think the correct suspend flow is:
> 
> 1. Client driver suspend: flush all command in mailbox channel.
> 2. gce driver suspend: Do nothing to gce hardware because all gce
> thread is empty.
> 3. System suspend: suspend the ddr.
> 
> If you find that gce pull the ddr when ddr suspend, that means client
> driver does not flush all command when suspend, so fix the client
> driver and gce would not pull ddr when ddr suspend. 
> 
> Regards,
> CK
> 

1.suspend issue is special gce hardware issue, gce client  driver
command already process done, but gce still pull ddr.

2. I will add new private data for MT8186 boot up issue in next version


> > 
> > > 
> > > > 
> > > > > 
> > > > > > 2. split cmdq clk enable/disable api, and control gce ddr
> > > > > > enable/disable
> > > > > > in clk enable/disable function to make sure it could
> > > > > > protect
> > > > > > when
> > > > > > cmdq
> > > > > > is multiple used by display and mdp
> > > > > > 
> > > > > > Signed-off-by: Yongqiang Niu <
> > > > > > yongqiang.niu@mediatek.corp-partner.google.com>
> > > > > > Signed-off-by: Allen-kh Cheng <
> > > > > > allen-kh.cheng@mediatek.corp-partner.google.com>
> > > > > > ---
> > > > > >  drivers/mailbox/mtk-cmdq-mailbox.c | 57
> > > > > > ++++++++++++++++++++++++++
> > > > > > ----
> > > > > >  1 file changed, 51 insertions(+), 6 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > > > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > > > index 2578e5aaa935..64a47470f062 100644
> > > > > > --- a/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > > > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > > > > > @@ -81,6 +81,8 @@ struct cmdq {
> > > > > >  	u8			shift_pa;
> > > > > >  	bool			control_by_sw;
> > > > > >  	u32			gce_num;
> > > > > > +	atomic_t		usage;
> > > > > > +	spinlock_t		lock;
> > > > > >  };
> > > > > >  
> > > > > >  struct gce_plat {
> > > > > > @@ -90,6 +92,46 @@ struct gce_plat {
> > > > > >  	u32 gce_num;
> > > > > >  };
> > > > > >  
> > > > > > +static s32 cmdq_clk_enable(struct cmdq *cmdq)
> > > > > > +{
> > > > > > +	s32 usage, ret;
> > > > > > +	unsigned long flags;
> > > > > > +
> > > > > > +	spin_lock_irqsave(&cmdq->lock, flags);
> > > > > > +
> > > > > > +	usage = atomic_inc_return(&cmdq->usage);
> > > > > > +
> > > > > > +	ret = clk_bulk_enable(cmdq->gce_num, cmdq->clocks);
> > > > > > +	if (usage <=0 || ret < 0) {
> > > > > > +		dev_err(cmdq->mbox.dev, "ref count %d ret %d
> > > > > > suspend
> > > > > > %d\n",
> > > > > > +			usage, ret, cmdq->suspended);
> > > > > > +	} else if (usage == 1) {
> > > > > > +		if (cmdq->control_by_sw)
> > > > > > +			writel((0x7 << 16) + 0x7, cmdq->base +
> > > > > > GCE_GCTL_VALUE);
> > > > > > +	}
> > > > > > +
> > > > > > +	spin_unlock_irqrestore(&cmdq->lock, flags);
> > > > > > +
> > > > > > +	return ret;
> > > > > > +}
> > > > > > +
> > > > > > +static void cmdq_clk_disable(struct cmdq *cmdq)
> > > > > > +{
> > > > > > +	s32 usage;
> > > > > > +
> > > > > > +	usage = atomic_dec_return(&cmdq->usage);
> > > > > > +
> > > > > > +	if (usage < 0) {
> > > > > > +		dev_err(cmdq->mbox.dev, "ref count %d suspend
> > > > > > %d\n",
> > > > > > +			usage, cmdq->suspended);
> > > > > > +	} else if (usage == 0) {
> > > > > > +		if (cmdq->control_by_sw)
> > > > > > +			writel(0x7, cmdq->base +
> > > > > > GCE_GCTL_VALUE);
> > > > > > +	}
> > > > > > +
> > > > > > +	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > > > +}
> > > > > > +
> > > > > >  u8 cmdq_get_shift_pa(struct mbox_chan *chan)
> > > > > >  {
> > > > > >  	struct cmdq *cmdq = container_of(chan->mbox, struct
> > > > > > cmdq,
> > > > > > mbox);
> > > > > > @@ -271,7 +313,8 @@ static void
> > > > > > cmdq_thread_irq_handler(struct
> > > > > > cmdq
> > > > > > *cmdq,
> > > > > >  
> > > > > >  	if (list_empty(&thread->task_busy_list)) {
> > > > > >  		cmdq_thread_disable(cmdq, thread);
> > > > > > -		clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > > > +
> > > > > > +		cmdq_clk_disable(cmdq);
> > > > > >  	}
> > > > > >  }
> > > > > >  
> > > > > > @@ -360,8 +403,7 @@ static int cmdq_mbox_send_data(struct
> > > > > > mbox_chan
> > > > > > *chan, void *data)
> > > > > >  	task->pkt = pkt;
> > > > > >  
> > > > > >  	if (list_empty(&thread->task_busy_list)) {
> > > > > > -		WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq-
> > > > > > > clocks));
> > > > > > 
> > > > > > -
> > > > > > +		WARN_ON(cmdq_clk_enable(cmdq) < 0);
> > > > > >  		/*
> > > > > >  		 * The thread reset will clear thread related
> > > > > > register
> > > > > > to 0,
> > > > > >  		 * including pc, end, priority, irq, suspend
> > > > > > and
> > > > > > enable. Thus
> > > > > > @@ -433,7 +475,7 @@ static void cmdq_mbox_shutdown(struct
> > > > > > mbox_chan
> > > > > > *chan)
> > > > > >  	}
> > > > > >  
> > > > > >  	cmdq_thread_disable(cmdq, thread);
> > > > > > -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > > > +	cmdq_clk_disable(cmdq);
> > > > > >  
> > > > > >  done:
> > > > > >  	/*
> > > > > > @@ -479,7 +521,8 @@ static int cmdq_mbox_flush(struct
> > > > > > mbox_chan
> > > > > > *chan, unsigned long timeout)
> > > > > >  
> > > > > >  	cmdq_thread_resume(thread);
> > > > > >  	cmdq_thread_disable(cmdq, thread);
> > > > > > -	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
> > > > > > +
> > > > > > +	cmdq_clk_disable(cmdq);
> > > > > >  
> > > > > >  out:
> > > > > >  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> > > > > > @@ -490,7 +533,8 @@ static int cmdq_mbox_flush(struct
> > > > > > mbox_chan
> > > > > > *chan, unsigned long timeout)
> > > > > >  	spin_unlock_irqrestore(&thread->chan->lock, flags);
> > > > > >  	if (readl_poll_timeout_atomic(thread->base +
> > > > > > CMDQ_THR_ENABLE_TASK,
> > > > > >  				      enable, enable == 0, 1,
> > > > > > timeout))
> > > > > > {
> > > > > > -		dev_err(cmdq->mbox.dev, "Fail to wait GCE
> > > > > > thread 0x%x
> > > > > > done\n",
> > > > > > +		dev_err(cmdq->mbox.dev,
> > > > > > +			"Fail to wait GCE thread 0x%x done\n",
> > > > > >  			(u32)(thread->base - cmdq->base));
> > > > > >  
> > > > > >  		return -EFAULT;
> > > > > > @@ -626,6 +670,7 @@ static int cmdq_probe(struct
> > > > > > platform_device
> > > > > > *pdev)
> > > > > >  
> > > > > >  	WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
> > > > > >  
> > > > > > +	spin_lock_init(&cmdq->lock);
> > > > > >  	cmdq_init(cmdq);
> > > > > >  
> > > > > >  	return 0;
> > > > > 
> > > > > 
> > > > 
> > > > 
> > > 
> > > 
> > 
> > 
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2022-08-16  2:51 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-15  3:07 [PATCH v1, 0/1] fix gce timeout issue Yongqiang Niu
2022-08-15  3:07 ` Yongqiang Niu
2022-08-15  3:07 ` [PATCH v1, 1/1] mailbox: mtk-cmdq: " Yongqiang Niu
2022-08-15  3:07   ` Yongqiang Niu
2022-08-15  5:24   ` CK Hu
2022-08-15  5:24     ` CK Hu
2022-08-15  5:51     ` yongqiang.niu
2022-08-15  5:51       ` yongqiang.niu
2022-08-15  6:23       ` CK Hu
2022-08-15  6:23         ` CK Hu
2022-08-15  9:51         ` yongqiang.niu
2022-08-15  9:51           ` yongqiang.niu
2022-08-16  1:49           ` CK Hu
2022-08-16  1:49             ` CK Hu
2022-08-16  2:14             ` yongqiang.niu
2022-08-16  2:14               ` yongqiang.niu
2022-08-15  3:24 ` [PATCH v1, 0/1] " Allen-KH Cheng
2022-08-15  3:24   ` Allen-KH Cheng
2022-08-15  4:30 ` Hsin-Yi Wang
2022-08-15  4:30   ` Hsin-Yi Wang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.