0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/io.h>
0012 #include <linux/err.h>
0013 #include <linux/init.h>
0014 #include <linux/module.h>
0015 #include <linux/kernel.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/mailbox_controller.h>
0019 #include <soc/microchip/mpfs.h>
0020
0021 #define SERVICES_CR_OFFSET 0x50u
0022 #define SERVICES_SR_OFFSET 0x54u
0023 #define MAILBOX_REG_OFFSET 0x800u
0024 #define MSS_SYS_MAILBOX_DATA_OFFSET 0u
0025 #define SCB_MASK_WIDTH 16u
0026
0027
0028
0029 #define SCB_CTRL_REQ (0)
0030 #define SCB_CTRL_REQ_MASK BIT(SCB_CTRL_REQ)
0031
0032 #define SCB_CTRL_BUSY (1)
0033 #define SCB_CTRL_BUSY_MASK BIT(SCB_CTRL_BUSY)
0034
0035 #define SCB_CTRL_ABORT (2)
0036 #define SCB_CTRL_ABORT_MASK BIT(SCB_CTRL_ABORT)
0037
0038 #define SCB_CTRL_NOTIFY (3)
0039 #define SCB_CTRL_NOTIFY_MASK BIT(SCB_CTRL_NOTIFY)
0040
0041 #define SCB_CTRL_POS (16)
0042 #define SCB_CTRL_MASK GENMASK_ULL(SCB_CTRL_POS + SCB_MASK_WIDTH, SCB_CTRL_POS)
0043
0044
0045
0046 #define SCB_STATUS_REQ (0)
0047 #define SCB_STATUS_REQ_MASK BIT(SCB_STATUS_REQ)
0048
0049 #define SCB_STATUS_BUSY (1)
0050 #define SCB_STATUS_BUSY_MASK BIT(SCB_STATUS_BUSY)
0051
0052 #define SCB_STATUS_ABORT (2)
0053 #define SCB_STATUS_ABORT_MASK BIT(SCB_STATUS_ABORT)
0054
0055 #define SCB_STATUS_NOTIFY (3)
0056 #define SCB_STATUS_NOTIFY_MASK BIT(SCB_STATUS_NOTIFY)
0057
0058 #define SCB_STATUS_POS (16)
0059 #define SCB_STATUS_MASK GENMASK_ULL(SCB_STATUS_POS + SCB_MASK_WIDTH, SCB_STATUS_POS)
0060
0061 struct mpfs_mbox {
0062 struct mbox_controller controller;
0063 struct device *dev;
0064 int irq;
0065 void __iomem *mbox_base;
0066 void __iomem *int_reg;
0067 struct mbox_chan chans[1];
0068 struct mpfs_mss_response *response;
0069 u16 resp_offset;
0070 };
0071
0072 static bool mpfs_mbox_busy(struct mpfs_mbox *mbox)
0073 {
0074 u32 status;
0075
0076 status = readl_relaxed(mbox->mbox_base + SERVICES_SR_OFFSET);
0077
0078 return status & SCB_STATUS_BUSY_MASK;
0079 }
0080
0081 static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data)
0082 {
0083 struct mpfs_mbox *mbox = (struct mpfs_mbox *)chan->con_priv;
0084 struct mpfs_mss_msg *msg = data;
0085 u32 tx_trigger;
0086 u16 opt_sel;
0087 u32 val = 0u;
0088
0089 mbox->response = msg->response;
0090 mbox->resp_offset = msg->resp_offset;
0091
0092 if (mpfs_mbox_busy(mbox))
0093 return -EBUSY;
0094
0095 if (msg->cmd_data_size) {
0096 u32 index;
0097 u8 extra_bits = msg->cmd_data_size & 3;
0098 u32 *word_buf = (u32 *)msg->cmd_data;
0099
0100 for (index = 0; index < (msg->cmd_data_size / 4); index++)
0101 writel_relaxed(word_buf[index],
0102 mbox->mbox_base + MAILBOX_REG_OFFSET + index * 0x4);
0103 if (extra_bits) {
0104 u8 i;
0105 u8 byte_off = ALIGN_DOWN(msg->cmd_data_size, 4);
0106 u8 *byte_buf = msg->cmd_data + byte_off;
0107
0108 val = readl_relaxed(mbox->mbox_base +
0109 MAILBOX_REG_OFFSET + index * 0x4);
0110
0111 for (i = 0u; i < extra_bits; i++) {
0112 val &= ~(0xffu << (i * 8u));
0113 val |= (byte_buf[i] << (i * 8u));
0114 }
0115
0116 writel_relaxed(val,
0117 mbox->mbox_base + MAILBOX_REG_OFFSET + index * 0x4);
0118 }
0119 }
0120
0121 opt_sel = ((msg->mbox_offset << 7u) | (msg->cmd_opcode & 0x7fu));
0122 tx_trigger = (opt_sel << SCB_CTRL_POS) & SCB_CTRL_MASK;
0123 tx_trigger |= SCB_CTRL_REQ_MASK | SCB_STATUS_NOTIFY_MASK;
0124 writel_relaxed(tx_trigger, mbox->mbox_base + SERVICES_CR_OFFSET);
0125
0126 return 0;
0127 }
0128
0129 static void mpfs_mbox_rx_data(struct mbox_chan *chan)
0130 {
0131 struct mpfs_mbox *mbox = (struct mpfs_mbox *)chan->con_priv;
0132 struct mpfs_mss_response *response = mbox->response;
0133 u16 num_words = ALIGN((response->resp_size), (4)) / 4U;
0134 u32 i;
0135
0136 if (!response->resp_msg) {
0137 dev_err(mbox->dev, "failed to assign memory for response %d\n", -ENOMEM);
0138 return;
0139 }
0140
0141 if (!mpfs_mbox_busy(mbox)) {
0142 for (i = 0; i < num_words; i++) {
0143 response->resp_msg[i] =
0144 readl_relaxed(mbox->mbox_base + MAILBOX_REG_OFFSET
0145 + mbox->resp_offset + i * 0x4);
0146 }
0147 }
0148
0149 mbox_chan_received_data(chan, response);
0150 }
0151
0152 static irqreturn_t mpfs_mbox_inbox_isr(int irq, void *data)
0153 {
0154 struct mbox_chan *chan = data;
0155 struct mpfs_mbox *mbox = (struct mpfs_mbox *)chan->con_priv;
0156
0157 writel_relaxed(0, mbox->int_reg);
0158
0159 mpfs_mbox_rx_data(chan);
0160
0161 mbox_chan_txdone(chan, 0);
0162 return IRQ_HANDLED;
0163 }
0164
0165 static int mpfs_mbox_startup(struct mbox_chan *chan)
0166 {
0167 struct mpfs_mbox *mbox = (struct mpfs_mbox *)chan->con_priv;
0168 int ret = 0;
0169
0170 if (!mbox)
0171 return -EINVAL;
0172
0173 ret = devm_request_irq(mbox->dev, mbox->irq, mpfs_mbox_inbox_isr, 0, "mpfs-mailbox", chan);
0174 if (ret)
0175 dev_err(mbox->dev, "failed to register mailbox interrupt:%d\n", ret);
0176
0177 return ret;
0178 }
0179
0180 static void mpfs_mbox_shutdown(struct mbox_chan *chan)
0181 {
0182 struct mpfs_mbox *mbox = (struct mpfs_mbox *)chan->con_priv;
0183
0184 devm_free_irq(mbox->dev, mbox->irq, chan);
0185 }
0186
0187 static const struct mbox_chan_ops mpfs_mbox_ops = {
0188 .send_data = mpfs_mbox_send_data,
0189 .startup = mpfs_mbox_startup,
0190 .shutdown = mpfs_mbox_shutdown,
0191 };
0192
0193 static int mpfs_mbox_probe(struct platform_device *pdev)
0194 {
0195 struct mpfs_mbox *mbox;
0196 struct resource *regs;
0197 int ret;
0198
0199 mbox = devm_kzalloc(&pdev->dev, sizeof(*mbox), GFP_KERNEL);
0200 if (!mbox)
0201 return -ENOMEM;
0202
0203 mbox->mbox_base = devm_platform_get_and_ioremap_resource(pdev, 0, ®s);
0204 if (IS_ERR(mbox->mbox_base))
0205 return PTR_ERR(mbox->mbox_base);
0206
0207 mbox->int_reg = devm_platform_get_and_ioremap_resource(pdev, 1, ®s);
0208 if (IS_ERR(mbox->int_reg))
0209 return PTR_ERR(mbox->int_reg);
0210
0211 mbox->irq = platform_get_irq(pdev, 0);
0212 if (mbox->irq < 0)
0213 return mbox->irq;
0214
0215 mbox->dev = &pdev->dev;
0216
0217 mbox->chans[0].con_priv = mbox;
0218 mbox->controller.dev = mbox->dev;
0219 mbox->controller.num_chans = 1;
0220 mbox->controller.chans = mbox->chans;
0221 mbox->controller.ops = &mpfs_mbox_ops;
0222 mbox->controller.txdone_irq = true;
0223
0224 ret = devm_mbox_controller_register(&pdev->dev, &mbox->controller);
0225 if (ret) {
0226 dev_err(&pdev->dev, "Registering MPFS mailbox controller failed\n");
0227 return ret;
0228 }
0229 dev_info(&pdev->dev, "Registered MPFS mailbox controller driver\n");
0230
0231 return 0;
0232 }
0233
0234 static const struct of_device_id mpfs_mbox_of_match[] = {
0235 {.compatible = "microchip,mpfs-mailbox", },
0236 {},
0237 };
0238 MODULE_DEVICE_TABLE(of, mpfs_mbox_of_match);
0239
0240 static struct platform_driver mpfs_mbox_driver = {
0241 .driver = {
0242 .name = "mpfs-mailbox",
0243 .of_match_table = mpfs_mbox_of_match,
0244 },
0245 .probe = mpfs_mbox_probe,
0246 };
0247 module_platform_driver(mpfs_mbox_driver);
0248
0249 MODULE_LICENSE("GPL v2");
0250 MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
0251 MODULE_DESCRIPTION("MPFS mailbox controller driver");