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 223 return ret; 224 } 225 226 static void mpfs_mbox_shutdown(struct mbox_chan *chan) 227 { 228 struct mpfs_mbox *mbox = (struct mpfs_mbox *)chan->con_priv; 229 230 devm_free_irq(mbox->dev, mbox->irq, chan); 231 } 232 233 static const struct mbox_chan_ops mpfs_mbox_ops = { 234 .send_data = mpfs_mbox_send_data, 235 .startup = mpfs_mbox_startup, 236 .shutdown = mpfs_mbox_shutdown, 237 .last_tx_done = mpfs_mbox_last_tx_done, 238 }; 239 240 static inline int mpfs_mbox_syscon_probe(struct mpfs_mbox *mbox, struct platform_device *pdev) 241 { 242 mbox->control_scb = syscon_regmap_lookup_by_compatible("microchip,mpfs-control-scb"); 243 if (IS_ERR(mbox->control_scb)) 244 return PTR_ERR(mbox->control_scb); 245 246 mbox->sysreg_scb = syscon_regmap_lookup_by_compatible("microchip,mpfs-sysreg-scb"); 247 if (IS_ERR(mbox->sysreg_scb)) 248 return PTR_ERR(mbox->sysreg_scb); 249 250 mbox->mbox_base = devm_platform_ioremap_resource(pdev, 0); 251 if (IS_ERR(mbox->mbox_base)) 252 return PTR_ERR(mbox->mbox_base); 253 254 return 0; 255 } 256 257 static inline int mpfs_mbox_old_format_probe(struct mpfs_mbox *mbox, struct platform_device *pdev) 258 { 259 dev_warn(&pdev->dev, "falling back to old devicetree format"); 260 261 mbox->ctrl_base = devm_platform_ioremap_resource(pdev, 0); 262 if (IS_ERR(mbox->ctrl_base)) 263 return PTR_ERR(mbox->ctrl_base); 264 265 mbox->int_reg = devm_platform_ioremap_resource(pdev, 1); 266 if (IS_ERR(mbox->int_reg)) 267 return PTR_ERR(mbox->int_reg); 268 269 mbox->mbox_base = devm_platform_ioremap_resource(pdev, 2); 270 if (IS_ERR(mbox->mbox_base)) // account for the old dt-binding w/ 2 regs 271 mbox->mbox_base = mbox->ctrl_base + MAILBOX_REG_OFFSET; 272 273 return 0; 274 } 275 276 static int mpfs_mbox_probe(struct platform_device *pdev) 277 { 278 struct mpfs_mbox *mbox; 279 int ret; 280 281 mbox = devm_kzalloc(&pdev->dev, sizeof(*mbox), GFP_KERNEL); 282 if (!mbox) 283 return -ENOMEM; 284 285 ret = mpfs_mbox_syscon_probe(mbox, pdev); 286 if (ret) { 287 /* 288 * set this to null, so it can be used as the decision for to 289 * regmap or not to regmap 290 */ 291 mbox->control_scb = NULL; 292 ret = mpfs_mbox_old_format_probe(mbox, pdev); 293 if (ret) 294 return ret; 295 } 296 mbox->irq = platform_get_irq(pdev, 0); 297 if (mbox->irq < 0) 298 return mbox->irq; 299 300 mbox->dev = &pdev->dev; 301 302 mbox->chans[0].con_priv = mbox; 303 mbox->controller.dev = mbox->dev; 304 mbox->controller.num_chans = 1; 305 mbox->controller.chans = mbox->chans; 306 mbox->controller.ops = &mpfs_mbox_ops; 307 mbox->controller.txdone_poll = true; 308 mbox->controller.txpoll_period = 10u; 309 310 ret = devm_mbox_controller_register(&pdev->dev, &mbox->controller); 311 if (ret) { 312 dev_err(&pdev->dev, "Registering MPFS mailbox controller failed\n"); 313 return ret; 314 } 315 dev_info(&pdev->dev, "Registered MPFS mailbox controller driver\n"); 316 317 return 0; 318 } 319 320 static const struct of_device_id mpfs_mbox_of_match[] = { 321 {.compatible = "microchip,mpfs-mailbox", }, 322 {}, 323 }; 324 MODULE_DEVICE_TABLE(of, mpfs_mbox_of_match); 325 326 static struct platform_driver mpfs_mbox_driver = { 327 .driver = { 328 .name = "mpfs-mailbox", 329 .of_match_table = mpfs_mbox_of_match, 330 }, 331 .probe = mpfs_mbox_probe, 332 }; 333 module_platform_driver(mpfs_mbox_driver); 334 335 MODULE_LICENSE("GPL v2"); 336 MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>"); 337 MODULE_DESCRIPTION("MPFS mailbox controller driver"); 338