/* Flush the indirect buffer to the kernel for submission to the card */ void R600CPFlushIndirect(ScrnInfoPtr pScrn, drmBufPtr ib) { drmBufPtr buffer = ib; int start = 0; drm_radeon_indirect_t indirect; int drmFD = RHDDRMFDGet(pScrn->scrnIndex); if (!buffer) return; while (buffer->used & 0x3c){ E32(buffer, CP_PACKET2()); /* fill up to multiple of 16 dwords */ } indirect.idx = buffer->idx; indirect.start = start; indirect.end = buffer->used; indirect.discard = 1; drmCommandWriteRead(drmFD, DRM_RADEON_INDIRECT, &indirect, sizeof(drm_radeon_indirect_t)); }
void radeondrm_commit_ring(struct drm_radeon_private *dev_priv) { int i, tail_aligned, num_p2; u_int32_t *ring; /* check if the ring is padded out to 16-dword alignment */ tail_aligned = dev_priv->ring.tail & (RADEON_RING_ALIGN - 1); if (tail_aligned) { num_p2 = RADEON_RING_ALIGN - tail_aligned; ring = dev_priv->ring.start; /* pad with some CP_PACKET2 */ for (i = 0; i < num_p2; i++) ring[dev_priv->ring.tail + i] = CP_PACKET2(); dev_priv->ring.tail += i; dev_priv->ring.space -= num_p2; } dev_priv->ring.tail &= dev_priv->ring.tail_mask; /* XXX 128byte aligned stuff */ /* flush write combining buffer and writes to ring */ DRM_MEMORYBARRIER(); radeondrm_get_ring_head(dev_priv); if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { RADEON_WRITE(R600_CP_RB_WPTR, dev_priv->ring.tail); /* read from PCI bus to ensure correct posting */ RADEON_READ(R600_CP_RB_RPTR); } else { RADEON_WRITE(RADEON_CP_RB_WPTR, dev_priv->ring.tail); /* read from PCI bus to ensure correct posting */ RADEON_READ(RADEON_CP_RB_RPTR); } }