mailbox and remoteproc

This commit is contained in:
Justin Hammond 2023-02-11 20:11:34 +08:00
parent ea57961469
commit ec62e8fc7b
6 changed files with 125 additions and 67 deletions

View file

@ -18,8 +18,8 @@
chosen { chosen {
stdout-path = "serial0:2000000n8"; stdout-path = "serial0:2000000n8";
bootargs = "console=ttyS0,2000000 loglevel=8 earlycon=sbi root=/dev/mmcblk0p2 rootwait rootfstype=ext4 dyndbg=\"file bl808_remoteproc.c +p; module bflb_ipc +p; file mailbox.c +p; file rpmsg-net.c +p;\""; //bootargs = "console=ttyS0,2000000 loglevel=8 earlycon=sbi root=/dev/mmcblk0p2 rootwait rootfstype=ext4 dyndbg=\"file bl808_remoteproc.c +p; module bflb_ipc +p; file mailbox.c +p; file rpmsg-net.c +p;\"";
//bootargs = "console=ttyS0,2000000 loglevel=8 earlycon=sbi root=/dev/mmcblk0p2 rootwait rootfstype=ext4 dyndbg=\"file rpmsg-net.c +p;\""; bootargs = "console=ttyS0,2000000 loglevel=8 earlycon=sbi root=/dev/mmcblk0p2 rootwait rootfstype=ext4 dyndbg=\"file rpmsg-net.c +p;\"";
linux,initrd-start = <0x0 0x52000000>; linux,initrd-start = <0x0 0x52000000>;
linux,initrd-end = <0x0 0x52941784>; linux,initrd-end = <0x0 0x52941784>;
}; };

View file

