summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/mailbox/mtk-cmdq-mailbox.c57
-rw-r--r--include/linux/mailbox/mtk-cmdq-mailbox.h2
2 files changed, 46 insertions, 13 deletions
diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index b24822ad8409..49d9264145aa 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -75,8 +75,22 @@ struct cmdq {
struct cmdq_thread *thread;
struct clk *clock;
bool suspended;
+ u8 shift_pa;
};
+struct gce_plat {
+ u32 thread_nr;
+ u8 shift;
+};
+
+u8 cmdq_get_shift_pa(struct mbox_chan *chan)
+{
+ struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox);
+
+ return cmdq->shift_pa;
+}
+EXPORT_SYMBOL(cmdq_get_shift_pa);
+
static int cmdq_thread_suspend(struct cmdq *cmdq, struct cmdq_thread *thread)
{
u32 status;
@@ -183,13 +197,15 @@ static void cmdq_task_handle_error(struct cmdq_task *task)
{
struct cmdq_thread *thread = task->thread;
struct cmdq_task *next_task;
+ struct cmdq *cmdq = task->cmdq;
- dev_err(task->cmdq->mbox.dev, "task 0x%p error\n", task);
- WARN_ON(cmdq_thread_suspend(task->cmdq, thread) < 0);
+ dev_err(cmdq->mbox.dev, "task 0x%p error\n", task);
+ WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
next_task = list_first_entry_or_null(&thread->task_busy_list,
struct cmdq_task, list_entry);
if (next_task)
- writel(next_task->pa_base, thread->base + CMDQ_THR_CURR_ADDR);
+ writel(next_task->pa_base >> cmdq->shift_pa,
+ thread->base + CMDQ_THR_CURR_ADDR);
cmdq_thread_resume(thread);
}
@@ -219,7 +235,7 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
else
return;
- curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR);
+ curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) << cmdq->shift_pa;
list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
list_entry) {
@@ -335,27 +351,31 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
WARN_ON(clk_enable(cmdq->clock) < 0);
WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
- writel(task->pa_base, thread->base + CMDQ_THR_CURR_ADDR);
- writel(task->pa_base + pkt->cmd_buf_size,
+ writel(task->pa_base >> cmdq->shift_pa,
+ thread->base + CMDQ_THR_CURR_ADDR);
+ writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->shift_pa,
thread->base + CMDQ_THR_END_ADDR);
+
writel(thread->priority, thread->base + CMDQ_THR_PRIORITY);
writel(CMDQ_THR_IRQ_EN, thread->base + CMDQ_THR_IRQ_ENABLE);
writel(CMDQ_THR_ENABLED, thread->base + CMDQ_THR_ENABLE_TASK);
} else {
WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
- curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR);
- end_pa = readl(thread->base + CMDQ_THR_END_ADDR);
+ curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) <<
+ cmdq->shift_pa;
+ end_pa = readl(thread->base + CMDQ_THR_END_ADDR) <<
+ cmdq->shift_pa;
/* check boundary */
if (curr_pa == end_pa - CMDQ_INST_SIZE ||
curr_pa == end_pa) {
/* set to this task directly */
- writel(task->pa_base,
+ writel(task->pa_base >> cmdq->shift_pa,
thread->base + CMDQ_THR_CURR_ADDR);
} else {
cmdq_task_insert_into_thread(task);
smp_mb(); /* modify jump before enable thread */
}
- writel(task->pa_base + pkt->cmd_buf_size,
+ writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->shift_pa,
thread->base + CMDQ_THR_END_ADDR);
cmdq_thread_resume(thread);
}
@@ -453,6 +473,7 @@ static int cmdq_probe(struct platform_device *pdev)
struct resource *res;
struct cmdq *cmdq;
int err, i;
+ struct gce_plat *plat_data;
cmdq = devm_kzalloc(dev, sizeof(*cmdq), GFP_KERNEL);
if (!cmdq)
@@ -471,7 +492,14 @@ static int cmdq_probe(struct platform_device *pdev)
return -EINVAL;
}
- cmdq->thread_nr = (u32)(unsigned long)of_device_get_match_data(dev);
+ plat_data = (struct gce_plat *)of_device_get_match_data(dev);
+ if (!plat_data) {
+ dev_err(dev, "failed to get match data\n");
+ return -EINVAL;
+ }
+
+ cmdq->thread_nr = plat_data->thread_nr;
+ cmdq->shift_pa = plat_data->shift;
cmdq->irq_mask = GENMASK(cmdq->thread_nr - 1, 0);
err = devm_request_irq(dev, cmdq->irq, cmdq_irq_handler, IRQF_SHARED,
"mtk_cmdq", cmdq);
@@ -534,9 +562,12 @@ static const struct dev_pm_ops cmdq_pm_ops = {
.resume = cmdq_resume,
};
+static const struct gce_plat gce_plat_v2 = {.thread_nr = 16};
+static const struct gce_plat gce_plat_v3 = {.thread_nr = 24};
+
static const struct of_device_id cmdq_of_ids[] = {
- {.compatible = "mediatek,mt8173-gce", .data = (void *)16},
- {.compatible = "mediatek,mt8183-gce", .data = (void *)24},
+ {.compatible = "mediatek,mt8173-gce", .data = (void *)&gce_plat_v2},
+ {.compatible = "mediatek,mt8183-gce", .data = (void *)&gce_plat_v3},
{}
};
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h
index a4dc45fbec0a..c342b8799be8 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -88,4 +88,6 @@ struct cmdq_pkt {
void *cl;
};
+u8 cmdq_get_shift_pa(struct mbox_chan *chan);
+
#endif /* __MTK_CMDQ_MAILBOX_H__ */