diff options
author | Lars-Peter Clausen <lars@metafoo.de> | 2009-02-09 04:25:41 +0100 |
---|---|---|
committer | Lars-Peter Clausen <lars@metafoo.de> | 2009-02-09 04:25:41 +0100 |
commit | 8062d7aa7bac7e06c1a00bd88ca78098550606ed (patch) | |
tree | dc369d9e4bbf29b06aa355c8e3751483a30f8ced | |
parent | ac3c1586c2f6d370536bcdaa95fb7147517738ee (diff) |
Read the ring write address from the hardware, rather then using a local write
address. If the hardware address changes, for example during suspend/resume the
code will still work.
-rw-r--r-- | src/glamo-cmdq.c | 39 | ||||
-rw-r--r-- | src/glamo.h | 2 |
2 files changed, 19 insertions, 22 deletions
diff --git a/src/glamo-cmdq.c b/src/glamo-cmdq.c index e9c5858..a678d01 100644 --- a/src/glamo-cmdq.c +++ b/src/glamo-cmdq.c @@ -316,7 +316,8 @@ GLAMODispatchCMDQCache(GlamoPtr pGlamo) size_t count, ring_count; size_t rest_size; size_t ring_read; - size_t old_ring_write = pGlamo->ring_write; + size_t new_ring_write; + size_t ring_write; if (!buf->used) return; @@ -325,50 +326,51 @@ GLAMODispatchCMDQCache(GlamoPtr pGlamo) count = buf->used; ring_count = pGlamo->ring_len; - - pGlamo->ring_write = (((pGlamo->ring_write + count) & CQ_MASK) + 1) & ~1; + ring_write = MMIO_IN16(mmio, GLAMO_REG_CMDQ_WRITE_ADDRL); + ring_write |= MMIO_IN16(mmio, GLAMO_REG_CMDQ_WRITE_ADDRH) << 16; + new_ring_write = (((ring_write + count) & CQ_MASK) + 1) & ~1; /* Wait until there is enough space to queue the cmd buffer */ - if (pGlamo->ring_write > old_ring_write) { + if (new_ring_write > ring_write) { do { ring_read = MMIO_IN16(mmio, GLAMO_REG_CMDQ_READ_ADDRL) & CQ_MASKL; ring_read |= ((MMIO_IN16(mmio, GLAMO_REG_CMDQ_READ_ADDRH) & CQ_MASKH) << 16); - } while(ring_read > old_ring_write && ring_read < pGlamo->ring_write); + } while(ring_read > ring_write && ring_read < new_ring_write); } else { do { ring_read = MMIO_IN16(mmio, GLAMO_REG_CMDQ_READ_ADDRL) & CQ_MASKL; ring_read |= ((MMIO_IN16(mmio, GLAMO_REG_CMDQ_READ_ADDRH) & CQ_MASKH) << 16); - } while(ring_read > old_ring_write || ring_read < pGlamo->ring_write); + } while(ring_read > ring_write || ring_read < new_ring_write); } /* Wrap around */ - if (old_ring_write >= pGlamo->ring_write) { - rest_size = (ring_count - old_ring_write); - memcpy((char*)(pGlamo->ring_addr) + old_ring_write, addr, rest_size); + if (ring_write >= new_ring_write) { + rest_size = (ring_count - ring_write); + memcpy((char*)(pGlamo->ring_addr) + ring_write, addr, rest_size); memcpy((char*)(pGlamo->ring_addr), addr+rest_size, count - rest_size); /* ring_write being 0 will result in a deadlock because the cmdq read * will never stop. To avoid such an behaviour insert an empty * instruction. */ - if(pGlamo->ring_write == 0) { + if(new_ring_write == 0) { memset((char*)(pGlamo->ring_addr), 0, 4); - pGlamo->ring_write = 4; + new_ring_write = 4; } /* Before changing write read has to stop */ GLAMOEngineWaitReal(pGlamo, GLAMO_ENGINE_CMDQ, FALSE); /* The write position has to change to trigger a read */ - if(old_ring_write == pGlamo->ring_write) { - memset((char*)(pGlamo->ring_addr + pGlamo->ring_write), 0, 4); - pGlamo->ring_write += 4; + if(ring_write == new_ring_write) { + memset((char*)(pGlamo->ring_addr + new_ring_write), 0, 4); + new_ring_write += 4; /* MMIO_OUT16(mmio, GLAMO_REG_CMDQ_WRITE_ADDRH, ((pGlamo->ring_write-4) >> 16) & CQ_MASKH); MMIO_OUT16(mmio, GLAMO_REG_CMDQ_WRITE_ADDRL, (pGlamo->ring_write-4) & CQ_MASKL);*/ } } else { - memcpy((char*)(pGlamo->ring_addr) + old_ring_write, addr, count); + memcpy((char*)(pGlamo->ring_addr) + ring_write, addr, count); GLAMOEngineWaitReal(pGlamo, GLAMO_ENGINE_CMDQ, FALSE); } MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_2D, @@ -376,16 +378,15 @@ GLAMODispatchCMDQCache(GlamoPtr pGlamo) 0); MMIO_OUT16(mmio, GLAMO_REG_CMDQ_WRITE_ADDRH, - (pGlamo->ring_write >> 16) & CQ_MASKH); + (new_ring_write >> 16) & CQ_MASKH); MMIO_OUT16(mmio, GLAMO_REG_CMDQ_WRITE_ADDRL, - pGlamo->ring_write & CQ_MASKL); + new_ring_write & CQ_MASKL); MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_2D, GLAMO_CLOCK_2D_EN_M6CLK, 0xffff); buf->used = 0; - GLAMOEngineWaitReal(pGlamo, GLAMO_ENGINE_ALL, FALSE); } @@ -405,8 +406,6 @@ GLAMOCMDQResetCP(GlamoPtr pGlamo) /* make the decoder happy? */ memset((char*)pGlamo->ring_addr, 0, pGlamo->ring_len); - pGlamo->ring_write = 0; - GLAMOEngineReset(pGlamo, GLAMO_ENGINE_CMDQ); queue_offset = pGlamo->exa_cmd_queue->offset; diff --git a/src/glamo.h b/src/glamo.h index aedef04..d65019b 100644 --- a/src/glamo.h +++ b/src/glamo.h @@ -139,8 +139,6 @@ typedef struct { ExaOffscreenArea *exa_cmd_queue; CARD16 *ring_addr; /* Beginning of ring buffer. */ - int ring_write; /* Index of write ptr in ring. */ - int ring_read; /* Index of read ptr in ring. */ int ring_len; /* |