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