@ -172,7 +172,7 @@
}; };
rproc: rproc@22054000 { rproc: rproc@22054000 {
compatible = "bflb,bl808-rproc"; compatible = "bflb,bflb-rproc";
reg = <0x22054000 0x4000>; reg = <0x22054000 0x4000>;
memory-region = <&vdev0vring0>, <&vdev0vring1>, <&vdev0buffer>; memory-region = <&vdev0vring0>, <&vdev0vring1>, <&vdev0buffer>;
mboxes = <&ipclic BFLB_IPC_TARGET_M0 BFLB_IPC_MBOX_VIRTIO BFLB_IPC_MBOX_VIRTIO_OP_KICK>, mboxes = <&ipclic BFLB_IPC_TARGET_M0 BFLB_IPC_MBOX_VIRTIO BFLB_IPC_MBOX_VIRTIO_OP_KICK>,

View file

@ -11,6 +11,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/bflb-mailbox.h>
#include <dt-bindings/mailbox/bflb-ipc.h> #include <dt-bindings/mailbox/bflb-ipc.h>
/* IPC Register offsets */ /* IPC Register offsets */
@ -65,8 +66,7 @@ static inline struct bflb_ipc *to_bflb_ipc(struct mbox_controller *mboxctlr)
static inline u32 bflb_ipc_get_hwirq(u16 source, u16 device) static inline u32 bflb_ipc_get_hwirq(u16 source, u16 device)
{ {
pr_debug("%s: source: %u, device: %u\n", __func__, source, device); // dev_dbg("%s: source: %u, device: %u\n", __func__, source, device);
return device; return device;
} }
@ -76,6 +76,7 @@ static inline u32 bflb_ipc_get_hwirq(u16 source, u16 device)
static void bflb_ipc_dump_regs(struct bflb_ipc *ipc) static void bflb_ipc_dump_regs(struct bflb_ipc *ipc)
{ {
int i; int i;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
dev_dbg(ipc->dev, "base %px %d\n", ipc->base[i], i); dev_dbg(ipc->dev, "base %px %d\n", ipc->base[i], i);
dev_dbg(ipc->dev, "ISWR: 0x%08x\n", readl(ipc->base[i] + IPC_REG_ISWR)); dev_dbg(ipc->dev, "ISWR: 0x%08x\n", readl(ipc->base[i] + IPC_REG_ISWR));
@ -90,7 +91,8 @@ static void bflb_ipc_dump_regs(struct bflb_ipc *ipc)
} }
#endif #endif
struct mbox_chan *bflb_mbox_find_chan(struct bflb_ipc *ipc, struct bflb_ipc_chan_info *chaninfo) { struct mbox_chan *bflb_mbox_find_chan(struct bflb_ipc *ipc, struct bflb_ipc_chan_info *chaninfo)
{
struct bflb_ipc_chan_info *mchan; struct bflb_ipc_chan_info *mchan;
struct mbox_controller *mboxctlr = &ipc->mboxctlr; struct mbox_controller *mboxctlr = &ipc->mboxctlr;
struct mbox_chan *chan; struct mbox_chan *chan;
@ -99,8 +101,6 @@ struct mbox_chan *bflb_mbox_find_chan(struct bflb_ipc *ipc, struct bflb_ipc_chan
dev = ipc->dev; dev = ipc->dev;
//dev_dbg(dev, "%s Find Chan %d %d %d\n", __func__, chaninfo->cpu_id, chaninfo->service_id, chaninfo->op_id);
for (chan_id = 0; chan_id < mboxctlr->num_chans; chan_id++) { for (chan_id = 0; chan_id < mboxctlr->num_chans; chan_id++) {
chan = &ipc->chans[chan_id]; chan = &ipc->chans[chan_id];
mchan = chan->con_priv; mchan = chan->con_priv;
@ -127,36 +127,32 @@ static void bflb_mbox_rx_irq_fn(int from_cpu, struct bflb_ipc *ipc)
{ {
struct mbox_chan *chan; struct mbox_chan *chan;
struct bflb_ipc_chan_info bflbchan; struct bflb_ipc_chan_info bflbchan;
struct bflb_mbox_msg msg;
u32 sig_op;
/* update this when we support LP */ /* update this when we support LP */
u32 sig_op = readl(ipc->base[1] + IPC_REG_ILSHR); sig_op = readl(ipc->base[1] + IPC_REG_ILSHR);
u32 param = readl(ipc->base[1] + IPC_REG_ILSLR); msg.param = readl(ipc->base[1] + IPC_REG_ILSLR);
WARN_ON(sig_op == 0); WARN_ON(sig_op == 0);
bflbchan.cpu_id = from_cpu; bflbchan.cpu_id = from_cpu;
bflbchan.service_id = (sig_op >> 16) & 0xFFFF; bflbchan.service_id = (sig_op >> 16) & 0xFFFF;
bflbchan.op_id = sig_op & 0xFFFF; bflbchan.op_id = sig_op & 0xFFFF;
chan = bflb_mbox_find_chan(ipc, &bflbchan); chan = bflb_mbox_find_chan(ipc, &bflbchan);
if (IS_ERR(chan)) { if (IS_ERR(chan)) {
dev_err(ipc->dev, "no channel for signal cpu_id: %d service: %d op: %d\r\n", bflbchan.cpu_id, bflbchan.service_id, bflbchan.op_id); dev_err(ipc->dev, "no channel for signal cpu_id: %d service: %d op: %d\r\n", bflbchan.cpu_id, bflbchan.service_id, bflbchan.op_id);
return; return;
} }
dev_info(ipc->dev, "Got MBOX Signal cpu: %d service %d op %d param %x\r\n", bflbchan.cpu_id, bflbchan.service_id, bflbchan.op_id, param); dev_dbg(ipc->dev, "Got MBOX Signal cpu: %d service %d op %d param %x\r\n", bflbchan.cpu_id, bflbchan.service_id, bflbchan.op_id, msg.param);
mbox_chan_received_data(chan, param); mbox_chan_received_data(chan, &msg);
dev_info(ipc->dev, "bflb_mbox_rx\r\n");
return;
} }
/* called when we get a interupt back on our TX IRQ. /* called when we get a interupt back on our TX IRQ.
* This is usualy a EOI interupt * This is a EOI interupt
*/ */
static void bflb_mbox_tx_irq_fn(u8 from_cpu, struct bflb_ipc *ipc) static void bflb_mbox_tx_irq_fn(u8 from_cpu, struct bflb_ipc *ipc)
{ {
@ -164,6 +160,7 @@ static void bflb_mbox_tx_irq_fn(u8 from_cpu, struct bflb_ipc *ipc)
struct bflb_ipc_chan_info bflbchan; struct bflb_ipc_chan_info bflbchan;
u32 sig_op = readl(ipc->base[2] + IPC_REG_ILSHR); u32 sig_op = readl(ipc->base[2] + IPC_REG_ILSHR);
u32 param = readl(ipc->base[2] + IPC_REG_ILSLR);
bflbchan.cpu_id = from_cpu; bflbchan.cpu_id = from_cpu;
bflbchan.service_id = (sig_op >> 16) & 0xFFFF; bflbchan.service_id = (sig_op >> 16) & 0xFFFF;
@ -171,15 +168,17 @@ static void bflb_mbox_tx_irq_fn(u8 from_cpu, struct bflb_ipc *ipc)
chan = bflb_mbox_find_chan(ipc, &bflbchan); chan = bflb_mbox_find_chan(ipc, &bflbchan);
if (IS_ERR(chan)) { if (IS_ERR(chan)) {
dev_err(ipc->dev, "no channel for EOI signal cpu_id: %d service: %d op: %d\r\n", bflbchan.cpu_id, bflbchan.service_id, bflbchan.op_id); dev_err(ipc->dev, "no channel for EOI signal cpu_id: %d service: %d op: %d Param: %d $$$$$$$$$", bflbchan.cpu_id, bflbchan.service_id, bflbchan.op_id, param);
return; return;
} }
dev_info(ipc->dev, "Got MBOX EOI Signal cpu: %d service %d op %d\r\n", bflbchan.cpu_id, bflbchan.service_id, bflbchan.op_id); dev_dbg(ipc->dev, "Got MBOX EOI Signal cpu: %d service %d op %d Param: %d $$$$$$$$$$$$$$$$$$$$", bflbchan.cpu_id, bflbchan.service_id, bflbchan.op_id, param);
/* clear the IPC_REG_ILSLR and IPC_REG_ILSHR */
writel(0, ipc->base[2] + IPC_REG_ILSLR);
writel(0, ipc->base[2] + IPC_REG_ILSHR);
mbox_chan_txdone(chan, 0); mbox_chan_txdone(chan, 0);
return;
} }
static irqreturn_t bflb_ipc_irq_fn(int irq, void *data) static irqreturn_t bflb_ipc_irq_fn(int irq, void *data)
@ -263,47 +262,61 @@ static const struct irq_domain_ops bflb_ipc_irq_ops = {
.xlate = bflb_ipc_domain_xlate, .xlate = bflb_ipc_domain_xlate,
}; };
/* JH: Figure out if M0 has processed the last signal sent #if 0
* by checking if the High/Low registers are cleared /* Shouldn't actually be fail as we clear the High/Low registers in a EOI
* but this protects if we screw up our mailbox handling
*/ */
static bool bflb_ipc_mbox_can_send(struct mbox_chan *chan) static bool bflb_ipc_mbox_can_send(struct mbox_chan *chan)
{ {
struct bflb_ipc *ipc = to_bflb_ipc(chan->mbox); struct bflb_ipc *ipc = to_bflb_ipc(chan->mbox);
u32 mbox_high = readl(ipc->base[2] + IPC_REG_ILSHR); /* check the low register first as we clear that last in our EOI, so this
* should protected to a limited extent
*/
u32 mbox_low = readl(ipc->base[2] + IPC_REG_ILSLR); u32 mbox_low = readl(ipc->base[2] + IPC_REG_ILSLR);
u32 mbox_high = readl(ipc->base[2] + IPC_REG_ILSHR);
dev_dbg(ipc->dev, "%s: low: 0x%08x high: 0x%08x\r\n", __func__, mbox_low, mbox_high);
if (mbox_low | mbox_high)
dev_warn_ratelimited(ipc->dev, "%s: low: 0x%08x high: 0x%08x\r\n", __func__, mbox_low, mbox_high);
writel(0, ipc->base[2] + IPC_REG_ILSLR);
writel(0, ipc->base[2] + IPC_REG_ILSHR);
return !(mbox_low | mbox_high); return !(mbox_low | mbox_high);
} }
#endif
static int bflb_ipc_mbox_send_data(struct mbox_chan *chan, void *data) static int bflb_ipc_mbox_send_data(struct mbox_chan *chan, void *data)
{ {
struct bflb_ipc *ipc = to_bflb_ipc(chan->mbox); struct bflb_ipc *ipc = to_bflb_ipc(chan->mbox);
struct bflb_ipc_chan_info *mchan = chan->con_priv; struct bflb_ipc_chan_info *mchan = chan->con_priv;
int *param = data; struct bflb_mbox_msg *msg = data;
u32 tmpVal = (mchan->service_id << 16) | (mchan->op_id & 0xFFFF); u32 tmpVal = (mchan->service_id << 16) | (mchan->op_id & 0xFFFF);
dev_dbg(ipc->dev, "%s: cpu: %d singal: %d op: %d (0x%x) param: %d\n", __func__, mchan->cpu_id, mchan->service_id, mchan->op_id, tmpVal, *param); #if 0
if (!bflb_ipc_mbox_can_send(chan))
return -EBUSY;
#endif
dev_dbg(ipc->dev, "%s %d: cpu: %d singal: %d op: %d (0x%x) param: %d", __func__, msg->id, mchan->cpu_id, mchan->service_id, mchan->op_id, tmpVal, msg->param);
// /* write our signal number to high register */ // /* write our signal number to high register */
writel(tmpVal, ipc->base[2] + IPC_REG_ILSHR); writel(tmpVal, ipc->base[2] + IPC_REG_ILSHR);
// /* write our data to low register */ // /* write our data to low register */
writel(*param, ipc->base[2] + IPC_REG_ILSLR); writel(msg->param, ipc->base[2] + IPC_REG_ILSLR);
/* and now kick the remote processor */ /* and now kick the remote processor */
writel((1 << BFLB_IPC_DEVICE_MBOX_TX), ipc->base[2] + IPC_REG_ISWR); writel((1 << BFLB_IPC_DEVICE_MBOX_TX), ipc->base[2] + IPC_REG_ISWR);
dev_dbg(ipc->dev, "%s: done\r\n", __func__); dev_dbg(ipc->dev, "%s %d: done param: %d", __func__, msg->id, msg->param);
return 0; return 0;
} }
static void bflb_ipc_mbox_shutdown(struct mbox_chan *chan) static void bflb_ipc_mbox_shutdown(struct mbox_chan *chan)
{ {
pr_debug("%s\n", __func__); struct bflb_ipc *ipc = to_bflb_ipc(chan->mbox);
dev_dbg(ipc->dev, "%s\n", __func__);
chan->con_priv = NULL; chan->con_priv = NULL;
} }
@ -320,7 +333,7 @@ static struct mbox_chan *bflb_ipc_mbox_xlate(struct mbox_controller *mboxctlr,
dev_dbg(dev, "%s\n", __func__); dev_dbg(dev, "%s\n", __func__);
if (ph->args_count != 3) { if (ph->args_count != 3) {
pr_debug("invalid number of arguments"); dev_err(dev, "invalid number of arguments");
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
@ -333,21 +346,20 @@ static struct mbox_chan *bflb_ipc_mbox_xlate(struct mbox_controller *mboxctlr,
else if (mchan->cpu_id == ph->args[0] && else if (mchan->cpu_id == ph->args[0] &&
mchan->service_id == ph->args[1] && mchan->service_id == ph->args[1] &&
mchan->op_id == ph->args[2]) { mchan->op_id == ph->args[2]) {
pr_debug("channel already in use %d %d %d", ph->args[0], ph->args[1], ph->args[2]); dev_err(dev, "channel already in use %d %d %d", ph->args[0], ph->args[1], ph->args[2]);
return ERR_PTR(-EBUSY); return ERR_PTR(-EBUSY);
} }
} }
if (chan_id >= mboxctlr->num_chans) { if (chan_id >= mboxctlr->num_chans) {
pr_debug("no free channels"); dev_err(dev, "no free channels");
return ERR_PTR(-EBUSY); return ERR_PTR(-EBUSY);
} }
mchan = devm_kzalloc(dev, sizeof(*mchan), GFP_KERNEL); mchan = devm_kzalloc(dev, sizeof(*mchan), GFP_KERNEL);
if (!mchan) { if (!mchan)
pr_debug("no memory for channel");
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
}
mchan->cpu_id = ph->args[0]; mchan->cpu_id = ph->args[0];
mchan->service_id = ph->args[1]; mchan->service_id = ph->args[1];
mchan->op_id = ph->args[2]; mchan->op_id = ph->args[2];

View file

@ -18,7 +18,9 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/remoteproc.h> #include <linux/remoteproc.h>
#include <linux/mailbox_client.h> #include <linux/mailbox_client.h>
#include <linux/mailbox_controller.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/bflb-mailbox.h>
#include "remoteproc_internal.h" #include "remoteproc_internal.h"
/** /**
@ -232,8 +234,6 @@ static int bflb_rproc_stop(struct rproc *rproc)
return 0; return 0;
} }
#include <linux/mailbox_controller.h>
/* kick the virtqueue to let M0 know there is a update to the vring */ /* kick the virtqueue to let M0 know there is a update to the vring */
static void bflb_rproc_send_kick(struct rproc *rproc, int vqid) static void bflb_rproc_send_kick(struct rproc *rproc, int vqid)
{ {
@ -241,27 +241,51 @@ static void bflb_rproc_send_kick(struct rproc *rproc, int vqid)
struct bflb_rproc *drproc = (struct bflb_rproc *)rproc->priv; struct bflb_rproc *drproc = (struct bflb_rproc *)rproc->priv;
struct bflb_mbox *mb = &drproc->mbox_tx; struct bflb_mbox *mb = &drproc->mbox_tx;
struct mbox_chan *chan = mb->chan; struct mbox_chan *chan = mb->chan;
struct bflb_mbox_msg *msg;
int ret; int ret;
int i;
static int count;
/* just for debugging atm */
count++;
msg = kzalloc(sizeof(struct bflb_mbox_msg), GFP_KERNEL);
if (!msg)
return;
/* we need a small delay before kicking the other side
* (I assume to allow the ring to update/flush etc?)
* without this, we get lots of "empty ring" messages on the
* other side
*/
mdelay(1);
msg->param = vqid;
msg->id = count;
/* Kick the other CPU to let it know the vrings are updated */ /* Kick the other CPU to let it know the vrings are updated */
dev_info(dev, "%s Mailbox: %s %d", __func__, mb->name, vqid); dev_dbg(dev, "%s %d Mailbox: %s %d", __func__, msg->id, mb->name, msg->param);
ret = mbox_send_message(chan, &vqid); /* we occasionally get a EOI timeout, so retry upto 3 times */
if (!ret) { for (i = 0; i < 3; i++) {
dev_err(dev, "%s Mailbox %s sending %d Failed: %d", __func__, mb->name, vqid, ret); ret = mbox_send_message(chan, msg);
} else { if (ret >= 0)
dev_info(dev, "%s Mailbox %s done %d size: %d free: %d: %d", __func__, mb->name, vqid, chan->msg_count, chan->msg_free, ret); goto done;
dev_warn(dev, "%s %d Mailbox %s sending %d Failed: %d - Retrying %d", __func__, msg->id, mb->name, msg->param, ret, i);
} }
done:
dev_dbg(dev, "%s %d Mailbox %s done %d: %d", __func__, msg->id, mb->name, msg->param, ret);
kfree(msg);
} }
static void bflb_rproc_recv_kick(struct work_struct *work) static void bflb_rproc_recv_kick(struct work_struct *work)
{ {
struct bflb_mbox *mb = container_of(work, struct bflb_mbox, vq_work); struct bflb_mbox *mb = container_of(work, struct bflb_mbox, vq_work);
struct rproc *rproc = dev_get_drvdata(mb->client.dev); struct rproc *rproc = dev_get_drvdata(mb->client.dev);
dev_info(rproc->dev.parent, "%s mailbox: %s: %d", __func__, mb->name, mb->vq_id); dev_dbg(rproc->dev.parent, "%s mailbox: %s: %d", __func__, mb->name, mb->vq_id);
/* not a bad thing if there is no messages, probably
* means that the previous ring kick processed the message
*/
if (rproc_vq_interrupt(rproc, mb->vq_id) == IRQ_NONE) if (rproc_vq_interrupt(rproc, mb->vq_id) == IRQ_NONE)
dev_dbg(&rproc->dev, "no message found in vq%d\n", mb->vq_id); dev_dbg(&rproc->dev, "no message found in vq%d\n", mb->vq_id);
} }
@ -274,12 +298,11 @@ static void bflb_rproc_rx_mbox_callback(struct mbox_client *client, void *data)
struct rproc *rproc = dev_get_drvdata(dev); struct rproc *rproc = dev_get_drvdata(dev);
struct bflb_rproc *drproc = (struct bflb_rproc *)rproc->priv; struct bflb_rproc *drproc = (struct bflb_rproc *)rproc->priv;
struct bflb_mbox *mb = &drproc->mbox_rx; struct bflb_mbox *mb = &drproc->mbox_rx;
struct bflb_mbox_msg *msg = data;
mb->vq_id = (int)data; mb->vq_id = msg->param;
dev_info(dev, "%s mailbox %s: %d", __func__, mb->name, mb->vq_id);
dev_dbg(dev, "%s mailbox %s: %d", __func__, mb->name, mb->vq_id);
queue_work(drproc->workqueue, &mb->vq_work); queue_work(drproc->workqueue, &mb->vq_work);
mbox_chan_txdone(mb->chan, 0); mbox_chan_txdone(mb->chan, 0);
@ -318,7 +341,8 @@ static const struct rproc_ops bflb_rproc_ops = {
.get_loaded_rsc_table = bflb_rproc_get_loaded_rsc_table, .get_loaded_rsc_table = bflb_rproc_get_loaded_rsc_table,
}; };
static int bflb_rproc_setup_mbox(struct rproc *rproc) { static int bflb_rproc_setup_mbox(struct rproc *rproc)
{
struct bflb_rproc *drproc = (struct bflb_rproc *)rproc->priv; struct bflb_rproc *drproc = (struct bflb_rproc *)rproc->priv;
struct bflb_mbox *tx_bflb_mbox = &drproc->mbox_tx; struct bflb_mbox *tx_bflb_mbox = &drproc->mbox_tx;
@ -335,7 +359,7 @@ static int bflb_rproc_setup_mbox(struct rproc *rproc) {
/* request the TX mailboxs */ /* request the TX mailboxs */
tx_mbox_cl->dev = dev->parent; tx_mbox_cl->dev = dev->parent;
tx_mbox_cl->tx_block = true; tx_mbox_cl->tx_block = true;
tx_mbox_cl->tx_tout = 100; tx_mbox_cl->tx_tout = 200;
strncpy(tx_bflb_mbox->name, "virtio-tx", sizeof(tx_bflb_mbox->name)); strncpy(tx_bflb_mbox->name, "virtio-tx", sizeof(tx_bflb_mbox->name));
tx_bflb_mbox->chan = mbox_request_channel_byname(tx_mbox_cl, "virtio-tx"); tx_bflb_mbox->chan = mbox_request_channel_byname(tx_mbox_cl, "virtio-tx");
if (IS_ERR(tx_bflb_mbox->chan)) { if (IS_ERR(tx_bflb_mbox->chan)) {
@ -397,6 +421,8 @@ static int bflb_rproc_probe(struct platform_device *pdev)
drproc = rproc->priv; drproc = rproc->priv;
drproc->rproc = rproc; drproc->rproc = rproc;
rproc->has_iommu = false; rproc->has_iommu = false;
rproc->sysfs_read_only = true;
platform_set_drvdata(pdev, rproc); platform_set_drvdata(pdev, rproc);
drproc->workqueue = create_workqueue(dev_name(dev)); drproc->workqueue = create_workqueue(dev_name(dev));
@ -456,7 +482,7 @@ static int bflb_rproc_remove(struct platform_device *pdev)
} }
static const struct of_device_id davinci_rproc_of_match[] __maybe_unused = { static const struct of_device_id davinci_rproc_of_match[] __maybe_unused = {
{ .compatible = "bflb,bl808-rproc", }, { .compatible = "bflb,bflb-rproc", },
{ /* sentinel */ }, { /* sentinel */ },
}; };
MODULE_DEVICE_TABLE(of, davinci_rproc_of_match); MODULE_DEVICE_TABLE(of, davinci_rproc_of_match);
@ -465,7 +491,7 @@ static struct platform_driver bflb_rproc_driver = {
.probe = bflb_rproc_probe, .probe = bflb_rproc_probe,
.remove = bflb_rproc_remove, .remove = bflb_rproc_remove,
.driver = { .driver = {
.name = "bl808-rproc", .name = "bflb-rproc",
.of_match_table = of_match_ptr(davinci_rproc_of_match), .of_match_table = of_match_ptr(davinci_rproc_of_match),
}, },
}; };

View file

@ -92,7 +92,8 @@ static int rpmsg_tty_write(struct tty_struct *tty, const u8 *buf, int len)
* Use rpmsg_trysend instead of rpmsg_send to send the message so the caller is not * Use rpmsg_trysend instead of rpmsg_send to send the message so the caller is not
* hung until a rpmsg buffer is available. In such case rpmsg_trysend returns -ENOMEM. * hung until a rpmsg buffer is available. In such case rpmsg_trysend returns -ENOMEM.
*/ */
ret = rpmsg_trysend(rpdev->ept, (void *)buf, msg_size); /* for bl808, we only have a few small buffers, and a slow M0 CPU, so lets use rpmsg_send */
ret = rpmsg_send(rpdev->ept, (void *)buf, msg_size);
if (ret) { if (ret) {
dev_dbg_ratelimited(&rpdev->dev, "rpmsg_send failed: %d\n", ret); dev_dbg_ratelimited(&rpdev->dev, "rpmsg_send failed: %d\n", ret);
return ret; return ret;

View file

@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
/*
* BL808 mailbox message format
*
* Copyright (C) 2021 The Asahi Linux Contributors
*/
#ifndef _LINUX_BFLB_MAILBOX_H_
#define _LINUX_BFLB_MAILBOX_H_
#include <linux/types.h>
/* encodes a single 32bit message sent over the single channel */
struct bflb_mbox_msg {
u32 param;
u32 id;
};
#endif