Lines Matching +full:clk +full:- +full:remote +full:- +full:icu1
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 */
44 u32 intr_mask[TH_1520_MBOX_CHANS - 1];
66 void __iomem *remote_icu[TH_1520_MBOX_CHANS - 1];
88 iowrite32(val, priv->cur_cpu_ch_base + offs); in th1520_mbox_write()
93 return ioread32(priv->cur_cpu_ch_base + offs); in th1520_mbox_read()
102 spin_lock_irqsave(&priv->mbox_lock, flags); in th1520_mbox_rmw()
107 spin_unlock_irqrestore(&priv->mbox_lock, flags); in th1520_mbox_rmw()
116 iowrite32(val, cp->comm_remote_base + offs); in th1520_mbox_chan_write()
118 iowrite32(val, cp->comm_local_base + offs); in th1520_mbox_chan_write()
125 return ioread32(cp->comm_remote_base + offs); in th1520_mbox_chan_read()
127 return ioread32(cp->comm_local_base + offs); in th1520_mbox_chan_read()
133 struct th1520_mbox_priv *priv = to_th1520_mbox_priv(cp->chan->mbox); in th1520_mbox_chan_rmw()
137 spin_lock_irqsave(&priv->mbox_lock, flags); in th1520_mbox_chan_rmw()
142 spin_unlock_irqrestore(&priv->mbox_lock, flags); in th1520_mbox_chan_rmw()
194 if (i == cp->idx) in th1520_mbox_chan_id_to_mapbit()
202 dev_err(cp->chan->mbox->dev, "convert to mapbit failed\n"); in th1520_mbox_chan_id_to_mapbit()
210 struct th1520_mbox_priv *priv = to_th1520_mbox_priv(chan->mbox); in th1520_mbox_isr()
211 struct th1520_mbox_con_priv *cp = chan->con_priv; in th1520_mbox_isr()
233 /* notify remote cpu */ in th1520_mbox_isr()
236 if (cp->idx != TH_1520_MBOX_ICU_CPU1 && in th1520_mbox_isr()
237 cp->idx != TH_1520_MBOX_ICU_CPU2) in th1520_mbox_isr()
263 struct th1520_mbox_con_priv *cp = chan->con_priv; in th1520_mbox_send_data()
273 struct th1520_mbox_priv *priv = to_th1520_mbox_priv(chan->mbox); in th1520_mbox_startup()
274 struct th1520_mbox_con_priv *cp = chan->con_priv; in th1520_mbox_startup()
279 /* clear local and remote generate and info0~info7 */ in th1520_mbox_startup()
307 ret = request_irq(priv->irq, th1520_mbox_isr, in th1520_mbox_startup()
308 IRQF_SHARED | IRQF_NO_SUSPEND, cp->irq_desc, chan); in th1520_mbox_startup()
310 dev_err(priv->dev, "Unable to acquire IRQ %d\n", priv->irq); in th1520_mbox_startup()
319 struct th1520_mbox_priv *priv = to_th1520_mbox_priv(chan->mbox); in th1520_mbox_shutdown()
320 struct th1520_mbox_con_priv *cp = chan->con_priv; in th1520_mbox_shutdown()
323 free_irq(priv->irq, chan); in th1520_mbox_shutdown()
339 priv->ctx = devm_kzalloc(priv->dev, sizeof(*priv->ctx), GFP_KERNEL); in th1520_mbox_init_generic()
340 if (!priv->ctx) in th1520_mbox_init_generic()
341 return -ENOMEM; in th1520_mbox_init_generic()
354 if (sp->args_count != 1) { in th1520_mbox_xlate()
355 dev_err(mbox->dev, "Invalid argument count %d\n", in th1520_mbox_xlate()
356 sp->args_count); in th1520_mbox_xlate()
357 return ERR_PTR(-EINVAL); in th1520_mbox_xlate()
360 chan = sp->args[0]; /* comm remote channel */ in th1520_mbox_xlate()
362 if (chan >= mbox->num_chans) { in th1520_mbox_xlate()
363 dev_err(mbox->dev, "Not supported channel number: %d\n", chan); in th1520_mbox_xlate()
364 return ERR_PTR(-EINVAL); in th1520_mbox_xlate()
368 dev_err(mbox->dev, "Cannot communicate with yourself\n"); in th1520_mbox_xlate()
369 return ERR_PTR(-EINVAL); in th1520_mbox_xlate()
372 return &mbox->chans[chan]; in th1520_mbox_xlate()
384 dev_err(&pdev->dev, "Failed to get resource: %s\n", res_name); in th1520_map_mmio()
385 return ERR_PTR(-EINVAL); in th1520_map_mmio()
388 mapped = devm_ioremap(&pdev->dev, res->start + offset, in th1520_map_mmio()
389 resource_size(res) - offset); in th1520_map_mmio()
391 dev_err(&pdev->dev, "Failed to map resource: %s\n", res_name); in th1520_map_mmio()
400 clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clocks), priv->clocks); in th1520_disable_clk()
405 struct device *dev = &pdev->dev; in th1520_mbox_probe()
413 return -ENOMEM; in th1520_mbox_probe()
415 priv->dev = dev; in th1520_mbox_probe()
417 priv->clocks[0].id = "clk-local"; in th1520_mbox_probe()
418 priv->clocks[1].id = "clk-remote-icu0"; in th1520_mbox_probe()
419 priv->clocks[2].id = "clk-remote-icu1"; in th1520_mbox_probe()
420 priv->clocks[3].id = "clk-remote-icu2"; in th1520_mbox_probe()
422 ret = devm_clk_bulk_get(dev, ARRAY_SIZE(priv->clocks), in th1520_mbox_probe()
423 priv->clocks); in th1520_mbox_probe()
429 ret = clk_bulk_prepare_enable(ARRAY_SIZE(priv->clocks), priv->clocks); in th1520_mbox_probe()
437 clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clocks), priv->clocks); in th1520_mbox_probe()
444 * mapped regions are irregular, particularly for remote-icu0. in th1520_mbox_probe()
448 priv->local_icu[TH_1520_MBOX_ICU_KERNEL_CPU0] = in th1520_mbox_probe()
450 if (IS_ERR(priv->local_icu[TH_1520_MBOX_ICU_KERNEL_CPU0])) in th1520_mbox_probe()
451 return PTR_ERR(priv->local_icu[TH_1520_MBOX_ICU_KERNEL_CPU0]); in th1520_mbox_probe()
453 priv->remote_icu[0] = th1520_map_mmio(pdev, "remote-icu0", 0x4000); in th1520_mbox_probe()
454 if (IS_ERR(priv->remote_icu[0])) in th1520_mbox_probe()
455 return PTR_ERR(priv->remote_icu[0]); in th1520_mbox_probe()
457 priv->remote_icu[1] = th1520_map_mmio(pdev, "remote-icu1", 0x0); in th1520_mbox_probe()
458 if (IS_ERR(priv->remote_icu[1])) in th1520_mbox_probe()
459 return PTR_ERR(priv->remote_icu[1]); in th1520_mbox_probe()
461 priv->remote_icu[2] = th1520_map_mmio(pdev, "remote-icu2", 0x0); in th1520_mbox_probe()
462 if (IS_ERR(priv->remote_icu[2])) in th1520_mbox_probe()
463 return PTR_ERR(priv->remote_icu[2]); in th1520_mbox_probe()
465 priv->local_icu[TH_1520_MBOX_ICU_CPU1] = in th1520_mbox_probe()
466 priv->local_icu[TH_1520_MBOX_ICU_KERNEL_CPU0] + in th1520_mbox_probe()
468 priv->local_icu[TH_1520_MBOX_ICU_CPU2] = in th1520_mbox_probe()
469 priv->local_icu[TH_1520_MBOX_ICU_CPU1] + in th1520_mbox_probe()
471 priv->local_icu[TH_1520_MBOX_ICU_CPU3] = in th1520_mbox_probe()
472 priv->local_icu[TH_1520_MBOX_ICU_CPU2] + in th1520_mbox_probe()
475 priv->cur_cpu_ch_base = priv->local_icu[TH_1520_MBOX_ICU_KERNEL_CPU0]; in th1520_mbox_probe()
477 priv->irq = platform_get_irq(pdev, 0); in th1520_mbox_probe()
478 if (priv->irq < 0) in th1520_mbox_probe()
479 return priv->irq; in th1520_mbox_probe()
483 struct th1520_mbox_con_priv *cp = &priv->con_priv[i]; in th1520_mbox_probe()
485 cp->idx = i; in th1520_mbox_probe()
486 cp->chan = &priv->mbox_chans[i]; in th1520_mbox_probe()
487 priv->mbox_chans[i].con_priv = cp; in th1520_mbox_probe()
488 snprintf(cp->irq_desc, sizeof(cp->irq_desc), in th1520_mbox_probe()
489 "th1520_mbox_chan[%i]", cp->idx); in th1520_mbox_probe()
491 cp->comm_local_base = priv->local_icu[i]; in th1520_mbox_probe()
493 cp->comm_remote_base = priv->remote_icu[remote_idx]; in th1520_mbox_probe()
498 spin_lock_init(&priv->mbox_lock); in th1520_mbox_probe()
500 priv->mbox.dev = dev; in th1520_mbox_probe()
501 priv->mbox.ops = &th1520_mbox_ops; in th1520_mbox_probe()
502 priv->mbox.chans = priv->mbox_chans; in th1520_mbox_probe()
503 priv->mbox.num_chans = TH_1520_MBOX_CHANS; in th1520_mbox_probe()
504 priv->mbox.of_xlate = th1520_mbox_xlate; in th1520_mbox_probe()
505 priv->mbox.txdone_irq = true; in th1520_mbox_probe()
515 return devm_mbox_controller_register(dev, &priv->mbox); in th1520_mbox_probe()
519 { .compatible = "thead,th1520-mbox" },
528 struct th1520_mbox_context *ctx = priv->ctx; in th1520_mbox_suspend_noirq()
535 ctx->intr_mask[i] = in th1520_mbox_suspend_noirq()
536 ioread32(priv->local_icu[i] + TH_1520_MBOX_MASK); in th1520_mbox_suspend_noirq()
544 struct th1520_mbox_context *ctx = priv->ctx; in th1520_mbox_resume_noirq()
548 iowrite32(ctx->intr_mask[i], in th1520_mbox_resume_noirq()
549 priv->local_icu[i] + TH_1520_MBOX_MASK); in th1520_mbox_resume_noirq()
560 clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clocks), priv->clocks); in th1520_mbox_runtime_suspend()
570 ret = clk_bulk_prepare_enable(ARRAY_SIZE(priv->clocks), priv->clocks); in th1520_mbox_runtime_resume()
589 .name = "th1520-mbox",
596 MODULE_DESCRIPTION("Thead TH-1520 mailbox IPC driver");