Lines Matching +full:sc9860 +full:- +full:mailbox

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Spreadtrum mailbox driver
87 fifo_len = priv->outbox_fifo_depth; in sprd_mbox_get_fifo_len()
91 fifo_len = wr_pos - rd_pos; in sprd_mbox_get_fifo_len()
93 fifo_len = priv->outbox_fifo_depth - rd_pos + wr_pos; in sprd_mbox_get_fifo_len()
106 fifo_sts = readl(priv->outbox_base + SPRD_MBOX_FIFO_STS); in sprd_mbox_outbox_isr()
110 dev_warn_ratelimited(priv->dev, "spurious outbox interrupt\n"); in sprd_mbox_outbox_isr()
115 msg[0] = readl(priv->outbox_base + SPRD_MBOX_MSG_LOW); in sprd_mbox_outbox_isr()
116 msg[1] = readl(priv->outbox_base + SPRD_MBOX_MSG_HIGH); in sprd_mbox_outbox_isr()
117 id = readl(priv->outbox_base + SPRD_MBOX_ID); in sprd_mbox_outbox_isr()
119 chan = &priv->chan[id]; in sprd_mbox_outbox_isr()
120 if (chan->cl) in sprd_mbox_outbox_isr()
123 dev_warn_ratelimited(priv->dev, in sprd_mbox_outbox_isr()
127 writel(0x1, priv->outbox_base + SPRD_MBOX_TRIGGER); in sprd_mbox_outbox_isr()
131 writel(SPRD_MBOX_IRQ_CLR, priv->outbox_base + SPRD_MBOX_IRQ_STS); in sprd_mbox_outbox_isr()
142 fifo_sts = readl(priv->inbox_base + SPRD_MBOX_FIFO_STS); in sprd_mbox_inbox_isr()
148 dev_warn_ratelimited(priv->dev, "spurious inbox interrupt\n"); in sprd_mbox_inbox_isr()
154 send_sts &= (send_sts - 1); in sprd_mbox_inbox_isr()
156 chan = &priv->chan[id]; in sprd_mbox_inbox_isr()
170 priv->inbox_base + SPRD_MBOX_FIFO_RST); in sprd_mbox_inbox_isr()
173 writel(SPRD_MBOX_IRQ_CLR, priv->inbox_base + SPRD_MBOX_IRQ_STS); in sprd_mbox_inbox_isr()
180 struct sprd_mbox_priv *priv = to_sprd_mbox_priv(chan->mbox); in sprd_mbox_send_data()
181 unsigned long id = (unsigned long)chan->con_priv; in sprd_mbox_send_data()
185 writel(data[0], priv->inbox_base + SPRD_MBOX_MSG_LOW); in sprd_mbox_send_data()
186 writel(data[1], priv->inbox_base + SPRD_MBOX_MSG_HIGH); in sprd_mbox_send_data()
189 writel(id, priv->inbox_base + SPRD_MBOX_ID); in sprd_mbox_send_data()
192 writel(0x1, priv->inbox_base + SPRD_MBOX_TRIGGER); in sprd_mbox_send_data()
199 struct sprd_mbox_priv *priv = to_sprd_mbox_priv(chan->mbox); in sprd_mbox_flush()
200 unsigned long id = (unsigned long)chan->con_priv; in sprd_mbox_flush()
206 busy = readl(priv->inbox_base + SPRD_MBOX_FIFO_STS) & in sprd_mbox_flush()
216 return -ETIME; in sprd_mbox_flush()
221 struct sprd_mbox_priv *priv = to_sprd_mbox_priv(chan->mbox); in sprd_mbox_startup()
224 mutex_lock(&priv->lock); in sprd_mbox_startup()
225 if (priv->refcnt++ == 0) { in sprd_mbox_startup()
227 writel(0x0, priv->outbox_base + SPRD_MBOX_FIFO_RST); in sprd_mbox_startup()
230 val = readl(priv->inbox_base + SPRD_MBOX_IRQ_MSK); in sprd_mbox_startup()
232 writel(val, priv->inbox_base + SPRD_MBOX_IRQ_MSK); in sprd_mbox_startup()
235 val = readl(priv->outbox_base + SPRD_MBOX_IRQ_MSK); in sprd_mbox_startup()
237 writel(val, priv->outbox_base + SPRD_MBOX_IRQ_MSK); in sprd_mbox_startup()
239 mutex_unlock(&priv->lock); in sprd_mbox_startup()
246 struct sprd_mbox_priv *priv = to_sprd_mbox_priv(chan->mbox); in sprd_mbox_shutdown()
248 mutex_lock(&priv->lock); in sprd_mbox_shutdown()
249 if (--priv->refcnt == 0) { in sprd_mbox_shutdown()
251 writel(SPRD_INBOX_FIFO_IRQ_MASK, priv->inbox_base + SPRD_MBOX_IRQ_MSK); in sprd_mbox_shutdown()
252 writel(SPRD_OUTBOX_FIFO_IRQ_MASK, priv->outbox_base + SPRD_MBOX_IRQ_MSK); in sprd_mbox_shutdown()
254 mutex_unlock(&priv->lock); in sprd_mbox_shutdown()
268 clk_disable_unprepare(priv->clk); in sprd_mbox_disable()
273 struct device *dev = &pdev->dev; in sprd_mbox_probe()
280 return -ENOMEM; in sprd_mbox_probe()
282 priv->dev = dev; in sprd_mbox_probe()
283 mutex_init(&priv->lock); in sprd_mbox_probe()
286 * The Spreadtrum mailbox uses an inbox to send messages to the target in sprd_mbox_probe()
289 * Thus the mailbox controller supplies 2 different register addresses in sprd_mbox_probe()
292 priv->inbox_base = devm_platform_ioremap_resource(pdev, 0); in sprd_mbox_probe()
293 if (IS_ERR(priv->inbox_base)) in sprd_mbox_probe()
294 return PTR_ERR(priv->inbox_base); in sprd_mbox_probe()
296 priv->outbox_base = devm_platform_ioremap_resource(pdev, 1); in sprd_mbox_probe()
297 if (IS_ERR(priv->outbox_base)) in sprd_mbox_probe()
298 return PTR_ERR(priv->outbox_base); in sprd_mbox_probe()
300 priv->clk = devm_clk_get(dev, "enable"); in sprd_mbox_probe()
301 if (IS_ERR(priv->clk)) { in sprd_mbox_probe()
302 dev_err(dev, "failed to get mailbox clock\n"); in sprd_mbox_probe()
303 return PTR_ERR(priv->clk); in sprd_mbox_probe()
306 ret = clk_prepare_enable(priv->clk); in sprd_mbox_probe()
312 dev_err(dev, "failed to add mailbox disable action\n"); in sprd_mbox_probe()
339 priv->outbox_fifo_depth = in sprd_mbox_probe()
340 readl(priv->outbox_base + SPRD_MBOX_FIFO_DEPTH) + 1; in sprd_mbox_probe()
341 priv->mbox.dev = dev; in sprd_mbox_probe()
342 priv->mbox.chans = &priv->chan[0]; in sprd_mbox_probe()
343 priv->mbox.num_chans = SPRD_MBOX_CHAN_MAX; in sprd_mbox_probe()
344 priv->mbox.ops = &sprd_mbox_ops; in sprd_mbox_probe()
345 priv->mbox.txdone_irq = true; in sprd_mbox_probe()
348 priv->chan[id].con_priv = (void *)id; in sprd_mbox_probe()
350 ret = devm_mbox_controller_register(dev, &priv->mbox); in sprd_mbox_probe()
352 dev_err(dev, "failed to register mailbox: %d\n", ret); in sprd_mbox_probe()
360 { .compatible = "sprd,sc9860-mailbox", },
367 .name = "sprd-mailbox",
375 MODULE_DESCRIPTION("Spreadtrum mailbox driver");