root/drivers/mailbox/tegra-hsp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tegra_hsp_readl
  2. tegra_hsp_writel
  3. tegra_hsp_channel_readl
  4. tegra_hsp_channel_writel
  5. tegra_hsp_doorbell_can_ring
  6. __tegra_hsp_doorbell_get
  7. tegra_hsp_doorbell_get
  8. tegra_hsp_doorbell_irq
  9. tegra_hsp_shared_irq
  10. tegra_hsp_doorbell_create
  11. tegra_hsp_doorbell_send_data
  12. tegra_hsp_doorbell_startup
  13. tegra_hsp_doorbell_shutdown
  14. tegra_hsp_mailbox_send_data
  15. tegra_hsp_mailbox_flush
  16. tegra_hsp_mailbox_startup
  17. tegra_hsp_mailbox_shutdown
  18. tegra_hsp_db_xlate
  19. tegra_hsp_sm_xlate
  20. tegra_hsp_add_doorbells
  21. tegra_hsp_add_mailboxes
  22. tegra_hsp_request_shared_irq
  23. tegra_hsp_probe
  24. tegra_hsp_resume
  25. tegra_hsp_init

   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 
  51 struct tegra_hsp_channel;
  52 struct tegra_hsp;
  53 
  54 struct tegra_hsp_channel {
  55         struct tegra_hsp *hsp;
  56         struct mbox_chan *chan;
  57         void __iomem *regs;
  58 };
  59 
  60 struct 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 
  68 struct tegra_hsp_mailbox {
  69         struct tegra_hsp_channel channel;
  70         unsigned int index;
  71         bool producer;
  72 };
  73 
  74 struct tegra_hsp_db_map {
  75         const char *name;
  76         unsigned int master;
  77         unsigned int index;
  78 };
  79 
  80 struct tegra_hsp_soc {
  81         const struct tegra_hsp_db_map *map;
  82         bool has_per_mb_ie;
  83 };
  84 
  85 struct 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 
 107 static inline u32 tegra_hsp_readl(struct tegra_hsp *hsp, unsigned int offset)
 108 {
 109         return readl(hsp->regs + offset);
 110 }
 111 
 112 static inline void tegra_hsp_writel(struct tegra_hsp *hsp, u32 value,
 113                                     unsigned int offset)
 114 {
 115         writel(value, hsp->regs + offset);
 116 }
 117 
 118 static inline u32 tegra_hsp_channel_readl(struct tegra_hsp_channel *channel,
 119                                           unsigned int offset)
 120 {
 121         return readl(channel->regs + offset);
 122 }
 123 
 124 static 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 
 130 static 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 
 139 static 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 
 151 static struct tegra_hsp_doorbell *
 152 tegra_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 
 164 static 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 
 203 static 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 
 268 static struct tegra_hsp_channel *
 269 tegra_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 
 297 static 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 
 306 static 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 
 339 static 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 
 360 static 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 
 366 static 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 
 393 static 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 
 415 static 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 
 458 static 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 
 486 static 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 
 493 static 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 
 532 static 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 
 555 static 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 
 572 static 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 
 595 static 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 
 631 static 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 
 774 static 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 
 797 static const struct dev_pm_ops tegra_hsp_pm_ops = {
 798         .resume_noirq = tegra_hsp_resume,
 799 };
 800 
 801 static 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 
 807 static const struct tegra_hsp_soc tegra186_hsp_soc = {
 808         .map = tegra186_hsp_db_map,
 809         .has_per_mb_ie = false,
 810 };
 811 
 812 static const struct tegra_hsp_soc tegra194_hsp_soc = {
 813         .map = tegra186_hsp_db_map,
 814         .has_per_mb_ie = true,
 815 };
 816 
 817 static 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 
 823 static 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 
 832 static int __init tegra_hsp_init(void)
 833 {
 834         return platform_driver_register(&tegra_hsp_driver);
 835 }
 836 core_initcall(tegra_hsp_init);

/* [<][>][^][v][top][bottom][index][help] */