mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-03-16 03:54:10 +00:00
remoteproc working
This commit is contained in:
parent
9348e10221
commit
d2cf411318
3 changed files with 80 additions and 33 deletions
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue