mailbox: omap: Add support for TI K3 SoCs

The TI K3 AM65x and J721E family of SoCs have a new Mailbox IP that
is based on the existing Mailbox IP present in OMAP architecture based
SoCs. Each instance of the legacy OMAP Mailbox IP is now a single cluster
within the newer Mailbox IP instance on K3 architecture based SoCs. A
single K3 Mailbox IP instance has multiple clusters with each cluster
providing the same functionality as the existing OMAP Mailbox IP.

Reuse the existing OMAP Mailbox driver to extend the support for this
newer IP present within the Main NavSS block on K3 SoCs. The K3 family
of SoCs use 64-bit ARMv8 processors for running Linux, so the driver is
also enhanced to deal with the differences between the 32-bit message
payloads and the 64-bit pointers used by the client drivers.

Signed-off-by: Suman Anna <s-anna@ti.com>
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
This commit is contained in:
Suman Anna 2019-06-04 12:01:46 -05:00 committed by Jassi Brar
parent 8c665292ec
commit 9c1f2a5dc2
3 changed files with 30 additions and 19 deletions

View File

@ -54,7 +54,7 @@ config ARMADA_37XX_RWTM_MBOX
config OMAP2PLUS_MBOX
tristate "OMAP2+ Mailbox framework support"
depends on ARCH_OMAP2PLUS
depends on ARCH_OMAP2PLUS || ARCH_K3
help
Mailbox implementation for OMAP family chips with hardware for
interprocessor communication involving DSP, IVA1.0 and IVA2 in

View File

@ -3,7 +3,7 @@
* OMAP mailbox driver
*
* Copyright (C) 2006-2009 Nokia Corporation. All rights reserved.
* Copyright (C) 2013-2016 Texas Instruments Incorporated - http://www.ti.com
* Copyright (C) 2013-2019 Texas Instruments Incorporated - http://www.ti.com
*
* Contact: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
* Suman Anna <s-anna@ti.com>
@ -141,14 +141,14 @@ void mbox_write_reg(struct omap_mbox_device *mdev, u32 val, size_t ofs)
}
/* Mailbox FIFO handle functions */
static mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox)
static u32 mbox_fifo_read(struct omap_mbox *mbox)
{
struct omap_mbox_fifo *fifo = &mbox->rx_fifo;
return (mbox_msg_t)mbox_read_reg(mbox->parent, fifo->msg);
return mbox_read_reg(mbox->parent, fifo->msg);
}
static void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
static void mbox_fifo_write(struct omap_mbox *mbox, u32 msg)
{
struct omap_mbox_fifo *fifo = &mbox->tx_fifo;
@ -256,14 +256,16 @@ static void mbox_rx_work(struct work_struct *work)
{
struct omap_mbox_queue *mq =
container_of(work, struct omap_mbox_queue, work);
mbox_msg_t msg;
mbox_msg_t data;
u32 msg;
int len;
while (kfifo_len(&mq->fifo) >= sizeof(msg)) {
len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
WARN_ON(len != sizeof(msg));
data = msg;
mbox_chan_received_data(mq->mbox->chan, (void *)msg);
mbox_chan_received_data(mq->mbox->chan, (void *)data);
spin_lock_irq(&mq->lock);
if (mq->full) {
mq->full = false;
@ -286,7 +288,7 @@ static void __mbox_tx_interrupt(struct omap_mbox *mbox)
static void __mbox_rx_interrupt(struct omap_mbox *mbox)
{
struct omap_mbox_queue *mq = mbox->rxq;
mbox_msg_t msg;
u32 msg;
int len;
while (!mbox_fifo_empty(mbox)) {
@ -540,13 +542,13 @@ static void omap_mbox_chan_shutdown(struct mbox_chan *chan)
mutex_unlock(&mdev->cfg_lock);
}
static int omap_mbox_chan_send_noirq(struct omap_mbox *mbox, void *data)
static int omap_mbox_chan_send_noirq(struct omap_mbox *mbox, u32 msg)
{
int ret = -EBUSY;
if (!mbox_fifo_full(mbox)) {
_omap_mbox_enable_irq(mbox, IRQ_RX);
mbox_fifo_write(mbox, (mbox_msg_t)data);
mbox_fifo_write(mbox, msg);
ret = 0;
_omap_mbox_disable_irq(mbox, IRQ_RX);
@ -558,12 +560,12 @@ static int omap_mbox_chan_send_noirq(struct omap_mbox *mbox, void *data)
return ret;
}
static int omap_mbox_chan_send(struct omap_mbox *mbox, void *data)
static int omap_mbox_chan_send(struct omap_mbox *mbox, u32 msg)
{
int ret = -EBUSY;
if (!mbox_fifo_full(mbox)) {
mbox_fifo_write(mbox, (mbox_msg_t)data);
mbox_fifo_write(mbox, msg);
ret = 0;
}
@ -576,14 +578,15 @@ static int omap_mbox_chan_send_data(struct mbox_chan *chan, void *data)
{
struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan);
int ret;
u32 msg = omap_mbox_message(data);
if (!mbox)
return -EINVAL;
if (mbox->send_no_irq)
ret = omap_mbox_chan_send_noirq(mbox, data);
ret = omap_mbox_chan_send_noirq(mbox, msg);
else
ret = omap_mbox_chan_send(mbox, data);
ret = omap_mbox_chan_send(mbox, msg);
return ret;
}
@ -656,6 +659,10 @@ static const struct of_device_id omap_mailbox_of_match[] = {
.compatible = "ti,omap4-mailbox",
.data = &omap4_data,
},
{
.compatible = "ti,am654-mailbox",
.data = &omap4_data,
},
{
/* end */
},
@ -830,7 +837,10 @@ static int omap_mbox_probe(struct platform_device *pdev)
mdev->intr_type = intr_type;
mdev->mboxes = list;
/* OMAP does not have a Tx-Done IRQ, but rather a Tx-Ready IRQ */
/*
* OMAP/K3 Mailbox IP does not have a Tx-Done IRQ, but rather a Tx-Ready
* IRQ and is needed to run the Tx state machine
*/
mdev->controller.txdone_irq = true;
mdev->controller.dev = mdev->dev;
mdev->controller.ops = &omap_mbox_chan_ops;
@ -899,9 +909,8 @@ static int __init omap_mbox_init(void)
return err;
/* kfifo size sanity check: alignment and minimal size */
mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t));
mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size,
sizeof(mbox_msg_t));
mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(u32));
mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, sizeof(u32));
err = platform_driver_register(&omap_mbox_driver);
if (err)

View File

@ -6,7 +6,9 @@
#ifndef OMAP_MAILBOX_H
#define OMAP_MAILBOX_H
typedef u32 mbox_msg_t;
typedef uintptr_t mbox_msg_t;
#define omap_mbox_message(data) (u32)(mbox_msg_t)(data)
typedef int __bitwise omap_mbox_irq_t;
#define IRQ_TX ((__force omap_mbox_irq_t) 1)