• Home
  • Raw
  • Download

Lines Matching +full:am654 +full:- +full:secure +full:- +full:proxy

1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2015-2017 Texas Instruments Incorporated - https://www.ti.com/
21 #include <linux/soc/ti/ti-msgmgr.h>
23 #define Q_DATA_OFFSET(proxy, queue, reg) \ argument
24 ((0x10000 * (proxy)) + (0x80 * (queue)) + ((reg) * 4))
40 * struct ti_msgmgr_valid_queue_desc - SoC valid queues meant for this processor
42 * @proxy_id: Proxy ID representing the processor in SoC
52 * struct ti_msgmgr_desc - Description of message manager integration
56 * @data_first_reg: First data register for proxy data region
57 * @data_last_reg: Last data register for proxy data region
63 * @data_region_name: Name of the proxy data region
64 * @status_region_name: Name of the proxy status region
65 * @ctrl_region_name: Name of the proxy control region
67 * @is_sproxy: Is this an Secure Proxy instance?
91 * struct ti_queue_inst - Description of a queue instance
94 * @proxy_id: Proxy Identifier as mapped on SoC
119 * struct ti_msgmgr_inst - Description of a Message Manager Instance
122 * @queue_proxy_region: Queue proxy region where queue buffers are located
145 * ti_msgmgr_queue_get_num_messages() - Get the number of pending messages
156 u32 status_cnt_mask = d->status_cnt_mask; in ti_msgmgr_queue_get_num_messages()
159 * We cannot use relaxed operation here - update may happen in ti_msgmgr_queue_get_num_messages()
160 * real-time. in ti_msgmgr_queue_get_num_messages()
162 val = readl(qinst->queue_state) & status_cnt_mask; in ti_msgmgr_queue_get_num_messages()
169 * ti_msgmgr_queue_is_error() - Check to see if there is queue error
181 if (!d->is_sproxy) in ti_msgmgr_queue_is_error()
185 * We cannot use relaxed operation here - update may happen in ti_msgmgr_queue_is_error()
186 * real-time. in ti_msgmgr_queue_is_error()
188 val = readl(qinst->queue_state) & d->status_err_mask; in ti_msgmgr_queue_is_error()
194 * ti_msgmgr_queue_rx_interrupt() - Interrupt handler for receive Queue
198 * Return: -EINVAL if there is no instance
205 struct device *dev = chan->mbox->dev; in ti_msgmgr_queue_rx_interrupt()
207 struct ti_queue_inst *qinst = chan->con_priv; in ti_msgmgr_queue_rx_interrupt()
216 return -EINVAL; in ti_msgmgr_queue_rx_interrupt()
220 if (qinst->is_tx) { in ti_msgmgr_queue_rx_interrupt()
222 qinst->name); in ti_msgmgr_queue_rx_interrupt()
226 desc = inst->desc; in ti_msgmgr_queue_rx_interrupt()
228 dev_err(dev, "Error on Rx channel %s\n", qinst->name); in ti_msgmgr_queue_rx_interrupt()
236 dev_dbg(dev, "Spurious event - 0 pending data!\n"); in ti_msgmgr_queue_rx_interrupt()
242 * remote producer - 0 could be valid data, so I wont make a judgement in ti_msgmgr_queue_rx_interrupt()
246 message.len = desc->max_message_size; in ti_msgmgr_queue_rx_interrupt()
247 message.buf = (u8 *)qinst->rx_buff; in ti_msgmgr_queue_rx_interrupt()
253 * with sub 32bit access - For example: if the last register read is in ti_msgmgr_queue_rx_interrupt()
263 for (data_reg = qinst->queue_buff_start, word_data = qinst->rx_buff, in ti_msgmgr_queue_rx_interrupt()
264 num_words = (desc->max_message_size / sizeof(u32)); in ti_msgmgr_queue_rx_interrupt()
265 num_words; num_words--, data_reg += sizeof(u32), word_data++) in ti_msgmgr_queue_rx_interrupt()
270 * is pending - so send the data up the stack.. in ti_msgmgr_queue_rx_interrupt()
280 * ti_msgmgr_queue_peek_data() - Peek to see if there are any rx messages.
287 struct ti_queue_inst *qinst = chan->con_priv; in ti_msgmgr_queue_peek_data()
288 struct device *dev = chan->mbox->dev; in ti_msgmgr_queue_peek_data()
290 const struct ti_msgmgr_desc *desc = inst->desc; in ti_msgmgr_queue_peek_data()
293 if (qinst->is_tx) in ti_msgmgr_queue_peek_data()
297 dev_err(dev, "Error on channel %s\n", qinst->name); in ti_msgmgr_queue_peek_data()
307 * ti_msgmgr_last_tx_done() - See if all the tx messages are sent
314 struct ti_queue_inst *qinst = chan->con_priv; in ti_msgmgr_last_tx_done()
315 struct device *dev = chan->mbox->dev; in ti_msgmgr_last_tx_done()
317 const struct ti_msgmgr_desc *desc = inst->desc; in ti_msgmgr_last_tx_done()
320 if (!qinst->is_tx) in ti_msgmgr_last_tx_done()
324 dev_err(dev, "Error on channel %s\n", qinst->name); in ti_msgmgr_last_tx_done()
330 if (desc->is_sproxy) { in ti_msgmgr_last_tx_done()
331 /* In secure proxy, msg_count indicates how many we can send */ in ti_msgmgr_last_tx_done()
340 * ti_msgmgr_send_data() - Send data
348 struct device *dev = chan->mbox->dev; in ti_msgmgr_send_data()
351 struct ti_queue_inst *qinst = chan->con_priv; in ti_msgmgr_send_data()
359 return -EINVAL; in ti_msgmgr_send_data()
361 desc = inst->desc; in ti_msgmgr_send_data()
364 dev_err(dev, "Error on channel %s\n", qinst->name); in ti_msgmgr_send_data()
368 if (desc->max_message_size < message->len) { in ti_msgmgr_send_data()
370 qinst->name, message->len, desc->max_message_size); in ti_msgmgr_send_data()
371 return -EINVAL; in ti_msgmgr_send_data()
375 for (data_reg = qinst->queue_buff_start, in ti_msgmgr_send_data()
376 num_words = message->len / sizeof(u32), in ti_msgmgr_send_data()
377 word_data = (u32 *)message->buf; in ti_msgmgr_send_data()
378 num_words; num_words--, data_reg += sizeof(u32), word_data++) in ti_msgmgr_send_data()
381 trail_bytes = message->len % sizeof(u32); in ti_msgmgr_send_data()
386 data_trail &= 0xFFFFFFFF >> (8 * (sizeof(u32) - trail_bytes)); in ti_msgmgr_send_data()
398 while (data_reg <= qinst->queue_buff_end) { in ti_msgmgr_send_data()
407 * ti_msgmgr_queue_rx_irq_req() - RX IRQ request
423 "rx_%03d", d->is_sproxy ? qinst->proxy_id : qinst->queue_id); in ti_msgmgr_queue_rx_irq_req()
426 if (qinst->irq < 0) { in ti_msgmgr_queue_rx_irq_req()
427 np = of_node_get(dev->of_node); in ti_msgmgr_queue_rx_irq_req()
429 return -ENODATA; in ti_msgmgr_queue_rx_irq_req()
430 qinst->irq = of_irq_get_byname(np, of_rx_irq_name); in ti_msgmgr_queue_rx_irq_req()
433 if (qinst->irq < 0) { in ti_msgmgr_queue_rx_irq_req()
436 qinst->queue_id, qinst->proxy_id, in ti_msgmgr_queue_rx_irq_req()
437 of_rx_irq_name, qinst->irq); in ti_msgmgr_queue_rx_irq_req()
438 return qinst->irq; in ti_msgmgr_queue_rx_irq_req()
443 ret = request_irq(qinst->irq, ti_msgmgr_queue_rx_interrupt, in ti_msgmgr_queue_rx_irq_req()
444 IRQF_SHARED, qinst->name, chan); in ti_msgmgr_queue_rx_irq_req()
447 qinst->irq, qinst->name, ret); in ti_msgmgr_queue_rx_irq_req()
454 * ti_msgmgr_queue_startup() - Startup queue
461 struct device *dev = chan->mbox->dev; in ti_msgmgr_queue_startup()
463 struct ti_queue_inst *qinst = chan->con_priv; in ti_msgmgr_queue_startup()
464 const struct ti_msgmgr_desc *d = inst->desc; in ti_msgmgr_queue_startup()
472 if (d->is_sproxy) { in ti_msgmgr_queue_startup()
473 qinst->is_tx = (readl(qinst->queue_ctrl) & in ti_msgmgr_queue_startup()
478 if (!msg_count && qinst->is_tx) { in ti_msgmgr_queue_startup()
480 qinst->name); in ti_msgmgr_queue_startup()
481 return -EINVAL; in ti_msgmgr_queue_startup()
485 if (!qinst->is_tx) { in ti_msgmgr_queue_startup()
487 qinst->rx_buff = kzalloc(d->max_message_size, GFP_KERNEL); in ti_msgmgr_queue_startup()
488 if (!qinst->rx_buff) in ti_msgmgr_queue_startup()
489 return -ENOMEM; in ti_msgmgr_queue_startup()
493 kfree(qinst->rx_buff); in ti_msgmgr_queue_startup()
502 * ti_msgmgr_queue_shutdown() - Shutdown the queue
507 struct ti_queue_inst *qinst = chan->con_priv; in ti_msgmgr_queue_shutdown()
509 if (!qinst->is_tx) { in ti_msgmgr_queue_shutdown()
510 free_irq(qinst->irq, chan); in ti_msgmgr_queue_shutdown()
511 kfree(qinst->rx_buff); in ti_msgmgr_queue_shutdown()
516 * ti_msgmgr_of_xlate() - Translation of phandle to queue
534 return ERR_PTR(-EINVAL); in ti_msgmgr_of_xlate()
536 d = inst->desc; in ti_msgmgr_of_xlate()
538 if (d->is_sproxy) in ti_msgmgr_of_xlate()
542 if (p->args_count != ncells) { in ti_msgmgr_of_xlate()
543 dev_err(inst->dev, "Invalid arguments in dt[%d]. Must be %d\n", in ti_msgmgr_of_xlate()
544 p->args_count, ncells); in ti_msgmgr_of_xlate()
545 return ERR_PTR(-EINVAL); in ti_msgmgr_of_xlate()
549 req_pid = p->args[0]; in ti_msgmgr_of_xlate()
551 req_qid = p->args[0]; in ti_msgmgr_of_xlate()
552 req_pid = p->args[1]; in ti_msgmgr_of_xlate()
555 if (d->is_sproxy) { in ti_msgmgr_of_xlate()
556 if (req_pid >= d->num_valid_queues) in ti_msgmgr_of_xlate()
558 qinst = &inst->qinsts[req_pid]; in ti_msgmgr_of_xlate()
559 return qinst->chan; in ti_msgmgr_of_xlate()
562 for (qinst = inst->qinsts, i = 0; i < inst->num_valid_queues; in ti_msgmgr_of_xlate()
564 if (req_qid == qinst->queue_id && req_pid == qinst->proxy_id) in ti_msgmgr_of_xlate()
565 return qinst->chan; in ti_msgmgr_of_xlate()
569 dev_err(inst->dev, "Queue ID %d, Proxy ID %d is wrong on %pOFn\n", in ti_msgmgr_of_xlate()
570 req_qid, req_pid, p->np); in ti_msgmgr_of_xlate()
571 return ERR_PTR(-ENOENT); in ti_msgmgr_of_xlate()
575 * ti_msgmgr_queue_setup() - Setup data structures for each queue instance
597 qinst->proxy_id = qd->proxy_id; in ti_msgmgr_queue_setup()
598 qinst->queue_id = qd->queue_id; in ti_msgmgr_queue_setup()
600 if (qinst->queue_id > d->queue_count) { in ti_msgmgr_queue_setup()
602 idx, qinst->queue_id, d->queue_count); in ti_msgmgr_queue_setup()
603 return -ERANGE; in ti_msgmgr_queue_setup()
606 if (d->is_sproxy) { in ti_msgmgr_queue_setup()
607 qinst->queue_buff_start = inst->queue_proxy_region + in ti_msgmgr_queue_setup()
608 SPROXY_THREAD_DATA_OFFSET(qinst->proxy_id, in ti_msgmgr_queue_setup()
609 d->data_first_reg); in ti_msgmgr_queue_setup()
610 qinst->queue_buff_end = inst->queue_proxy_region + in ti_msgmgr_queue_setup()
611 SPROXY_THREAD_DATA_OFFSET(qinst->proxy_id, in ti_msgmgr_queue_setup()
612 d->data_last_reg); in ti_msgmgr_queue_setup()
613 qinst->queue_state = inst->queue_state_debug_region + in ti_msgmgr_queue_setup()
614 SPROXY_THREAD_STATUS_OFFSET(qinst->proxy_id); in ti_msgmgr_queue_setup()
615 qinst->queue_ctrl = inst->queue_ctrl_region + in ti_msgmgr_queue_setup()
616 SPROXY_THREAD_CTRL_OFFSET(qinst->proxy_id); in ti_msgmgr_queue_setup()
620 snprintf(qinst->name, sizeof(qinst->name), "%s %s_%03d", in ti_msgmgr_queue_setup()
621 dev_name(dev), dir, qinst->proxy_id); in ti_msgmgr_queue_setup()
623 qinst->queue_buff_start = inst->queue_proxy_region + in ti_msgmgr_queue_setup()
624 Q_DATA_OFFSET(qinst->proxy_id, qinst->queue_id, in ti_msgmgr_queue_setup()
625 d->data_first_reg); in ti_msgmgr_queue_setup()
626 qinst->queue_buff_end = inst->queue_proxy_region + in ti_msgmgr_queue_setup()
627 Q_DATA_OFFSET(qinst->proxy_id, qinst->queue_id, in ti_msgmgr_queue_setup()
628 d->data_last_reg); in ti_msgmgr_queue_setup()
629 qinst->queue_state = in ti_msgmgr_queue_setup()
630 inst->queue_state_debug_region + in ti_msgmgr_queue_setup()
631 Q_STATE_OFFSET(qinst->queue_id); in ti_msgmgr_queue_setup()
632 qinst->is_tx = qd->is_tx; in ti_msgmgr_queue_setup()
633 dir = qinst->is_tx ? "tx" : "rx"; in ti_msgmgr_queue_setup()
634 snprintf(qinst->name, sizeof(qinst->name), "%s %s_%03d_%03d", in ti_msgmgr_queue_setup()
635 dev_name(dev), dir, qinst->queue_id, qinst->proxy_id); in ti_msgmgr_queue_setup()
638 qinst->chan = chan; in ti_msgmgr_queue_setup()
640 /* Setup an error value for IRQ - Lazy allocation */ in ti_msgmgr_queue_setup()
641 qinst->irq = -EINVAL; in ti_msgmgr_queue_setup()
643 chan->con_priv = qinst; in ti_msgmgr_queue_setup()
646 idx, qinst->queue_id, qinst->proxy_id, qinst->irq, in ti_msgmgr_queue_setup()
647 qinst->queue_buff_start, qinst->queue_buff_end); in ti_msgmgr_queue_setup()
705 {.compatible = "ti,k2g-message-manager", .data = &k2g_desc},
706 {.compatible = "ti,am654-secure-proxy", .data = &am654_desc},
714 struct device *dev = &pdev->dev; in ti_msgmgr_probe()
725 int ret = -EINVAL; in ti_msgmgr_probe()
728 if (!dev->of_node) { in ti_msgmgr_probe()
730 return -EINVAL; in ti_msgmgr_probe()
732 np = dev->of_node; in ti_msgmgr_probe()
737 return -EINVAL; in ti_msgmgr_probe()
739 desc = of_id->data; in ti_msgmgr_probe()
743 return -ENOMEM; in ti_msgmgr_probe()
745 inst->dev = dev; in ti_msgmgr_probe()
746 inst->desc = desc; in ti_msgmgr_probe()
749 desc->data_region_name); in ti_msgmgr_probe()
750 inst->queue_proxy_region = devm_ioremap_resource(dev, res); in ti_msgmgr_probe()
751 if (IS_ERR(inst->queue_proxy_region)) in ti_msgmgr_probe()
752 return PTR_ERR(inst->queue_proxy_region); in ti_msgmgr_probe()
755 desc->status_region_name); in ti_msgmgr_probe()
756 inst->queue_state_debug_region = devm_ioremap_resource(dev, res); in ti_msgmgr_probe()
757 if (IS_ERR(inst->queue_state_debug_region)) in ti_msgmgr_probe()
758 return PTR_ERR(inst->queue_state_debug_region); in ti_msgmgr_probe()
760 if (desc->is_sproxy) { in ti_msgmgr_probe()
762 desc->ctrl_region_name); in ti_msgmgr_probe()
763 inst->queue_ctrl_region = devm_ioremap_resource(dev, res); in ti_msgmgr_probe()
764 if (IS_ERR(inst->queue_ctrl_region)) in ti_msgmgr_probe()
765 return PTR_ERR(inst->queue_ctrl_region); in ti_msgmgr_probe()
768 dev_dbg(dev, "proxy region=%p, queue_state=%p\n", in ti_msgmgr_probe()
769 inst->queue_proxy_region, inst->queue_state_debug_region); in ti_msgmgr_probe()
771 queue_count = desc->num_valid_queues; in ti_msgmgr_probe()
772 if (!queue_count || queue_count > desc->queue_count) { in ti_msgmgr_probe()
774 queue_count, desc->queue_count); in ti_msgmgr_probe()
775 return -ERANGE; in ti_msgmgr_probe()
777 inst->num_valid_queues = queue_count; in ti_msgmgr_probe()
781 return -ENOMEM; in ti_msgmgr_probe()
782 inst->qinsts = qinst; in ti_msgmgr_probe()
786 return -ENOMEM; in ti_msgmgr_probe()
787 inst->chans = chans; in ti_msgmgr_probe()
789 if (desc->is_sproxy) { in ti_msgmgr_probe()
792 /* All proxies may be valid in Secure Proxy instance */ in ti_msgmgr_probe()
804 for (i = 0, queue_desc = desc->valid_queues; in ti_msgmgr_probe()
814 mbox = &inst->mbox; in ti_msgmgr_probe()
815 mbox->dev = dev; in ti_msgmgr_probe()
816 mbox->ops = &ti_msgmgr_chan_ops; in ti_msgmgr_probe()
817 mbox->chans = inst->chans; in ti_msgmgr_probe()
818 mbox->num_chans = inst->num_valid_queues; in ti_msgmgr_probe()
819 mbox->txdone_irq = false; in ti_msgmgr_probe()
820 mbox->txdone_poll = desc->tx_polled; in ti_msgmgr_probe()
821 if (desc->tx_polled) in ti_msgmgr_probe()
822 mbox->txpoll_period = desc->tx_poll_timeout_ms; in ti_msgmgr_probe()
823 mbox->of_xlate = ti_msgmgr_of_xlate; in ti_msgmgr_probe()
836 .name = "ti-msgmgr",
845 MODULE_ALIAS("platform:ti-msgmgr");