33 #include <linux/module.h>
42 #include <linux/sched.h>
43 #include <linux/slab.h>
50 #define DRV_NAME "pxa3xx-gcu"
51 #define MISCDEV_MINOR 197
54 #define GCCR_SYNC_CLR (1 << 9)
55 #define GCCR_BP_RST (1 << 8)
56 #define GCCR_ABORT (1 << 6)
57 #define GCCR_STOP (1 << 4)
59 #define REG_GCISCR 0x04
60 #define REG_GCIECR 0x08
61 #define REG_GCRBBR 0x20
62 #define REG_GCRBLR 0x24
63 #define REG_GCRBHR 0x28
64 #define REG_GCRBTR 0x2C
65 #define REG_GCRBEXHR 0x30
67 #define IE_EOB (1 << 0)
68 #define IE_EEOB (1 << 5)
71 #define SHARED_SIZE PAGE_ALIGN(sizeof(struct pxa3xx_gcu_shared))
76 #ifdef PXA3XX_GCU_DEBUG
79 QPRINT(priv, KERN_DEBUG, msg); \
82 #define QDUMP(msg) do {} while (0)
87 QPRINT(priv, KERN_ERR, msg); \
117 static inline unsigned long
129 #define QPRINT(priv, level, msg) \
132 struct pxa3xx_gcu_shared *shared = priv->shared; \
133 u32 base = gc_readl(priv, REG_GCRBBR); \
135 do_gettimeofday(&tv); \
137 printk(level "%ld.%03ld.%03ld - %-17s: %-21s (%s, " \
139 "0x%02lx, B 0x%08lx [%ld], E %5ld, H %5ld, " \
141 tv.tv_sec - priv->base_time.tv_sec, \
142 tv.tv_usec / 1000, tv.tv_usec % 1000, \
144 shared->hw_running ? "running" : " idle", \
145 gc_readl(priv, REG_GCISCR), \
146 gc_readl(priv, REG_GCRBBR), \
147 gc_readl(priv, REG_GCRBLR), \
148 (gc_readl(priv, REG_GCRBEXHR) - base) / 4, \
149 (gc_readl(priv, REG_GCRBHR) - base) / 4, \
150 (gc_readl(priv, REG_GCRBTR) - base) / 4); \
189 "%s, STATUS 0x%02lx, B 0x%08lx [%ld], E %5ld, H %5ld, T %5ld\n",
206 next = running->
next;
208 priv->
free = running;
218 unsigned int num = 0;
226 shared->
buffer[num++] = 0x05000000;
229 shared->
buffer[num++] = 0x00000001;
234 shared->
buffer[num++] = 0x05000000;
247 gc_writel(priv,
REG_GCRBLR, ((num + 63) & ~63) * 4);
251 pxa3xx_gcu_handle_irq(
int irq,
void *
ctx)
291 dump_whole_state(priv);
306 QDUMP(
"Waiting for idle...");
310 priv->
shared->num_wait_idle++;
312 while (priv->
shared->hw_running) {
313 int num = priv->
shared->num_interrupts;
323 priv->
shared->num_interrupts == num) {
340 QDUMP(
"Waiting for free...");
344 priv->
shared->num_wait_free++;
346 while (!priv->
free) {
373 pxa3xx_gcu_misc_write(
struct file *filp,
const char *buff,
374 size_t count, loff_t *offp)
382 int words = count / 4;
386 priv->
shared->num_writes++;
388 priv->
shared->num_words += words;
396 ret = pxa3xx_gcu_wait_free(priv);
409 spin_unlock_irqrestore(&priv->
spinlock, flags);
418 spin_unlock_irqrestore(&priv->
spinlock, flags);
425 buffer->
ptr[words] = 0x01000000;
443 if (!priv->
shared->hw_running)
446 spin_unlock_irqrestore(&priv->
spinlock, flags);
453 pxa3xx_gcu_misc_ioctl(
struct file *filp,
unsigned int cmd,
unsigned long arg)
462 pxa3xx_gcu_reset(priv);
463 spin_unlock_irqrestore(&priv->
spinlock, flags);
467 return pxa3xx_gcu_wait_idle(priv);
507 #ifdef PXA3XX_GCU_DEBUG_TIMER
508 static struct timer_list pxa3xx_gcu_debug_timer;
510 static void pxa3xx_gcu_debug_timedout(
unsigned long ptr)
518 pxa3xx_gcu_debug_timer.function = pxa3xx_gcu_debug_timedout;
519 pxa3xx_gcu_debug_timer.data =
ptr;
520 pxa3xx_gcu_debug_timer.expires =
jiffies + 5*
HZ;
525 static void pxa3xx_gcu_init_debug_timer(
void)
527 pxa3xx_gcu_debug_timedout((
unsigned long) &pxa3xx_gcu_debug_timer);
530 static inline void pxa3xx_gcu_init_debug_timer(
void) {}
588 for (i = 0; i < 8; i++) {
589 ret = add_buffer(dev, priv);
591 dev_err(&dev->
dev,
"failed to allocate DMA memory\n");
606 priv->
misc_fops.write = pxa3xx_gcu_misc_write;
607 priv->
misc_fops.unlocked_ioctl = pxa3xx_gcu_misc_ioctl;
608 priv->
misc_fops.mmap = pxa3xx_gcu_misc_mmap;
617 dev_err(&dev->
dev,
"misc_register() for minor %d failed\n",
625 dev_err(&dev->
dev,
"no I/O memory resource defined\n");
627 goto err_misc_deregister;
631 dev_err(&dev->
dev,
"failed to request I/O memory\n");
633 goto err_misc_deregister;
638 dev_err(&dev->
dev,
"failed to map I/O memory\n");
640 goto err_free_mem_region;
648 dev_err(&dev->
dev,
"failed to allocate DMA memory\n");
655 if (IS_ERR(priv->
clk)) {
663 dev_err(&dev->
dev,
"failed to enable clock\n");
683 platform_set_drvdata(dev, priv);
685 pxa3xx_gcu_reset(priv);
686 pxa3xx_gcu_init_debug_timer();
688 dev_info(&dev->
dev,
"registered @0x%p, DMA 0x%p (%d bytes), IRQ %d\n",
711 platform_set_drvdata(dev,
NULL);
712 free_buffers(dev, priv);
723 pxa3xx_gcu_wait_idle(priv);
730 platform_set_drvdata(dev,
NULL);
732 free_buffers(dev, priv);
739 .probe = pxa3xx_gcu_probe,