aboutsummaryrefslogtreecommitdiff
path: root/drivers/mfd/glamo/glamo-cmdq.c
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2009-04-29 01:51:34 +0100
committerThomas White <taw@bitwiz.org.uk>2009-04-29 01:51:34 +0100
commit96807c14e0ce090968a90dd2fe3df360e6f96ad1 (patch)
tree58c8ef56a38bd66749f05ca124ade3e584b24ba6 /drivers/mfd/glamo/glamo-cmdq.c
parent8898aa0a73462db0acf7ac09cc066e1d13ad198b (diff)
Command queue fixes
This still doesn't quite work... Signed-off-by: Thomas White <taw@bitwiz.org.uk>
Diffstat (limited to 'drivers/mfd/glamo/glamo-cmdq.c')
-rw-r--r--drivers/mfd/glamo/glamo-cmdq.c44
1 files changed, 28 insertions, 16 deletions
diff --git a/drivers/mfd/glamo/glamo-cmdq.c b/drivers/mfd/glamo/glamo-cmdq.c
index 58cdcfd5da0..b7edaa0f71d 100644
--- a/drivers/mfd/glamo/glamo-cmdq.c
+++ b/drivers/mfd/glamo/glamo-cmdq.c
@@ -109,11 +109,12 @@ glamo_cmdq_wait(struct glamodrm_handle *gdrm, enum glamo_engine engine)
}
printk(KERN_INFO "Waiting for engine idle...\n");
- for ( i=0; i<10000; i++ ) {
+ for ( i=0; i<1000; i++ ) {
status = reg_read(gdrm, GLAMO_REG_CMDQ_STATUS);
if ((status & mask) == val) break;
+ mdelay(1);
}
- if ( i == 10000 ) printk(KERN_WARNING "[glamo-drm] CmdQ timeout!\n");
+ if ( i == 1000 ) printk(KERN_WARNING "[glamo-drm] CmdQ timeout!\n");
}
@@ -128,7 +129,7 @@ int glamo_ioctl_cmdbuf(struct drm_device *dev, void *data,
drm_glamo_cmd_buffer_t *cbuf = data;
u16 *addr;
- printk(KERN_INFO "glamo_ioctl_cmdbuf\n");
+ printk(KERN_INFO "glamo_ioctl_cmdbuf: %i bytes\n", cbuf->bufsz);
gdrm = dev->dev_private;
count = cbuf->bufsz;
@@ -138,9 +139,11 @@ int glamo_ioctl_cmdbuf(struct drm_device *dev, void *data,
ring_write = reg_read(gdrm, GLAMO_REG_CMDQ_WRITE_ADDRL);
ring_write |= (reg_read(gdrm, GLAMO_REG_CMDQ_WRITE_ADDRH) << 16);
+ printk(KERN_INFO "Old write pointer = 0x%x\n", ring_write);
/* Calculate where we'll end up */
- new_ring_write = (((ring_write + count) & CQ_MASK) + 1) & ~1;
+ new_ring_write = (ring_write + count) % GLAMO_CMDQ_SIZE;
+ printk(KERN_INFO "New write pointer = 0x%x\n", new_ring_write);
/* Wait until there is enough space to queue the cmd buffer */
if (new_ring_write > ring_write) {
@@ -149,32 +152,37 @@ int glamo_ioctl_cmdbuf(struct drm_device *dev, void *data,
& CQ_MASKL;
ring_read |= ((reg_read(gdrm, GLAMO_REG_CMDQ_READ_ADDRH)
& CQ_MASKH) << 16);
+ printk(KERN_INFO "ring_read now 0x%x\n", ring_read);
+ /* Loop while the read pointer is between the old and new
+ * positions */
} while (ring_read > ring_write && ring_read < new_ring_write);
} else {
- do {
+ do {
ring_read = reg_read(gdrm, GLAMO_REG_CMDQ_READ_ADDRL)
& CQ_MASKL;
ring_read |= ((reg_read(gdrm, GLAMO_REG_CMDQ_READ_ADDRH)
& CQ_MASKH) << 16);
+ printk(KERN_INFO "ring_read now 0x%x\n", ring_read);
} while (ring_read > ring_write || ring_read < new_ring_write);
}
+ /* Are we about to wrap around? */
if (ring_write >= new_ring_write) {
size_t rest_size;
int i;
-
+ printk(KERN_INFO "Command queue is wrapping around...\n");
/* Wrap around */
rest_size = GLAMO_CMDQ_SIZE - ring_write; /* Space left */
/* Write from current position to end */
- for ( i=0; i<rest_size; i+=2 ) {
- iowrite16(*(addr+i), gdrm->cmdq_base + ring_write + i);
+ for ( i=0; i<rest_size; i++ ) {
+ iowrite16(*(addr+i), gdrm->cmdq_base+ring_write+(i*2));
}
/* Write from start */
- for ( i=0; i<(count-rest_size); i+=2 ) {
- iowrite16(*(addr+rest_size+i), gdrm->cmdq_base + i);
+ for ( i=0; i<(count-rest_size); i++ ) {
+ iowrite16(*(addr+rest_size+i), gdrm->cmdq_base+(i*2));
}
/* ring_write being 0 will result in a deadlock because the
@@ -202,20 +210,25 @@ int glamo_ioctl_cmdbuf(struct drm_device *dev, void *data,
} else {
int i;
-
/* The easy case */
- for ( i=0; i<count; i+=2 ) {
- iowrite16(*(addr+i), gdrm->cmdq_base + ring_write + i);
+ for ( i=0; i<count/2; i++ ) { /* Number of words */
+ printk(KERN_INFO "Writing 2 byes at 0x%x : %4x\n",
+ ring_write+(i*2), *(addr+i));
+ iowrite16(*(addr+i), gdrm->cmdq_base+ring_write+(i*2));
}
glamo_cmdq_wait(gdrm, GLAMO_ENGINE_CMDQ);
}
/* Finally, update the write pointer */
+ 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) & CQ_MASKH);
+ (new_ring_write >> 16) & 0x7f);
reg_write(gdrm, GLAMO_REG_CMDQ_WRITE_ADDRL,
- new_ring_write & CQ_MASKL);
+ new_ring_write & 0xffff);
+ glamo_engine_clkreg_set(gdrm->glamo_core, GLAMO_ENGINE_2D,
+ GLAMO_CLOCK_2D_EN_M6CLK, 0xffff);
glamo_cmdq_wait(gdrm, GLAMO_ENGINE_ALL);
@@ -242,7 +255,6 @@ int glamo_cmdq_init(struct glamodrm_handle *gdrm)
/* Length of command queue in 1k blocks, minus one */
reg_write(gdrm, GLAMO_REG_CMDQ_LEN, (GLAMO_CMDQ_SIZE >> 10)-1);
-
reg_write(gdrm, GLAMO_REG_CMDQ_WRITE_ADDRH, 0);
reg_write(gdrm, GLAMO_REG_CMDQ_WRITE_ADDRL, 0);
reg_write(gdrm, GLAMO_REG_CMDQ_READ_ADDRH, 0);