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