1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Microchip PolarFire SoC (MPFS) system controller/mailbox controller driver 4 * 5 * Copyright (c) 2020-2022 Microchip Corporation. All rights reserved. 6 * 7 * Author: Conor Dooley <conor.dooley@microchip.com> 8 * 9 */ 10 11 #include <linux/io.h> 12 #include <linux/err.h> 13 #include <linux/init.h> 14 #include <linux/module.h> 15 #include <linux/kernel.h> 16 #include <linux/regmap.h> 17 #include <linux/interrupt.h> 18 #include <linux/mfd/syscon.h> 19 #include <linux/platform_device.h> 20 #include <linux/mailbox_controller.h> 21 #include <soc/microchip/mpfs.h> 22 23 #define MESSAGE_INT_OFFSET 0x18cu 24 #define SERVICES_CR_OFFSET 0x50u 25 #define SERVICES_SR_OFFSET 0x54u 26 #define MAILBOX_REG_OFFSET 0x800u 27 #define MSS_SYS_MAILBOX_DATA_OFFSET 0u 28 #define SCB_MASK_WIDTH 16u 29 30 /* SCBCTRL service control register */ 31 32 #define SCB_CTRL_REQ (0) 33 #define SCB_CTRL_REQ_MASK BIT(SCB_CTRL_REQ) 34 35 #define SCB_CTRL_BUSY (1) 36 #define SCB_CTRL_BUSY_MASK BIT(SCB_CTRL_BUSY) 37 38 #define SCB_CTRL_ABORT (2) 39 #define SCB_CTRL_ABORT_MASK BIT(SCB_CTRL_ABORT) 40 41 #define SCB_CTRL_NOTIFY (3) 42 #define SCB_CTRL_NOTIFY_MASK BIT(SCB_CTRL_NOTIFY) 43 44 #define SCB_CTRL_POS (16) 45 #define SCB_CTRL_MASK GENMASK(SCB_CTRL_POS + SCB_MASK_WIDTH - 1, SCB_CTRL_POS) 46 47 /* SCBCTRL service status register */ 48 49 #define SCB_STATUS_REQ (0) 50 #define SCB_STATUS_REQ_MASK BIT(SCB_STATUS_REQ) 51 52 #define SCB_STATUS_BUSY (1) 53 #define SCB_STATUS_BUSY_MASK BIT(SCB_STATUS_BUSY) 54 55 #define SCB_STATUS_ABORT (2) 56 #define SCB_STATUS_ABORT_MASK BIT(SCB_STATUS_ABORT) 57 58 #define SCB_STATUS_NOTIFY (3) 59 #define SCB_STATUS_NOTIFY_MASK BIT(SCB_STATUS_NOTIFY) 60 61 #define SCB_STATUS_POS (16) 62 #define SCB_STATUS_MASK GENMASK(SCB_STATUS_POS + SCB_MASK_WIDTH - 1, SCB_STATUS_POS) 63 64 struct mpfs_mbox { 65 struct mbox_controller controller; 66 struct device *dev; 67 int irq; 68 void __iomem *ctrl_base; 69 void __iomem *mbox_base; 70 void __iomem *int_reg; 71 struct mbox_chan chans[1]; 72 struct mpfs_mss_response *response; 73 struct regmap *sysreg_scb, *control_scb; 74 u16 resp_offset; 75 }; 76 77 static bool mpfs_mbox_busy(struct mpfs_mbox *mbox) 78 { 79 u32 status; 80 81 if (mbox->control_scb) 82 regmap_read(mbox->control_scb, SERVICES_SR_OFFSET, &status); 83 else 84 status = readl_relaxed(mbox->ctrl_base + SERVICES_SR_OFFSET); 85 86 return status & SCB_STATUS_BUSY_MASK; 87 } 88 89 static bool mpfs_mbox_last_tx_done(struct mbox_chan *chan) 90 { 91 struct mpfs_mbox *mbox = (struct mpfs_mbox *)chan->con_priv; 92 struct mpfs_mss_response *response = mbox->response; 93 u32 val; 94 95 if (mpfs_mbox_busy(mbox)) 96 return false; 97 98 /* 99 * The service status is stored in bits 31:16 of the SERVICES_SR 100 * register & is only valid when the system controller is not busy. 101 * Failed services are intended to generated interrupts, but in reality 102 * this does not happen, so the status must be checked here. 103 */ 104 if (mbox->control_scb) 105 regmap_read(mbox->control_scb, SERVICES_SR_OFFSET, &val); 106 else 107 val = readl_relaxed(mbox->ctrl_base + SERVICES_SR_OFFSET); 108 109 response->resp_status = (val & SCB_STATUS_MASK) >> SCB_STATUS_POS; 110 111 return true; 112 } 113 114 static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data) 115 { 116 struct mpfs_mbox *mbox = (struct mpfs_mbox *)chan->con_priv; 117 struct mpfs_mss_msg *msg = data; 118 u32 tx_trigger; 119 u16 opt_sel; 120 u32 val = 0u; 121 122 mbox->response = msg->response; 123 mbox->resp_offset = msg->resp_offset; 124 125 if (mpfs_mbox_busy(mbox)) 126 return -EBUSY; 127 128 if (msg->cmd_data_size) { 129 u32 index; 130 u8 extra_bits = msg->cmd_data_size & 3; 131 u32 *word_buf = (u32 *)msg->cmd_data; 132 133 for (index = 0; index < (msg->cmd_data_size / 4); index++) 134 writel_relaxed(word_buf[index], 135 mbox->mbox_base + msg->mbox_offset + index * 0x4); 136 if (extra_bits) { 137 u8 i; 138 u8 byte_off = ALIGN_DOWN(msg->cmd_data_size, 4); 139 u8 *byte_buf = msg->cmd_data + byte_off; 140 141 val = readl_relaxed(mbox->mbox_base + msg->mbox_offset + index * 0x4); 142 143 for (i = 0u; i < extra_bits; i++) { 144 val &= ~(0xffu << (i * 8u)); 145 val |= (byte_buf[i] << (i * 8u)); 146 } 147 148 writel_relaxed(val, mbox->mbox_base + msg->mbox_offset + index * 0x4); 149 } 150 } 151 152 opt_sel = ((msg->mbox_offset << 7u) | (msg->cmd_opcode & 0x7fu)); 153 154 tx_trigger = (opt_sel << SCB_CTRL_POS) & SCB_CTRL_MASK; 155 tx_trigger |= SCB_CTRL_REQ_MASK | SCB_STATUS_NOTIFY_MASK; 156 157 if (mbox->control_scb) 158 regmap_write(mbox->control_scb, SERVICES_CR_OFFSET, tx_trigger); 159 else 160 writel_relaxed(tx_trigger, mbox->ctrl_base + SERVICES_CR_OFFSET); 161 162 163 return 0; 164 } 165 166 static void mpfs_mbox_rx_data(struct mbox_chan *chan) 167 { 168 struct mpfs_mbox *mbox = (struct mpfs_mbox *)chan->con_priv; 169 struct mpfs_mss_response *response = mbox->response; 170 u16 num_words = ALIGN((response->resp_size), (4)) / 4U; 171 u32 i; 172 173 if (!response->resp_msg) { 174 dev_err(mbox->dev, "failed to assign memory for response %d\n", -ENOMEM); 175 return; 176 } 177 178 /* 179 * We should *never* get an interrupt while the controller is 180 * still in the busy state. If we do, something has gone badly 181 * wrong & the content of the mailbox would not be valid. 182 */ 183 if (mpfs_mbox_busy(mbox)) { 184 dev_err(mbox->dev, "got an interrupt but system controller is busy\n"); 185 response->resp_status = 0xDEAD; 186 return; 187 } 188 189 for (i = 0; i < num_words; i++) { 190 response->resp_msg[i] = 191 readl_relaxed(mbox->mbox_base 192 + mbox->resp_offset + i * 0x4); 193 } 194 195 mbox_chan_received_data(chan, response); 196 } 197 198 static irqreturn_t mpfs_mbox_inbox_isr(int irq, void *data) 199 { 200 struct mbox_chan *chan = data; 201 struct mpfs_mbox *mbox = (struct mpfs_mbox *)chan->con_priv; 202 203 if (mbox->sysreg_scb) 204 regmap_write(mbox->sysreg_scb, MESSAGE_INT_OFFSET, 0); 205 else 206 writel_relaxed(0, mbox->int_reg); 207 208 mpfs_mbox_rx_data(chan); 209 210 return IRQ_HANDLED; 211 } 212 213 static int mpfs_mbox_startup(struct mbox_chan *chan) 214 { 215 struct mpfs_mbox *mbox = (struct mpfs_mbox *)chan->con_priv; 216 int ret = 0; 217 218 if (!mbox) 219 return -EINVAL; 220 221 ret = devm_request_irq(mbox->dev, mbox->irq, mpfs_mbox_inbox_isr, 0, "mpfs-mailbox", chan); 222 if (ret) 223 dev_err(mbox->dev, "failed to register mailbox interrupt:%d\n", ret); 224 225 return ret; 226 } 227 228 static void mpfs_mbox_shutdown(struct mbox_chan *chan) 229 { 230 struct mpfs_mbox *mbox = (struct mpfs_mbox *)chan->con_priv; 231 232 devm_free_irq(mbox->dev, mbox->irq, chan); 233 } 234 235 static const struct mbox_chan_ops mpfs_mbox_ops = { 236 .send_data = mpfs_mbox_send_data, 237 .startup = mpfs_mbox_startup, 238 .shutdown = mpfs_mbox_shutdown, 239 .last_tx_done = mpfs_mbox_last_tx_done, 240 }; 241 242 static inline int mpfs_mbox_syscon_probe(struct mpfs_mbox *mbox, struct platform_device *pdev) 243 { 244 mbox->control_scb = syscon_regmap_lookup_by_compatible("microchip,mpfs-control-scb"); 245 if (IS_ERR(mbox->control_scb)) 246 return PTR_ERR(mbox->control_scb); 247 248 mbox->sysreg_scb = syscon_regmap_lookup_by_compatible("microchip,mpfs-sysreg-scb"); 249 if (IS_ERR(mbox->sysreg_scb)) 250 return PTR_ERR(mbox->sysreg_scb); 251 252 mbox->mbox_base = devm_platform_ioremap_resource(pdev, 0); 253 if (IS_ERR(mbox->mbox_base)) 254 return PTR_ERR(mbox->mbox_base); 255 256 return 0; 257 } 258 259 static inline int mpfs_mbox_old_format_probe(struct mpfs_mbox *mbox, struct platform_device *pdev) 260 { 261 dev_warn(&pdev->dev, "falling back to old devicetree format"); 262 263 mbox->ctrl_base = devm_platform_ioremap_resource(pdev, 0); 264 if (IS_ERR(mbox->ctrl_base)) 265 return PTR_ERR(mbox->ctrl_base); 266 267 mbox->int_reg = devm_platform_ioremap_resource(pdev, 1); 268 if (IS_ERR(mbox->int_reg)) 269 return PTR_ERR(mbox->int_reg); 270 271 mbox->mbox_base = devm_platform_ioremap_resource(pdev, 2); 272 if (IS_ERR(mbox->mbox_base)) // account for the old dt-binding w/ 2 regs 273 mbox->mbox_base = mbox->ctrl_base + MAILBOX_REG_OFFSET; 274 275 return 0; 276 } 277 278 static int mpfs_mbox_probe(struct platform_device *pdev) 279 { 280 struct mpfs_mbox *mbox; 281 int ret; 282 283 mbox = devm_kzalloc(&pdev->dev, sizeof(*mbox), GFP_KERNEL); 284 if (!mbox) 285 return -ENOMEM; 286 287 ret = mpfs_mbox_syscon_probe(mbox, pdev); 288 if (ret) { 289 /* 290 * set this to null, so it can be used as the decision for to 291 * regmap or not to regmap 292 */ 293 mbox->control_scb = NULL; 294 ret = mpfs_mbox_old_format_probe(mbox, pdev); 295 if (ret) 296 return ret; 297 } 298 mbox->irq = platform_get_irq(pdev, 0); 299 if (mbox->irq < 0) 300 return mbox->irq; 301 302 mbox->dev = &pdev->dev; 303 304 mbox->chans[0].con_priv = mbox; 305 mbox->controller.dev = mbox->dev; 306 mbox->controller.num_chans = 1; 307 mbox->controller.chans = mbox->chans; 308 mbox->controller.ops = &mpfs_mbox_ops; 309 mbox->controller.txdone_poll = true; 310 mbox->controller.txpoll_period = 10u; 311 312 ret = devm_mbox_controller_register(&pdev->dev, &mbox->controller); 313 if (ret) { 314 dev_err(&pdev->dev, "Registering MPFS mailbox controller failed\n"); 315 return ret; 316 } 317 dev_info(&pdev->dev, "Registered MPFS mailbox controller driver\n"); 318 319 return 0; 320 } 321 322 static const struct of_device_id mpfs_mbox_of_match[] = { 323 {.compatible = "microchip,mpfs-mailbox", }, 324 {}, 325 }; 326 MODULE_DEVICE_TABLE(of, mpfs_mbox_of_match); 327 328 static struct platform_driver mpfs_mbox_driver = { 329 .driver = { 330 .name = "mpfs-mailbox", 331 .of_match_table = mpfs_mbox_of_match, 332 }, 333 .probe = mpfs_mbox_probe, 334 }; 335 module_platform_driver(mpfs_mbox_driver); 336 337 MODULE_LICENSE("GPL v2"); 338 MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>"); 339 MODULE_DESCRIPTION("MPFS mailbox controller driver"); 340