[PATCH] mailbox: remove runtime GCE clk control
jason-jh.lin
jason-jh.lin at mediatek.com
Tue Dec 14 01:17:41 PST 2021
1. GCE is a frequently used module, so runtime controlling
GCE clk may not saving too much power.
2. mt8195 sharing the same event table for 2 GCE core.
Runtime controlling 2 GCE clk will cause display HW register
configured in worng stream done event issue below:
GCE should config HW in every vblanking duration.
The stream done event is the start signal of vblanking.
If stream done event is sent between GCE clk_disable
and clk_enable. After GCE clk_enable the stream done event
may not appear immediately and have about 3us delay.
Normal case:
clk_disable -> get EventA -> clk_enable -> clear EventA
-> wait EventB -> get EventB -> config HW
Abnormal case:
clk_disable -> get EventA -> clk_enable -> EventA delay appear
-> clear EventA fail -> wait EventB but get EventA -> config HW
So just remove the runtime GCE clock contorl.
Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
drivers/mailbox/mtk-cmdq-mailbox.c | 18 +++++-------------
1 file changed, 5 insertions(+), 13 deletions(-)
diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index 342b91f16e65..1faf35e8aff0 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -127,13 +127,11 @@ static void cmdq_init(struct cmdq *cmdq)
{
int i;
- WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq->clocks));
if (cmdq->control_by_sw)
writel(0x7, cmdq->base + GCE_GCTL_VALUE);
writel(CMDQ_THR_ACTIVE_SLOT_CYCLES, cmdq->base + CMDQ_THR_SLOT_CYCLES);
for (i = 0; i <= CMDQ_MAX_EVENT; i++)
writel(i, cmdq->base + CMDQ_SYNC_TOKEN_UPDATE);
- clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
}
static int cmdq_thread_reset(struct cmdq *cmdq, struct cmdq_thread *thread)
@@ -269,10 +267,8 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
break;
}
- if (list_empty(&thread->task_busy_list)) {
+ if (list_empty(&thread->task_busy_list))
cmdq_thread_disable(cmdq, thread);
- clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
- }
}
static irqreturn_t cmdq_irq_handler(int irq, void *dev)
@@ -316,7 +312,7 @@ static int cmdq_suspend(struct device *dev)
if (task_running)
dev_warn(dev, "exist running task(s) in suspend\n");
- clk_bulk_unprepare(cmdq->gce_num, cmdq->clocks);
+ clk_bulk_disable_unprepare(cmdq->gce_num, cmdq->clocks);
return 0;
}
@@ -325,7 +321,7 @@ static int cmdq_resume(struct device *dev)
{
struct cmdq *cmdq = dev_get_drvdata(dev);
- WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
+ WARN_ON(clk_bulk_prepare_enable(cmdq->gce_num, cmdq->clocks));
cmdq->suspended = false;
return 0;
}
@@ -334,7 +330,7 @@ static int cmdq_remove(struct platform_device *pdev)
{
struct cmdq *cmdq = platform_get_drvdata(pdev);
- clk_bulk_unprepare(cmdq->gce_num, cmdq->clocks);
+ clk_bulk_disable_unprepare(cmdq->gce_num, cmdq->clocks);
return 0;
}
@@ -360,8 +356,6 @@ 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));
-
/*
* The thread reset will clear thread related register to 0,
* including pc, end, priority, irq, suspend and enable. Thus
@@ -433,7 +427,6 @@ static void cmdq_mbox_shutdown(struct mbox_chan *chan)
}
cmdq_thread_disable(cmdq, thread);
- clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
done:
/*
@@ -479,7 +472,6 @@ 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);
out:
spin_unlock_irqrestore(&thread->chan->lock, flags);
@@ -621,7 +613,7 @@ static int cmdq_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, cmdq);
- WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
+ WARN_ON(clk_bulk_prepare_enable(cmdq->gce_num, cmdq->clocks));
cmdq_init(cmdq);
--
2.18.0
More information about the Linux-mediatek
mailing list