1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Spreadtrum mailbox driver 4 * 5 * Copyright (c) 2020 Spreadtrum Communications Inc. 6 */ 7 8 #include <linux/delay.h> 9 #include <linux/err.h> 10 #include <linux/interrupt.h> 11 #include <linux/io.h> 12 #include <linux/mailbox_controller.h> 13 #include <linux/module.h> 14 #include <linux/of.h> 15 #include <linux/platform_device.h> 16 #include <linux/clk.h> 17 18 #define SPRD_MBOX_ID 0x0 19 #define SPRD_MBOX_MSG_LOW 0x4 20 #define SPRD_MBOX_MSG_HIGH 0x8 21 #define SPRD_MBOX_TRIGGER 0xc 22 #define SPRD_MBOX_FIFO_RST 0x10 23 #define SPRD_MBOX_FIFO_STS 0x14 24 #define SPRD_MBOX_IRQ_STS 0x18 25 #define SPRD_MBOX_IRQ_MSK 0x1c 26 #define SPRD_MBOX_LOCK 0x20 27 #define SPRD_MBOX_FIFO_DEPTH 0x24 /* outbox only */ 28 #define SPRD_MBOX_IN_FIFO_STS2 0x24 /* inbox only, revision 2 */ 29 30 /* Bit and mask definition for inbox's SPRD_MBOX_FIFO_STS register */ 31 #define SPRD_INBOX_FIFO_DELIVER_MASK GENMASK(23, 16) 32 #define SPRD_INBOX_FIFO_OVERLOW_MASK GENMASK(15, 8) 33 #define SPRD_INBOX_FIFO_DELIVER_SHIFT 16 34 #define SPRD_INBOX_FIFO_BUSY_MASK GENMASK(7, 0) 35 36 /* Bit and mask definition for R2 inbox's SPRD_MBOX_FIFO_RST register */ 37 #define SPRD_INBOX_R2_FIFO_OVERFLOW_DELIVER_RST GENMASK(31, 0) 38 39 /* Bit and mask definition for R2 inbox's SPRD_MBOX_FIFO_STS register */ 40 #define SPRD_INBOX_R2_FIFO_DELIVER_MASK GENMASK(15, 0) 41 42 /* Bit and mask definition for SPRD_MBOX_IN_FIFO_STS2 register */ 43 #define SPRD_INBOX_R2_FIFO_OVERFLOW_MASK GENMASK(31, 16) 44 #define SPRD_INBOX_R2_FIFO_BUSY_MASK GENMASK(15, 0) 45 46 /* Bit and mask definition for SPRD_MBOX_IRQ_STS register */ 47 #define SPRD_MBOX_IRQ_CLR GENMASK(31, 0) 48 49 /* Bit and mask definition for outbox's SPRD_MBOX_FIFO_STS register */ 50 #define SPRD_OUTBOX_FIFO_FULL BIT(2) 51 #define SPRD_OUTBOX_FIFO_WR_SHIFT 16 52 #define SPRD_OUTBOX_FIFO_RD_SHIFT 24 53 #define SPRD_OUTBOX_FIFO_POS_MASK GENMASK(7, 0) 54 55 /* Bit and mask definition for inbox's SPRD_MBOX_IRQ_MSK register */ 56 #define SPRD_INBOX_FIFO_BLOCK_IRQ BIT(0) 57 #define SPRD_INBOX_FIFO_OVERFLOW_IRQ BIT(1) 58 #define SPRD_INBOX_FIFO_DELIVER_IRQ BIT(2) 59 #define SPRD_INBOX_FIFO_IRQ_MASK GENMASK(2, 0) 60 61 /* Bit and mask definition for outbox's SPRD_MBOX_IRQ_MSK register */ 62 #define SPRD_OUTBOX_FIFO_NOT_EMPTY_IRQ BIT(0) 63 #define SPRD_OUTBOX_FIFO_IRQ_MASK GENMASK(4, 0) 64 65 #define SPRD_OUTBOX_BASE_SPAN 0x1000 66 #define SPRD_MBOX_R1_CHAN_MAX 8 67 #define SPRD_MBOX_R2_CHAN_MAX 16 68 69 enum sprd_mbox_version { 70 SPRD_MBOX_R1, 71 SPRD_MBOX_R2, 72 }; 73 74 struct sprd_mbox_info { 75 enum sprd_mbox_version version; 76 unsigned long supp_id; 77 }; 78 79 struct sprd_mbox_priv { 80 struct mbox_controller mbox; 81 struct device *dev; 82 void __iomem *inbox_base; 83 void __iomem *outbox_base; 84 /* Base register address for supplementary outbox */ 85 void __iomem *supp_base; 86 u32 outbox_fifo_depth; 87 88 const struct sprd_mbox_info *info; 89 90 struct mutex lock; 91 u32 refcnt; 92 struct mbox_chan chan[SPRD_MBOX_R2_CHAN_MAX]; 93 }; 94 95 static struct sprd_mbox_priv *to_sprd_mbox_priv(struct mbox_controller *mbox) 96 { 97 return container_of(mbox, struct sprd_mbox_priv, mbox); 98 } 99 100 static u32 sprd_mbox_get_fifo_len(struct sprd_mbox_priv *priv, u32 fifo_sts) 101 { 102 u32 wr_pos = (fifo_sts >> SPRD_OUTBOX_FIFO_WR_SHIFT) & 103 SPRD_OUTBOX_FIFO_POS_MASK; 104 u32 rd_pos = (fifo_sts >> SPRD_OUTBOX_FIFO_RD_SHIFT) & 105 SPRD_OUTBOX_FIFO_POS_MASK; 106 u32 fifo_len; 107 108 /* 109 * If the read pointer is equal with write pointer, which means the fifo 110 * is full or empty. 111 */ 112 if (wr_pos == rd_pos) { 113 if (fifo_sts & SPRD_OUTBOX_FIFO_FULL) 114 fifo_len = priv->outbox_fifo_depth; 115 else 116 fifo_len = 0; 117 } else if (wr_pos > rd_pos) { 118 fifo_len = wr_pos - rd_pos; 119 } else { 120 fifo_len = priv->outbox_fifo_depth - rd_pos + wr_pos; 121 } 122 123 return fifo_len; 124 } 125 126 static irqreturn_t do_outbox_isr(void __iomem *base, struct sprd_mbox_priv *priv) 127 { 128 struct mbox_chan *chan; 129 u32 fifo_sts, fifo_len, msg[2]; 130 int i, id; 131 132 fifo_sts = readl(base + SPRD_MBOX_FIFO_STS); 133 134 fifo_len = sprd_mbox_get_fifo_len(priv, fifo_sts); 135 if (!fifo_len) { 136 dev_warn_ratelimited(priv->dev, "spurious outbox interrupt\n"); 137 return IRQ_NONE; 138 } 139 140 for (i = 0; i < fifo_len; i++) { 141 msg[0] = readl(base + SPRD_MBOX_MSG_LOW); 142 msg[1] = readl(base + SPRD_MBOX_MSG_HIGH); 143 id = readl(base + SPRD_MBOX_ID); 144 145 chan = &priv->chan[id]; 146 if (chan->cl) 147 mbox_chan_received_data(chan, (void *)msg); 148 else 149 dev_warn_ratelimited(priv->dev, 150 "message's been dropped at ch[%d]\n", id); 151 152 /* Trigger to update outbox FIFO pointer */ 153 writel(0x1, base + SPRD_MBOX_TRIGGER); 154 } 155 156 /* Clear irq status after reading all message. */ 157 writel(SPRD_MBOX_IRQ_CLR, base + SPRD_MBOX_IRQ_STS); 158 159 return IRQ_HANDLED; 160 } 161 162 static irqreturn_t sprd_mbox_outbox_isr(int irq, void *data) 163 { 164 struct sprd_mbox_priv *priv = data; 165 166 return do_outbox_isr(priv->outbox_base, priv); 167 } 168 169 static irqreturn_t sprd_mbox_supp_isr(int irq, void *data) 170 { 171 struct sprd_mbox_priv *priv = data; 172 173 return do_outbox_isr(priv->supp_base, priv); 174 } 175 176 static irqreturn_t sprd_mbox_inbox_isr(int irq, void *data) 177 { 178 struct sprd_mbox_priv *priv = data; 179 struct mbox_chan *chan; 180 u32 fifo_sts, fifo_sts2, send_sts, busy, id; 181 182 fifo_sts = readl(priv->inbox_base + SPRD_MBOX_FIFO_STS); 183 184 if (priv->info->version == SPRD_MBOX_R2) 185 fifo_sts2 = readl(priv->inbox_base + SPRD_MBOX_IN_FIFO_STS2); 186 187 /* Get the inbox data delivery status */ 188 if (priv->info->version == SPRD_MBOX_R2) { 189 send_sts = fifo_sts & SPRD_INBOX_R2_FIFO_DELIVER_MASK; 190 } else { 191 send_sts = (fifo_sts & SPRD_INBOX_FIFO_DELIVER_MASK) >> 192 SPRD_INBOX_FIFO_DELIVER_SHIFT; 193 } 194 195 if (!send_sts) { 196 dev_warn_ratelimited(priv->dev, "spurious inbox interrupt\n"); 197 return IRQ_NONE; 198 } 199 200 /* Clear FIFO delivery and overflow status first */ 201 if (priv->info->version == SPRD_MBOX_R2) { 202 writel(SPRD_INBOX_R2_FIFO_OVERFLOW_DELIVER_RST, 203 priv->inbox_base + SPRD_MBOX_FIFO_RST); 204 } else { 205 writel(fifo_sts & (SPRD_INBOX_FIFO_DELIVER_MASK | SPRD_INBOX_FIFO_OVERLOW_MASK), 206 priv->inbox_base + SPRD_MBOX_FIFO_RST); 207 } 208 209 while (send_sts) { 210 id = __ffs(send_sts); 211 send_sts &= (send_sts - 1); 212 213 chan = &priv->chan[id]; 214 215 /* 216 * Check if the message was fetched by remote target, if yes, 217 * that means the transmission has been completed. 218 */ 219 if (priv->info->version == SPRD_MBOX_R2) 220 busy = fifo_sts2 & SPRD_INBOX_R2_FIFO_BUSY_MASK; 221 else 222 busy = fifo_sts & SPRD_INBOX_FIFO_BUSY_MASK; 223 224 if (!(busy & BIT(id))) 225 mbox_chan_txdone(chan, 0); 226 } 227 228 /* Clear irq status */ 229 writel(SPRD_MBOX_IRQ_CLR, priv->inbox_base + SPRD_MBOX_IRQ_STS); 230 231 return IRQ_HANDLED; 232 } 233 234 static int sprd_mbox_send_data(struct mbox_chan *chan, void *msg) 235 { 236 struct sprd_mbox_priv *priv = to_sprd_mbox_priv(chan->mbox); 237 unsigned long id = (unsigned long)chan->con_priv; 238 u32 *data = msg; 239 240 /* Write data into inbox FIFO, and only support 8 bytes every time */ 241 writel(data[0], priv->inbox_base + SPRD_MBOX_MSG_LOW); 242 writel(data[1], priv->inbox_base + SPRD_MBOX_MSG_HIGH); 243 244 /* Set target core id */ 245 writel(id, priv->inbox_base + SPRD_MBOX_ID); 246 247 /* Trigger remote request */ 248 writel(0x1, priv->inbox_base + SPRD_MBOX_TRIGGER); 249 250 return 0; 251 } 252 253 static int sprd_mbox_flush(struct mbox_chan *chan, unsigned long timeout) 254 { 255 struct sprd_mbox_priv *priv = to_sprd_mbox_priv(chan->mbox); 256 unsigned long id = (unsigned long)chan->con_priv; 257 u32 busy; 258 259 timeout = jiffies + msecs_to_jiffies(timeout); 260 261 while (time_before(jiffies, timeout)) { 262 busy = readl(priv->inbox_base + SPRD_MBOX_FIFO_STS) & 263 SPRD_INBOX_FIFO_BUSY_MASK; 264 if (!(busy & BIT(id))) { 265 mbox_chan_txdone(chan, 0); 266 return 0; 267 } 268 269 udelay(1); 270 } 271 272 return -ETIME; 273 } 274 275 static int sprd_mbox_startup(struct mbox_chan *chan) 276 { 277 struct sprd_mbox_priv *priv = to_sprd_mbox_priv(chan->mbox); 278 u32 val; 279 280 mutex_lock(&priv->lock); 281 if (priv->refcnt++ == 0) { 282 /* Select outbox FIFO mode and reset the outbox FIFO status */ 283 writel(0x0, priv->outbox_base + SPRD_MBOX_FIFO_RST); 284 285 /* Enable inbox FIFO delivery interrupt */ 286 val = SPRD_INBOX_FIFO_IRQ_MASK; 287 val &= ~SPRD_INBOX_FIFO_DELIVER_IRQ; 288 writel(val, priv->inbox_base + SPRD_MBOX_IRQ_MSK); 289 290 /* Enable outbox FIFO not empty interrupt */ 291 val = SPRD_OUTBOX_FIFO_IRQ_MASK; 292 val &= ~SPRD_OUTBOX_FIFO_NOT_EMPTY_IRQ; 293 writel(val, priv->outbox_base + SPRD_MBOX_IRQ_MSK); 294 295 /* Enable supplementary outbox as the fundamental one */ 296 if (priv->supp_base) { 297 writel(0x0, priv->supp_base + SPRD_MBOX_FIFO_RST); 298 writel(val, priv->supp_base + SPRD_MBOX_IRQ_MSK); 299 } 300 } 301 mutex_unlock(&priv->lock); 302 303 return 0; 304 } 305 306 static void sprd_mbox_shutdown(struct mbox_chan *chan) 307 { 308 struct sprd_mbox_priv *priv = to_sprd_mbox_priv(chan->mbox); 309 310 mutex_lock(&priv->lock); 311 if (--priv->refcnt == 0) { 312 /* Disable inbox & outbox interrupt */ 313 writel(SPRD_INBOX_FIFO_IRQ_MASK, priv->inbox_base + SPRD_MBOX_IRQ_MSK); 314 writel(SPRD_OUTBOX_FIFO_IRQ_MASK, priv->outbox_base + SPRD_MBOX_IRQ_MSK); 315 316 if (priv->supp_base) 317 writel(SPRD_OUTBOX_FIFO_IRQ_MASK, 318 priv->supp_base + SPRD_MBOX_IRQ_MSK); 319 } 320 mutex_unlock(&priv->lock); 321 } 322 323 static const struct mbox_chan_ops sprd_mbox_ops = { 324 .send_data = sprd_mbox_send_data, 325 .flush = sprd_mbox_flush, 326 .startup = sprd_mbox_startup, 327 .shutdown = sprd_mbox_shutdown, 328 }; 329 330 static int sprd_mbox_probe(struct platform_device *pdev) 331 { 332 struct device *dev = &pdev->dev; 333 struct sprd_mbox_priv *priv; 334 int ret, inbox_irq, outbox_irq, supp_irq; 335 unsigned long id; 336 struct clk *clk; 337 338 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 339 if (!priv) 340 return -ENOMEM; 341 342 priv->dev = dev; 343 mutex_init(&priv->lock); 344 345 priv->info = of_device_get_match_data(dev); 346 if (!priv->info) 347 return -EINVAL; 348 349 /* 350 * Unisoc mailbox uses an inbox to send messages to the target 351 * core, and uses (an) outbox(es) to receive messages from other 352 * cores. 353 * 354 * Thus in general the mailbox controller supplies 2 different 355 * register addresses and IRQ numbers for inbox and outbox. 356 * 357 * If necessary, a supplementary inbox could be enabled optionally 358 * with an independent FIFO and an extra interrupt. 359 */ 360 priv->inbox_base = devm_platform_ioremap_resource(pdev, 0); 361 if (IS_ERR(priv->inbox_base)) 362 return PTR_ERR(priv->inbox_base); 363 364 priv->outbox_base = devm_platform_ioremap_resource(pdev, 1); 365 if (IS_ERR(priv->outbox_base)) 366 return PTR_ERR(priv->outbox_base); 367 368 clk = devm_clk_get_enabled(dev, "enable"); 369 if (IS_ERR(clk)) { 370 dev_err(dev, "failed to get mailbox clock\n"); 371 return PTR_ERR(clk); 372 } 373 374 inbox_irq = platform_get_irq_byname(pdev, "inbox"); 375 if (inbox_irq < 0) 376 return inbox_irq; 377 378 ret = devm_request_irq(dev, inbox_irq, sprd_mbox_inbox_isr, 379 IRQF_NO_SUSPEND, dev_name(dev), priv); 380 if (ret) { 381 dev_err(dev, "failed to request inbox IRQ: %d\n", ret); 382 return ret; 383 } 384 385 outbox_irq = platform_get_irq_byname(pdev, "outbox"); 386 if (outbox_irq < 0) 387 return outbox_irq; 388 389 ret = devm_request_irq(dev, outbox_irq, sprd_mbox_outbox_isr, 390 IRQF_NO_SUSPEND, dev_name(dev), priv); 391 if (ret) { 392 dev_err(dev, "failed to request outbox IRQ: %d\n", ret); 393 return ret; 394 } 395 396 /* Supplementary outbox IRQ is optional */ 397 supp_irq = platform_get_irq_byname(pdev, "supp-outbox"); 398 if (supp_irq > 0) { 399 ret = devm_request_irq(dev, supp_irq, sprd_mbox_supp_isr, 400 IRQF_NO_SUSPEND, dev_name(dev), priv); 401 if (ret) { 402 dev_err(dev, "failed to request outbox IRQ: %d\n", ret); 403 return ret; 404 } 405 406 if (!priv->info->supp_id) { 407 dev_err(dev, "no supplementary outbox specified\n"); 408 return -ENODEV; 409 } 410 priv->supp_base = priv->outbox_base + 411 (SPRD_OUTBOX_BASE_SPAN * priv->info->supp_id); 412 } 413 414 /* Get the default outbox FIFO depth */ 415 priv->outbox_fifo_depth = 416 readl(priv->outbox_base + SPRD_MBOX_FIFO_DEPTH) + 1; 417 priv->mbox.dev = dev; 418 priv->mbox.chans = &priv->chan[0]; 419 priv->mbox.ops = &sprd_mbox_ops; 420 priv->mbox.txdone_irq = true; 421 422 if (priv->info->version == SPRD_MBOX_R2) 423 priv->mbox.num_chans = SPRD_MBOX_R2_CHAN_MAX; 424 else 425 priv->mbox.num_chans = SPRD_MBOX_R1_CHAN_MAX; 426 427 for (id = 0; id < priv->mbox.num_chans; id++) 428 priv->chan[id].con_priv = (void *)id; 429 430 ret = devm_mbox_controller_register(dev, &priv->mbox); 431 if (ret) { 432 dev_err(dev, "failed to register mailbox: %d\n", ret); 433 return ret; 434 } 435 436 return 0; 437 } 438 439 static const struct sprd_mbox_info sc9860_mbox_info = { 440 .version = SPRD_MBOX_R1, 441 }; 442 443 static const struct sprd_mbox_info sc9863a_mbox_info = { 444 .version = SPRD_MBOX_R1, 445 .supp_id = 7, 446 }; 447 448 static const struct sprd_mbox_info ums9230_mbox_info = { 449 .version = SPRD_MBOX_R2, 450 .supp_id = 6, 451 }; 452 453 static const struct of_device_id sprd_mbox_of_match[] = { 454 { .compatible = "sprd,sc9860-mailbox", .data = &sc9860_mbox_info }, 455 { .compatible = "sprd,sc9863a-mailbox", .data = &sc9863a_mbox_info }, 456 { .compatible = "sprd,ums9230-mailbox", .data = &ums9230_mbox_info }, 457 { }, 458 }; 459 MODULE_DEVICE_TABLE(of, sprd_mbox_of_match); 460 461 static struct platform_driver sprd_mbox_driver = { 462 .driver = { 463 .name = "sprd-mailbox", 464 .of_match_table = sprd_mbox_of_match, 465 }, 466 .probe = sprd_mbox_probe, 467 }; 468 module_platform_driver(sprd_mbox_driver); 469 470 MODULE_AUTHOR("Baolin Wang <baolin.wang@unisoc.com>"); 471 MODULE_DESCRIPTION("Spreadtrum mailbox driver"); 472 MODULE_LICENSE("GPL v2"); 473