Lines Matching +full:chan +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
102 * @chan: Mailbox channel
107 char name[30]; member
116 struct mbox_chan *chan; member
122 * struct ti_msgmgr_inst - Description of a Message Manager Instance
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()
196 static int ti_msgmgr_queue_rx_data(struct mbox_chan *chan, struct ti_queue_inst *qinst, in ti_msgmgr_queue_rx_data() argument
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()
238 mbox_chan_received_data(chan, (void *)&message); in ti_msgmgr_queue_rx_data()
243 static int ti_msgmgr_queue_rx_poll_timeout(struct mbox_chan *chan, int timeout_us) in ti_msgmgr_queue_rx_poll_timeout() argument
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()
258 ti_msgmgr_queue_rx_data(chan, qinst, desc); 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
274 struct mbox_chan *chan = p; in ti_msgmgr_queue_rx_interrupt() local
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()
307 ti_msgmgr_queue_rx_data(chan, qinst, desc); in ti_msgmgr_queue_rx_interrupt()
313 * ti_msgmgr_queue_peek_data() - Peek to see if there are any rx messages.
314 * @chan: Channel Pointer
318 static bool ti_msgmgr_queue_peek_data(struct mbox_chan *chan) in ti_msgmgr_queue_peek_data() argument
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
341 * @chan: Channel pointer
345 static bool ti_msgmgr_last_tx_done(struct mbox_chan *chan) in ti_msgmgr_last_tx_done() argument
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()
372 static bool ti_msgmgr_chan_has_polled_queue_rx(struct mbox_chan *chan) in ti_msgmgr_chan_has_polled_queue_rx() argument
376 if (!chan) in ti_msgmgr_chan_has_polled_queue_rx()
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
385 * @chan: Channel Pointer
390 static int ti_msgmgr_send_data(struct mbox_chan *chan, void *data) in ti_msgmgr_send_data() argument
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()
439 if (data_reg <= qinst->queue_buff_end) in ti_msgmgr_send_data()
440 writel(0, qinst->queue_buff_end); in ti_msgmgr_send_data()
443 if (ti_msgmgr_chan_has_polled_queue_rx(message->chan_rx)) in ti_msgmgr_send_data()
444 ret = ti_msgmgr_queue_rx_poll_timeout(message->chan_rx, in ti_msgmgr_send_data()
445 message->timeout_rx_ms * 1000); in ti_msgmgr_send_data()
451 * ti_msgmgr_queue_rx_irq_req() - RX IRQ request
455 * @chan: Channel pointer
460 struct mbox_chan *chan) in ti_msgmgr_queue_rx_irq_req() argument
467 "rx_%03d", d->is_sproxy ? qinst->proxy_id : qinst->queue_id); in ti_msgmgr_queue_rx_irq_req()
470 if (qinst->irq < 0) { in ti_msgmgr_queue_rx_irq_req()
471 np = of_node_get(dev->of_node); in ti_msgmgr_queue_rx_irq_req()
473 return -ENODATA; in ti_msgmgr_queue_rx_irq_req()
474 qinst->irq = of_irq_get_byname(np, of_rx_irq_name); in ti_msgmgr_queue_rx_irq_req()
477 if (qinst->irq < 0) { in ti_msgmgr_queue_rx_irq_req()
480 qinst->queue_id, qinst->proxy_id, in ti_msgmgr_queue_rx_irq_req()
481 of_rx_irq_name, qinst->irq); in ti_msgmgr_queue_rx_irq_req()
482 return qinst->irq; in ti_msgmgr_queue_rx_irq_req()
487 ret = request_irq(qinst->irq, ti_msgmgr_queue_rx_interrupt, in ti_msgmgr_queue_rx_irq_req()
488 IRQF_SHARED, qinst->name, chan); in ti_msgmgr_queue_rx_irq_req()
491 qinst->irq, qinst->name, ret); in ti_msgmgr_queue_rx_irq_req()
498 * ti_msgmgr_queue_startup() - Startup queue
499 * @chan: Channel pointer
503 static int ti_msgmgr_queue_startup(struct mbox_chan *chan) in ti_msgmgr_queue_startup() argument
505 struct device *dev = chan->mbox->dev; in ti_msgmgr_queue_startup()
507 struct ti_queue_inst *qinst = chan->con_priv; in ti_msgmgr_queue_startup()
508 const struct ti_msgmgr_desc *d = inst->desc; in ti_msgmgr_queue_startup()
516 if (d->is_sproxy) { in ti_msgmgr_queue_startup()
517 qinst->is_tx = (readl(qinst->queue_ctrl) & in ti_msgmgr_queue_startup()
522 if (!msg_count && qinst->is_tx) { in ti_msgmgr_queue_startup()
524 qinst->name); in ti_msgmgr_queue_startup()
525 return -EINVAL; in ti_msgmgr_queue_startup()
529 if (!qinst->is_tx) { in ti_msgmgr_queue_startup()
531 qinst->rx_buff = kzalloc(d->max_message_size, GFP_KERNEL); in ti_msgmgr_queue_startup()
532 if (!qinst->rx_buff) in ti_msgmgr_queue_startup()
533 return -ENOMEM; in ti_msgmgr_queue_startup()
535 ret = ti_msgmgr_queue_rx_irq_req(dev, d, qinst, chan); in ti_msgmgr_queue_startup()
537 kfree(qinst->rx_buff); in ti_msgmgr_queue_startup()
546 * ti_msgmgr_queue_shutdown() - Shutdown the queue
547 * @chan: Channel pointer
549 static void ti_msgmgr_queue_shutdown(struct mbox_chan *chan) in ti_msgmgr_queue_shutdown() argument
551 struct ti_queue_inst *qinst = chan->con_priv; in ti_msgmgr_queue_shutdown()
553 if (!qinst->is_tx) { in ti_msgmgr_queue_shutdown()
554 free_irq(qinst->irq, chan); in ti_msgmgr_queue_shutdown()
555 kfree(qinst->rx_buff); in ti_msgmgr_queue_shutdown()
560 * ti_msgmgr_of_xlate() - Translation of phandle to queue
578 return ERR_PTR(-EINVAL); in ti_msgmgr_of_xlate()
580 d = inst->desc; in ti_msgmgr_of_xlate()
582 if (d->is_sproxy) in ti_msgmgr_of_xlate()
586 if (p->args_count != ncells) { in ti_msgmgr_of_xlate()
587 dev_err(inst->dev, "Invalid arguments in dt[%d]. Must be %d\n", in ti_msgmgr_of_xlate()
588 p->args_count, ncells); in ti_msgmgr_of_xlate()
589 return ERR_PTR(-EINVAL); in ti_msgmgr_of_xlate()
593 req_pid = p->args[0]; in ti_msgmgr_of_xlate()
595 req_qid = p->args[0]; in ti_msgmgr_of_xlate()
596 req_pid = p->args[1]; in ti_msgmgr_of_xlate()
599 if (d->is_sproxy) { in ti_msgmgr_of_xlate()
600 if (req_pid >= d->num_valid_queues) in ti_msgmgr_of_xlate()
602 qinst = &inst->qinsts[req_pid]; in ti_msgmgr_of_xlate()
603 return qinst->chan; in ti_msgmgr_of_xlate()
606 for (qinst = inst->qinsts, i = 0; i < inst->num_valid_queues; in ti_msgmgr_of_xlate()
608 if (req_qid == qinst->queue_id && req_pid == qinst->proxy_id) in ti_msgmgr_of_xlate()
609 return qinst->chan; in ti_msgmgr_of_xlate()
613 dev_err(inst->dev, "Queue ID %d, Proxy ID %d is wrong on %pOFn\n", in ti_msgmgr_of_xlate()
614 req_qid, req_pid, p->np); in ti_msgmgr_of_xlate()
615 return ERR_PTR(-ENOENT); in ti_msgmgr_of_xlate()
619 * ti_msgmgr_queue_setup() - Setup data structures for each queue instance
627 * @chan: pointer to mailbox channel
637 struct mbox_chan *chan) in ti_msgmgr_queue_setup() argument
641 qinst->proxy_id = qd->proxy_id; in ti_msgmgr_queue_setup()
642 qinst->queue_id = qd->queue_id; in ti_msgmgr_queue_setup()
644 if (qinst->queue_id > d->queue_count) { in ti_msgmgr_queue_setup()
646 idx, qinst->queue_id, d->queue_count); in ti_msgmgr_queue_setup()
647 return -ERANGE; in ti_msgmgr_queue_setup()
650 if (d->is_sproxy) { in ti_msgmgr_queue_setup()
651 qinst->queue_buff_start = inst->queue_proxy_region + in ti_msgmgr_queue_setup()
652 SPROXY_THREAD_DATA_OFFSET(qinst->proxy_id, in ti_msgmgr_queue_setup()
653 d->data_first_reg); in ti_msgmgr_queue_setup()
654 qinst->queue_buff_end = inst->queue_proxy_region + in ti_msgmgr_queue_setup()
655 SPROXY_THREAD_DATA_OFFSET(qinst->proxy_id, in ti_msgmgr_queue_setup()
656 d->data_last_reg); in ti_msgmgr_queue_setup()
657 qinst->queue_state = inst->queue_state_debug_region + in ti_msgmgr_queue_setup()
658 SPROXY_THREAD_STATUS_OFFSET(qinst->proxy_id); in ti_msgmgr_queue_setup()
659 qinst->queue_ctrl = inst->queue_ctrl_region + in ti_msgmgr_queue_setup()
660 SPROXY_THREAD_CTRL_OFFSET(qinst->proxy_id); in ti_msgmgr_queue_setup()
664 snprintf(qinst->name, sizeof(qinst->name), "%s %s_%03d", in ti_msgmgr_queue_setup()
665 dev_name(dev), dir, qinst->proxy_id); in ti_msgmgr_queue_setup()
667 qinst->queue_buff_start = inst->queue_proxy_region + in ti_msgmgr_queue_setup()
668 Q_DATA_OFFSET(qinst->proxy_id, qinst->queue_id, in ti_msgmgr_queue_setup()
669 d->data_first_reg); in ti_msgmgr_queue_setup()
670 qinst->queue_buff_end = inst->queue_proxy_region + in ti_msgmgr_queue_setup()
671 Q_DATA_OFFSET(qinst->proxy_id, qinst->queue_id, in ti_msgmgr_queue_setup()
672 d->data_last_reg); in ti_msgmgr_queue_setup()
673 qinst->queue_state = in ti_msgmgr_queue_setup()
674 inst->queue_state_debug_region + in ti_msgmgr_queue_setup()
675 Q_STATE_OFFSET(qinst->queue_id); in ti_msgmgr_queue_setup()
676 qinst->is_tx = qd->is_tx; in ti_msgmgr_queue_setup()
677 dir = qinst->is_tx ? "tx" : "rx"; in ti_msgmgr_queue_setup()
678 snprintf(qinst->name, sizeof(qinst->name), "%s %s_%03d_%03d", in ti_msgmgr_queue_setup()
679 dev_name(dev), dir, qinst->queue_id, qinst->proxy_id); in ti_msgmgr_queue_setup()
682 qinst->chan = chan; in ti_msgmgr_queue_setup()
684 /* Setup an error value for IRQ - Lazy allocation */ in ti_msgmgr_queue_setup()
685 qinst->irq = -EINVAL; in ti_msgmgr_queue_setup()
687 chan->con_priv = qinst; in ti_msgmgr_queue_setup()
690 idx, qinst->queue_id, qinst->proxy_id, qinst->irq, in ti_msgmgr_queue_setup()
691 qinst->queue_buff_start, qinst->queue_buff_end); in ti_msgmgr_queue_setup()
698 disable_irq(qinst->irq); in ti_msgmgr_queue_rx_set_polled_mode()
699 qinst->polled_rx_mode = true; in ti_msgmgr_queue_rx_set_polled_mode()
701 enable_irq(qinst->irq); in ti_msgmgr_queue_rx_set_polled_mode()
702 qinst->polled_rx_mode = false; in ti_msgmgr_queue_rx_set_polled_mode()
719 for (qinst = inst->qinsts, i = 0; i < inst->num_valid_queues; qinst++, i++) { in ti_msgmgr_suspend()
720 if (!qinst->is_tx) in ti_msgmgr_suspend()
733 for (qinst = inst->qinsts, i = 0; i < inst->num_valid_queues; qinst++, i++) { in ti_msgmgr_resume()
734 if (!qinst->is_tx) in ti_msgmgr_resume()
797 {.compatible = "ti,k2g-message-manager", .data = &k2g_desc},
798 {.compatible = "ti,am654-secure-proxy", .data = &am654_desc},
806 struct device *dev = &pdev->dev; in ti_msgmgr_probe()
817 int ret = -EINVAL; in ti_msgmgr_probe()
820 if (!dev->of_node) { in ti_msgmgr_probe()
822 return -EINVAL; in ti_msgmgr_probe()
824 np = dev->of_node; in ti_msgmgr_probe()
829 return -EINVAL; in ti_msgmgr_probe()
831 desc = of_id->data; in ti_msgmgr_probe()
835 return -ENOMEM; in ti_msgmgr_probe()
837 inst->dev = dev; in ti_msgmgr_probe()
838 inst->desc = desc; in ti_msgmgr_probe()
841 desc->data_region_name); in ti_msgmgr_probe()
842 inst->queue_proxy_region = devm_ioremap_resource(dev, res); in ti_msgmgr_probe()
843 if (IS_ERR(inst->queue_proxy_region)) in ti_msgmgr_probe()
844 return PTR_ERR(inst->queue_proxy_region); in ti_msgmgr_probe()
847 desc->status_region_name); in ti_msgmgr_probe()
848 inst->queue_state_debug_region = devm_ioremap_resource(dev, res); in ti_msgmgr_probe()
849 if (IS_ERR(inst->queue_state_debug_region)) in ti_msgmgr_probe()
850 return PTR_ERR(inst->queue_state_debug_region); in ti_msgmgr_probe()
852 if (desc->is_sproxy) { in ti_msgmgr_probe()
854 desc->ctrl_region_name); in ti_msgmgr_probe()
855 inst->queue_ctrl_region = devm_ioremap_resource(dev, res); in ti_msgmgr_probe()
856 if (IS_ERR(inst->queue_ctrl_region)) in ti_msgmgr_probe()
857 return PTR_ERR(inst->queue_ctrl_region); in ti_msgmgr_probe()
861 inst->queue_proxy_region, inst->queue_state_debug_region); in ti_msgmgr_probe()
863 queue_count = desc->num_valid_queues; in ti_msgmgr_probe()
864 if (!queue_count || queue_count > desc->queue_count) { in ti_msgmgr_probe()
866 queue_count, desc->queue_count); in ti_msgmgr_probe()
867 return -ERANGE; in ti_msgmgr_probe()
869 inst->num_valid_queues = queue_count; in ti_msgmgr_probe()
873 return -ENOMEM; in ti_msgmgr_probe()
874 inst->qinsts = qinst; in ti_msgmgr_probe()
878 return -ENOMEM; in ti_msgmgr_probe()
879 inst->chans = chans; in ti_msgmgr_probe()
881 if (desc->is_sproxy) { in ti_msgmgr_probe()
896 for (i = 0, queue_desc = desc->valid_queues; in ti_msgmgr_probe()
906 mbox = &inst->mbox; in ti_msgmgr_probe()
907 mbox->dev = dev; in ti_msgmgr_probe()
908 mbox->ops = &ti_msgmgr_chan_ops; in ti_msgmgr_probe()
909 mbox->chans = inst->chans; in ti_msgmgr_probe()
910 mbox->num_chans = inst->num_valid_queues; in ti_msgmgr_probe()
911 mbox->txdone_irq = false; in ti_msgmgr_probe()
912 mbox->txdone_poll = desc->tx_polled; in ti_msgmgr_probe()
913 if (desc->tx_polled) in ti_msgmgr_probe()
914 mbox->txpoll_period = desc->tx_poll_timeout_ms; in ti_msgmgr_probe()
915 mbox->of_xlate = ti_msgmgr_of_xlate; in ti_msgmgr_probe()
928 .name = "ti-msgmgr",
938 MODULE_ALIAS("platform:ti-msgmgr");