linux/drivers/mailbox/tegra-hsp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2016-2018, NVIDIA CORPORATION.  All rights reserved.
   4 */
   5
   6#include <linux/delay.h>
   7#include <linux/interrupt.h>
   8#include <linux/io.h>
   9#include <linux/mailbox_controller.h>
  10#include <linux/of.h>
  11#include <linux/of_device.h>
  12#include <linux/platform_device.h>
  13#include <linux/pm.h>
  14#include <linux/slab.h>
  15
  16#include <dt-bindings/mailbox/tegra186-hsp.h>
  17
  18#include "mailbox.h"
  19
  20#define HSP_INT_IE(x)           (0x100 + ((x) * 4))
  21#define HSP_INT_IV              0x300
  22#define HSP_INT_IR              0x304
  23
  24#define HSP_INT_EMPTY_SHIFT     0
  25#define HSP_INT_EMPTY_MASK      0xff
  26#define HSP_INT_FULL_SHIFT      8
  27#define HSP_INT_FULL_MASK       0xff
  28
  29#define HSP_INT_DIMENSIONING    0x380
  30#define HSP_nSM_SHIFT           0
  31#define HSP_nSS_SHIFT           4
  32#define HSP_nAS_SHIFT           8
  33#define HSP_nDB_SHIFT           12
  34#define HSP_nSI_SHIFT           16
  35#define HSP_nINT_MASK           0xf
  36
  37#define HSP_DB_TRIGGER  0x0
  38#define HSP_DB_ENABLE   0x4
  39#define HSP_DB_RAW      0x8
  40#define HSP_DB_PENDING  0xc
  41
  42#define HSP_SM_SHRD_MBOX        0x0
  43#define HSP_SM_SHRD_MBOX_FULL   BIT(31)
  44#define HSP_SM_SHRD_MBOX_FULL_INT_IE    0x04
  45#define HSP_SM_SHRD_MBOX_EMPTY_INT_IE   0x08
  46
  47#define HSP_DB_CCPLEX           1
  48#define HSP_DB_BPMP             3
  49#define HSP_DB_MAX              7
  50
  51struct tegra_hsp_channel;
  52struct tegra_hsp;
  53
  54struct tegra_hsp_channel {
  55        struct tegra_hsp *hsp;
  56        struct mbox_chan *chan;
  57        void __iomem *regs;
  58};
  59
  60struct tegra_hsp_doorbell {
  61        struct tegra_hsp_channel channel;
  62        struct list_head list;
  63        const char *name;
  64        unsigned int master;
  65        unsigned int index;
  66};
  67
  68struct tegra_hsp_mailbox {
  69        struct tegra_hsp_channel channel;
  70        unsigned int index;
  71        bool producer;
  72};
  73
  74struct tegra_hsp_db_map {
  75        const char *name;
  76        unsigned int master;
  77        unsigned int index;
  78};
  79
  80struct tegra_hsp_soc {
  81        const struct tegra_hsp_db_map *map;
  82        bool has_per_mb_ie;
  83};
  84
  85struct tegra_hsp {
  86        struct device *dev;
  87        const struct tegra_hsp_soc *soc;
  88        struct mbox_controller mbox_db;
  89        struct mbox_controller mbox_sm;
  90        void __iomem *regs;
  91        unsigned int doorbell_irq;
  92        unsigned int *shared_irqs;
  93        unsigned int shared_irq;
  94        unsigned int num_sm;
  95        unsigned int num_as;
  96        unsigned int num_ss;
  97        unsigned int num_db;
  98        unsigned int num_si;
  99        spinlock_t lock;
 100
 101        struct list_head doorbells;
 102        struct tegra_hsp_mailbox *mailboxes;
 103
 104        unsigned long mask;
 105};
 106
 107static inline u32 tegra_hsp_readl(struct tegra_hsp *hsp, unsigned int offset)
 108{
 109        return readl(hsp->regs + offset);
 110}
 111
 112static inline void tegra_hsp_writel(struct tegra_hsp *hsp, u32 value,
 113                                    unsigned int offset)
 114{
 115        writel(value, hsp->regs + offset);
 116}
 117
 118static inline u32 tegra_hsp_channel_readl(struct tegra_hsp_channel *channel,
 119                                          unsigned int offset)
 120{
 121        return readl(channel->regs + offset);
 122}
 123
 124static inline void tegra_hsp_channel_writel(struct tegra_hsp_channel *channel,
 125                                            u32 value, unsigned int offset)
 126{
 127        writel(value, channel->regs + offset);
 128}
 129
 130static bool tegra_hsp_doorbell_can_ring(struct tegra_hsp_doorbell *db)
 131{
 132        u32 value;
 133
 134        value = tegra_hsp_channel_readl(&db->channel, HSP_DB_ENABLE);
 135
 136        return (value & BIT(TEGRA_HSP_DB_MASTER_CCPLEX)) != 0;
 137}
 138
 139static struct tegra_hsp_doorbell *
 140__tegra_hsp_doorbell_get(struct tegra_hsp *hsp, unsigned int master)
 141{
 142        struct tegra_hsp_doorbell *entry;
 143
 144        list_for_each_entry(entry, &hsp->doorbells, list)
 145                if (entry->master == master)
 146                        return entry;
 147
 148        return NULL;
 149}
 150
 151static struct tegra_hsp_doorbell *
 152tegra_hsp_doorbell_get(struct tegra_hsp *hsp, unsigned int master)
 153{
 154        struct tegra_hsp_doorbell *db;
 155        unsigned long flags;
 156
 157        spin_lock_irqsave(&hsp->lock, flags);
 158        db = __tegra_hsp_doorbell_get(hsp, master);
 159        spin_unlock_irqrestore(&hsp->lock, flags);
 160
 161        return db;
 162}
 163
 164static irqreturn_t tegra_hsp_doorbell_irq(int irq, void *data)
 165{
 166        struct tegra_hsp *hsp = data;
 167        struct tegra_hsp_doorbell *db;
 168        unsigned long master, value;
 169
 170        db = tegra_hsp_doorbell_get(hsp, TEGRA_HSP_DB_MASTER_CCPLEX);
 171        if (!db)
 172                return IRQ_NONE;
 173
 174        value = tegra_hsp_channel_readl(&db->channel, HSP_DB_PENDING);
 175        tegra_hsp_channel_writel(&db->channel, value, HSP_DB_PENDING);
 176
 177        spin_lock(&hsp->lock);
 178
 179        for_each_set_bit(master, &value, hsp->mbox_db.num_chans) {
 180                struct tegra_hsp_doorbell *db;
 181
 182                db = __tegra_hsp_doorbell_get(hsp, master);
 183                /*
 184                 * Depending on the bootloader chain, the CCPLEX doorbell will
 185                 * have some doorbells enabled, which means that requesting an
 186                 * interrupt will immediately fire.
 187                 *
 188                 * In that case, db->channel.chan will still be NULL here and
 189                 * cause a crash if not properly guarded.
 190                 *
 191                 * It remains to be seen if ignoring the doorbell in that case
 192                 * is the correct solution.
 193                 */
 194                if (db && db->channel.chan)
 195                        mbox_chan_received_data(db->channel.chan, NULL);
 196        }
 197
 198        spin_unlock(&hsp->lock);
 199
 200        return IRQ_HANDLED;
 201}
 202
 203static irqreturn_t tegra_hsp_shared_irq(int irq, void *data)
 204{
 205        struct tegra_hsp *hsp = data;
 206        unsigned long bit, mask;
 207        u32 status, value;
 208        void *msg;
 209
 210        status = tegra_hsp_readl(hsp, HSP_INT_IR) & hsp->mask;
 211
 212        /* process EMPTY interrupts first */
 213        mask = (status >> HSP_INT_EMPTY_SHIFT) & HSP_INT_EMPTY_MASK;
 214
 215        for_each_set_bit(bit, &mask, hsp->num_sm) {
 216                struct tegra_hsp_mailbox *mb = &hsp->mailboxes[bit];
 217
 218                if (mb->producer) {
 219                        /*
 220                         * Disable EMPTY interrupts until data is sent with
 221                         * the next message. These interrupts are level-
 222                         * triggered, so if we kept them enabled they would
 223                         * constantly trigger until we next write data into
 224                         * the message.
 225                         */
 226                        spin_lock(&hsp->lock);
 227
 228                        hsp->mask &= ~BIT(HSP_INT_EMPTY_SHIFT + mb->index);
 229                        tegra_hsp_writel(hsp, hsp->mask,
 230                                         HSP_INT_IE(hsp->shared_irq));
 231
 232                        spin_unlock(&hsp->lock);
 233
 234                        mbox_chan_txdone(mb->channel.chan, 0);
 235                }
 236        }
 237
 238        /* process FULL interrupts */
 239        mask = (status >> HSP_INT_FULL_SHIFT) & HSP_INT_FULL_MASK;
 240
 241        for_each_set_bit(bit, &mask, hsp->num_sm) {
 242                struct tegra_hsp_mailbox *mb = &hsp->mailboxes[bit];
 243
 244                if (!mb->producer) {
 245                        value = tegra_hsp_channel_readl(&mb->channel,
 246                                                        HSP_SM_SHRD_MBOX);
 247                        value &= ~HSP_SM_SHRD_MBOX_FULL;
 248                        msg = (void *)(unsigned long)value;
 249                        mbox_chan_received_data(mb->channel.chan, msg);
 250
 251                        /*
 252                         * Need to clear all bits here since some producers,
 253                         * such as TCU, depend on fields in the register
 254                         * getting cleared by the consumer.
 255                         *
 256                         * The mailbox API doesn't give the consumers a way
 257                         * of doing that explicitly, so we have to make sure
 258                         * we cover all possible cases.
 259                         */
 260                        tegra_hsp_channel_writel(&mb->channel, 0x0,
 261                                                 HSP_SM_SHRD_MBOX);
 262                }
 263        }
 264
 265        return IRQ_HANDLED;
 266}
 267
 268static struct tegra_hsp_channel *
 269tegra_hsp_doorbell_create(struct tegra_hsp *hsp, const char *name,
 270                          unsigned int master, unsigned int index)
 271{
 272        struct tegra_hsp_doorbell *db;
 273        unsigned int offset;
 274        unsigned long flags;
 275
 276        db = devm_kzalloc(hsp->dev, sizeof(*db), GFP_KERNEL);
 277        if (!db)
 278                return ERR_PTR(-ENOMEM);
 279
 280        offset = (1 + (hsp->num_sm / 2) + hsp->num_ss + hsp->num_as) * SZ_64K;
 281        offset += index * 0x100;
 282
 283        db->channel.regs = hsp->regs + offset;
 284        db->channel.hsp = hsp;
 285
 286        db->name = devm_kstrdup_const(hsp->dev, name, GFP_KERNEL);
 287        db->master = master;
 288        db->index = index;
 289
 290        spin_lock_irqsave(&hsp->lock, flags);
 291        list_add_tail(&db->list, &hsp->doorbells);
 292        spin_unlock_irqrestore(&hsp->lock, flags);
 293
 294        return &db->channel;
 295}
 296
 297static int tegra_hsp_doorbell_send_data(struct mbox_chan *chan, void *data)
 298{
 299        struct tegra_hsp_doorbell *db = chan->con_priv;
 300
 301        tegra_hsp_channel_writel(&db->channel, 1, HSP_DB_TRIGGER);
 302
 303        return 0;
 304}
 305
 306static int tegra_hsp_doorbell_startup(struct mbox_chan *chan)
 307{
 308        struct tegra_hsp_doorbell *db = chan->con_priv;
 309        struct tegra_hsp *hsp = db->channel.hsp;
 310        struct tegra_hsp_doorbell *ccplex;
 311        unsigned long flags;
 312        u32 value;
 313
 314        if (db->master >= chan->mbox->num_chans) {
 315                dev_err(chan->mbox->dev,
 316                        "invalid master ID %u for HSP channel\n",
 317                        db->master);
 318                return -EINVAL;
 319        }
 320
 321        ccplex = tegra_hsp_doorbell_get(hsp, TEGRA_HSP_DB_MASTER_CCPLEX);
 322        if (!ccplex)
 323                return -ENODEV;
 324
 325        if (!tegra_hsp_doorbell_can_ring(db))
 326                return -ENODEV;
 327
 328        spin_lock_irqsave(&hsp->lock, flags);
 329
 330        value = tegra_hsp_channel_readl(&ccplex->channel, HSP_DB_ENABLE);
 331        value |= BIT(db->master);
 332        tegra_hsp_channel_writel(&ccplex->channel, value, HSP_DB_ENABLE);
 333
 334        spin_unlock_irqrestore(&hsp->lock, flags);
 335
 336        return 0;
 337}
 338
 339static void tegra_hsp_doorbell_shutdown(struct mbox_chan *chan)
 340{
 341        struct tegra_hsp_doorbell *db = chan->con_priv;
 342        struct tegra_hsp *hsp = db->channel.hsp;
 343        struct tegra_hsp_doorbell *ccplex;
 344        unsigned long flags;
 345        u32 value;
 346
 347        ccplex = tegra_hsp_doorbell_get(hsp, TEGRA_HSP_DB_MASTER_CCPLEX);
 348        if (!ccplex)
 349                return;
 350
 351        spin_lock_irqsave(&hsp->lock, flags);
 352
 353        value = tegra_hsp_channel_readl(&ccplex->channel, HSP_DB_ENABLE);
 354        value &= ~BIT(db->master);
 355        tegra_hsp_channel_writel(&ccplex->channel, value, HSP_DB_ENABLE);
 356
 357        spin_unlock_irqrestore(&hsp->lock, flags);
 358}
 359
 360static const struct mbox_chan_ops tegra_hsp_db_ops = {
 361        .send_data = tegra_hsp_doorbell_send_data,
 362        .startup = tegra_hsp_doorbell_startup,
 363        .shutdown = tegra_hsp_doorbell_shutdown,
 364};
 365
 366static int tegra_hsp_mailbox_send_data(struct mbox_chan *chan, void *data)
 367{
 368        struct tegra_hsp_mailbox *mb = chan->con_priv;
 369        struct tegra_hsp *hsp = mb->channel.hsp;
 370        unsigned long flags;
 371        u32 value;
 372
 373        if (WARN_ON(!mb->producer))
 374                return -EPERM;
 375
 376        /* copy data and mark mailbox full */
 377        value = (u32)(unsigned long)data;
 378        value |= HSP_SM_SHRD_MBOX_FULL;
 379
 380        tegra_hsp_channel_writel(&mb->channel, value, HSP_SM_SHRD_MBOX);
 381
 382        /* enable EMPTY interrupt for the shared mailbox */
 383        spin_lock_irqsave(&hsp->lock, flags);
 384
 385        hsp->mask |= BIT(HSP_INT_EMPTY_SHIFT + mb->index);
 386        tegra_hsp_writel(hsp, hsp->mask, HSP_INT_IE(hsp->shared_irq));
 387
 388        spin_unlock_irqrestore(&hsp->lock, flags);
 389
 390        return 0;
 391}
 392
 393static int tegra_hsp_mailbox_flush(struct mbox_chan *chan,
 394                                   unsigned long timeout)
 395{
 396        struct tegra_hsp_mailbox *mb = chan->con_priv;
 397        struct tegra_hsp_channel *ch = &mb->channel;
 398        u32 value;
 399
 400        timeout = jiffies + msecs_to_jiffies(timeout);
 401
 402        while (time_before(jiffies, timeout)) {
 403                value = tegra_hsp_channel_readl(ch, HSP_SM_SHRD_MBOX);
 404                if ((value & HSP_SM_SHRD_MBOX_FULL) == 0) {
 405                        mbox_chan_txdone(chan, 0);
 406                        return 0;
 407                }
 408
 409                udelay(1);
 410        }
 411
 412        return -ETIME;
 413}
 414
 415static int tegra_hsp_mailbox_startup(struct mbox_chan *chan)
 416{
 417        struct tegra_hsp_mailbox *mb = chan->con_priv;
 418        struct tegra_hsp_channel *ch = &mb->channel;
 419        struct tegra_hsp *hsp = mb->channel.hsp;
 420        unsigned long flags;
 421
 422        chan->txdone_method = TXDONE_BY_IRQ;
 423
 424        /*
 425         * Shared mailboxes start out as consumers by default. FULL and EMPTY
 426         * interrupts are coalesced at the same shared interrupt.
 427         *
 428         * Keep EMPTY interrupts disabled at startup and only enable them when
 429         * the mailbox is actually full. This is required because the FULL and
 430         * EMPTY interrupts are level-triggered, so keeping EMPTY interrupts
 431         * enabled all the time would cause an interrupt storm while mailboxes
 432         * are idle.
 433         */
 434
 435        spin_lock_irqsave(&hsp->lock, flags);
 436
 437        if (mb->producer)
 438                hsp->mask &= ~BIT(HSP_INT_EMPTY_SHIFT + mb->index);
 439        else
 440                hsp->mask |= BIT(HSP_INT_FULL_SHIFT + mb->index);
 441
 442        tegra_hsp_writel(hsp, hsp->mask, HSP_INT_IE(hsp->shared_irq));
 443
 444        spin_unlock_irqrestore(&hsp->lock, flags);
 445
 446        if (hsp->soc->has_per_mb_ie) {
 447                if (mb->producer)
 448                        tegra_hsp_channel_writel(ch, 0x0,
 449                                                 HSP_SM_SHRD_MBOX_EMPTY_INT_IE);
 450                else
 451                        tegra_hsp_channel_writel(ch, 0x1,
 452                                                 HSP_SM_SHRD_MBOX_FULL_INT_IE);
 453        }
 454
 455        return 0;
 456}
 457
 458static void tegra_hsp_mailbox_shutdown(struct mbox_chan *chan)
 459{
 460        struct tegra_hsp_mailbox *mb = chan->con_priv;
 461        struct tegra_hsp_channel *ch = &mb->channel;
 462        struct tegra_hsp *hsp = mb->channel.hsp;
 463        unsigned long flags;
 464
 465        if (hsp->soc->has_per_mb_ie) {
 466                if (mb->producer)
 467                        tegra_hsp_channel_writel(ch, 0x0,
 468                                                 HSP_SM_SHRD_MBOX_EMPTY_INT_IE);
 469                else
 470                        tegra_hsp_channel_writel(ch, 0x0,
 471                                                 HSP_SM_SHRD_MBOX_FULL_INT_IE);
 472        }
 473
 474        spin_lock_irqsave(&hsp->lock, flags);
 475
 476        if (mb->producer)
 477                hsp->mask &= ~BIT(HSP_INT_EMPTY_SHIFT + mb->index);
 478        else
 479                hsp->mask &= ~BIT(HSP_INT_FULL_SHIFT + mb->index);
 480
 481        tegra_hsp_writel(hsp, hsp->mask, HSP_INT_IE(hsp->shared_irq));
 482
 483        spin_unlock_irqrestore(&hsp->lock, flags);
 484}
 485
 486static const struct mbox_chan_ops tegra_hsp_sm_ops = {
 487        .send_data = tegra_hsp_mailbox_send_data,
 488        .flush = tegra_hsp_mailbox_flush,
 489        .startup = tegra_hsp_mailbox_startup,
 490        .shutdown = tegra_hsp_mailbox_shutdown,
 491};
 492
 493static struct mbox_chan *tegra_hsp_db_xlate(struct mbox_controller *mbox,
 494                                            const struct of_phandle_args *args)
 495{
 496        struct tegra_hsp *hsp = container_of(mbox, struct tegra_hsp, mbox_db);
 497        unsigned int type = args->args[0], master = args->args[1];
 498        struct tegra_hsp_channel *channel = ERR_PTR(-ENODEV);
 499        struct tegra_hsp_doorbell *db;
 500        struct mbox_chan *chan;
 501        unsigned long flags;
 502        unsigned int i;
 503
 504        if (type != TEGRA_HSP_MBOX_TYPE_DB || !hsp->doorbell_irq)
 505                return ERR_PTR(-ENODEV);
 506
 507        db = tegra_hsp_doorbell_get(hsp, master);
 508        if (db)
 509                channel = &db->channel;
 510
 511        if (IS_ERR(channel))
 512                return ERR_CAST(channel);
 513
 514        spin_lock_irqsave(&hsp->lock, flags);
 515
 516        for (i = 0; i < mbox->num_chans; i++) {
 517                chan = &mbox->chans[i];
 518                if (!chan->con_priv) {
 519                        channel->chan = chan;
 520                        chan->con_priv = db;
 521                        break;
 522                }
 523
 524                chan = NULL;
 525        }
 526
 527        spin_unlock_irqrestore(&hsp->lock, flags);
 528
 529        return chan ?: ERR_PTR(-EBUSY);
 530}
 531
 532static struct mbox_chan *tegra_hsp_sm_xlate(struct mbox_controller *mbox,
 533                                            const struct of_phandle_args *args)
 534{
 535        struct tegra_hsp *hsp = container_of(mbox, struct tegra_hsp, mbox_sm);
 536        unsigned int type = args->args[0], index;
 537        struct tegra_hsp_mailbox *mb;
 538
 539        index = args->args[1] & TEGRA_HSP_SM_MASK;
 540
 541        if (type != TEGRA_HSP_MBOX_TYPE_SM || !hsp->shared_irqs ||
 542            index >= hsp->num_sm)
 543                return ERR_PTR(-ENODEV);
 544
 545        mb = &hsp->mailboxes[index];
 546
 547        if ((args->args[1] & TEGRA_HSP_SM_FLAG_TX) == 0)
 548                mb->producer = false;
 549        else
 550                mb->producer = true;
 551
 552        return mb->channel.chan;
 553}
 554
 555static int tegra_hsp_add_doorbells(struct tegra_hsp *hsp)
 556{
 557        const struct tegra_hsp_db_map *map = hsp->soc->map;
 558        struct tegra_hsp_channel *channel;
 559
 560        while (map->name) {
 561                channel = tegra_hsp_doorbell_create(hsp, map->name,
 562                                                    map->master, map->index);
 563                if (IS_ERR(channel))
 564                        return PTR_ERR(channel);
 565
 566                map++;
 567        }
 568
 569        return 0;
 570}
 571
 572static int tegra_hsp_add_mailboxes(struct tegra_hsp *hsp, struct device *dev)
 573{
 574        int i;
 575
 576        hsp->mailboxes = devm_kcalloc(dev, hsp->num_sm, sizeof(*hsp->mailboxes),
 577                                      GFP_KERNEL);
 578        if (!hsp->mailboxes)
 579                return -ENOMEM;
 580
 581        for (i = 0; i < hsp->num_sm; i++) {
 582                struct tegra_hsp_mailbox *mb = &hsp->mailboxes[i];
 583
 584                mb->index = i;
 585
 586                mb->channel.hsp = hsp;
 587                mb->channel.regs = hsp->regs + SZ_64K + i * SZ_32K;
 588                mb->channel.chan = &hsp->mbox_sm.chans[i];
 589                mb->channel.chan->con_priv = mb;
 590        }
 591
 592        return 0;
 593}
 594
 595static int tegra_hsp_request_shared_irq(struct tegra_hsp *hsp)
 596{
 597        unsigned int i, irq = 0;
 598        int err;
 599
 600        for (i = 0; i < hsp->num_si; i++) {
 601                irq = hsp->shared_irqs[i];
 602                if (irq <= 0)
 603                        continue;
 604
 605                err = devm_request_irq(hsp->dev, irq, tegra_hsp_shared_irq, 0,
 606                                       dev_name(hsp->dev), hsp);
 607                if (err < 0) {
 608                        dev_err(hsp->dev, "failed to request interrupt: %d\n",
 609                                err);
 610                        continue;
 611                }
 612
 613                hsp->shared_irq = i;
 614
 615                /* disable all interrupts */
 616                tegra_hsp_writel(hsp, 0, HSP_INT_IE(hsp->shared_irq));
 617
 618                dev_dbg(hsp->dev, "interrupt requested: %u\n", irq);
 619
 620                break;
 621        }
 622
 623        if (i == hsp->num_si) {
 624                dev_err(hsp->dev, "failed to find available interrupt\n");
 625                return -ENOENT;
 626        }
 627
 628        return 0;
 629}
 630
 631static int tegra_hsp_probe(struct platform_device *pdev)
 632{
 633        struct tegra_hsp *hsp;
 634        struct resource *res;
 635        unsigned int i;
 636        u32 value;
 637        int err;
 638
 639        hsp = devm_kzalloc(&pdev->dev, sizeof(*hsp), GFP_KERNEL);
 640        if (!hsp)
 641                return -ENOMEM;
 642
 643        hsp->dev = &pdev->dev;
 644        hsp->soc = of_device_get_match_data(&pdev->dev);
 645        INIT_LIST_HEAD(&hsp->doorbells);
 646        spin_lock_init(&hsp->lock);
 647
 648        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 649        hsp->regs = devm_ioremap_resource(&pdev->dev, res);
 650        if (IS_ERR(hsp->regs))
 651                return PTR_ERR(hsp->regs);
 652
 653        value = tegra_hsp_readl(hsp, HSP_INT_DIMENSIONING);
 654        hsp->num_sm = (value >> HSP_nSM_SHIFT) & HSP_nINT_MASK;
 655        hsp->num_ss = (value >> HSP_nSS_SHIFT) & HSP_nINT_MASK;
 656        hsp->num_as = (value >> HSP_nAS_SHIFT) & HSP_nINT_MASK;
 657        hsp->num_db = (value >> HSP_nDB_SHIFT) & HSP_nINT_MASK;
 658        hsp->num_si = (value >> HSP_nSI_SHIFT) & HSP_nINT_MASK;
 659
 660        err = platform_get_irq_byname_optional(pdev, "doorbell");
 661        if (err >= 0)
 662                hsp->doorbell_irq = err;
 663
 664        if (hsp->num_si > 0) {
 665                unsigned int count = 0;
 666
 667                hsp->shared_irqs = devm_kcalloc(&pdev->dev, hsp->num_si,
 668                                                sizeof(*hsp->shared_irqs),
 669                                                GFP_KERNEL);
 670                if (!hsp->shared_irqs)
 671                        return -ENOMEM;
 672
 673                for (i = 0; i < hsp->num_si; i++) {
 674                        char *name;
 675
 676                        name = kasprintf(GFP_KERNEL, "shared%u", i);
 677                        if (!name)
 678                                return -ENOMEM;
 679
 680                        err = platform_get_irq_byname_optional(pdev, name);
 681                        if (err >= 0) {
 682                                hsp->shared_irqs[i] = err;
 683                                count++;
 684                        }
 685
 686                        kfree(name);
 687                }
 688
 689                if (count == 0) {
 690                        devm_kfree(&pdev->dev, hsp->shared_irqs);
 691                        hsp->shared_irqs = NULL;
 692                }
 693        }
 694
 695        /* setup the doorbell controller */
 696        hsp->mbox_db.of_xlate = tegra_hsp_db_xlate;
 697        hsp->mbox_db.num_chans = 32;
 698        hsp->mbox_db.dev = &pdev->dev;
 699        hsp->mbox_db.ops = &tegra_hsp_db_ops;
 700
 701        hsp->mbox_db.chans = devm_kcalloc(&pdev->dev, hsp->mbox_db.num_chans,
 702                                          sizeof(*hsp->mbox_db.chans),
 703                                          GFP_KERNEL);
 704        if (!hsp->mbox_db.chans)
 705                return -ENOMEM;
 706
 707        if (hsp->doorbell_irq) {
 708                err = tegra_hsp_add_doorbells(hsp);
 709                if (err < 0) {
 710                        dev_err(&pdev->dev, "failed to add doorbells: %d\n",
 711                                err);
 712                        return err;
 713                }
 714        }
 715
 716        err = devm_mbox_controller_register(&pdev->dev, &hsp->mbox_db);
 717        if (err < 0) {
 718                dev_err(&pdev->dev, "failed to register doorbell mailbox: %d\n",
 719                        err);
 720                return err;
 721        }
 722
 723        /* setup the shared mailbox controller */
 724        hsp->mbox_sm.of_xlate = tegra_hsp_sm_xlate;
 725        hsp->mbox_sm.num_chans = hsp->num_sm;
 726        hsp->mbox_sm.dev = &pdev->dev;
 727        hsp->mbox_sm.ops = &tegra_hsp_sm_ops;
 728
 729        hsp->mbox_sm.chans = devm_kcalloc(&pdev->dev, hsp->mbox_sm.num_chans,
 730                                          sizeof(*hsp->mbox_sm.chans),
 731                                          GFP_KERNEL);
 732        if (!hsp->mbox_sm.chans)
 733                return -ENOMEM;
 734
 735        if (hsp->shared_irqs) {
 736                err = tegra_hsp_add_mailboxes(hsp, &pdev->dev);
 737                if (err < 0) {
 738                        dev_err(&pdev->dev, "failed to add mailboxes: %d\n",
 739                                err);
 740                        return err;
 741                }
 742        }
 743
 744        err = devm_mbox_controller_register(&pdev->dev, &hsp->mbox_sm);
 745        if (err < 0) {
 746                dev_err(&pdev->dev, "failed to register shared mailbox: %d\n",
 747                        err);
 748                return err;
 749        }
 750
 751        platform_set_drvdata(pdev, hsp);
 752
 753        if (hsp->doorbell_irq) {
 754                err = devm_request_irq(&pdev->dev, hsp->doorbell_irq,
 755                                       tegra_hsp_doorbell_irq, IRQF_NO_SUSPEND,
 756                                       dev_name(&pdev->dev), hsp);
 757                if (err < 0) {
 758                        dev_err(&pdev->dev,
 759                                "failed to request doorbell IRQ#%u: %d\n",
 760                                hsp->doorbell_irq, err);
 761                        return err;
 762                }
 763        }
 764
 765        if (hsp->shared_irqs) {
 766                err = tegra_hsp_request_shared_irq(hsp);
 767                if (err < 0)
 768                        return err;
 769        }
 770
 771        return 0;
 772}
 773
 774static int __maybe_unused tegra_hsp_resume(struct device *dev)
 775{
 776        struct tegra_hsp *hsp = dev_get_drvdata(dev);
 777        unsigned int i;
 778        struct tegra_hsp_doorbell *db;
 779
 780        list_for_each_entry(db, &hsp->doorbells, list) {
 781                if (db && db->channel.chan)
 782                        tegra_hsp_doorbell_startup(db->channel.chan);
 783        }
 784
 785        if (hsp->mailboxes) {
 786                for (i = 0; i < hsp->num_sm; i++) {
 787                        struct tegra_hsp_mailbox *mb = &hsp->mailboxes[i];
 788
 789                        if (mb->channel.chan->cl)
 790                                tegra_hsp_mailbox_startup(mb->channel.chan);
 791                }
 792        }
 793
 794        return 0;
 795}
 796
 797static const struct dev_pm_ops tegra_hsp_pm_ops = {
 798        .resume_noirq = tegra_hsp_resume,
 799};
 800
 801static const struct tegra_hsp_db_map tegra186_hsp_db_map[] = {
 802        { "ccplex", TEGRA_HSP_DB_MASTER_CCPLEX, HSP_DB_CCPLEX, },
 803        { "bpmp",   TEGRA_HSP_DB_MASTER_BPMP,   HSP_DB_BPMP,   },
 804        { /* sentinel */ }
 805};
 806
 807static const struct tegra_hsp_soc tegra186_hsp_soc = {
 808        .map = tegra186_hsp_db_map,
 809        .has_per_mb_ie = false,
 810};
 811
 812static const struct tegra_hsp_soc tegra194_hsp_soc = {
 813        .map = tegra186_hsp_db_map,
 814        .has_per_mb_ie = true,
 815};
 816
 817static const struct of_device_id tegra_hsp_match[] = {
 818        { .compatible = "nvidia,tegra186-hsp", .data = &tegra186_hsp_soc },
 819        { .compatible = "nvidia,tegra194-hsp", .data = &tegra194_hsp_soc },
 820        { }
 821};
 822
 823static struct platform_driver tegra_hsp_driver = {
 824        .driver = {
 825                .name = "tegra-hsp",
 826                .of_match_table = tegra_hsp_match,
 827                .pm = &tegra_hsp_pm_ops,
 828        },
 829        .probe = tegra_hsp_probe,
 830};
 831
 832static int __init tegra_hsp_init(void)
 833{
 834        return platform_driver_register(&tegra_hsp_driver);
 835}
 836core_initcall(tegra_hsp_init);
 837