linux/drivers/soc/ixp4xx/ixp4xx-qmgr.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Intel IXP4xx Queue Manager driver for Linux
   4 *
   5 * Copyright (C) 2007 Krzysztof Halasa <khc@pm.waw.pl>
   6 */
   7
   8#include <linux/ioport.h>
   9#include <linux/interrupt.h>
  10#include <linux/kernel.h>
  11#include <linux/module.h>
  12#include <linux/of.h>
  13#include <linux/platform_device.h>
  14#include <linux/soc/ixp4xx/qmgr.h>
  15#include <linux/soc/ixp4xx/cpu.h>
  16
  17static struct qmgr_regs __iomem *qmgr_regs;
  18static int qmgr_irq_1;
  19static int qmgr_irq_2;
  20static spinlock_t qmgr_lock;
  21static u32 used_sram_bitmap[4]; /* 128 16-dword pages */
  22static void (*irq_handlers[QUEUES])(void *pdev);
  23static void *irq_pdevs[QUEUES];
  24
  25#if DEBUG_QMGR
  26char qmgr_queue_descs[QUEUES][32];
  27#endif
  28
  29void qmgr_put_entry(unsigned int queue, u32 val)
  30{
  31#if DEBUG_QMGR
  32        BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
  33
  34        printk(KERN_DEBUG "Queue %s(%i) put %X\n",
  35               qmgr_queue_descs[queue], queue, val);
  36#endif
  37        __raw_writel(val, &qmgr_regs->acc[queue][0]);
  38}
  39
  40u32 qmgr_get_entry(unsigned int queue)
  41{
  42        u32 val;
  43        val = __raw_readl(&qmgr_regs->acc[queue][0]);
  44#if DEBUG_QMGR
  45        BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
  46
  47        printk(KERN_DEBUG "Queue %s(%i) get %X\n",
  48               qmgr_queue_descs[queue], queue, val);
  49#endif
  50        return val;
  51}
  52
  53static int __qmgr_get_stat1(unsigned int queue)
  54{
  55        return (__raw_readl(&qmgr_regs->stat1[queue >> 3])
  56                >> ((queue & 7) << 2)) & 0xF;
  57}
  58
  59static int __qmgr_get_stat2(unsigned int queue)
  60{
  61        BUG_ON(queue >= HALF_QUEUES);
  62        return (__raw_readl(&qmgr_regs->stat2[queue >> 4])
  63                >> ((queue & 0xF) << 1)) & 0x3;
  64}
  65
  66/**
  67 * qmgr_stat_empty() - checks if a hardware queue is empty
  68 * @queue:      queue number
  69 *
  70 * Returns non-zero value if the queue is empty.
  71 */
  72int qmgr_stat_empty(unsigned int queue)
  73{
  74        BUG_ON(queue >= HALF_QUEUES);
  75        return __qmgr_get_stat1(queue) & QUEUE_STAT1_EMPTY;
  76}
  77
  78/**
  79 * qmgr_stat_below_low_watermark() - checks if a queue is below low watermark
  80 * @queue:      queue number
  81 *
  82 * Returns non-zero value if the queue is below low watermark.
  83 */
  84int qmgr_stat_below_low_watermark(unsigned int queue)
  85{
  86        if (queue >= HALF_QUEUES)
  87                return (__raw_readl(&qmgr_regs->statne_h) >>
  88                        (queue - HALF_QUEUES)) & 0x01;
  89        return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_EMPTY;
  90}
  91
  92/**
  93 * qmgr_stat_full() - checks if a hardware queue is full
  94 * @queue:      queue number
  95 *
  96 * Returns non-zero value if the queue is full.
  97 */
  98int qmgr_stat_full(unsigned int queue)
  99{
 100        if (queue >= HALF_QUEUES)
 101                return (__raw_readl(&qmgr_regs->statf_h) >>
 102                        (queue - HALF_QUEUES)) & 0x01;
 103        return __qmgr_get_stat1(queue) & QUEUE_STAT1_FULL;
 104}
 105
 106/**
 107 * qmgr_stat_overflow() - checks if a hardware queue experienced overflow
 108 * @queue:      queue number
 109 *
 110 * Returns non-zero value if the queue experienced overflow.
 111 */
 112int qmgr_stat_overflow(unsigned int queue)
 113{
 114        return __qmgr_get_stat2(queue) & QUEUE_STAT2_OVERFLOW;
 115}
 116
 117void qmgr_set_irq(unsigned int queue, int src,
 118                  void (*handler)(void *pdev), void *pdev)
 119{
 120        unsigned long flags;
 121
 122        spin_lock_irqsave(&qmgr_lock, flags);
 123        if (queue < HALF_QUEUES) {
 124                u32 __iomem *reg;
 125                int bit;
 126                BUG_ON(src > QUEUE_IRQ_SRC_NOT_FULL);
 127                reg = &qmgr_regs->irqsrc[queue >> 3]; /* 8 queues per u32 */
 128                bit = (queue % 8) * 4; /* 3 bits + 1 reserved bit per queue */
 129                __raw_writel((__raw_readl(reg) & ~(7 << bit)) | (src << bit),
 130                             reg);
 131        } else
 132                /* IRQ source for queues 32-63 is fixed */
 133                BUG_ON(src != QUEUE_IRQ_SRC_NOT_NEARLY_EMPTY);
 134
 135        irq_handlers[queue] = handler;
 136        irq_pdevs[queue] = pdev;
 137        spin_unlock_irqrestore(&qmgr_lock, flags);
 138}
 139
 140
 141static irqreturn_t qmgr_irq1_a0(int irq, void *pdev)
 142{
 143        int i, ret = 0;
 144        u32 en_bitmap, src, stat;
 145
 146        /* ACK - it may clear any bits so don't rely on it */
 147        __raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[0]);
 148
 149        en_bitmap = __raw_readl(&qmgr_regs->irqen[0]);
 150        while (en_bitmap) {
 151                i = __fls(en_bitmap); /* number of the last "low" queue */
 152                en_bitmap &= ~BIT(i);
 153                src = __raw_readl(&qmgr_regs->irqsrc[i >> 3]);
 154                stat = __raw_readl(&qmgr_regs->stat1[i >> 3]);
 155                if (src & 4) /* the IRQ condition is inverted */
 156                        stat = ~stat;
 157                if (stat & BIT(src & 3)) {
 158                        irq_handlers[i](irq_pdevs[i]);
 159                        ret = IRQ_HANDLED;
 160                }
 161        }
 162        return ret;
 163}
 164
 165
 166static irqreturn_t qmgr_irq2_a0(int irq, void *pdev)
 167{
 168        int i, ret = 0;
 169        u32 req_bitmap;
 170
 171        /* ACK - it may clear any bits so don't rely on it */
 172        __raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[1]);
 173
 174        req_bitmap = __raw_readl(&qmgr_regs->irqen[1]) &
 175                     __raw_readl(&qmgr_regs->statne_h);
 176        while (req_bitmap) {
 177                i = __fls(req_bitmap); /* number of the last "high" queue */
 178                req_bitmap &= ~BIT(i);
 179                irq_handlers[HALF_QUEUES + i](irq_pdevs[HALF_QUEUES + i]);
 180                ret = IRQ_HANDLED;
 181        }
 182        return ret;
 183}
 184
 185
 186static irqreturn_t qmgr_irq(int irq, void *pdev)
 187{
 188        int i, half = (irq == qmgr_irq_1 ? 0 : 1);
 189        u32 req_bitmap = __raw_readl(&qmgr_regs->irqstat[half]);
 190
 191        if (!req_bitmap)
 192                return 0;
 193        __raw_writel(req_bitmap, &qmgr_regs->irqstat[half]); /* ACK */
 194
 195        while (req_bitmap) {
 196                i = __fls(req_bitmap); /* number of the last queue */
 197                req_bitmap &= ~BIT(i);
 198                i += half * HALF_QUEUES;
 199                irq_handlers[i](irq_pdevs[i]);
 200        }
 201        return IRQ_HANDLED;
 202}
 203
 204
 205void qmgr_enable_irq(unsigned int queue)
 206{
 207        unsigned long flags;
 208        int half = queue / 32;
 209        u32 mask = 1 << (queue & (HALF_QUEUES - 1));
 210
 211        spin_lock_irqsave(&qmgr_lock, flags);
 212        __raw_writel(__raw_readl(&qmgr_regs->irqen[half]) | mask,
 213                     &qmgr_regs->irqen[half]);
 214        spin_unlock_irqrestore(&qmgr_lock, flags);
 215}
 216
 217void qmgr_disable_irq(unsigned int queue)
 218{
 219        unsigned long flags;
 220        int half = queue / 32;
 221        u32 mask = 1 << (queue & (HALF_QUEUES - 1));
 222
 223        spin_lock_irqsave(&qmgr_lock, flags);
 224        __raw_writel(__raw_readl(&qmgr_regs->irqen[half]) & ~mask,
 225                     &qmgr_regs->irqen[half]);
 226        __raw_writel(mask, &qmgr_regs->irqstat[half]); /* clear */
 227        spin_unlock_irqrestore(&qmgr_lock, flags);
 228}
 229
 230static inline void shift_mask(u32 *mask)
 231{
 232        mask[3] = mask[3] << 1 | mask[2] >> 31;
 233        mask[2] = mask[2] << 1 | mask[1] >> 31;
 234        mask[1] = mask[1] << 1 | mask[0] >> 31;
 235        mask[0] <<= 1;
 236}
 237
 238#if DEBUG_QMGR
 239int qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
 240                       unsigned int nearly_empty_watermark,
 241                       unsigned int nearly_full_watermark,
 242                       const char *desc_format, const char* name)
 243#else
 244int __qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
 245                         unsigned int nearly_empty_watermark,
 246                         unsigned int nearly_full_watermark)
 247#endif
 248{
 249        u32 cfg, addr = 0, mask[4]; /* in 16-dwords */
 250        int err;
 251
 252        BUG_ON(queue >= QUEUES);
 253
 254        if ((nearly_empty_watermark | nearly_full_watermark) & ~7)
 255                return -EINVAL;
 256
 257        switch (len) {
 258        case  16:
 259                cfg = 0 << 24;
 260                mask[0] = 0x1;
 261                break;
 262        case  32:
 263                cfg = 1 << 24;
 264                mask[0] = 0x3;
 265                break;
 266        case  64:
 267                cfg = 2 << 24;
 268                mask[0] = 0xF;
 269                break;
 270        case 128:
 271                cfg = 3 << 24;
 272                mask[0] = 0xFF;
 273                break;
 274        default:
 275                return -EINVAL;
 276        }
 277
 278        cfg |= nearly_empty_watermark << 26;
 279        cfg |= nearly_full_watermark << 29;
 280        len /= 16;              /* in 16-dwords: 1, 2, 4 or 8 */
 281        mask[1] = mask[2] = mask[3] = 0;
 282
 283        if (!try_module_get(THIS_MODULE))
 284                return -ENODEV;
 285
 286        spin_lock_irq(&qmgr_lock);
 287        if (__raw_readl(&qmgr_regs->sram[queue])) {
 288                err = -EBUSY;
 289                goto err;
 290        }
 291
 292        while (1) {
 293                if (!(used_sram_bitmap[0] & mask[0]) &&
 294                    !(used_sram_bitmap[1] & mask[1]) &&
 295                    !(used_sram_bitmap[2] & mask[2]) &&
 296                    !(used_sram_bitmap[3] & mask[3]))
 297                        break; /* found free space */
 298
 299                addr++;
 300                shift_mask(mask);
 301                if (addr + len > ARRAY_SIZE(qmgr_regs->sram)) {
 302                        printk(KERN_ERR "qmgr: no free SRAM space for"
 303                               " queue %i\n", queue);
 304                        err = -ENOMEM;
 305                        goto err;
 306                }
 307        }
 308
 309        used_sram_bitmap[0] |= mask[0];
 310        used_sram_bitmap[1] |= mask[1];
 311        used_sram_bitmap[2] |= mask[2];
 312        used_sram_bitmap[3] |= mask[3];
 313        __raw_writel(cfg | (addr << 14), &qmgr_regs->sram[queue]);
 314#if DEBUG_QMGR
 315        snprintf(qmgr_queue_descs[queue], sizeof(qmgr_queue_descs[0]),
 316                 desc_format, name);
 317        printk(KERN_DEBUG "qmgr: requested queue %s(%i) addr = 0x%02X\n",
 318               qmgr_queue_descs[queue], queue, addr);
 319#endif
 320        spin_unlock_irq(&qmgr_lock);
 321        return 0;
 322
 323err:
 324        spin_unlock_irq(&qmgr_lock);
 325        module_put(THIS_MODULE);
 326        return err;
 327}
 328
 329void qmgr_release_queue(unsigned int queue)
 330{
 331        u32 cfg, addr, mask[4];
 332
 333        BUG_ON(queue >= QUEUES); /* not in valid range */
 334
 335        spin_lock_irq(&qmgr_lock);
 336        cfg = __raw_readl(&qmgr_regs->sram[queue]);
 337        addr = (cfg >> 14) & 0xFF;
 338
 339        BUG_ON(!addr);          /* not requested */
 340
 341        switch ((cfg >> 24) & 3) {
 342        case 0: mask[0] = 0x1; break;
 343        case 1: mask[0] = 0x3; break;
 344        case 2: mask[0] = 0xF; break;
 345        case 3: mask[0] = 0xFF; break;
 346        }
 347
 348        mask[1] = mask[2] = mask[3] = 0;
 349
 350        while (addr--)
 351                shift_mask(mask);
 352
 353#if DEBUG_QMGR
 354        printk(KERN_DEBUG "qmgr: releasing queue %s(%i)\n",
 355               qmgr_queue_descs[queue], queue);
 356        qmgr_queue_descs[queue][0] = '\x0';
 357#endif
 358
 359        while ((addr = qmgr_get_entry(queue)))
 360                printk(KERN_ERR "qmgr: released queue %i not empty: 0x%08X\n",
 361                       queue, addr);
 362
 363        __raw_writel(0, &qmgr_regs->sram[queue]);
 364
 365        used_sram_bitmap[0] &= ~mask[0];
 366        used_sram_bitmap[1] &= ~mask[1];
 367        used_sram_bitmap[2] &= ~mask[2];
 368        used_sram_bitmap[3] &= ~mask[3];
 369        irq_handlers[queue] = NULL; /* catch IRQ bugs */
 370        spin_unlock_irq(&qmgr_lock);
 371
 372        module_put(THIS_MODULE);
 373}
 374
 375static int ixp4xx_qmgr_probe(struct platform_device *pdev)
 376{
 377        int i, err;
 378        irq_handler_t handler1, handler2;
 379        struct device *dev = &pdev->dev;
 380        struct resource *res;
 381        int irq1, irq2;
 382
 383        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 384        if (!res)
 385                return -ENODEV;
 386        qmgr_regs = devm_ioremap_resource(dev, res);
 387        if (IS_ERR(qmgr_regs))
 388                return PTR_ERR(qmgr_regs);
 389
 390        irq1 = platform_get_irq(pdev, 0);
 391        if (irq1 <= 0)
 392                return irq1 ? irq1 : -EINVAL;
 393        qmgr_irq_1 = irq1;
 394        irq2 = platform_get_irq(pdev, 1);
 395        if (irq2 <= 0)
 396                return irq2 ? irq2 : -EINVAL;
 397        qmgr_irq_2 = irq2;
 398
 399        /* reset qmgr registers */
 400        for (i = 0; i < 4; i++) {
 401                __raw_writel(0x33333333, &qmgr_regs->stat1[i]);
 402                __raw_writel(0, &qmgr_regs->irqsrc[i]);
 403        }
 404        for (i = 0; i < 2; i++) {
 405                __raw_writel(0, &qmgr_regs->stat2[i]);
 406                __raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[i]); /* clear */
 407                __raw_writel(0, &qmgr_regs->irqen[i]);
 408        }
 409
 410        __raw_writel(0xFFFFFFFF, &qmgr_regs->statne_h);
 411        __raw_writel(0, &qmgr_regs->statf_h);
 412
 413        for (i = 0; i < QUEUES; i++)
 414                __raw_writel(0, &qmgr_regs->sram[i]);
 415
 416        if (cpu_is_ixp42x_rev_a0()) {
 417                handler1 = qmgr_irq1_a0;
 418                handler2 = qmgr_irq2_a0;
 419        } else
 420                handler1 = handler2 = qmgr_irq;
 421
 422        err = devm_request_irq(dev, irq1, handler1, 0, "IXP4xx Queue Manager",
 423                               NULL);
 424        if (err) {
 425                dev_err(dev, "failed to request IRQ%i (%i)\n",
 426                        irq1, err);
 427                return err;
 428        }
 429
 430        err = devm_request_irq(dev, irq2, handler2, 0, "IXP4xx Queue Manager",
 431                               NULL);
 432        if (err) {
 433                dev_err(dev, "failed to request IRQ%i (%i)\n",
 434                        irq2, err);
 435                return err;
 436        }
 437
 438        used_sram_bitmap[0] = 0xF; /* 4 first pages reserved for config */
 439        spin_lock_init(&qmgr_lock);
 440
 441        dev_info(dev, "IXP4xx Queue Manager initialized.\n");
 442        return 0;
 443}
 444
 445static int ixp4xx_qmgr_remove(struct platform_device *pdev)
 446{
 447        synchronize_irq(qmgr_irq_1);
 448        synchronize_irq(qmgr_irq_2);
 449        return 0;
 450}
 451
 452static const struct of_device_id ixp4xx_qmgr_of_match[] = {
 453        {
 454                .compatible = "intel,ixp4xx-ahb-queue-manager",
 455        },
 456        {},
 457};
 458
 459static struct platform_driver ixp4xx_qmgr_driver = {
 460        .driver = {
 461                .name           = "ixp4xx-qmgr",
 462                .of_match_table = of_match_ptr(ixp4xx_qmgr_of_match),
 463        },
 464        .probe = ixp4xx_qmgr_probe,
 465        .remove = ixp4xx_qmgr_remove,
 466};
 467module_platform_driver(ixp4xx_qmgr_driver);
 468
 469MODULE_LICENSE("GPL v2");
 470MODULE_AUTHOR("Krzysztof Halasa");
 471
 472EXPORT_SYMBOL(qmgr_put_entry);
 473EXPORT_SYMBOL(qmgr_get_entry);
 474EXPORT_SYMBOL(qmgr_stat_empty);
 475EXPORT_SYMBOL(qmgr_stat_below_low_watermark);
 476EXPORT_SYMBOL(qmgr_stat_full);
 477EXPORT_SYMBOL(qmgr_stat_overflow);
 478EXPORT_SYMBOL(qmgr_set_irq);
 479EXPORT_SYMBOL(qmgr_enable_irq);
 480EXPORT_SYMBOL(qmgr_disable_irq);
 481#if DEBUG_QMGR
 482EXPORT_SYMBOL(qmgr_queue_descs);
 483EXPORT_SYMBOL(qmgr_request_queue);
 484#else
 485EXPORT_SYMBOL(__qmgr_request_queue);
 486#endif
 487EXPORT_SYMBOL(qmgr_release_queue);
 488