mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-03-15 11:34:41 +00:00
IPC Mailbox Changes
This commit is contained in:
parent
7c892825e7
commit
e17d63c2b6
4 changed files with 135 additions and 13 deletions
|
@ -18,7 +18,7 @@
|
|||
|
||||
chosen {
|
||||
stdout-path = "serial0:2000000n8";
|
||||
bootargs = "console=ttyS0,2000000 loglevel=8 earlycon=sbi root=/dev/mmcblk0p2 rootwait rootfstype=ext4";
|
||||
bootargs = "console=ttyS0,2000000 loglevel=8 earlycon=sbi root=/dev/mmcblk0p2 rootwait rootfstype=ext4 dyndbg=\"file drivers/remoteproc/* +p; file drivers/rpmsg/* +p; file drivers/virtio/* +p; file drivers/mailbox/* +p;\"";
|
||||
linux,initrd-start = <0x0 0x52000000>;
|
||||
linux,initrd-end = <0x0 0x52941784>;
|
||||
};
|
||||
|
@ -28,6 +28,7 @@
|
|||
reg = <0x50000000 0x04000000>;
|
||||
};
|
||||
|
||||
|
||||
xip_flash@58500000 {
|
||||
compatible = "mtd-rom";
|
||||
reg = <0x58500000 0x400000>;
|
||||
|
@ -53,6 +54,7 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&enet0 {
|
||||
&rproc {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
|
|
@ -59,6 +59,31 @@
|
|||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
reserved-memory {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
/* putting this at the top of uncached WRAM for the moment */
|
||||
vdev0vring0: vdev0vring0@22054000 {
|
||||
compatible = "shared-dma-pool";
|
||||
reg = <0x22050000 0x4000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
vdev0vring1: vdev0vring1@22055000 {
|
||||
compatible = "shared-dma-pool";
|
||||
reg = <0x22054000 0x4000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
vdev0buffer: vdev0buffer@22056000 {
|
||||
compatible = "shared-dma-pool";
|
||||
reg = <0x22042000 0x8000>;
|
||||
no-map;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
soc {
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
@ -140,5 +165,22 @@
|
|||
#interrupt-cells = <2>;
|
||||
riscv,ndev = <64>;
|
||||
};
|
||||
|
||||
clint: timer@e4000000 {
|
||||
compatible = "thead,c900-clint";
|
||||
reg = <0xe4000000 0xc000>;
|
||||
interrupts-extended = <&cpu0_intc 3>,
|
||||
<&cpu0_intc 7>;
|
||||
};
|
||||
|
||||
|
||||
rproc: rproc@22054000 {
|
||||
compatible = "bflb,bl808-rproc";
|
||||
reg = <0x22054000 0x4000>;
|
||||
memory-region = <&vdev0vring0>, <&vdev0vring1>, <&vdev0buffer>;
|
||||
mboxes = <&ipclic BFLB_IPC_TARGET_M0 BFLB_IPC_MBOX_VIRTIO_KICK>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -64,6 +64,7 @@ static inline u32 bflb_ipc_get_hwirq(u16 source, u16 device)
|
|||
{
|
||||
pr_debug("%s: source: %u, device: %u\n", __func__, source, device);
|
||||
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
|
@ -72,7 +73,7 @@ static void bflb_ipc_dump_regs(struct bflb_ipc *ipc)
|
|||
{
|
||||
int i;
|
||||
for (i=0; i<4; i++) {
|
||||
dev_dbg(ipc->dev, "base %px\n", ipc->base[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, "IRSRR: 0x%08x\n", readl(ipc->base[i] + IPC_REG_IRSRR));
|
||||
dev_dbg(ipc->dev, "ICR: 0x%08x\n", readl(ipc->base[i] + IPC_REG_ICR));
|
||||
|
@ -85,6 +86,30 @@ static void bflb_ipc_dump_regs(struct bflb_ipc *ipc)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* check the High/Low registers for the MBOX and send it off to
|
||||
* the mailbox.
|
||||
* JH: I'm guessing Source should map to the mailbox? But I've only allocated a single
|
||||
* mailbox so far, so its discarded.
|
||||
*/
|
||||
|
||||
static void bflb_mbox_poll(struct bflb_ipc *ipc)
|
||||
{
|
||||
|
||||
u32 signal = readl(ipc->base[1] + IPC_REG_ILSHR);
|
||||
u32 source = readl(ipc->base[1] + IPC_REG_ILSLR);
|
||||
|
||||
dev_dbg(ipc->dev, "signal: 0x%08x, source: 0x%08x\r\n", signal, source);
|
||||
|
||||
mbox_chan_received_data(&ipc->chans[0], signal);
|
||||
|
||||
/* clear the IPC_REG_ILSLR and IPC_REG_ILSHR */
|
||||
writel(0, ipc->base[1] + IPC_REG_ILSLR);
|
||||
writel(0, ipc->base[1] + IPC_REG_ILSHR);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static irqreturn_t bflb_ipc_irq_fn(int irq, void *data)
|
||||
{
|
||||
struct bflb_ipc *ipc = data;
|
||||
|
@ -92,12 +117,22 @@ static irqreturn_t bflb_ipc_irq_fn(int irq, void *data)
|
|||
int pos;
|
||||
|
||||
stat = readl(ipc->base[1] + IPC_REG_ISR);
|
||||
for_each_set_bit(pos, &stat, 32)
|
||||
generic_handle_domain_irq(ipc->irq_domain, pos);
|
||||
|
||||
|
||||
/*JH: I'm guessing there is a better way to pull out the mailbox IPC from others ?*/
|
||||
|
||||
for_each_set_bit(pos, &stat, 32) {
|
||||
if (pos == BFLB_IPC_DEVICE_MBOX)
|
||||
bflb_mbox_poll(ipc);
|
||||
else
|
||||
generic_handle_domain_irq(ipc->irq_domain, pos);
|
||||
}
|
||||
writel(stat, ipc->base[1] + IPC_REG_ICR);
|
||||
|
||||
/* EOI the irqs */
|
||||
writel(stat, ipc->base[2] + IPC_REG_ISWR);
|
||||
/* EOI the irqs except our MBOX */
|
||||
/* JH: I don't EOI the mailbox, I just look to see if the High/Low registers are cleared on M0 side */
|
||||
if (stat != (1 << BFLB_IPC_DEVICE_MBOX))
|
||||
writel(stat, ipc->base[2] + IPC_REG_ISWR);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@ -157,17 +192,42 @@ static const struct irq_domain_ops bflb_ipc_irq_ops = {
|
|||
.xlate = bflb_ipc_domain_xlate,
|
||||
};
|
||||
|
||||
/* 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)
|
||||
{
|
||||
struct bflb_ipc *ipc = to_bflb_ipc(chan->mbox);
|
||||
|
||||
u32 mbox_high = readl(ipc->base[2] + IPC_REG_ILSHR);
|
||||
u32 mbox_low = readl(ipc->base[2] + IPC_REG_ILSLR);
|
||||
|
||||
dev_dbg(ipc->dev, "%s: low: 0x%08x high: 0x%08x\r\n", __func__, mbox_low, mbox_high);
|
||||
|
||||
return !(mbox_low | mbox_high);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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;
|
||||
u32 hwirq;
|
||||
|
||||
hwirq = bflb_ipc_get_hwirq(mchan->client_id, mchan->signal_id);
|
||||
if (!bflb_ipc_mbox_can_send(chan))
|
||||
return -EBUSY;
|
||||
|
||||
dev_dbg(ipc->dev, "%s: hwirq: %u\n", __func__, hwirq);
|
||||
|
||||
// writel(hwirq, ipc->base + IPC_REG_SEND_ID);
|
||||
dev_dbg(ipc->dev, "%s: %d %d\n", __func__, mchan->client_id, mchan->signal_id);
|
||||
|
||||
|
||||
// /* write our signal number to high register */
|
||||
writel(mchan->signal_id, ipc->base[2] + IPC_REG_ILSHR);
|
||||
// /* write our data to low register */
|
||||
writel((u32)data, ipc->base[2] + IPC_REG_ILSLR);
|
||||
|
||||
/* and now kick the remote processor */
|
||||
writel((1 << BFLB_IPC_DEVICE_MBOX), ipc->base[2] + IPC_REG_ISWR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -219,6 +279,7 @@ static struct mbox_chan *bflb_ipc_mbox_xlate(struct mbox_controller *mbox,
|
|||
return chan;
|
||||
}
|
||||
|
||||
|
||||
static const struct mbox_chan_ops ipc_mbox_chan_ops = {
|
||||
.send_data = bflb_ipc_mbox_send_data,
|
||||
.shutdown = bflb_ipc_mbox_shutdown,
|
||||
|
@ -236,6 +297,7 @@ static int bflb_ipc_setup_mbox(struct bflb_ipc *ipc,
|
|||
/*
|
||||
* Find out the number of clients interested in this mailbox
|
||||
* and create channels accordingly.
|
||||
* JH: How do we allocate them so we can lookup by name?
|
||||
*/
|
||||
ipc->num_chans = 0;
|
||||
for_each_node_with_property(client_dn, "mboxes") {
|
||||
|
@ -253,7 +315,7 @@ static int bflb_ipc_setup_mbox(struct bflb_ipc *ipc,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
dev_dbg(dev, "%s: num_chans: %d", __func__, ipc->num_chans);
|
||||
/* If no clients are found, skip registering as a mbox controller */
|
||||
if (!ipc->num_chans)
|
||||
return 0;
|
||||
|
@ -272,6 +334,14 @@ static int bflb_ipc_setup_mbox(struct bflb_ipc *ipc,
|
|||
mbox->txdone_irq = false;
|
||||
mbox->txdone_poll = false;
|
||||
|
||||
|
||||
/* 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);
|
||||
|
||||
/* unmask our interupt */
|
||||
writel(BIT(BFLB_IPC_DEVICE_MBOX), ipc->base[1] + IPC_REG_IUSR);
|
||||
|
||||
return devm_mbox_controller_register(dev, mbox);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,15 @@
|
|||
/* Peripheral device ID */
|
||||
#define BFLB_IPC_DEVICE_SDHCI 0
|
||||
#define BFLB_IPC_DEVICE_UART2 1
|
||||
#define BFLB_IPC_DEVICE_USB 2
|
||||
#define BFLB_IPC_DEVICE_USB 2
|
||||
#define BFLB_IPC_DEVICE_EMAC 3
|
||||
#define BFLB_IPC_DEVICE_MBOX 5
|
||||
|
||||
#define BFLB_IPC_TARGET_M0 0
|
||||
#define BFLB_IPC_TARGET_LP 1
|
||||
|
||||
/* MailBox Signals */
|
||||
#define BFLB_IPC_MBOX_VIRTIO_KICK 1
|
||||
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue