Lines Matching +full:ixp4xx +full:- +full:ahb +full:- +full:queue +full:- +full:manager
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Intel IXP4xx Queue Manager driver for Linux
14 #include <linux/soc/ixp4xx/qmgr.h>
20 static u32 used_sram_bitmap[4]; /* 128 16-dword pages */
28 void qmgr_put_entry(unsigned int queue, u32 val) in qmgr_put_entry() argument
31 BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */ in qmgr_put_entry()
33 printk(KERN_DEBUG "Queue %s(%i) put %X\n", in qmgr_put_entry()
34 qmgr_queue_descs[queue], queue, val); in qmgr_put_entry()
36 __raw_writel(val, &qmgr_regs->acc[queue][0]); in qmgr_put_entry()
39 u32 qmgr_get_entry(unsigned int queue) in qmgr_get_entry() argument
42 val = __raw_readl(&qmgr_regs->acc[queue][0]); in qmgr_get_entry()
44 BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */ in qmgr_get_entry()
46 printk(KERN_DEBUG "Queue %s(%i) get %X\n", in qmgr_get_entry()
47 qmgr_queue_descs[queue], queue, val); in qmgr_get_entry()
52 static int __qmgr_get_stat1(unsigned int queue) in __qmgr_get_stat1() argument
54 return (__raw_readl(&qmgr_regs->stat1[queue >> 3]) in __qmgr_get_stat1()
55 >> ((queue & 7) << 2)) & 0xF; in __qmgr_get_stat1()
58 static int __qmgr_get_stat2(unsigned int queue) in __qmgr_get_stat2() argument
60 BUG_ON(queue >= HALF_QUEUES); in __qmgr_get_stat2()
61 return (__raw_readl(&qmgr_regs->stat2[queue >> 4]) in __qmgr_get_stat2()
62 >> ((queue & 0xF) << 1)) & 0x3; in __qmgr_get_stat2()
66 * qmgr_stat_empty() - checks if a hardware queue is empty
67 * @queue: queue number
69 * Returns non-zero value if the queue is empty.
71 int qmgr_stat_empty(unsigned int queue) in qmgr_stat_empty() argument
73 BUG_ON(queue >= HALF_QUEUES); in qmgr_stat_empty()
74 return __qmgr_get_stat1(queue) & QUEUE_STAT1_EMPTY; in qmgr_stat_empty()
78 * qmgr_stat_below_low_watermark() - checks if a queue is below low watermark
79 * @queue: queue number
81 * Returns non-zero value if the queue is below low watermark.
83 int qmgr_stat_below_low_watermark(unsigned int queue) in qmgr_stat_below_low_watermark() argument
85 if (queue >= HALF_QUEUES) in qmgr_stat_below_low_watermark()
86 return (__raw_readl(&qmgr_regs->statne_h) >> in qmgr_stat_below_low_watermark()
87 (queue - HALF_QUEUES)) & 0x01; in qmgr_stat_below_low_watermark()
88 return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_EMPTY; in qmgr_stat_below_low_watermark()
92 * qmgr_stat_full() - checks if a hardware queue is full
93 * @queue: queue number
95 * Returns non-zero value if the queue is full.
97 int qmgr_stat_full(unsigned int queue) in qmgr_stat_full() argument
99 if (queue >= HALF_QUEUES) in qmgr_stat_full()
100 return (__raw_readl(&qmgr_regs->statf_h) >> in qmgr_stat_full()
101 (queue - HALF_QUEUES)) & 0x01; in qmgr_stat_full()
102 return __qmgr_get_stat1(queue) & QUEUE_STAT1_FULL; in qmgr_stat_full()
106 * qmgr_stat_overflow() - checks if a hardware queue experienced overflow
107 * @queue: queue number
109 * Returns non-zero value if the queue experienced overflow.
111 int qmgr_stat_overflow(unsigned int queue) in qmgr_stat_overflow() argument
113 return __qmgr_get_stat2(queue) & QUEUE_STAT2_OVERFLOW; in qmgr_stat_overflow()
116 void qmgr_set_irq(unsigned int queue, int src, in qmgr_set_irq() argument
122 if (queue < HALF_QUEUES) { in qmgr_set_irq()
126 reg = &qmgr_regs->irqsrc[queue >> 3]; /* 8 queues per u32 */ in qmgr_set_irq()
127 bit = (queue % 8) * 4; /* 3 bits + 1 reserved bit per queue */ in qmgr_set_irq()
131 /* IRQ source for queues 32-63 is fixed */ in qmgr_set_irq()
134 irq_handlers[queue] = handler; in qmgr_set_irq()
135 irq_pdevs[queue] = pdev; in qmgr_set_irq()
145 /* ACK - it may clear any bits so don't rely on it */ in qmgr_irq1_a0()
146 __raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[0]); in qmgr_irq1_a0()
148 en_bitmap = qmgr_regs->irqen[0]; in qmgr_irq1_a0()
150 i = __fls(en_bitmap); /* number of the last "low" queue */ in qmgr_irq1_a0()
152 src = qmgr_regs->irqsrc[i >> 3]; in qmgr_irq1_a0()
153 stat = qmgr_regs->stat1[i >> 3]; in qmgr_irq1_a0()
170 /* ACK - it may clear any bits so don't rely on it */ in qmgr_irq2_a0()
171 __raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[1]); in qmgr_irq2_a0()
173 req_bitmap = qmgr_regs->irqen[1] & qmgr_regs->statne_h; in qmgr_irq2_a0()
175 i = __fls(req_bitmap); /* number of the last "high" queue */ in qmgr_irq2_a0()
187 u32 req_bitmap = __raw_readl(&qmgr_regs->irqstat[half]); in qmgr_irq()
191 __raw_writel(req_bitmap, &qmgr_regs->irqstat[half]); /* ACK */ in qmgr_irq()
194 i = __fls(req_bitmap); /* number of the last queue */ in qmgr_irq()
203 void qmgr_enable_irq(unsigned int queue) in qmgr_enable_irq() argument
206 int half = queue / 32; in qmgr_enable_irq()
207 u32 mask = 1 << (queue & (HALF_QUEUES - 1)); in qmgr_enable_irq()
210 __raw_writel(__raw_readl(&qmgr_regs->irqen[half]) | mask, in qmgr_enable_irq()
211 &qmgr_regs->irqen[half]); in qmgr_enable_irq()
215 void qmgr_disable_irq(unsigned int queue) in qmgr_disable_irq() argument
218 int half = queue / 32; in qmgr_disable_irq()
219 u32 mask = 1 << (queue & (HALF_QUEUES - 1)); in qmgr_disable_irq()
222 __raw_writel(__raw_readl(&qmgr_regs->irqen[half]) & ~mask, in qmgr_disable_irq()
223 &qmgr_regs->irqen[half]); in qmgr_disable_irq()
224 __raw_writel(mask, &qmgr_regs->irqstat[half]); /* clear */ in qmgr_disable_irq()
237 int qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */, in qmgr_request_queue() argument
242 int __qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */, in qmgr_request_queue()
247 u32 cfg, addr = 0, mask[4]; /* in 16-dwords */ in qmgr_request_queue()
250 BUG_ON(queue >= QUEUES); in qmgr_request_queue()
253 return -EINVAL; in qmgr_request_queue()
273 return -EINVAL; in qmgr_request_queue()
278 len /= 16; /* in 16-dwords: 1, 2, 4 or 8 */ in qmgr_request_queue()
282 return -ENODEV; in qmgr_request_queue()
285 if (__raw_readl(&qmgr_regs->sram[queue])) { in qmgr_request_queue()
286 err = -EBUSY; in qmgr_request_queue()
299 if (addr + len > ARRAY_SIZE(qmgr_regs->sram)) { in qmgr_request_queue()
301 " queue %i\n", queue); in qmgr_request_queue()
302 err = -ENOMEM; in qmgr_request_queue()
311 __raw_writel(cfg | (addr << 14), &qmgr_regs->sram[queue]); in qmgr_request_queue()
313 snprintf(qmgr_queue_descs[queue], sizeof(qmgr_queue_descs[0]), in qmgr_request_queue()
315 printk(KERN_DEBUG "qmgr: requested queue %s(%i) addr = 0x%02X\n", in qmgr_request_queue()
316 qmgr_queue_descs[queue], queue, addr); in qmgr_request_queue()
327 void qmgr_release_queue(unsigned int queue) in qmgr_release_queue() argument
331 BUG_ON(queue >= QUEUES); /* not in valid range */ in qmgr_release_queue()
334 cfg = __raw_readl(&qmgr_regs->sram[queue]); in qmgr_release_queue()
348 while (addr--) in qmgr_release_queue()
352 printk(KERN_DEBUG "qmgr: releasing queue %s(%i)\n", in qmgr_release_queue()
353 qmgr_queue_descs[queue], queue); in qmgr_release_queue()
354 qmgr_queue_descs[queue][0] = '\x0'; in qmgr_release_queue()
357 while ((addr = qmgr_get_entry(queue))) in qmgr_release_queue()
358 printk(KERN_ERR "qmgr: released queue %i not empty: 0x%08X\n", in qmgr_release_queue()
359 queue, addr); in qmgr_release_queue()
361 __raw_writel(0, &qmgr_regs->sram[queue]); in qmgr_release_queue()
367 irq_handlers[queue] = NULL; /* catch IRQ bugs */ in qmgr_release_queue()
377 struct device *dev = &pdev->dev; in ixp4xx_qmgr_probe()
383 return -ENODEV; in ixp4xx_qmgr_probe()
390 return irq1 ? irq1 : -EINVAL; in ixp4xx_qmgr_probe()
394 return irq2 ? irq2 : -EINVAL; in ixp4xx_qmgr_probe()
399 __raw_writel(0x33333333, &qmgr_regs->stat1[i]); in ixp4xx_qmgr_probe()
400 __raw_writel(0, &qmgr_regs->irqsrc[i]); in ixp4xx_qmgr_probe()
403 __raw_writel(0, &qmgr_regs->stat2[i]); in ixp4xx_qmgr_probe()
404 __raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[i]); /* clear */ in ixp4xx_qmgr_probe()
405 __raw_writel(0, &qmgr_regs->irqen[i]); in ixp4xx_qmgr_probe()
408 __raw_writel(0xFFFFFFFF, &qmgr_regs->statne_h); in ixp4xx_qmgr_probe()
409 __raw_writel(0, &qmgr_regs->statf_h); in ixp4xx_qmgr_probe()
412 __raw_writel(0, &qmgr_regs->sram[i]); in ixp4xx_qmgr_probe()
420 err = devm_request_irq(dev, irq1, handler1, 0, "IXP4xx Queue Manager", in ixp4xx_qmgr_probe()
428 err = devm_request_irq(dev, irq2, handler2, 0, "IXP4xx Queue Manager", in ixp4xx_qmgr_probe()
439 dev_info(dev, "IXP4xx Queue Manager initialized.\n"); in ixp4xx_qmgr_probe()
452 .compatible = "intel,ixp4xx-ahb-queue-manager",
459 .name = "ixp4xx-qmgr",