[RFC PATCH 2/2] imx: mailbox: Introduce TX doorbell with ACK

From: daniel . baluta
Date: Mon Jun 10 2019 - 10:18:59 EST


From: Daniel Baluta <daniel.baluta@xxxxxxx>

TX doorbell with ACK will allow us to push the doorbell ring button
(trigger GIR) and also will allow us to handle the response from DSP.

DSP firmware found on i.MX8 boards implements a duplex
communication protocol over MU channels.

On the host side (Linux) we need to plugin into Sound Open Firmware IPC
communication infrastructure which handles all the details (e.g message
queuing, tx/rx logic) [1] and the users are only required to provide the
following callbacks:

- send_msg (for Tx)
- irq_handler (Ack of Tx, request from DSP)

In order to implement send_msg and irq_handler we will use two MU
channels:
* channel #0, TX doorbell with ACK
* channel #1, RX doorbell

Sending a request Host -> DSP (channel #0)
- send_msg callback
- write data into SHMEM
- push doorbell ring button (trigger GIR)
- irq handler
- handle DSP request (channel #1)
- read SHMEM and trigger SOF IPC state machine
- send ACK (push doorbell ring button for channel #1)
- handle DSP response (ACK) (channel #0)
- read SHMEM and trigger IPC state machine

The easisest way to implement this is to directly access the MU
registers but since the MU is abstracted using the mailbox interface
we need to use that instead.

[1] https://elixir.bootlin.com/linux/v5.2-rc4/source/sound/soc/sof/ipc.c

Signed-off-by: Daniel Baluta <daniel.baluta@xxxxxxx>
---
drivers/mailbox/imx-mailbox.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index 9f74dee1a58c..3a91611e17d2 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -42,6 +42,7 @@ enum imx_mu_chan_type {
IMX_MU_TYPE_RX, /* Rx */
IMX_MU_TYPE_TXDB, /* Tx doorbell */
IMX_MU_TYPE_RXDB, /* Rx doorbell */
+ IMX_MU_TYPE_TXDB_ACK /* Tx doorbell with Ack */
};

struct imx_mu_con_priv {
@@ -124,6 +125,7 @@ static irqreturn_t imx_mu_isr(int irq, void *p)
(ctrl & IMX_MU_xCR_RIEn(cp->idx));
break;
case IMX_MU_TYPE_RXDB:
+ case IMX_MU_TYPE_TXDB_ACK:
val &= IMX_MU_xSR_GIPn(cp->idx) &
(ctrl & IMX_MU_xCR_GIEn(cp->idx));
break;
@@ -200,6 +202,7 @@ static int imx_mu_startup(struct mbox_chan *chan)
imx_mu_xcr_rmw(priv, IMX_MU_xCR_RIEn(cp->idx), 0);
break;
case IMX_MU_TYPE_RXDB:
+ case IMX_MU_TYPE_TXDB_ACK:
imx_mu_xcr_rmw(priv, IMX_MU_xCR_GIEn(cp->idx), 0);
break;
default:
--
2.17.1