Thread (14 messages) read the whole thread 14 messages, 3 authors, 2016-03-17

[PATCH V2 2/2] mailbox: Introduce TI message manager driver

From: jassisinghbrar@gmail.com (Jassi Brar)
Date: 2016-03-04 05:18:25
Also in: linux-devicetree, lkml

On Sat, Feb 27, 2016 at 3:54 AM, Nishanth Menon [off-list ref] wrote:
Support for TI Message Manager Module. This hardware block manages a
bunch of hardware queues meant for communication between processor
entities.

Clients sitting on top of this would manage the required protocol
for communicating with the counterpart entities.

For more details on TI Message Manager hardware block, see documentation
that will is available here: http://www.ti.com/lit/ug/spruhy8/spruhy8.pdf
Chapter 8.1(Message Manager)

Signed-off-by: Nishanth Menon <nm@ti.com>
---
V2: Changes since V1:
        - Major refactoring of code for binding changes
        - moved list of valid K2G queueus into driver
        - split up probe into sub functions for easier maintenance

V1: https://patchwork.kernel.org/patch/8237171/

 drivers/mailbox/Kconfig     |  11 +
 drivers/mailbox/Makefile    |   2 +
 drivers/mailbox/ti-msgmgr.c | 657
Do you want to call it something more specific than 'msgmgr from TI'?
Maybe its about Keystone, like mailbox-keystone.c ?

+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/ti-msgmgr.h>
This seems a bit bold. I think  include/linux/soc/ti/ is the right place.

+       /* Do I actually have messages to read? */
+       msg_count = ti_msgmgr_queue_get_num_messages(qinst);
+       if (!msg_count) {
+               /* Shared IRQ? */
+               dev_dbg(dev, "Spurious event - 0 pending data!\n");
+               return IRQ_NONE;
+       }
+
+       /*
+        * I have no idea about the protocol being used to communicate with the
+        * remote producer - 0 could be valid data, so I wont make a judgement
+        * of how many bytes I should be reading. Let the client figure this
+        * out.. I just read the full message and pass it on..
+        */
Exactly. And similarly when you send data, you should not have more
than one message in transit. Now please see my note in
ti_msgmgr_send_data()

+static int ti_msgmgr_send_data(struct mbox_chan *chan, void *data)
+{
+       struct device *dev = chan->mbox->dev;
+       struct ti_msgmgr_inst *inst = dev_get_drvdata(dev);
+       const struct ti_msgmgr_desc *desc;
+       struct ti_queue_inst *qinst = chan->con_priv;
+       int msg_count, num_words, trail_bytes;
+       struct ti_msgmgr_message *message = data;
+       void __iomem *data_reg;
+       u32 *word_data;
+
+       if (WARN_ON(!inst)) {
+               dev_err(dev, "no platform drv data??\n");
+               return -EINVAL;
+       }
+       desc = inst->desc;
+
+       if (desc->max_message_size < message->len) {
+               dev_err(dev, "Queue %s message length %d > max %d\n",
+                       qinst->name, message->len, desc->max_message_size);
+               return -EINVAL;
+       }
+
+       /* Are we able to send this or not? */
+       msg_count = ti_msgmgr_queue_get_num_messages(qinst);
+       if (msg_count >= desc->max_messages) {
+               dev_warn(dev, "Queue %s is full (%d messages)\n", qinst->name,
+                        msg_count);
+               return -EBUSY;
+       }
This seems fishy. mailbox api always submit 1 'complete' message to be
sent and checks for completion by last_tx_done() before calling
send_data() again. Controller drivers are not supposed to queue
messages - mailbox core does. So you should never be unable to send a
message.

+       /*
+        * NOTE about register access involved here:
+        * the hardware block is implemented with 32bit access operations and no
+        * support for data splitting.  We don't want the hardware to misbehave
+        * with sub 32bit access - For example: if the last register write is
+        * split into byte wise access, it can result in the queue getting
+        * stuck or dummy messages being transmitted or indeterminate behavior.
+        * The same can occur if out of order operations take place.
+        * Hence, we do not use memcpy_toio or ___iowrite32_copy here, instead
+        * we use writel which ensures the sequencing we need.
+        */
.... deja-vu ?

+
+/* Keystone K2G SoC integration details */
+static const struct ti_msgmgr_valid_queue_desc k2g_valid_queues[] = {
+       {.queue_id = 0, .proxy_id = 0, .is_tx = true,},
+       {.queue_id = 1, .proxy_id = 0, .is_tx = true,},
+       {.queue_id = 2, .proxy_id = 0, .is_tx = true,},
+       {.queue_id = 3, .proxy_id = 0, .is_tx = true,},
+       {.queue_id = 5, .proxy_id = 2, .is_tx = false,},
+       {.queue_id = 56, .proxy_id = 1, .is_tx = true,},
+       {.queue_id = 57, .proxy_id = 2, .is_tx = false,},
+       {.queue_id = 58, .proxy_id = 3, .is_tx = true,},
+       {.queue_id = 59, .proxy_id = 4, .is_tx = true,},
+       {.queue_id = 60, .proxy_id = 5, .is_tx = true,},
+       {.queue_id = 61, .proxy_id = 6, .is_tx = true,},
+};
+
+static const struct ti_msgmgr_desc k2g_desc = {
+       .queue_count = 64,
+       .max_message_size = 64,
+       .max_messages = 128,
+       .q_slices = 1,
+       .q_proxies = 1,
+       .data_first_reg = 16,
+       .data_last_reg = 31,
+       .tx_polled = false,
+       .valid_queues = k2g_valid_queues,
+       .num_valid_queues = ARRAY_SIZE(k2g_valid_queues),
+};
If these parameters are very configurable, maybe they should be in DT?

Thanks.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help