From 96807c14e0ce090968a90dd2fe3df360e6f96ad1 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 29 Apr 2009 01:51:34 +0100 Subject: Command queue fixes This still doesn't quite work... Signed-off-by: Thomas White --- drivers/mfd/glamo/glamo-cmdq.c | 44 +++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 16 deletions(-) (limited to 'drivers/mfd/glamo/glamo-cmdq.c') 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; icmdq_base + ring_write + i); + for ( i=0; icmdq_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; icmdq_base + ring_write + i); + for ( i=0; icmdq_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); -- cgit v1.2.3