Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright (c) 2017-2018 HiSilicon Limited.
0003 // Copyright (c) 2017-2018 Linaro Limited.
0004 
0005 #include <linux/bitops.h>
0006 #include <linux/delay.h>
0007 #include <linux/device.h>
0008 #include <linux/err.h>
0009 #include <linux/interrupt.h>
0010 #include <linux/io.h>
0011 #include <linux/iopoll.h>
0012 #include <linux/mailbox_controller.h>
0013 #include <linux/module.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/slab.h>
0016 
0017 #include "mailbox.h"
0018 
0019 #define MBOX_CHAN_MAX           32
0020 
0021 #define MBOX_RX             0x0
0022 #define MBOX_TX             0x1
0023 
0024 #define MBOX_BASE(mbox, ch)     ((mbox)->base + ((ch) * 0x40))
0025 #define MBOX_SRC_REG            0x00
0026 #define MBOX_DST_REG            0x04
0027 #define MBOX_DCLR_REG           0x08
0028 #define MBOX_DSTAT_REG          0x0c
0029 #define MBOX_MODE_REG           0x10
0030 #define MBOX_IMASK_REG          0x14
0031 #define MBOX_ICLR_REG           0x18
0032 #define MBOX_SEND_REG           0x1c
0033 #define MBOX_DATA_REG           0x20
0034 
0035 #define MBOX_IPC_LOCK_REG       0xa00
0036 #define MBOX_IPC_UNLOCK         0x1acce551
0037 
0038 #define MBOX_AUTOMATIC_ACK      1
0039 
0040 #define MBOX_STATE_IDLE         BIT(4)
0041 #define MBOX_STATE_READY        BIT(5)
0042 #define MBOX_STATE_ACK          BIT(7)
0043 
0044 #define MBOX_MSG_LEN            8
0045 
0046 /**
0047  * struct hi3660_chan_info - Hi3660 mailbox channel information
0048  * @dst_irq:    Interrupt vector for remote processor
0049  * @ack_irq:    Interrupt vector for local processor
0050  *
0051  * A channel can be used for TX or RX, it can trigger remote
0052  * processor interrupt to notify remote processor and can receive
0053  * interrupt if it has an incoming message.
0054  */
0055 struct hi3660_chan_info {
0056     unsigned int dst_irq;
0057     unsigned int ack_irq;
0058 };
0059 
0060 /**
0061  * struct hi3660_mbox - Hi3660 mailbox controller data
0062  * @dev:    Device to which it is attached
0063  * @base:   Base address of the register mapping region
0064  * @chan:   Representation of channels in mailbox controller
0065  * @mchan:  Representation of channel info
0066  * @controller: Representation of a communication channel controller
0067  *
0068  * Mailbox controller includes 32 channels and can allocate
0069  * channel for message transferring.
0070  */
0071 struct hi3660_mbox {
0072     struct device *dev;
0073     void __iomem *base;
0074     struct mbox_chan chan[MBOX_CHAN_MAX];
0075     struct hi3660_chan_info mchan[MBOX_CHAN_MAX];
0076     struct mbox_controller controller;
0077 };
0078 
0079 static struct hi3660_mbox *to_hi3660_mbox(struct mbox_controller *mbox)
0080 {
0081     return container_of(mbox, struct hi3660_mbox, controller);
0082 }
0083 
0084 static int hi3660_mbox_check_state(struct mbox_chan *chan)
0085 {
0086     unsigned long ch = (unsigned long)chan->con_priv;
0087     struct hi3660_mbox *mbox = to_hi3660_mbox(chan->mbox);
0088     struct hi3660_chan_info *mchan = &mbox->mchan[ch];
0089     void __iomem *base = MBOX_BASE(mbox, ch);
0090     unsigned long val;
0091     unsigned int ret;
0092 
0093     /* Mailbox is ready to use */
0094     if (readl(base + MBOX_MODE_REG) & MBOX_STATE_READY)
0095         return 0;
0096 
0097     /* Wait for acknowledge from remote */
0098     ret = readx_poll_timeout_atomic(readl, base + MBOX_MODE_REG,
0099             val, (val & MBOX_STATE_ACK), 1000, 300000);
0100     if (ret) {
0101         dev_err(mbox->dev, "%s: timeout for receiving ack\n", __func__);
0102         return ret;
0103     }
0104 
0105     /* clear ack state, mailbox will get back to ready state */
0106     writel(BIT(mchan->ack_irq), base + MBOX_ICLR_REG);
0107 
0108     return 0;
0109 }
0110 
0111 static int hi3660_mbox_unlock(struct mbox_chan *chan)
0112 {
0113     struct hi3660_mbox *mbox = to_hi3660_mbox(chan->mbox);
0114     unsigned int val, retry = 3;
0115 
0116     do {
0117         writel(MBOX_IPC_UNLOCK, mbox->base + MBOX_IPC_LOCK_REG);
0118 
0119         val = readl(mbox->base + MBOX_IPC_LOCK_REG);
0120         if (!val)
0121             break;
0122 
0123         udelay(10);
0124     } while (retry--);
0125 
0126     if (val)
0127         dev_err(mbox->dev, "%s: failed to unlock mailbox\n", __func__);
0128 
0129     return (!val) ? 0 : -ETIMEDOUT;
0130 }
0131 
0132 static int hi3660_mbox_acquire_channel(struct mbox_chan *chan)
0133 {
0134     unsigned long ch = (unsigned long)chan->con_priv;
0135     struct hi3660_mbox *mbox = to_hi3660_mbox(chan->mbox);
0136     struct hi3660_chan_info *mchan = &mbox->mchan[ch];
0137     void __iomem *base = MBOX_BASE(mbox, ch);
0138     unsigned int val, retry;
0139 
0140     for (retry = 10; retry; retry--) {
0141         /* Check if channel is in idle state */
0142         if (readl(base + MBOX_MODE_REG) & MBOX_STATE_IDLE) {
0143             writel(BIT(mchan->ack_irq), base + MBOX_SRC_REG);
0144 
0145             /* Check ack bit has been set successfully */
0146             val = readl(base + MBOX_SRC_REG);
0147             if (val & BIT(mchan->ack_irq))
0148                 break;
0149         }
0150     }
0151 
0152     if (!retry)
0153         dev_err(mbox->dev, "%s: failed to acquire channel\n", __func__);
0154 
0155     return retry ? 0 : -ETIMEDOUT;
0156 }
0157 
0158 static int hi3660_mbox_startup(struct mbox_chan *chan)
0159 {
0160     int ret;
0161 
0162     ret = hi3660_mbox_unlock(chan);
0163     if (ret)
0164         return ret;
0165 
0166     ret = hi3660_mbox_acquire_channel(chan);
0167     if (ret)
0168         return ret;
0169 
0170     return 0;
0171 }
0172 
0173 static int hi3660_mbox_send_data(struct mbox_chan *chan, void *msg)
0174 {
0175     unsigned long ch = (unsigned long)chan->con_priv;
0176     struct hi3660_mbox *mbox = to_hi3660_mbox(chan->mbox);
0177     struct hi3660_chan_info *mchan = &mbox->mchan[ch];
0178     void __iomem *base = MBOX_BASE(mbox, ch);
0179     u32 *buf = msg;
0180     unsigned int i;
0181     int ret;
0182 
0183     ret = hi3660_mbox_check_state(chan);
0184     if (ret)
0185         return ret;
0186 
0187     /* Clear mask for destination interrupt */
0188     writel_relaxed(~BIT(mchan->dst_irq), base + MBOX_IMASK_REG);
0189 
0190     /* Config destination for interrupt vector */
0191     writel_relaxed(BIT(mchan->dst_irq), base + MBOX_DST_REG);
0192 
0193     /* Automatic acknowledge mode */
0194     writel_relaxed(MBOX_AUTOMATIC_ACK, base + MBOX_MODE_REG);
0195 
0196     /* Fill message data */
0197     for (i = 0; i < MBOX_MSG_LEN; i++)
0198         writel_relaxed(buf[i], base + MBOX_DATA_REG + i * 4);
0199 
0200     /* Trigger data transferring */
0201     writel(BIT(mchan->ack_irq), base + MBOX_SEND_REG);
0202     return 0;
0203 }
0204 
0205 static const struct mbox_chan_ops hi3660_mbox_ops = {
0206     .startup    = hi3660_mbox_startup,
0207     .send_data  = hi3660_mbox_send_data,
0208 };
0209 
0210 static struct mbox_chan *hi3660_mbox_xlate(struct mbox_controller *controller,
0211                        const struct of_phandle_args *spec)
0212 {
0213     struct hi3660_mbox *mbox = to_hi3660_mbox(controller);
0214     struct hi3660_chan_info *mchan;
0215     unsigned int ch = spec->args[0];
0216 
0217     if (ch >= MBOX_CHAN_MAX) {
0218         dev_err(mbox->dev, "Invalid channel idx %d\n", ch);
0219         return ERR_PTR(-EINVAL);
0220     }
0221 
0222     mchan = &mbox->mchan[ch];
0223     mchan->dst_irq = spec->args[1];
0224     mchan->ack_irq = spec->args[2];
0225 
0226     return &mbox->chan[ch];
0227 }
0228 
0229 static const struct of_device_id hi3660_mbox_of_match[] = {
0230     { .compatible = "hisilicon,hi3660-mbox", },
0231     {},
0232 };
0233 
0234 MODULE_DEVICE_TABLE(of, hi3660_mbox_of_match);
0235 
0236 static int hi3660_mbox_probe(struct platform_device *pdev)
0237 {
0238     struct device *dev = &pdev->dev;
0239     struct hi3660_mbox *mbox;
0240     struct mbox_chan *chan;
0241     unsigned long ch;
0242     int err;
0243 
0244     mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
0245     if (!mbox)
0246         return -ENOMEM;
0247 
0248     mbox->base = devm_platform_ioremap_resource(pdev, 0);
0249     if (IS_ERR(mbox->base))
0250         return PTR_ERR(mbox->base);
0251 
0252     mbox->dev = dev;
0253     mbox->controller.dev = dev;
0254     mbox->controller.chans = mbox->chan;
0255     mbox->controller.num_chans = MBOX_CHAN_MAX;
0256     mbox->controller.ops = &hi3660_mbox_ops;
0257     mbox->controller.of_xlate = hi3660_mbox_xlate;
0258 
0259     /* Initialize mailbox channel data */
0260     chan = mbox->chan;
0261     for (ch = 0; ch < MBOX_CHAN_MAX; ch++)
0262         chan[ch].con_priv = (void *)ch;
0263 
0264     err = devm_mbox_controller_register(dev, &mbox->controller);
0265     if (err) {
0266         dev_err(dev, "Failed to register mailbox %d\n", err);
0267         return err;
0268     }
0269 
0270     platform_set_drvdata(pdev, mbox);
0271     dev_info(dev, "Mailbox enabled\n");
0272     return 0;
0273 }
0274 
0275 static struct platform_driver hi3660_mbox_driver = {
0276     .probe  = hi3660_mbox_probe,
0277     .driver = {
0278         .name = "hi3660-mbox",
0279         .of_match_table = hi3660_mbox_of_match,
0280     },
0281 };
0282 
0283 static int __init hi3660_mbox_init(void)
0284 {
0285     return platform_driver_register(&hi3660_mbox_driver);
0286 }
0287 core_initcall(hi3660_mbox_init);
0288 
0289 static void __exit hi3660_mbox_exit(void)
0290 {
0291     platform_driver_unregister(&hi3660_mbox_driver);
0292 }
0293 module_exit(hi3660_mbox_exit);
0294 
0295 MODULE_LICENSE("GPL");
0296 MODULE_DESCRIPTION("Hisilicon Hi3660 Mailbox Controller");
0297 MODULE_AUTHOR("Leo Yan <leo.yan@linaro.org>");