aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAndreas Pokorny <andreas.pokorny@gmail.com>2009-06-05 14:00:22 +0200
committerAndreas Pokorny <andreas.pokorny@gmail.com>2009-06-05 14:00:22 +0200
commitec86761a55c9c7d5201b71d2ae660193c212d407 (patch)
treee51841602919f07d75836bc6a002485c5bb4d188 /drivers
parent0eb3e1b44f23003ff35d2af8c12ba266b12f3aa9 (diff)
Adding Glamo CMDQ IRQ
The code is still not functional, only the first set of commands get executed. Signed-off-by: Andreas Pokorny <andreas.pokorny@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mfd/glamo/glamo-cmdq.c95
-rw-r--r--drivers/mfd/glamo/glamo-cmdq.h2
-rw-r--r--drivers/mfd/glamo/glamo-drm-drv.c2
3 files changed, 71 insertions, 28 deletions
diff --git a/drivers/mfd/glamo/glamo-cmdq.c b/drivers/mfd/glamo/glamo-cmdq.c
index 064706470e9..e156d16180d 100644
--- a/drivers/mfd/glamo/glamo-cmdq.c
+++ b/drivers/mfd/glamo/glamo-cmdq.c
@@ -73,6 +73,21 @@ static u16 reg_read(struct glamodrm_handle *gdrm, u_int16_t reg)
return ioread16(gdrm->reg_base + reg);
}
+static void glamo_enable_cmdq_irq(struct glamodrm_handle *gdrm)
+{
+ uint16_t irq_status = reg_read(gdrm, GLAMO_REG_IRQ_ENABLE );
+ irq_status |= GLAMO_IRQ_CMDQUEUE;
+ reg_write(gdrm, GLAMO_REG_IRQ_ENABLE, irq_status );
+}
+
+static void glamo_set_cmdq_irq(struct glamodrm_handle *gdrm)
+{
+ uint16_t irq_status = reg_read(gdrm, GLAMO_REG_IRQ_SET);
+ irq_status |= GLAMO_IRQ_CMDQUEUE;
+ reg_write(gdrm, GLAMO_REG_IRQ_SET, irq_status );
+}
+
+
static void
glamo_cmdq_wait(struct glamodrm_handle *gdrm, enum glamo_engine engine)
@@ -130,7 +145,9 @@ static int glamo_add_to_ring(struct glamodrm_handle *gdrm, u16 *addr,
size_t ring_write, ring_read;
size_t new_ring_write;
unsigned long flags;
- uint16_t irq_status;
+
+
+ printk( KERN_INFO "[glamo-drm] glamo add to ring %d bytes\n", count);
up(&gdrm->add_to_ring);
@@ -205,31 +222,30 @@ static int glamo_add_to_ring(struct glamodrm_handle *gdrm, u16 *addr,
iowrite16(*(addr+i), gdrm->cmdq_base+ring_write+(i*2));
}
+ /* this completes the command - if we do not add that
+ * the commands get executed in a loop */
+ iowrite16(0x0000, gdrm->cmdq_base + new_ring_write);
+ iowrite16(0x0000, gdrm->cmdq_base + new_ring_write + 2);
+ new_ring_write += 4;
+
}
+
spin_lock_irqsave( &gdrm->new_ring_write_lock, flags );
gdrm->new_ring_write = new_ring_write;
spin_unlock_irqrestore( &gdrm->new_ring_write_lock, flags );
-#if 0
- /* Before changing write position, read has to stop
- * (Brought across from xf86-video-glamo)
- * TAW: Really? Is pausing the clock not enough? */
- glamo_cmdq_wait(gdrm, GLAMO_ENGINE_CMDQ);
- /* Note that CLOCK_2D_EN_M6CLK has nothing to do with the 2D engine */
- glamo_engine_clkreg_set(gdrm->glamo_core, GLAMO_ENGINE_2D,
- GLAMO_CLOCK_2D_EN_M6CLK, 0x0000);
- reg_write(gdrm, GLAMO_REG_CMDQ_WRITE_ADDRH,
- (new_ring_write >> 16) & 0x7f);
- reg_write(gdrm, GLAMO_REG_CMDQ_WRITE_ADDRL,
- new_ring_write & 0xffff);
- glamo_engine_clkreg_set(gdrm->glamo_core, GLAMO_ENGINE_2D,
- GLAMO_CLOCK_2D_EN_M6CLK, 0xffff);
-#endif
+ /* We try to make the irq happen somehow :( */
+ printk(KERN_INFO "[glamo-drm] enabling...\n");
+ glamo_enable_cmdq_irq(gdrm);
+ printk(KERN_INFO "[glamo-drm] writing CMDQ_CONTROL ...\n");
+ reg_write(gdrm, GLAMO_REG_CMDQ_CONTROL,
+ 1 << 12 | /* Turbo flip (?) */
+ 3 << 8 | /* SQ Idle interrupt */
+ 8 << 4); /* HQ threshold */
+ printk(KERN_INFO "[glamo-drm] ..expecting irq real soon now\n");
+
- irq_status = reg_read(gdrm, GLAMO_REG_IRQ_ENABLE );
- irq_status |= GLAMO_IRQ_CMDQUEUE;
- reg_write(gdrm, GLAMO_REG_IRQ_ENABLE, irq_status );
- down(&gdrm->add_to_ring);
+ down(&gdrm->add_to_ring);
return 0;
}
@@ -240,12 +256,11 @@ static void glamo_cmdq_irq(unsigned int irq, struct irq_desc *desc)
struct glamodrm_handle * gdrm = desc->handler_data;
ssize_t new_ring_write;
- printk( KERN_INFO "IRQ.\n");
if(!gdrm)
return;
/* ack the interrupt source */
- /* reg_write(gdrm, GLAMO_REG_IRQ_CLEAR, GLAMO_IRQ_CMDQUEUE); */
+ /*reg_write(gdrm, GLAMO_REG_IRQ_CLEAR, GLAMO_IRQ_CMDQUEUE);*/
spin_lock_irqsave(&gdrm->new_ring_write_lock, flags);
new_ring_write = gdrm->new_ring_write;
@@ -261,7 +276,8 @@ static void glamo_cmdq_irq(unsigned int irq, struct irq_desc *desc)
glamo_engine_clkreg_set(gdrm->glamo_core, GLAMO_ENGINE_2D,
GLAMO_CLOCK_2D_EN_M6CLK, 0xffff);
- printk( KERN_INFO "Just wrote: %d\n", new_ring_write);
+ printk( KERN_INFO "[glamo-drm] Write Pointer: %d\n", new_ring_write);
+ /*glamo_enable_cmdq_irq(gdrm); */
}
@@ -359,6 +375,7 @@ fail:
int glamo_ioctl_cmdbuf(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
+ int ret = 0;
struct glamodrm_handle *gdrm;
unsigned int count;
drm_glamo_cmd_buffer_t *cbuf = data;
@@ -372,22 +389,36 @@ int glamo_ioctl_cmdbuf(struct drm_device *dev, void *data,
cmds = drm_alloc(count, DRM_MEM_DRIVER);
if ( cmds == NULL ) return -ENOMEM;
- if ( copy_from_user(cmds, cbuf->buf, count) ) return -EINVAL;
+ if ( copy_from_user(cmds, cbuf->buf, count) ) {
+ printk( KERN_WARNING "[glamo-drm] copy from user failed\n");
+ ret = -EINVAL;
+ goto cleanup;
+ }
/* Check the buffer isn't going to tell Glamo to enact naughtiness */
- if ( !glamo_sanitize_buffer(cmds, count) ) return -EINVAL;
+ if ( !glamo_sanitize_buffer(cmds, count) ) {
+ printk( KERN_WARNING "[glamo-drm] sanitize buffer failed\n");
+ ret = -EINVAL;
+ goto cleanup;
+ }
/* Perform relocation, if necessary */
if ( cbuf->nobjs ) {
if ( glamo_do_relocation(gdrm, cbuf, cmds, dev, file_priv) )
- return -EINVAL; /* Relocation failed */
+ {
+ printk( KERN_WARNING "[glamo-drm] Relocation failed\n");
+ ret = -EINVAL;
+ goto cleanup;
+ }
}
glamo_add_to_ring(gdrm, cmds, count);
+
+cleanup:
drm_free(cmds, 1, DRM_MEM_DRIVER);
- return 0;
+ return ret;
}
@@ -421,6 +452,8 @@ int glamo_cmdq_init(struct glamodrm_handle *gdrm)
set_irq_handler(IRQ_GLAMO(GLAMO_IRQIDX_CMDQUEUE), glamo_cmdq_irq);
set_irq_data(IRQ_GLAMO(GLAMO_IRQIDX_CMDQUEUE), gdrm);
+ glamo_enable_cmdq_irq(gdrm);
+
/* initial write position is 0 */
gdrm->new_ring_write = 0;
@@ -432,7 +465,7 @@ int glamo_cmdq_init(struct glamodrm_handle *gdrm)
reg_write(gdrm, GLAMO_REG_CMDQ_READ_ADDRL, 0);
reg_write(gdrm, GLAMO_REG_CMDQ_CONTROL,
1 << 12 | /* Turbo flip (?) */
- 4 << 8 | /* SQ Idle interrupt */
+ 3 << 8 | /* SQ Idle interrupt */
8 << 4); /* HQ threshold */
/* Wait for things to settle down */
@@ -440,3 +473,9 @@ int glamo_cmdq_init(struct glamodrm_handle *gdrm)
return 0;
}
+
+int glamo_cmdq_shutdown(struct glamodrm_handle *gdrm)
+{
+ set_irq_handler(IRQ_GLAMO(GLAMO_IRQIDX_CMDQUEUE), handle_level_irq);
+ return 0;
+}
diff --git a/drivers/mfd/glamo/glamo-cmdq.h b/drivers/mfd/glamo/glamo-cmdq.h
index f5d5ce6ae5a..e72fea9bec5 100644
--- a/drivers/mfd/glamo/glamo-cmdq.h
+++ b/drivers/mfd/glamo/glamo-cmdq.h
@@ -1,6 +1,7 @@
/* Smedia Glamo 336x/337x command queue handling
*
* Copyright (c) 2008-2009 Thomas White <taw@bitwiz.org.uk>
+ * Copyright (c) 2009 Andreas Pokorny <andreas.pokorny@gmail.com>
* Based on xf86-video-glamo
* Copyright 2007 OpenMoko, Inc.
* Copyright © 2009 Lars-Peter Clausen <lars@metafoo.de>
@@ -34,6 +35,7 @@ extern int glamo_ioctl_cmdbuf(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int glamo_cmdq_init(struct glamodrm_handle *gdrm);
+extern int glamo_cmdq_shutdown(struct glamodrm_handle *gdrm);
#endif /* __GLAMO_CMDQ_H */
diff --git a/drivers/mfd/glamo/glamo-drm-drv.c b/drivers/mfd/glamo/glamo-drm-drv.c
index 2208a8ef5f7..856622d9e76 100644
--- a/drivers/mfd/glamo/glamo-drm-drv.c
+++ b/drivers/mfd/glamo/glamo-drm-drv.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 2009 Openmoko, Inc. Jorge Luis Zapata <turran@openmoko.com>
* Copyright (C) 2008-2009 Thomas White <taw@bitwiz.org.uk>
+ * Copyright (C) 2009 Andreas Pokorny <andreas.pokorny@gmail.com>
*
* All rights reserved.
*
@@ -278,6 +279,7 @@ static int glamodrm_remove(struct platform_device *pdev)
glamo_engine_disable(glamocore, GLAMO_ENGINE_3D);
glamo_buffer_final(gdrm);
+ glamo_cmdq_shutdown(gdrm);
drm_exit(&glamodrm_drm_driver);
platform_set_drvdata(pdev, NULL);