From d2cf4113184fc3442b993c0bf6332f61ad8f7ed4 Mon Sep 17 00:00:00 2001 From: Justin Hammond Date: Mon, 6 Feb 2023 13:13:07 +0800 Subject: [PATCH] remoteproc working --- arch/riscv/boot/dts/bouffalolab/bl808.dtsi | 14 ++-- drivers/mailbox/bflb-ipc.c | 11 ++- drivers/remoteproc/bl808_remoteproc.c | 88 ++++++++++++++++------ 3 files changed, 80 insertions(+), 33 deletions(-) diff --git a/arch/riscv/boot/dts/bouffalolab/bl808.dtsi b/arch/riscv/boot/dts/bouffalolab/bl808.dtsi index 54bacab429eb..a7cfc6da1451 100644 --- a/arch/riscv/boot/dts/bouffalolab/bl808.dtsi +++ b/arch/riscv/boot/dts/bouffalolab/bl808.dtsi @@ -64,21 +64,19 @@ #size-cells = <1>; ranges; /* putting this at the top of uncached WRAM for the moment */ - vdev0vring0: vdev0vring0@22054000 { + vdev0vring0: vdev0vring0@22048000 { compatible = "shared-dma-pool"; - reg = <0x22050000 0x4000>; + reg = <0x22048000 0x4000>; no-map; }; - - vdev0vring1: vdev0vring1@22055000 { + vdev0vring1: vdev0vring1@2204C000 { compatible = "shared-dma-pool"; - reg = <0x22054000 0x4000>; + reg = <0x2204C000 0x4000>; no-map; }; - - vdev0buffer: vdev0buffer@22056000 { + vdev0buffer: vdev0buffer@22050000 { compatible = "shared-dma-pool"; - reg = <0x22042000 0x8000>; + reg = <0x22050000 0x8000>; no-map; }; }; diff --git a/drivers/mailbox/bflb-ipc.c b/drivers/mailbox/bflb-ipc.c index 458a502a2dfa..78500d9fa33f 100644 --- a/drivers/mailbox/bflb-ipc.c +++ b/drivers/mailbox/bflb-ipc.c @@ -195,7 +195,7 @@ static const struct irq_domain_ops bflb_ipc_irq_ops = { /* JH: Figure out if M0 has processed the last signal sent * by checking if the High/Low registers are cleared */ -static int 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); @@ -214,9 +214,10 @@ 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_chan_info *mchan = chan->con_priv; - if (!bflb_ipc_mbox_can_send(chan)) + if (!bflb_ipc_mbox_can_send(chan)) { + dev_dbg(ipc->dev, "MBOX is busy"); return -EBUSY; - + } dev_dbg(ipc->dev, "%s: %d %d\n", __func__, mchan->client_id, mchan->signal_id); @@ -283,6 +284,7 @@ static struct mbox_chan *bflb_ipc_mbox_xlate(struct mbox_controller *mbox, static const struct mbox_chan_ops ipc_mbox_chan_ops = { .send_data = bflb_ipc_mbox_send_data, .shutdown = bflb_ipc_mbox_shutdown, + .last_tx_done = bflb_ipc_mbox_can_send, }; static int bflb_ipc_setup_mbox(struct bflb_ipc *ipc, @@ -332,7 +334,8 @@ static int bflb_ipc_setup_mbox(struct bflb_ipc *ipc, mbox->ops = &ipc_mbox_chan_ops; mbox->of_xlate = bflb_ipc_mbox_xlate; mbox->txdone_irq = false; - mbox->txdone_poll = false; + mbox->txdone_poll = true; + /* clear the IPC_REG_ILSLR and IPC_REG_ILSHR */ diff --git a/drivers/remoteproc/bl808_remoteproc.c b/drivers/remoteproc/bl808_remoteproc.c index 10a3db04f104..722d3943c1db 100644 --- a/drivers/remoteproc/bl808_remoteproc.c +++ b/drivers/remoteproc/bl808_remoteproc.c @@ -21,6 +21,16 @@ #include "remoteproc_internal.h" +//#define MBOX_NB_MBX 1 + +struct bl808_mbox { + const unsigned char name[10]; + struct mbox_client client; + struct mbox_chan *chan; + struct work_struct vq_work; + int vq_id; +}; + /** * struct bl808_rproc - bl808 remote processor instance state @@ -30,10 +40,12 @@ */ struct bl808_rproc { struct rproc *rproc; - struct mbox_chan *mbox; - struct mbox_client client; + struct bl808_mbox mbox; + struct workqueue_struct *workqueue; }; + + /* The feature bitmap for virtio rpmsg */ #define VIRTIO_RPMSG_F_NS 0 /* RP supports name service notifications */ @@ -49,7 +61,7 @@ struct bl808_rproc { #define VRING_ALIGN 0x1000 #define RING_TX FW_RSC_U32_ADDR_ANY #define RING_RX FW_RSC_U32_ADDR_ANY -#define VRING_SIZE 2 +#define VRING_SIZE 4 #define NUM_TABLE_ENTRIES 1 @@ -96,8 +108,8 @@ struct remote_resource_table resources = { }, /* Vring rsc entry - part of vdev rsc entry */ - {RING_TX, VRING_ALIGN, VRING_SIZE, 1, 0}, - {RING_RX, VRING_ALIGN, VRING_SIZE, 2, 0}, + {0x22048000, VRING_ALIGN, VRING_SIZE, 0, 0x22048000}, + {0x2204C000, VRING_ALIGN, VRING_SIZE, 1, 0x2204C000}, }; /* return a pointer to our resource table @@ -129,7 +141,7 @@ static int bl808_rproc_mem_alloc(struct rproc *rproc, /* Update memory entry va */ mem->va = va; - dev_dbg(dev, "Allocated memory region: %pa+%zx -> %p", &mem->dma, mem->len, mem->va); + dev_dbg(dev, "Allocated memory region: %pa+%zx -> %px", &mem->dma, mem->len, mem->va); return 0; } @@ -174,7 +186,7 @@ static int bl808_rproc_setupmem(struct rproc *rproc) /* No need to map vdev buffer */ if (strcmp(it.node->name, "vdev0buffer")) { /* Register memory region */ - dev_dbg(dev, "registering memory region %s", it.node->name); + dev_dbg(dev, "registering memory region %s %llx", it.node->name, rmem->base); mem = rproc_mem_entry_init(dev, NULL, (dma_addr_t)rmem->base, rmem->size, rmem->base, @@ -183,7 +195,7 @@ static int bl808_rproc_setupmem(struct rproc *rproc) it.node->name); } else { /* Register reserved memory for vdev buffer allocation */ - dev_dbg(dev, "registering reserved memory region %s", it.node->name); + dev_dbg(dev, "registering reserved memory region %s %llx", it.node->name, rmem->base); mem = rproc_of_resm_mem_entry_init(dev, index, rmem->size, rmem->base, @@ -232,23 +244,42 @@ static void bl808_rproc_kick(struct rproc *rproc, int vqid) /* Kick the other CPU to let it know the vrings are updated */ dev_dbg(dev, "bl808_rproc_kick %d", vqid); - mbox_send_message(drproc->mbox, (void*)vqid); + mbox_send_message(drproc->mbox.chan, (void*)vqid); } +static void bflb_rproc_mb_vq_work(struct work_struct *work) +{ + struct bl808_mbox *mb = container_of(work, struct bl808_mbox, vq_work); + struct rproc *rproc = dev_get_drvdata(mb->client.dev); + + if (rproc_vq_interrupt(rproc, mb->vq_id) == IRQ_NONE) + dev_dbg(&rproc->dev, "no message found in vq%d\n", mb->vq_id); +} + + /* M0 signaled us there is a update on the vring, check it */ static void bflb_rproc_mbox_callback(struct mbox_client *client, void *data) { struct device *dev = client->dev; struct rproc *rproc = dev_get_drvdata(dev); - u32 vqid = (u32)data; + struct bl808_rproc *drproc = (struct bl808_rproc *)rproc->priv; + struct bl808_mbox *mb = &drproc->mbox; - dev_dbg(dev, "bflb_rproc_mbox_callback %d", vqid); + mb->vq_id = (u32)data; - if (vqid > 0 && vqid < 3) - rproc_vq_interrupt(rproc, vqid); - else - dev_err(dev, "bflb_rproc_mbox_callback: Invalid vqid %d", vqid); + dev_dbg(dev, "bflb_rproc_mbox_callback %d", mb->vq_id); + + queue_work(drproc->workqueue, &mb->vq_work); + +// if (vqid > 0 && vqid < 3) { +// rproc_vq_interrupt(rproc, vqid); + // rproc_vq_interrupt(rproc, 0); + // pr_debug("rproc_vq_interrupt 0"); + // rproc_vq_interrupt(rproc, 1); + // pr_debug("rproc_vq_interrupt 1"); +// } else +// dev_err(dev, "bflb_rproc_mbox_callback: Invalid vqid %d", vqid); } /* M0 is already running when we boot @@ -259,24 +290,26 @@ static int bl808_rproc_attach(struct rproc *rproc) { struct device *dev = &rproc->dev; struct bl808_rproc *drproc = (struct bl808_rproc *)rproc->priv; + struct mbox_client *vq1_mbox = &drproc->mbox.client; + struct bl808_mbox *chan = &drproc->mbox; int ret; - /* request the mailbox */ - struct mbox_client *vq1_mbox = &drproc->client; + /* request the mailboxs */ vq1_mbox->dev = dev->parent; - dev_dbg(vq1_mbox->dev, "bl808_rproc_attachasdfadfsdf: Attaching to %s", rproc->name); vq1_mbox->tx_done = NULL; vq1_mbox->rx_callback = bflb_rproc_mbox_callback; vq1_mbox->tx_block = false; vq1_mbox->knows_txdone = false; - drproc->mbox = mbox_request_channel(vq1_mbox, 0); - if (IS_ERR(drproc->mbox)) { + chan->chan = mbox_request_channel(vq1_mbox, 0); + if (IS_ERR(chan->chan)) { ret = -EBUSY; dev_err(dev, "mbox_request_channel failed: %ld\n", - PTR_ERR(drproc->mbox)); + PTR_ERR(chan->chan)); return ret; } + INIT_WORK(&chan->vq_work, bflb_rproc_mb_vq_work); + dev_dbg(dev, "bl808_rproc_attach: Attaching to %s", rproc->name); return 0; @@ -292,6 +325,7 @@ static int bl808_rproc_detach(struct rproc *rproc) return 0; } + static const struct rproc_ops bl808_rproc_ops = { .start = bl808_rproc_start, .stop = bl808_rproc_stop, @@ -330,6 +364,13 @@ static int bl808_rproc_probe(struct platform_device *pdev) drproc->rproc = rproc; rproc->has_iommu = false; + drproc->workqueue = create_workqueue(dev_name(dev)); + if (!drproc->workqueue) { + dev_err(dev, "cannot create workqueue\n"); + ret = -ENOMEM; + goto free_wkq; + } + ret = rproc_add(rproc); if (ret) { dev_err(dev, "rproc_add failed: %d\n", ret); @@ -342,6 +383,8 @@ static int bl808_rproc_probe(struct platform_device *pdev) return 0; +free_wkq: + destroy_workqueue(drproc->workqueue); free_rproc: rproc_free(rproc); free_mem: @@ -353,12 +396,15 @@ free_mem: static int bl808_rproc_remove(struct platform_device *pdev) { struct rproc *rproc = platform_get_drvdata(pdev); + struct bl808_rproc *drproc = (struct bl808_rproc *)rproc->priv; struct device *dev = &pdev->dev; dev_dbg(dev, "bl808_rproc_remove"); /*XXX TODO: we need to unregister our mailbox? */ + destroy_workqueue(drproc->workqueue); + rproc_del(rproc); rproc_free(rproc); if (dev->of_node)