Skip to content

Commit 0858fde

Browse files
Dennis YC HsiehJassiBrar
authored andcommitted
mailbox: cmdq: variablize address shift in platform
Some gce hardware shift pc and end address in register to support large dram addressing. Implement gce address shift when write or read pc and end register. And add shift bit in platform definition. Signed-off-by: Dennis YC Hsieh <[email protected]> Signed-off-by: Jassi Brar <[email protected]>
1 parent 6cb4f3b commit 0858fde

File tree

2 files changed

+46
-13
lines changed

2 files changed

+46
-13
lines changed

drivers/mailbox/mtk-cmdq-mailbox.c

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,22 @@ struct cmdq {
7575
struct cmdq_thread *thread;
7676
struct clk *clock;
7777
bool suspended;
78+
u8 shift_pa;
7879
};
7980

81+
struct gce_plat {
82+
u32 thread_nr;
83+
u8 shift;
84+
};
85+
86+
u8 cmdq_get_shift_pa(struct mbox_chan *chan)
87+
{
88+
struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox);
89+
90+
return cmdq->shift_pa;
91+
}
92+
EXPORT_SYMBOL(cmdq_get_shift_pa);
93+
8094
static int cmdq_thread_suspend(struct cmdq *cmdq, struct cmdq_thread *thread)
8195
{
8296
u32 status;
@@ -183,13 +197,15 @@ static void cmdq_task_handle_error(struct cmdq_task *task)
183197
{
184198
struct cmdq_thread *thread = task->thread;
185199
struct cmdq_task *next_task;
200+
struct cmdq *cmdq = task->cmdq;
186201

187-
dev_err(task->cmdq->mbox.dev, "task 0x%p error\n", task);
188-
WARN_ON(cmdq_thread_suspend(task->cmdq, thread) < 0);
202+
dev_err(cmdq->mbox.dev, "task 0x%p error\n", task);
203+
WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
189204
next_task = list_first_entry_or_null(&thread->task_busy_list,
190205
struct cmdq_task, list_entry);
191206
if (next_task)
192-
writel(next_task->pa_base, thread->base + CMDQ_THR_CURR_ADDR);
207+
writel(next_task->pa_base >> cmdq->shift_pa,
208+
thread->base + CMDQ_THR_CURR_ADDR);
193209
cmdq_thread_resume(thread);
194210
}
195211

@@ -219,7 +235,7 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
219235
else
220236
return;
221237

222-
curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR);
238+
curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) << cmdq->shift_pa;
223239

224240
list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
225241
list_entry) {
@@ -335,27 +351,31 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
335351
WARN_ON(clk_enable(cmdq->clock) < 0);
336352
WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
337353

338-
writel(task->pa_base, thread->base + CMDQ_THR_CURR_ADDR);
339-
writel(task->pa_base + pkt->cmd_buf_size,
354+
writel(task->pa_base >> cmdq->shift_pa,
355+
thread->base + CMDQ_THR_CURR_ADDR);
356+
writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->shift_pa,
340357
thread->base + CMDQ_THR_END_ADDR);
358+
341359
writel(thread->priority, thread->base + CMDQ_THR_PRIORITY);
342360
writel(CMDQ_THR_IRQ_EN, thread->base + CMDQ_THR_IRQ_ENABLE);
343361
writel(CMDQ_THR_ENABLED, thread->base + CMDQ_THR_ENABLE_TASK);
344362
} else {
345363
WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
346-
curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR);
347-
end_pa = readl(thread->base + CMDQ_THR_END_ADDR);
364+
curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) <<
365+
cmdq->shift_pa;
366+
end_pa = readl(thread->base + CMDQ_THR_END_ADDR) <<
367+
cmdq->shift_pa;
348368
/* check boundary */
349369
if (curr_pa == end_pa - CMDQ_INST_SIZE ||
350370
curr_pa == end_pa) {
351371
/* set to this task directly */
352-
writel(task->pa_base,
372+
writel(task->pa_base >> cmdq->shift_pa,
353373
thread->base + CMDQ_THR_CURR_ADDR);
354374
} else {
355375
cmdq_task_insert_into_thread(task);
356376
smp_mb(); /* modify jump before enable thread */
357377
}
358-
writel(task->pa_base + pkt->cmd_buf_size,
378+
writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->shift_pa,
359379
thread->base + CMDQ_THR_END_ADDR);
360380
cmdq_thread_resume(thread);
361381
}
@@ -453,6 +473,7 @@ static int cmdq_probe(struct platform_device *pdev)
453473
struct resource *res;
454474
struct cmdq *cmdq;
455475
int err, i;
476+
struct gce_plat *plat_data;
456477

457478
cmdq = devm_kzalloc(dev, sizeof(*cmdq), GFP_KERNEL);
458479
if (!cmdq)
@@ -471,7 +492,14 @@ static int cmdq_probe(struct platform_device *pdev)
471492
return -EINVAL;
472493
}
473494

474-
cmdq->thread_nr = (u32)(unsigned long)of_device_get_match_data(dev);
495+
plat_data = (struct gce_plat *)of_device_get_match_data(dev);
496+
if (!plat_data) {
497+
dev_err(dev, "failed to get match data\n");
498+
return -EINVAL;
499+
}
500+
501+
cmdq->thread_nr = plat_data->thread_nr;
502+
cmdq->shift_pa = plat_data->shift;
475503
cmdq->irq_mask = GENMASK(cmdq->thread_nr - 1, 0);
476504
err = devm_request_irq(dev, cmdq->irq, cmdq_irq_handler, IRQF_SHARED,
477505
"mtk_cmdq", cmdq);
@@ -534,9 +562,12 @@ static const struct dev_pm_ops cmdq_pm_ops = {
534562
.resume = cmdq_resume,
535563
};
536564

565+
static const struct gce_plat gce_plat_v2 = {.thread_nr = 16};
566+
static const struct gce_plat gce_plat_v3 = {.thread_nr = 24};
567+
537568
static const struct of_device_id cmdq_of_ids[] = {
538-
{.compatible = "mediatek,mt8173-gce", .data = (void *)16},
539-
{.compatible = "mediatek,mt8183-gce", .data = (void *)24},
569+
{.compatible = "mediatek,mt8173-gce", .data = (void *)&gce_plat_v2},
570+
{.compatible = "mediatek,mt8183-gce", .data = (void *)&gce_plat_v3},
540571
{}
541572
};
542573

include/linux/mailbox/mtk-cmdq-mailbox.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,6 @@ struct cmdq_pkt {
8888
void *cl;
8989
};
9090

91+
u8 cmdq_get_shift_pa(struct mbox_chan *chan);
92+
9193
#endif /* __MTK_CMDQ_MAILBOX_H__ */

0 commit comments

Comments
 (0)