1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * OMAP mailbox driver 4 * 5 * Copyright (C) 2006-2009 Nokia Corporation. All rights reserved. 6 * Copyright (C) 2013-2021 Texas Instruments Incorporated - https://www.ti.com 7 * 8 * Contact: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> 9 * Suman Anna <s-anna@ti.com> 10 */ 11 12 #include <linux/interrupt.h> 13 #include <linux/spinlock.h> 14 #include <linux/mutex.h> 15 #include <linux/slab.h> 16 #include <linux/kfifo.h> 17 #include <linux/err.h> 18 #include <linux/io.h> 19 #include <linux/module.h> 20 #include <linux/of.h> 21 #include <linux/platform_device.h> 22 #include <linux/pm_runtime.h> 23 #include <linux/mailbox_controller.h> 24 25 #define MAILBOX_REVISION 0x000 26 #define MAILBOX_MESSAGE(m) (0x040 + 4 * (m)) 27 #define MAILBOX_FIFOSTATUS(m) (0x080 + 4 * (m)) 28 #define MAILBOX_MSGSTATUS(m) (0x0c0 + 4 * (m)) 29 30 #define OMAP2_MAILBOX_IRQSTATUS(u) (0x100 + 8 * (u)) 31 #define OMAP2_MAILBOX_IRQENABLE(u) (0x104 + 8 * (u)) 32 33 #define OMAP4_MAILBOX_IRQSTATUS(u) (0x104 + 0x10 * (u)) 34 #define OMAP4_MAILBOX_IRQENABLE(u) (0x108 + 0x10 * (u)) 35 #define OMAP4_MAILBOX_IRQENABLE_CLR(u) (0x10c + 0x10 * (u)) 36 37 #define MAILBOX_IRQSTATUS(type, u) (type ? OMAP4_MAILBOX_IRQSTATUS(u) : \ 38 OMAP2_MAILBOX_IRQSTATUS(u)) 39 #define MAILBOX_IRQENABLE(type, u) (type ? OMAP4_MAILBOX_IRQENABLE(u) : \ 40 OMAP2_MAILBOX_IRQENABLE(u)) 41 #define MAILBOX_IRQDISABLE(type, u) (type ? OMAP4_MAILBOX_IRQENABLE_CLR(u) \ 42 : OMAP2_MAILBOX_IRQENABLE(u)) 43 44 #define MAILBOX_IRQ_NEWMSG(m) (1 << (2 * (m))) 45 #define MAILBOX_IRQ_NOTFULL(m) (1 << (2 * (m) + 1)) 46 47 /* Interrupt register configuration types */ 48 #define MBOX_INTR_CFG_TYPE1 0 49 #define MBOX_INTR_CFG_TYPE2 1 50 51 typedef enum { 52 IRQ_TX = 1, 53 IRQ_RX = 2, 54 } omap_mbox_irq_t; 55 56 struct omap_mbox_fifo { 57 unsigned long msg; 58 unsigned long fifo_stat; 59 unsigned long msg_stat; 60 unsigned long irqenable; 61 unsigned long irqstatus; 62 unsigned long irqdisable; 63 u32 intr_bit; 64 }; 65 66 struct omap_mbox_match_data { 67 u32 intr_type; 68 bool is_exclusive; 69 }; 70 71 struct omap_mbox_device { 72 struct device *dev; 73 struct mutex cfg_lock; 74 void __iomem *mbox_base; 75 u32 *irq_ctx; 76 u32 num_users; 77 u32 num_fifos; 78 u32 intr_type; 79 const struct omap_mbox_match_data *mbox_data; 80 }; 81 82 struct omap_mbox { 83 const char *name; 84 int irq; 85 struct omap_mbox_device *parent; 86 struct omap_mbox_fifo tx_fifo; 87 struct omap_mbox_fifo rx_fifo; 88 u32 intr_type; 89 struct mbox_chan *chan; 90 bool send_no_irq; 91 }; 92 93 static inline 94 unsigned int mbox_read_reg(struct omap_mbox_device *mdev, size_t ofs) 95 { 96 return __raw_readl(mdev->mbox_base + ofs); 97 } 98 99 static inline 100 void mbox_write_reg(struct omap_mbox_device *mdev, u32 val, size_t ofs) 101 { 102 __raw_writel(val, mdev->mbox_base + ofs); 103 } 104 105 /* Mailbox FIFO handle functions */ 106 static u32 mbox_fifo_read(struct omap_mbox *mbox) 107 { 108 struct omap_mbox_fifo *fifo = &mbox->rx_fifo; 109 110 return mbox_read_reg(mbox->parent, fifo->msg); 111 } 112 113 static void mbox_fifo_write(struct omap_mbox *mbox, u32 msg) 114 { 115 struct omap_mbox_fifo *fifo = &mbox->tx_fifo; 116 117 mbox_write_reg(mbox->parent, msg, fifo->msg); 118 } 119 120 static int mbox_fifo_empty(struct omap_mbox *mbox) 121 { 122 struct omap_mbox_fifo *fifo = &mbox->rx_fifo; 123 124 return (mbox_read_reg(mbox->parent, fifo->msg_stat) == 0); 125 } 126 127 static int mbox_fifo_full(struct omap_mbox *mbox) 128 { 129 struct omap_mbox_fifo *fifo = &mbox->tx_fifo; 130 131 return mbox_read_reg(mbox->parent, fifo->fifo_stat); 132 } 133 134 /* Mailbox IRQ handle functions */ 135 static void ack_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 136 { 137 struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ? 138 &mbox->tx_fifo : &mbox->rx_fifo; 139 u32 bit = fifo->intr_bit; 140 u32 irqstatus = fifo->irqstatus; 141 142 mbox_write_reg(mbox->parent, bit, irqstatus); 143 144 /* Flush posted write for irq status to avoid spurious interrupts */ 145 mbox_read_reg(mbox->parent, irqstatus); 146 } 147 148 static int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 149 { 150 struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ? 151 &mbox->tx_fifo : &mbox->rx_fifo; 152 u32 bit = fifo->intr_bit; 153 u32 irqenable = fifo->irqenable; 154 u32 irqstatus = fifo->irqstatus; 155 156 u32 enable = mbox_read_reg(mbox->parent, irqenable); 157 u32 status = mbox_read_reg(mbox->parent, irqstatus); 158 159 return (int)(enable & status & bit); 160 } 161 162 static void omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 163 { 164 u32 l; 165 struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ? 166 &mbox->tx_fifo : &mbox->rx_fifo; 167 u32 bit = fifo->intr_bit; 168 u32 irqenable = fifo->irqenable; 169 170 l = mbox_read_reg(mbox->parent, irqenable); 171 l |= bit; 172 mbox_write_reg(mbox->parent, l, irqenable); 173 } 174 175 static void omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 176 { 177 struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ? 178 &mbox->tx_fifo : &mbox->rx_fifo; 179 u32 bit = fifo->intr_bit; 180 u32 irqdisable = fifo->irqdisable; 181 182 /* 183 * Read and update the interrupt configuration register for pre-OMAP4. 184 * OMAP4 and later SoCs have a dedicated interrupt disabling register. 185 */ 186 if (!mbox->intr_type) 187 bit = mbox_read_reg(mbox->parent, irqdisable) & ~bit; 188 189 mbox_write_reg(mbox->parent, bit, irqdisable); 190 } 191 192 /* 193 * Mailbox interrupt handler 194 */ 195 static void __mbox_tx_interrupt(struct omap_mbox *mbox) 196 { 197 omap_mbox_disable_irq(mbox, IRQ_TX); 198 ack_mbox_irq(mbox, IRQ_TX); 199 mbox_chan_txdone(mbox->chan, 0); 200 } 201 202 static void __mbox_rx_interrupt(struct omap_mbox *mbox) 203 { 204 u32 msg; 205 206 while (!mbox_fifo_empty(mbox)) { 207 msg = mbox_fifo_read(mbox); 208 mbox_chan_received_data(mbox->chan, (void *)(uintptr_t)msg); 209 } 210 211 /* clear IRQ source. */ 212 ack_mbox_irq(mbox, IRQ_RX); 213 } 214 215 static irqreturn_t mbox_interrupt(int irq, void *p) 216 { 217 struct omap_mbox *mbox = p; 218 219 if (is_mbox_irq(mbox, IRQ_TX)) 220 __mbox_tx_interrupt(mbox); 221 222 if (is_mbox_irq(mbox, IRQ_RX)) 223 __mbox_rx_interrupt(mbox); 224 225 return IRQ_HANDLED; 226 } 227 228 static int omap_mbox_startup(struct omap_mbox *mbox) 229 { 230 int ret = 0; 231 232 ret = request_threaded_irq(mbox->irq, NULL, mbox_interrupt, 233 IRQF_SHARED | IRQF_ONESHOT, mbox->name, 234 mbox); 235 if (unlikely(ret)) { 236 pr_err("failed to register mailbox interrupt:%d\n", ret); 237 return ret; 238 } 239 240 if (mbox->send_no_irq) 241 mbox->chan->txdone_method = MBOX_TXDONE_BY_ACK; 242 243 omap_mbox_enable_irq(mbox, IRQ_RX); 244 245 return 0; 246 } 247 248 static void omap_mbox_fini(struct omap_mbox *mbox) 249 { 250 omap_mbox_disable_irq(mbox, IRQ_RX); 251 free_irq(mbox->irq, mbox); 252 } 253 254 static int omap_mbox_chan_startup(struct mbox_chan *chan) 255 { 256 struct omap_mbox *mbox = chan->con_priv; 257 struct omap_mbox_device *mdev = mbox->parent; 258 int ret = 0; 259 260 mutex_lock(&mdev->cfg_lock); 261 pm_runtime_get_sync(mdev->dev); 262 ret = omap_mbox_startup(mbox); 263 if (ret) 264 pm_runtime_put_sync(mdev->dev); 265 mutex_unlock(&mdev->cfg_lock); 266 return ret; 267 } 268 269 static void omap_mbox_chan_shutdown(struct mbox_chan *chan) 270 { 271 struct omap_mbox *mbox = chan->con_priv; 272 struct omap_mbox_device *mdev = mbox->parent; 273 274 mutex_lock(&mdev->cfg_lock); 275 omap_mbox_fini(mbox); 276 pm_runtime_put_sync(mdev->dev); 277 mutex_unlock(&mdev->cfg_lock); 278 } 279 280 static int omap_mbox_chan_send_noirq(struct omap_mbox *mbox, u32 msg) 281 { 282 if (mbox_fifo_full(mbox)) 283 return -EBUSY; 284 285 omap_mbox_enable_irq(mbox, IRQ_RX); 286 mbox_fifo_write(mbox, msg); 287 omap_mbox_disable_irq(mbox, IRQ_RX); 288 289 /* we must read and ack the interrupt directly from here */ 290 mbox_fifo_read(mbox); 291 ack_mbox_irq(mbox, IRQ_RX); 292 293 return 0; 294 } 295 296 static int omap_mbox_chan_send(struct omap_mbox *mbox, u32 msg) 297 { 298 if (mbox_fifo_full(mbox)) { 299 /* always enable the interrupt */ 300 omap_mbox_enable_irq(mbox, IRQ_TX); 301 return -EBUSY; 302 } 303 304 mbox_fifo_write(mbox, msg); 305 306 /* always enable the interrupt */ 307 omap_mbox_enable_irq(mbox, IRQ_TX); 308 return 0; 309 } 310 311 static int omap_mbox_chan_send_data(struct mbox_chan *chan, void *data) 312 { 313 struct omap_mbox *mbox = chan->con_priv; 314 int ret; 315 u32 msg = (u32)(uintptr_t)(data); 316 317 if (!mbox) 318 return -EINVAL; 319 320 if (mbox->send_no_irq) 321 ret = omap_mbox_chan_send_noirq(mbox, msg); 322 else 323 ret = omap_mbox_chan_send(mbox, msg); 324 325 return ret; 326 } 327 328 static const struct mbox_chan_ops omap_mbox_chan_ops = { 329 .startup = omap_mbox_chan_startup, 330 .send_data = omap_mbox_chan_send_data, 331 .shutdown = omap_mbox_chan_shutdown, 332 }; 333 334 #ifdef CONFIG_PM_SLEEP 335 static int omap_mbox_suspend(struct device *dev) 336 { 337 struct omap_mbox_device *mdev = dev_get_drvdata(dev); 338 u32 usr, fifo, reg; 339 340 if (pm_runtime_status_suspended(dev)) 341 return 0; 342 343 if (mdev->mbox_data->is_exclusive) { 344 for (fifo = 0; fifo < mdev->num_fifos; fifo++) { 345 if (mbox_read_reg(mdev, MAILBOX_MSGSTATUS(fifo))) { 346 dev_err(mdev->dev, "fifo %d has unexpected unread messages\n", 347 fifo); 348 return -EBUSY; 349 } 350 } 351 } 352 353 for (usr = 0; usr < mdev->num_users; usr++) { 354 reg = MAILBOX_IRQENABLE(mdev->intr_type, usr); 355 mdev->irq_ctx[usr] = mbox_read_reg(mdev, reg); 356 } 357 358 return 0; 359 } 360 361 static int omap_mbox_resume(struct device *dev) 362 { 363 struct omap_mbox_device *mdev = dev_get_drvdata(dev); 364 u32 usr, reg; 365 366 if (pm_runtime_status_suspended(dev)) 367 return 0; 368 369 for (usr = 0; usr < mdev->num_users; usr++) { 370 reg = MAILBOX_IRQENABLE(mdev->intr_type, usr); 371 mbox_write_reg(mdev, mdev->irq_ctx[usr], reg); 372 } 373 374 return 0; 375 } 376 #endif 377 378 static const struct dev_pm_ops omap_mbox_pm_ops = { 379 SET_SYSTEM_SLEEP_PM_OPS(omap_mbox_suspend, omap_mbox_resume) 380 }; 381 382 static const struct omap_mbox_match_data omap2_data = { MBOX_INTR_CFG_TYPE1, true }; 383 static const struct omap_mbox_match_data omap4_data = { MBOX_INTR_CFG_TYPE2, true }; 384 static const struct omap_mbox_match_data am654_data = { MBOX_INTR_CFG_TYPE2, false }; 385 386 static const struct of_device_id omap_mailbox_of_match[] = { 387 { 388 .compatible = "ti,omap2-mailbox", 389 .data = &omap2_data, 390 }, 391 { 392 .compatible = "ti,omap3-mailbox", 393 .data = &omap2_data, 394 }, 395 { 396 .compatible = "ti,omap4-mailbox", 397 .data = &omap4_data, 398 }, 399 { 400 .compatible = "ti,am654-mailbox", 401 .data = &am654_data, 402 }, 403 { 404 .compatible = "ti,am64-mailbox", 405 .data = &am654_data, 406 }, 407 { 408 /* end */ 409 }, 410 }; 411 MODULE_DEVICE_TABLE(of, omap_mailbox_of_match); 412 413 static struct mbox_chan *omap_mbox_of_xlate(struct mbox_controller *controller, 414 const struct of_phandle_args *sp) 415 { 416 phandle phandle = sp->args[0]; 417 struct device_node *node; 418 struct omap_mbox_device *mdev; 419 struct omap_mbox *mbox; 420 int i; 421 422 mdev = dev_get_drvdata(controller->dev); 423 if (WARN_ON(!mdev)) 424 return ERR_PTR(-EINVAL); 425 426 node = of_find_node_by_phandle(phandle); 427 if (!node) { 428 pr_err("%s: could not find node phandle 0x%x\n", 429 __func__, phandle); 430 return ERR_PTR(-ENODEV); 431 } 432 433 for (i = 0; i < controller->num_chans; i++) { 434 mbox = controller->chans[i].con_priv; 435 if (!strcmp(mbox->name, node->name)) { 436 of_node_put(node); 437 return &controller->chans[i]; 438 } 439 } 440 441 of_node_put(node); 442 return ERR_PTR(-ENOENT); 443 } 444 445 static int omap_mbox_probe(struct platform_device *pdev) 446 { 447 int ret; 448 struct mbox_chan *chnls; 449 struct omap_mbox *mbox; 450 struct omap_mbox_device *mdev; 451 struct omap_mbox_fifo *fifo; 452 struct device_node *node = pdev->dev.of_node; 453 struct device_node *child; 454 struct mbox_controller *controller; 455 u32 intr_type, info_count; 456 u32 num_users, num_fifos; 457 u32 tmp[3]; 458 u32 l; 459 int i; 460 461 if (!node) { 462 pr_err("%s: only DT-based devices are supported\n", __func__); 463 return -ENODEV; 464 } 465 466 if (of_property_read_u32(node, "ti,mbox-num-users", &num_users)) 467 return -ENODEV; 468 469 if (of_property_read_u32(node, "ti,mbox-num-fifos", &num_fifos)) 470 return -ENODEV; 471 472 info_count = of_get_available_child_count(node); 473 if (!info_count) { 474 dev_err(&pdev->dev, "no available mbox devices found\n"); 475 return -ENODEV; 476 } 477 478 mdev = devm_kzalloc(&pdev->dev, sizeof(*mdev), GFP_KERNEL); 479 if (!mdev) 480 return -ENOMEM; 481 482 mdev->mbox_data = device_get_match_data(&pdev->dev); 483 if (!mdev->mbox_data) 484 return -ENODEV; 485 486 intr_type = mdev->mbox_data->intr_type; 487 488 mdev->mbox_base = devm_platform_ioremap_resource(pdev, 0); 489 if (IS_ERR(mdev->mbox_base)) 490 return PTR_ERR(mdev->mbox_base); 491 492 mdev->irq_ctx = devm_kcalloc(&pdev->dev, num_users, sizeof(u32), 493 GFP_KERNEL); 494 if (!mdev->irq_ctx) 495 return -ENOMEM; 496 497 chnls = devm_kcalloc(&pdev->dev, info_count + 1, sizeof(*chnls), 498 GFP_KERNEL); 499 if (!chnls) 500 return -ENOMEM; 501 502 child = NULL; 503 for (i = 0; i < info_count; i++) { 504 int tx_id, tx_irq, tx_usr; 505 int rx_id, rx_usr; 506 507 mbox = devm_kzalloc(&pdev->dev, sizeof(*mbox), GFP_KERNEL); 508 if (!mbox) 509 return -ENOMEM; 510 511 child = of_get_next_available_child(node, child); 512 ret = of_property_read_u32_array(child, "ti,mbox-tx", tmp, 513 ARRAY_SIZE(tmp)); 514 if (ret) 515 return ret; 516 tx_id = tmp[0]; 517 tx_irq = tmp[1]; 518 tx_usr = tmp[2]; 519 520 ret = of_property_read_u32_array(child, "ti,mbox-rx", tmp, 521 ARRAY_SIZE(tmp)); 522 if (ret) 523 return ret; 524 rx_id = tmp[0]; 525 /* rx_irq = tmp[1]; */ 526 rx_usr = tmp[2]; 527 528 if (tx_id >= num_fifos || rx_id >= num_fifos || 529 tx_usr >= num_users || rx_usr >= num_users) 530 return -EINVAL; 531 532 fifo = &mbox->tx_fifo; 533 fifo->msg = MAILBOX_MESSAGE(tx_id); 534 fifo->fifo_stat = MAILBOX_FIFOSTATUS(tx_id); 535 fifo->intr_bit = MAILBOX_IRQ_NOTFULL(tx_id); 536 fifo->irqenable = MAILBOX_IRQENABLE(intr_type, tx_usr); 537 fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, tx_usr); 538 fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, tx_usr); 539 540 fifo = &mbox->rx_fifo; 541 fifo->msg = MAILBOX_MESSAGE(rx_id); 542 fifo->msg_stat = MAILBOX_MSGSTATUS(rx_id); 543 fifo->intr_bit = MAILBOX_IRQ_NEWMSG(rx_id); 544 fifo->irqenable = MAILBOX_IRQENABLE(intr_type, rx_usr); 545 fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, rx_usr); 546 fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, rx_usr); 547 548 mbox->send_no_irq = of_property_read_bool(child, "ti,mbox-send-noirq"); 549 mbox->intr_type = intr_type; 550 551 mbox->parent = mdev; 552 mbox->name = child->name; 553 mbox->irq = platform_get_irq(pdev, tx_irq); 554 if (mbox->irq < 0) 555 return mbox->irq; 556 mbox->chan = &chnls[i]; 557 chnls[i].con_priv = mbox; 558 } 559 560 mutex_init(&mdev->cfg_lock); 561 mdev->dev = &pdev->dev; 562 mdev->num_users = num_users; 563 mdev->num_fifos = num_fifos; 564 mdev->intr_type = intr_type; 565 566 controller = devm_kzalloc(&pdev->dev, sizeof(*controller), GFP_KERNEL); 567 if (!controller) 568 return -ENOMEM; 569 /* 570 * OMAP/K3 Mailbox IP does not have a Tx-Done IRQ, but rather a Tx-Ready 571 * IRQ and is needed to run the Tx state machine 572 */ 573 controller->txdone_irq = true; 574 controller->dev = mdev->dev; 575 controller->ops = &omap_mbox_chan_ops; 576 controller->chans = chnls; 577 controller->num_chans = info_count; 578 controller->of_xlate = omap_mbox_of_xlate; 579 ret = devm_mbox_controller_register(mdev->dev, controller); 580 if (ret) 581 return ret; 582 583 platform_set_drvdata(pdev, mdev); 584 devm_pm_runtime_enable(mdev->dev); 585 586 ret = pm_runtime_resume_and_get(mdev->dev); 587 if (ret < 0) 588 return ret; 589 590 /* 591 * just print the raw revision register, the format is not 592 * uniform across all SoCs 593 */ 594 l = mbox_read_reg(mdev, MAILBOX_REVISION); 595 dev_info(mdev->dev, "omap mailbox rev 0x%x\n", l); 596 597 ret = pm_runtime_put_sync(mdev->dev); 598 if (ret < 0 && ret != -ENOSYS) 599 return ret; 600 601 return 0; 602 } 603 604 static struct platform_driver omap_mbox_driver = { 605 .probe = omap_mbox_probe, 606 .driver = { 607 .name = "omap-mailbox", 608 .pm = &omap_mbox_pm_ops, 609 .of_match_table = omap_mailbox_of_match, 610 }, 611 }; 612 module_platform_driver(omap_mbox_driver); 613 614 MODULE_LICENSE("GPL v2"); 615 MODULE_DESCRIPTION("omap mailbox: interrupt driven messaging"); 616 MODULE_AUTHOR("Toshihiro Kobayashi"); 617 MODULE_AUTHOR("Hiroshi DOYU"); 618