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