Lines Matching +full:clk +full:- +full:remote +full:- +full:icu2
1 // SPDX-License-Identifier: GPL-2.0
6 #include <linux/clk.h>
30 /* Generate remote icu IRQ Register */
42 /* store MBOX context across system-wide suspend/resume transitions */
66 void __iomem *remote_icu[TH_1520_MBOX_CHANS - 1];
88 iowrite32(val, priv->cur_cpu_ch_base + offs);
93 return ioread32(priv->cur_cpu_ch_base + offs);
102 spin_lock_irqsave(&priv->mbox_lock, flags);
107 spin_unlock_irqrestore(&priv->mbox_lock, flags);
116 iowrite32(val, cp->comm_remote_base + offs);
118 iowrite32(val, cp->comm_local_base + offs);
125 return ioread32(cp->comm_remote_base + offs);
127 return ioread32(cp->comm_local_base + offs);
133 struct th1520_mbox_priv *priv = to_th1520_mbox_priv(cp->chan->mbox);
137 spin_lock_irqsave(&priv->mbox_lock, flags);
142 spin_unlock_irqrestore(&priv->mbox_lock, flags);
194 if (i == cp->idx)
202 dev_err(cp->chan->mbox->dev, "convert to mapbit failed\n");
210 struct th1520_mbox_priv *priv = to_th1520_mbox_priv(chan->mbox);
211 struct th1520_mbox_con_priv *cp = chan->con_priv;
233 /* notify remote cpu */
236 if (cp->idx != TH_1520_MBOX_ICU_CPU1 &&
237 cp->idx != TH_1520_MBOX_ICU_CPU2)
263 struct th1520_mbox_con_priv *cp = chan->con_priv;
273 struct th1520_mbox_priv *priv = to_th1520_mbox_priv(chan->mbox);
274 struct th1520_mbox_con_priv *cp = chan->con_priv;
279 /* clear local and remote generate and info0~info7 */
307 ret = request_irq(priv->irq, th1520_mbox_isr,
308 IRQF_SHARED | IRQF_NO_SUSPEND, cp->irq_desc, chan);
310 dev_err(priv->dev, "Unable to acquire IRQ %d\n", priv->irq);
319 struct th1520_mbox_priv *priv = to_th1520_mbox_priv(chan->mbox);
320 struct th1520_mbox_con_priv *cp = chan->con_priv;
323 free_irq(priv->irq, chan);
339 priv->ctx = devm_kzalloc(priv->dev, sizeof(*priv->ctx), GFP_KERNEL);
340 if (!priv->ctx)
341 return -ENOMEM;
354 if (sp->args_count != 1) {
355 dev_err(mbox->dev, "Invalid argument count %d\n",
356 sp->args_count);
357 return ERR_PTR(-EINVAL);
360 chan = sp->args[0]; /* comm remote channel */
362 if (chan >= mbox->num_chans) {
363 dev_err(mbox->dev, "Not supported channel number: %d\n", chan);
364 return ERR_PTR(-EINVAL);
368 dev_err(mbox->dev, "Cannot communicate with yourself\n");
369 return ERR_PTR(-EINVAL);
372 return &mbox->chans[chan];
384 dev_err(&pdev->dev, "Failed to get resource: %s\n", res_name);
385 return ERR_PTR(-EINVAL);
388 mapped = devm_ioremap(&pdev->dev, res->start + offset,
389 resource_size(res) - offset);
391 dev_err(&pdev->dev, "Failed to map resource: %s\n", res_name);
392 return ERR_PTR(-ENOMEM);
402 clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clocks), priv->clocks);
407 struct device *dev = &pdev->dev;
415 return -ENOMEM;
417 priv->dev = dev;
419 priv->clocks[0].id = "clk-local";
420 priv->clocks[1].id = "clk-remote-icu0";
421 priv->clocks[2].id = "clk-remote-icu1";
422 priv->clocks[3].id = "clk-remote-icu2";
424 ret = devm_clk_bulk_get(dev, ARRAY_SIZE(priv->clocks),
425 priv->clocks);
431 ret = clk_bulk_prepare_enable(ARRAY_SIZE(priv->clocks), priv->clocks);
439 clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clocks), priv->clocks);
446 * mapped regions are irregular, particularly for remote-icu0.
450 priv->local_icu[TH_1520_MBOX_ICU_KERNEL_CPU0] =
452 if (IS_ERR(priv->local_icu[TH_1520_MBOX_ICU_KERNEL_CPU0]))
453 return PTR_ERR(priv->local_icu[TH_1520_MBOX_ICU_KERNEL_CPU0]);
455 priv->remote_icu[0] = th1520_map_mmio(pdev, "remote-icu0", 0x4000);
456 if (IS_ERR(priv->remote_icu[0]))
457 return PTR_ERR(priv->remote_icu[0]);
459 priv->remote_icu[1] = th1520_map_mmio(pdev, "remote-icu1", 0x0);
460 if (IS_ERR(priv->remote_icu[1]))
461 return PTR_ERR(priv->remote_icu[1]);
463 priv->remote_icu[2] = th1520_map_mmio(pdev, "remote-icu2", 0x0);
464 if (IS_ERR(priv->remote_icu[2]))
465 return PTR_ERR(priv->remote_icu[2]);
467 priv->local_icu[TH_1520_MBOX_ICU_CPU1] =
468 priv->local_icu[TH_1520_MBOX_ICU_KERNEL_CPU0] +
470 priv->local_icu[TH_1520_MBOX_ICU_CPU2] =
471 priv->local_icu[TH_1520_MBOX_ICU_CPU1] +
473 priv->local_icu[TH_1520_MBOX_ICU_CPU3] =
474 priv->local_icu[TH_1520_MBOX_ICU_CPU2] +
477 priv->cur_cpu_ch_base = priv->local_icu[TH_1520_MBOX_ICU_KERNEL_CPU0];
479 priv->irq = platform_get_irq(pdev, 0);
480 if (priv->irq < 0)
481 return priv->irq;
485 struct th1520_mbox_con_priv *cp = &priv->con_priv[i];
487 cp->idx = i;
488 cp->chan = &priv->mbox_chans[i];
489 priv->mbox_chans[i].con_priv = cp;
490 snprintf(cp->irq_desc, sizeof(cp->irq_desc),
491 "th1520_mbox_chan[%i]", cp->idx);
493 cp->comm_local_base = priv->local_icu[i];
495 cp->comm_remote_base = priv->remote_icu[remote_idx];
500 spin_lock_init(&priv->mbox_lock);
502 priv->mbox.dev = dev;
503 priv->mbox.ops = &th1520_mbox_ops;
504 priv->mbox.chans = priv->mbox_chans;
505 priv->mbox.num_chans = TH_1520_MBOX_CHANS;
506 priv->mbox.of_xlate = th1520_mbox_xlate;
507 priv->mbox.txdone_irq = true;
517 return devm_mbox_controller_register(dev, &priv->mbox);
521 { .compatible = "thead,th1520-mbox" },
530 struct th1520_mbox_context *ctx = priv->ctx;
537 ctx->intr_mask[i] =
538 ioread32(priv->local_icu[i] + TH_1520_MBOX_MASK);
546 struct th1520_mbox_context *ctx = priv->ctx;
550 iowrite32(ctx->intr_mask[i],
551 priv->local_icu[i] + TH_1520_MBOX_MASK);
562 clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clocks), priv->clocks);
572 ret = clk_bulk_prepare_enable(ARRAY_SIZE(priv->clocks), priv->clocks);
591 .name = "th1520-mbox",
598 MODULE_DESCRIPTION("Thead TH-1520 mailbox IPC driver");