Lines Matching +full:mbox +full:- +full:name
1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2015-2022 Texas Instruments Incorporated - https://www.ti.com/
22 #include <linux/soc/ti/ti-msgmgr.h>
41 * struct ti_msgmgr_valid_queue_desc - SoC valid queues meant for this processor
53 * struct ti_msgmgr_desc - Description of message manager integration
64 * @data_region_name: Name of the proxy data region
65 * @status_region_name: Name of the proxy status region
66 * @ctrl_region_name: Name of the proxy control region
92 * struct ti_queue_inst - Description of a queue instance
93 * @name: Queue Name
107 char name[30]; member
122 * struct ti_msgmgr_inst - Description of a Message Manager Instance
132 * @mbox: Mailbox Controller
143 struct mbox_controller mbox; member
148 * ti_msgmgr_queue_get_num_messages() - Get the number of pending messages
159 u32 status_cnt_mask = d->status_cnt_mask; in ti_msgmgr_queue_get_num_messages()
162 * We cannot use relaxed operation here - update may happen in ti_msgmgr_queue_get_num_messages()
163 * real-time. in ti_msgmgr_queue_get_num_messages()
165 val = readl(qinst->queue_state) & status_cnt_mask; in ti_msgmgr_queue_get_num_messages()
172 * ti_msgmgr_queue_is_error() - Check to see if there is queue error
184 if (!d->is_sproxy) in ti_msgmgr_queue_is_error()
188 * We cannot use relaxed operation here - update may happen in ti_msgmgr_queue_is_error()
189 * real-time. in ti_msgmgr_queue_is_error()
191 val = readl(qinst->queue_state) & d->status_err_mask; in ti_msgmgr_queue_is_error()
206 * remote producer - 0 could be valid data, so I wont make a judgement in ti_msgmgr_queue_rx_data()
210 message.len = desc->max_message_size; in ti_msgmgr_queue_rx_data()
211 message.buf = (u8 *)qinst->rx_buff; in ti_msgmgr_queue_rx_data()
217 * with sub 32bit access - For example: if the last register read is in ti_msgmgr_queue_rx_data()
227 for (data_reg = qinst->queue_buff_start, word_data = qinst->rx_buff, in ti_msgmgr_queue_rx_data()
228 num_words = (desc->max_message_size / sizeof(u32)); in ti_msgmgr_queue_rx_data()
229 num_words; num_words--, data_reg += sizeof(u32), word_data++) in ti_msgmgr_queue_rx_data()
234 * is pending - so send the data up the stack.. in ti_msgmgr_queue_rx_data()
245 struct device *dev = chan->mbox->dev; in ti_msgmgr_queue_rx_poll_timeout()
247 struct ti_queue_inst *qinst = chan->con_priv; in ti_msgmgr_queue_rx_poll_timeout()
248 const struct ti_msgmgr_desc *desc = inst->desc; in ti_msgmgr_queue_rx_poll_timeout()
252 ret = readl_poll_timeout_atomic(qinst->queue_state, msg_count, in ti_msgmgr_queue_rx_poll_timeout()
253 (msg_count & desc->status_cnt_mask), in ti_msgmgr_queue_rx_poll_timeout()
264 * ti_msgmgr_queue_rx_interrupt() - Interrupt handler for receive Queue
268 * Return: -EINVAL if there is no instance
275 struct device *dev = chan->mbox->dev; in ti_msgmgr_queue_rx_interrupt()
277 struct ti_queue_inst *qinst = chan->con_priv; in ti_msgmgr_queue_rx_interrupt()
283 return -EINVAL; in ti_msgmgr_queue_rx_interrupt()
287 if (qinst->is_tx) { in ti_msgmgr_queue_rx_interrupt()
289 qinst->name); in ti_msgmgr_queue_rx_interrupt()
293 desc = inst->desc; in ti_msgmgr_queue_rx_interrupt()
295 dev_err(dev, "Error on Rx channel %s\n", qinst->name); in ti_msgmgr_queue_rx_interrupt()
303 dev_dbg(dev, "Spurious event - 0 pending data!\n"); in ti_msgmgr_queue_rx_interrupt()
313 * ti_msgmgr_queue_peek_data() - Peek to see if there are any rx messages.
320 struct ti_queue_inst *qinst = chan->con_priv; in ti_msgmgr_queue_peek_data()
321 struct device *dev = chan->mbox->dev; in ti_msgmgr_queue_peek_data()
323 const struct ti_msgmgr_desc *desc = inst->desc; in ti_msgmgr_queue_peek_data()
326 if (qinst->is_tx) in ti_msgmgr_queue_peek_data()
330 dev_err(dev, "Error on channel %s\n", qinst->name); in ti_msgmgr_queue_peek_data()
340 * ti_msgmgr_last_tx_done() - See if all the tx messages are sent
347 struct ti_queue_inst *qinst = chan->con_priv; in ti_msgmgr_last_tx_done()
348 struct device *dev = chan->mbox->dev; in ti_msgmgr_last_tx_done()
350 const struct ti_msgmgr_desc *desc = inst->desc; in ti_msgmgr_last_tx_done()
353 if (!qinst->is_tx) in ti_msgmgr_last_tx_done()
357 dev_err(dev, "Error on channel %s\n", qinst->name); in ti_msgmgr_last_tx_done()
363 if (desc->is_sproxy) { in ti_msgmgr_last_tx_done()
379 qinst = chan->con_priv; in ti_msgmgr_chan_has_polled_queue_rx()
380 return qinst->polled_rx_mode; in ti_msgmgr_chan_has_polled_queue_rx()
384 * ti_msgmgr_send_data() - Send data
392 struct device *dev = chan->mbox->dev; in ti_msgmgr_send_data()
395 struct ti_queue_inst *qinst = chan->con_priv; in ti_msgmgr_send_data()
404 return -EINVAL; in ti_msgmgr_send_data()
406 desc = inst->desc; in ti_msgmgr_send_data()
409 dev_err(dev, "Error on channel %s\n", qinst->name); in ti_msgmgr_send_data()
413 if (desc->max_message_size < message->len) { in ti_msgmgr_send_data()
415 qinst->name, message->len, desc->max_message_size); in ti_msgmgr_send_data()
416 return -EINVAL; in ti_msgmgr_send_data()
420 for (data_reg = qinst->queue_buff_start, in ti_msgmgr_send_data()
421 num_words = message->len / sizeof(u32), in ti_msgmgr_send_data()
422 word_data = (u32 *)message->buf; in ti_msgmgr_send_data()
423 num_words; num_words--, data_reg += sizeof(u32), word_data++) in ti_msgmgr_send_data()
426 trail_bytes = message->len % sizeof(u32); in ti_msgmgr_send_data()
431 data_trail &= 0xFFFFFFFF >> (8 * (sizeof(u32) - trail_bytes)); in ti_msgmgr_send_data()
443 while (data_reg <= qinst->queue_buff_end) { in ti_msgmgr_send_data()
449 if (ti_msgmgr_chan_has_polled_queue_rx(message->chan_rx)) in ti_msgmgr_send_data()
450 ret = ti_msgmgr_queue_rx_poll_timeout(message->chan_rx, in ti_msgmgr_send_data()
451 message->timeout_rx_ms * 1000); in ti_msgmgr_send_data()
457 * ti_msgmgr_queue_rx_irq_req() - RX IRQ request
473 "rx_%03d", d->is_sproxy ? qinst->proxy_id : qinst->queue_id); in ti_msgmgr_queue_rx_irq_req()
476 if (qinst->irq < 0) { in ti_msgmgr_queue_rx_irq_req()
477 np = of_node_get(dev->of_node); in ti_msgmgr_queue_rx_irq_req()
479 return -ENODATA; in ti_msgmgr_queue_rx_irq_req()
480 qinst->irq = of_irq_get_byname(np, of_rx_irq_name); in ti_msgmgr_queue_rx_irq_req()
483 if (qinst->irq < 0) { in ti_msgmgr_queue_rx_irq_req()
486 qinst->queue_id, qinst->proxy_id, in ti_msgmgr_queue_rx_irq_req()
487 of_rx_irq_name, qinst->irq); in ti_msgmgr_queue_rx_irq_req()
488 return qinst->irq; in ti_msgmgr_queue_rx_irq_req()
493 ret = request_irq(qinst->irq, ti_msgmgr_queue_rx_interrupt, in ti_msgmgr_queue_rx_irq_req()
494 IRQF_SHARED, qinst->name, chan); in ti_msgmgr_queue_rx_irq_req()
497 qinst->irq, qinst->name, ret); in ti_msgmgr_queue_rx_irq_req()
504 * ti_msgmgr_queue_startup() - Startup queue
511 struct device *dev = chan->mbox->dev; in ti_msgmgr_queue_startup()
513 struct ti_queue_inst *qinst = chan->con_priv; in ti_msgmgr_queue_startup()
514 const struct ti_msgmgr_desc *d = inst->desc; in ti_msgmgr_queue_startup()
522 if (d->is_sproxy) { in ti_msgmgr_queue_startup()
523 qinst->is_tx = (readl(qinst->queue_ctrl) & in ti_msgmgr_queue_startup()
528 if (!msg_count && qinst->is_tx) { in ti_msgmgr_queue_startup()
530 qinst->name); in ti_msgmgr_queue_startup()
531 return -EINVAL; in ti_msgmgr_queue_startup()
535 if (!qinst->is_tx) { in ti_msgmgr_queue_startup()
537 qinst->rx_buff = kzalloc(d->max_message_size, GFP_KERNEL); in ti_msgmgr_queue_startup()
538 if (!qinst->rx_buff) in ti_msgmgr_queue_startup()
539 return -ENOMEM; in ti_msgmgr_queue_startup()
543 kfree(qinst->rx_buff); in ti_msgmgr_queue_startup()
552 * ti_msgmgr_queue_shutdown() - Shutdown the queue
557 struct ti_queue_inst *qinst = chan->con_priv; in ti_msgmgr_queue_shutdown()
559 if (!qinst->is_tx) { in ti_msgmgr_queue_shutdown()
560 free_irq(qinst->irq, chan); in ti_msgmgr_queue_shutdown()
561 kfree(qinst->rx_buff); in ti_msgmgr_queue_shutdown()
566 * ti_msgmgr_of_xlate() - Translation of phandle to queue
567 * @mbox: Mailbox controller
573 static struct mbox_chan *ti_msgmgr_of_xlate(struct mbox_controller *mbox, in ti_msgmgr_of_xlate() argument
582 inst = container_of(mbox, struct ti_msgmgr_inst, mbox); in ti_msgmgr_of_xlate()
584 return ERR_PTR(-EINVAL); in ti_msgmgr_of_xlate()
586 d = inst->desc; in ti_msgmgr_of_xlate()
588 if (d->is_sproxy) in ti_msgmgr_of_xlate()
592 if (p->args_count != ncells) { in ti_msgmgr_of_xlate()
593 dev_err(inst->dev, "Invalid arguments in dt[%d]. Must be %d\n", in ti_msgmgr_of_xlate()
594 p->args_count, ncells); in ti_msgmgr_of_xlate()
595 return ERR_PTR(-EINVAL); in ti_msgmgr_of_xlate()
599 req_pid = p->args[0]; in ti_msgmgr_of_xlate()
601 req_qid = p->args[0]; in ti_msgmgr_of_xlate()
602 req_pid = p->args[1]; in ti_msgmgr_of_xlate()
605 if (d->is_sproxy) { in ti_msgmgr_of_xlate()
606 if (req_pid >= d->num_valid_queues) in ti_msgmgr_of_xlate()
608 qinst = &inst->qinsts[req_pid]; in ti_msgmgr_of_xlate()
609 return qinst->chan; in ti_msgmgr_of_xlate()
612 for (qinst = inst->qinsts, i = 0; i < inst->num_valid_queues; in ti_msgmgr_of_xlate()
614 if (req_qid == qinst->queue_id && req_pid == qinst->proxy_id) in ti_msgmgr_of_xlate()
615 return qinst->chan; in ti_msgmgr_of_xlate()
619 dev_err(inst->dev, "Queue ID %d, Proxy ID %d is wrong on %pOFn\n", in ti_msgmgr_of_xlate()
620 req_qid, req_pid, p->np); in ti_msgmgr_of_xlate()
621 return ERR_PTR(-ENOENT); in ti_msgmgr_of_xlate()
625 * ti_msgmgr_queue_setup() - Setup data structures for each queue instance
647 qinst->proxy_id = qd->proxy_id; in ti_msgmgr_queue_setup()
648 qinst->queue_id = qd->queue_id; in ti_msgmgr_queue_setup()
650 if (qinst->queue_id > d->queue_count) { in ti_msgmgr_queue_setup()
652 idx, qinst->queue_id, d->queue_count); in ti_msgmgr_queue_setup()
653 return -ERANGE; in ti_msgmgr_queue_setup()
656 if (d->is_sproxy) { in ti_msgmgr_queue_setup()
657 qinst->queue_buff_start = inst->queue_proxy_region + in ti_msgmgr_queue_setup()
658 SPROXY_THREAD_DATA_OFFSET(qinst->proxy_id, in ti_msgmgr_queue_setup()
659 d->data_first_reg); in ti_msgmgr_queue_setup()
660 qinst->queue_buff_end = inst->queue_proxy_region + in ti_msgmgr_queue_setup()
661 SPROXY_THREAD_DATA_OFFSET(qinst->proxy_id, in ti_msgmgr_queue_setup()
662 d->data_last_reg); in ti_msgmgr_queue_setup()
663 qinst->queue_state = inst->queue_state_debug_region + in ti_msgmgr_queue_setup()
664 SPROXY_THREAD_STATUS_OFFSET(qinst->proxy_id); in ti_msgmgr_queue_setup()
665 qinst->queue_ctrl = inst->queue_ctrl_region + in ti_msgmgr_queue_setup()
666 SPROXY_THREAD_CTRL_OFFSET(qinst->proxy_id); in ti_msgmgr_queue_setup()
670 snprintf(qinst->name, sizeof(qinst->name), "%s %s_%03d", in ti_msgmgr_queue_setup()
671 dev_name(dev), dir, qinst->proxy_id); in ti_msgmgr_queue_setup()
673 qinst->queue_buff_start = inst->queue_proxy_region + in ti_msgmgr_queue_setup()
674 Q_DATA_OFFSET(qinst->proxy_id, qinst->queue_id, in ti_msgmgr_queue_setup()
675 d->data_first_reg); in ti_msgmgr_queue_setup()
676 qinst->queue_buff_end = inst->queue_proxy_region + in ti_msgmgr_queue_setup()
677 Q_DATA_OFFSET(qinst->proxy_id, qinst->queue_id, in ti_msgmgr_queue_setup()
678 d->data_last_reg); in ti_msgmgr_queue_setup()
679 qinst->queue_state = in ti_msgmgr_queue_setup()
680 inst->queue_state_debug_region + in ti_msgmgr_queue_setup()
681 Q_STATE_OFFSET(qinst->queue_id); in ti_msgmgr_queue_setup()
682 qinst->is_tx = qd->is_tx; in ti_msgmgr_queue_setup()
683 dir = qinst->is_tx ? "tx" : "rx"; in ti_msgmgr_queue_setup()
684 snprintf(qinst->name, sizeof(qinst->name), "%s %s_%03d_%03d", in ti_msgmgr_queue_setup()
685 dev_name(dev), dir, qinst->queue_id, qinst->proxy_id); in ti_msgmgr_queue_setup()
688 qinst->chan = chan; in ti_msgmgr_queue_setup()
690 /* Setup an error value for IRQ - Lazy allocation */ in ti_msgmgr_queue_setup()
691 qinst->irq = -EINVAL; in ti_msgmgr_queue_setup()
693 chan->con_priv = qinst; in ti_msgmgr_queue_setup()
696 idx, qinst->queue_id, qinst->proxy_id, qinst->irq, in ti_msgmgr_queue_setup()
697 qinst->queue_buff_start, qinst->queue_buff_end); in ti_msgmgr_queue_setup()
704 disable_irq(qinst->irq); in ti_msgmgr_queue_rx_set_polled_mode()
705 qinst->polled_rx_mode = true; in ti_msgmgr_queue_rx_set_polled_mode()
707 enable_irq(qinst->irq); in ti_msgmgr_queue_rx_set_polled_mode()
708 qinst->polled_rx_mode = false; in ti_msgmgr_queue_rx_set_polled_mode()
725 for (qinst = inst->qinsts, i = 0; i < inst->num_valid_queues; qinst++, i++) { in ti_msgmgr_suspend()
726 if (!qinst->is_tx) in ti_msgmgr_suspend()
739 for (qinst = inst->qinsts, i = 0; i < inst->num_valid_queues; qinst++, i++) { in ti_msgmgr_resume()
740 if (!qinst->is_tx) in ti_msgmgr_resume()
803 {.compatible = "ti,k2g-message-manager", .data = &k2g_desc},
804 {.compatible = "ti,am654-secure-proxy", .data = &am654_desc},
812 struct device *dev = &pdev->dev; in ti_msgmgr_probe()
817 struct mbox_controller *mbox; in ti_msgmgr_probe() local
821 int ret = -EINVAL; in ti_msgmgr_probe()
824 if (!dev->of_node) { in ti_msgmgr_probe()
826 return -EINVAL; in ti_msgmgr_probe()
828 np = dev->of_node; in ti_msgmgr_probe()
832 return -ENOMEM; in ti_msgmgr_probe()
834 inst->dev = dev; in ti_msgmgr_probe()
835 inst->desc = desc = device_get_match_data(dev); in ti_msgmgr_probe()
837 inst->queue_proxy_region = in ti_msgmgr_probe()
838 devm_platform_ioremap_resource_byname(pdev, desc->data_region_name); in ti_msgmgr_probe()
839 if (IS_ERR(inst->queue_proxy_region)) in ti_msgmgr_probe()
840 return PTR_ERR(inst->queue_proxy_region); in ti_msgmgr_probe()
842 inst->queue_state_debug_region = in ti_msgmgr_probe()
843 devm_platform_ioremap_resource_byname(pdev, desc->status_region_name); in ti_msgmgr_probe()
844 if (IS_ERR(inst->queue_state_debug_region)) in ti_msgmgr_probe()
845 return PTR_ERR(inst->queue_state_debug_region); in ti_msgmgr_probe()
847 if (desc->is_sproxy) { in ti_msgmgr_probe()
848 inst->queue_ctrl_region = in ti_msgmgr_probe()
849 devm_platform_ioremap_resource_byname(pdev, desc->ctrl_region_name); in ti_msgmgr_probe()
850 if (IS_ERR(inst->queue_ctrl_region)) in ti_msgmgr_probe()
851 return PTR_ERR(inst->queue_ctrl_region); in ti_msgmgr_probe()
855 inst->queue_proxy_region, inst->queue_state_debug_region); in ti_msgmgr_probe()
857 queue_count = desc->num_valid_queues; in ti_msgmgr_probe()
858 if (!queue_count || queue_count > desc->queue_count) { in ti_msgmgr_probe()
860 queue_count, desc->queue_count); in ti_msgmgr_probe()
861 return -ERANGE; in ti_msgmgr_probe()
863 inst->num_valid_queues = queue_count; in ti_msgmgr_probe()
867 return -ENOMEM; in ti_msgmgr_probe()
868 inst->qinsts = qinst; in ti_msgmgr_probe()
872 return -ENOMEM; in ti_msgmgr_probe()
873 inst->chans = chans; in ti_msgmgr_probe()
875 if (desc->is_sproxy) { in ti_msgmgr_probe()
890 for (i = 0, queue_desc = desc->valid_queues; in ti_msgmgr_probe()
900 mbox = &inst->mbox; in ti_msgmgr_probe()
901 mbox->dev = dev; in ti_msgmgr_probe()
902 mbox->ops = &ti_msgmgr_chan_ops; in ti_msgmgr_probe()
903 mbox->chans = inst->chans; in ti_msgmgr_probe()
904 mbox->num_chans = inst->num_valid_queues; in ti_msgmgr_probe()
905 mbox->txdone_irq = false; in ti_msgmgr_probe()
906 mbox->txdone_poll = desc->tx_polled; in ti_msgmgr_probe()
907 if (desc->tx_polled) in ti_msgmgr_probe()
908 mbox->txpoll_period = desc->tx_poll_timeout_ms; in ti_msgmgr_probe()
909 mbox->of_xlate = ti_msgmgr_of_xlate; in ti_msgmgr_probe()
912 ret = devm_mbox_controller_register(dev, mbox); in ti_msgmgr_probe()
922 .name = "ti-msgmgr",
932 MODULE_ALIAS("platform:ti-msgmgr");