static int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv) { u32 tmp; int i; dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { tmp = RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT); tmp |= RADEON_RB3D_DC_FLUSH_ALL; RADEON_WRITE(RADEON_RB3D_DSTCACHE_CTLSTAT, tmp); for (i = 0; i < dev_priv->usec_timeout; i++) { if (!(RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT) & RADEON_RB3D_DC_BUSY)) { return 0; } DRM_UDELAY(1); } } else { /* don't flush or purge cache here or lockup */ return 0; } #if RADEON_FIFO_DEBUG DRM_ERROR("failed!\n"); radeon_status(dev_priv); #endif return -EBUSY; }
/** * uvd_v1_0_ring_test - register write test * * @rdev: radeon_device pointer * @ring: radeon_ring pointer * * Test if we can successfully write to the context register */ int uvd_v1_0_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) { uint32_t tmp = 0; unsigned i; int r; WREG32(UVD_CONTEXT_ID, 0xCAFEDEAD); r = radeon_ring_lock(rdev, ring, 3); if (r) { DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n", ring->idx, r); return r; } radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0)); radeon_ring_write(ring, 0xDEADBEEF); radeon_ring_unlock_commit(rdev, ring); for (i = 0; i < rdev->usec_timeout; i++) { tmp = RREG32(UVD_CONTEXT_ID); if (tmp == 0xDEADBEEF) break; DRM_UDELAY(1); } if (i < rdev->usec_timeout) { DRM_INFO("ring test on %d succeeded in %d usecs\n", ring->idx, i); } else { DRM_ERROR("radeon: ring %d test failed (0x%08X)\n", ring->idx, tmp); r = -EINVAL; } return r; }
/** * radeon_vce_ring_test - test if VCE ring is working * * @rdev: radeon_device pointer * @ring: the engine to test on * */ int radeon_vce_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) { uint32_t rptr = vce_v1_0_get_rptr(rdev, ring); unsigned i; int r; r = radeon_ring_lock(rdev, ring, 16); if (r) { DRM_ERROR("radeon: vce failed to lock ring %d (%d).\n", ring->idx, r); return r; } radeon_ring_write(ring, VCE_CMD_END); radeon_ring_unlock_commit(rdev, ring); for (i = 0; i < rdev->usec_timeout; i++) { if (vce_v1_0_get_rptr(rdev, ring) != rptr) break; DRM_UDELAY(1); } if (i < rdev->usec_timeout) { DRM_INFO("ring test on %d succeeded in %d usecs\n", ring->idx, i); } else { DRM_ERROR("radeon: ring %d test failed\n", ring->idx); r = -ETIMEDOUT; } return r; }
static int nv50_dma_push_wait(struct nouveau_channel *chan, int count) { uint32_t cnt = 0, prev_get = 0; while (chan->dma.ib_free < count) { uint32_t get = nvif_rd32(&chan->user, 0x88); if (get != prev_get) { prev_get = get; cnt = 0; } if ((++cnt & 0xff) == 0) { DRM_UDELAY(1); if (cnt > 100000) return -EBUSY; } chan->dma.ib_free = get - chan->dma.ib_put; if (chan->dma.ib_free <= 0) chan->dma.ib_free += chan->dma.ib_max; } return 0; }
/** * uvd_v6_0_ring_test_ring - register write test * * @ring: amdgpu_ring pointer * * Test if we can successfully write to the context register */ static int uvd_v6_0_ring_test_ring(struct amdgpu_ring *ring) { struct amdgpu_device *adev = ring->adev; uint32_t tmp = 0; unsigned i; int r; WREG32(mmUVD_CONTEXT_ID, 0xCAFEDEAD); r = amdgpu_ring_alloc(ring, 3); if (r) return r; amdgpu_ring_write(ring, PACKET0(mmUVD_CONTEXT_ID, 0)); amdgpu_ring_write(ring, 0xDEADBEEF); amdgpu_ring_commit(ring); for (i = 0; i < adev->usec_timeout; i++) { tmp = RREG32(mmUVD_CONTEXT_ID); if (tmp == 0xDEADBEEF) break; DRM_UDELAY(1); } if (i >= adev->usec_timeout) r = -ETIMEDOUT; return r; }
static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, u16 address, u8 *recv, int recv_bytes, u8 delay) { struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; u8 msg[4]; int msg_bytes = 4; u8 ack; int ret; unsigned retry; msg[0] = address; msg[1] = address >> 8; msg[2] = AUX_NATIVE_READ << 4; msg[3] = (msg_bytes << 4) | (recv_bytes - 1); for (retry = 0; retry < 4; retry++) { ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_bytes, recv, recv_bytes, delay, &ack); if (ret == -EBUSY) continue; else if (ret < 0) return ret; if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) return ret; else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) DRM_UDELAY(400); else if (ret == 0) return -EPROTO; else return -EIO; } return -EIO; }
static int savage_bci_wait_fifo_shadow(drm_savage_private_t * dev_priv, unsigned int n) { uint32_t mask = dev_priv->status_used_mask; uint32_t threshold = dev_priv->bci_threshold_hi; uint32_t status; int i; #if SAVAGE_BCI_DEBUG if (n > dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - threshold) DRM_ERROR("Trying to emit %d words " "(more than guaranteed space in COB)\n", n); #endif for (i = 0; i < SAVAGE_DEFAULT_USEC_TIMEOUT; i++) { DRM_MEMORYBARRIER(); status = dev_priv->status_ptr[0]; if ((status & mask) < threshold) return 0; DRM_UDELAY(1); } #if SAVAGE_BCI_DEBUG DRM_ERROR("failed!\n"); DRM_INFO(" status=0x%08x, threshold=0x%08x\n", status, threshold); #endif return -EBUSY; }
static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv) { int i, ret; dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; ret = radeon_do_wait_for_fifo(dev_priv, 64); if (ret) return ret; for (i = 0; i < dev_priv->usec_timeout; i++) { if (!(RADEON_READ(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)) { radeon_do_pixcache_flush(dev_priv); return 0; } DRM_UDELAY(1); } DRM_DEBUG("wait idle failed status : 0x%08X 0x%08X\n", RADEON_READ(RADEON_RBBM_STATUS), RADEON_READ(R300_VAP_CNTL_STATUS)); #if RADEON_FIFO_DEBUG DRM_ERROR("failed!\n"); radeon_status(dev_priv); #endif return -EBUSY; }
/** * uvd_v6_0_ring_test_ring - register write test * * @ring: amdgpu_ring pointer * * Test if we can successfully write to the context register */ static int uvd_v6_0_ring_test_ring(struct amdgpu_ring *ring) { struct amdgpu_device *adev = ring->adev; uint32_t tmp = 0; unsigned i; int r; WREG32(mmUVD_CONTEXT_ID, 0xCAFEDEAD); r = amdgpu_ring_alloc(ring, 3); if (r) { DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", ring->idx, r); return r; } amdgpu_ring_write(ring, PACKET0(mmUVD_CONTEXT_ID, 0)); amdgpu_ring_write(ring, 0xDEADBEEF); amdgpu_ring_commit(ring); for (i = 0; i < adev->usec_timeout; i++) { tmp = RREG32(mmUVD_CONTEXT_ID); if (tmp == 0xDEADBEEF) break; DRM_UDELAY(1); } if (i < adev->usec_timeout) { DRM_INFO("ring test on %d succeeded in %d usecs\n", ring->idx, i); } else { DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n", ring->idx, tmp); r = -EINVAL; } return r; }
/** * cik_sdma_ib_test - test an IB on the DMA engine * * @rdev: radeon_device pointer * @ring: radeon_ring structure holding ring information * * Test a simple IB in the DMA ring (CIK). * Returns 0 on success, error on failure. */ int cik_sdma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) { struct radeon_ib ib; unsigned i; unsigned index; int r; u32 tmp = 0; u64 gpu_addr; if (ring->idx == R600_RING_TYPE_DMA_INDEX) index = R600_WB_DMA_RING_TEST_OFFSET; else index = CAYMAN_WB_DMA1_RING_TEST_OFFSET; gpu_addr = rdev->wb.gpu_addr + index; tmp = 0xCAFEDEAD; rdev->wb.wb[index/4] = cpu_to_le32(tmp); r = radeon_ib_get(rdev, ring->idx, &ib, NULL, 256); if (r) { DRM_ERROR("radeon: failed to get ib (%d).\n", r); return r; } ib.ptr[0] = SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0); ib.ptr[1] = lower_32_bits(gpu_addr); ib.ptr[2] = upper_32_bits(gpu_addr); ib.ptr[3] = 1; ib.ptr[4] = 0xDEADBEEF; ib.length_dw = 5; r = radeon_ib_schedule(rdev, &ib, NULL, false); if (r) { radeon_ib_free(rdev, &ib); DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); return r; } r = radeon_fence_wait(ib.fence, false); if (r) { DRM_ERROR("radeon: fence wait failed (%d).\n", r); return r; } for (i = 0; i < rdev->usec_timeout; i++) { tmp = le32_to_cpu(rdev->wb.wb[index/4]); if (tmp == 0xDEADBEEF) break; DRM_UDELAY(1); } if (i < rdev->usec_timeout) { DRM_INFO("ib test on ring %d succeeded in %u usecs\n", ib.fence->ring, i); } else { DRM_ERROR("radeon: ib test failed (0x%08X)\n", tmp); r = -EINVAL; } radeon_ib_free(rdev, &ib); return r; }
static int nouveau_fbcon_sync(struct fb_info *info) { struct nouveau_fbdev *nfbdev = info->par; struct drm_device *dev = nfbdev->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *chan = dev_priv->channel; int ret, i; if (!chan || !chan->accel_done || in_interrupt() || info->state != FBINFO_STATE_RUNNING || info->flags & FBINFO_HWACCEL_DISABLED) return 0; if (!mutex_trylock(&chan->mutex)) return 0; ret = RING_SPACE(chan, 4); if (ret) { mutex_unlock(&chan->mutex); nouveau_fbcon_gpu_lockup(info); return 0; } if (dev_priv->card_type >= NV_C0) { BEGIN_NVC0(chan, 2, NvSub2D, 0x010c, 1); OUT_RING (chan, 0); BEGIN_NVC0(chan, 2, NvSub2D, 0x0100, 1); OUT_RING (chan, 0); } else { BEGIN_RING(chan, 0, 0x0104, 1); OUT_RING (chan, 0); BEGIN_RING(chan, 0, 0x0100, 1); OUT_RING (chan, 0); } nouveau_bo_wr32(chan->notifier_bo, chan->m2mf_ntfy/4 + 3, 0xffffffff); FIRE_RING(chan); mutex_unlock(&chan->mutex); ret = -EBUSY; for (i = 0; i < 100000; i++) { if (!nouveau_bo_rd32(chan->notifier_bo, chan->m2mf_ntfy/4 + 3)) { ret = 0; break; } DRM_UDELAY(1); } if (ret) { nouveau_fbcon_gpu_lockup(info); return 0; } chan->accel_done = false; return 0; }
void mga_do_dma_flush( drm_mga_private_t *dev_priv ) { drm_mga_primary_buffer_t *primary = &dev_priv->prim; u32 head, tail; u32 status = 0; int i; DMA_LOCALS; DRM_DEBUG( "\n" ); /* We need to wait so that we can do an safe flush */ for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK; if ( status == MGA_ENDPRDMASTS ) break; DRM_UDELAY( 1 ); } if ( primary->tail == primary->last_flush ) { DRM_DEBUG( " bailing out...\n" ); return; } tail = primary->tail + dev_priv->primary->offset; /* We need to pad the stream between flushes, as the card * actually (partially?) reads the first of these commands. * See page 4-16 in the G400 manual, middle of the page or so. */ BEGIN_DMA( 1 ); DMA_BLOCK( MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000 ); ADVANCE_DMA(); primary->last_flush = primary->tail; head = MGA_READ( MGA_PRIMADDRESS ); if ( head <= tail ) { primary->space = primary->size - primary->tail; } else { primary->space = head - tail; } DRM_DEBUG( " head = 0x%06lx\n", head - dev_priv->primary->offset ); DRM_DEBUG( " tail = 0x%06lx\n", tail - dev_priv->primary->offset ); DRM_DEBUG( " space = 0x%06x\n", primary->space ); mga_flush_write_combine(); MGA_WRITE( MGA_PRIMEND, tail | MGA_PAGPXFER ); DRM_DEBUG( "done.\n" ); }
/** * cik_sdma_ib_test - test an IB on the DMA engine * * @rdev: radeon_device pointer * @ring: radeon_ring structure holding ring information * * Test a simple IB in the DMA ring (CIK). * Returns 0 on success, error on failure. */ int cik_sdma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) { struct radeon_ib ib; unsigned i; int r; void __iomem *ptr = (void *)rdev->vram_scratch.ptr; u32 tmp = 0; if (!ptr) { DRM_ERROR("invalid vram scratch pointer\n"); return -EINVAL; } tmp = 0xCAFEDEAD; writel(tmp, ptr); r = radeon_ib_get(rdev, ring->idx, &ib, NULL, 256); if (r) { DRM_ERROR("radeon: failed to get ib (%d).\n", r); return r; } ib.ptr[0] = SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0); ib.ptr[1] = rdev->vram_scratch.gpu_addr & 0xfffffffc; ib.ptr[2] = upper_32_bits(rdev->vram_scratch.gpu_addr); ib.ptr[3] = 1; ib.ptr[4] = 0xDEADBEEF; ib.length_dw = 5; r = radeon_ib_schedule(rdev, &ib, NULL); if (r) { radeon_ib_free(rdev, &ib); DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); return r; } r = radeon_fence_wait(ib.fence, false); if (r) { DRM_ERROR("radeon: fence wait failed (%d).\n", r); return r; } for (i = 0; i < rdev->usec_timeout; i++) { tmp = readl(ptr); if (tmp == 0xDEADBEEF) break; DRM_UDELAY(1); } if (i < rdev->usec_timeout) { DRM_INFO("ib test on ring %d succeeded in %u usecs\n", ib.fence->ring, i); } else { DRM_ERROR("radeon: ib test failed (0x%08X)\n", tmp); r = -EINVAL; } radeon_ib_free(rdev, &ib); return r; }
/** * cik_sdma_ring_test_ring - simple async dma engine test * * @ring: amdgpu_ring structure holding ring information * * Test the DMA engine by writing using it to write an * value to memory. (CIK). * Returns 0 for success, error for failure. */ static int cik_sdma_ring_test_ring(struct amdgpu_ring *ring) { struct amdgpu_device *adev = ring->adev; unsigned i; unsigned index; int r; u32 tmp; u64 gpu_addr; r = amdgpu_wb_get(adev, &index); if (r) { dev_err(adev->dev, "(%d) failed to allocate wb slot\n", r); return r; } gpu_addr = adev->wb.gpu_addr + (index * 4); tmp = 0xCAFEDEAD; adev->wb.wb[index] = cpu_to_le32(tmp); r = amdgpu_ring_alloc(ring, 5); if (r) { DRM_ERROR("amdgpu: dma failed to lock ring %d (%d).\n", ring->idx, r); amdgpu_wb_free(adev, index); return r; } amdgpu_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0)); amdgpu_ring_write(ring, lower_32_bits(gpu_addr)); amdgpu_ring_write(ring, upper_32_bits(gpu_addr)); amdgpu_ring_write(ring, 1); /* number of DWs to follow */ amdgpu_ring_write(ring, 0xDEADBEEF); amdgpu_ring_commit(ring); for (i = 0; i < adev->usec_timeout; i++) { tmp = le32_to_cpu(adev->wb.wb[index]); if (tmp == 0xDEADBEEF) break; DRM_UDELAY(1); } if (i < adev->usec_timeout) { DRM_INFO("ring test on %d succeeded in %d usecs\n", ring->idx, i); } else { DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n", ring->idx, tmp); r = -EINVAL; } amdgpu_wb_free(adev, index); return r; }
/* * Global GPU functions */ int rs690_mc_wait_for_idle(struct radeon_device *rdev) { unsigned i; uint32_t tmp; for (i = 0; i < rdev->usec_timeout; i++) { /* read MC_STATUS */ tmp = RREG32_MC(RS690_MC_STATUS); if (tmp & RS690_MC_STATUS_IDLE) { return 0; } DRM_UDELAY(1); } return -1; }
void rs400_gart_tlb_flush(struct radeon_device *rdev) { uint32_t tmp; unsigned int timeout = rdev->usec_timeout; WREG32_MC(RS480_GART_CACHE_CNTRL, RS480_GART_CACHE_INVALIDATE); do { tmp = RREG32_MC(RS480_GART_CACHE_CNTRL); if ((tmp & RS480_GART_CACHE_INVALIDATE) == 0) break; DRM_UDELAY(1); timeout--; } while (timeout > 0); WREG32_MC(RS480_GART_CACHE_CNTRL, 0); }
/** * cik_sdma_ring_test - simple async dma engine test * * @rdev: radeon_device pointer * @ring: radeon_ring structure holding ring information * * Test the DMA engine by writing using it to write an * value to memory. (CIK). * Returns 0 for success, error for failure. */ int cik_sdma_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) { unsigned i; int r; unsigned index; u32 tmp; u64 gpu_addr; if (ring->idx == R600_RING_TYPE_DMA_INDEX) index = R600_WB_DMA_RING_TEST_OFFSET; else index = CAYMAN_WB_DMA1_RING_TEST_OFFSET; gpu_addr = rdev->wb.gpu_addr + index; tmp = 0xCAFEDEAD; rdev->wb.wb[index/4] = cpu_to_le32(tmp); r = radeon_ring_lock(rdev, ring, 5); if (r) { DRM_ERROR("radeon: dma failed to lock ring %d (%d).\n", ring->idx, r); return r; } radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0)); radeon_ring_write(ring, lower_32_bits(gpu_addr)); radeon_ring_write(ring, upper_32_bits(gpu_addr)); radeon_ring_write(ring, 1); /* number of DWs to follow */ radeon_ring_write(ring, 0xDEADBEEF); radeon_ring_unlock_commit(rdev, ring, false); for (i = 0; i < rdev->usec_timeout; i++) { tmp = le32_to_cpu(rdev->wb.wb[index/4]); if (tmp == 0xDEADBEEF) break; DRM_UDELAY(1); } if (i < rdev->usec_timeout) { DRM_INFO("ring test on %d succeeded in %d usecs\n", ring->idx, i); } else { DRM_ERROR("radeon: ring %d test failed (0x%08X)\n", ring->idx, tmp); r = -EINVAL; } return r; }
int mga_do_dma_idle( drm_mga_private_t *dev_priv ) { u32 status = 0; int i; DRM_DEBUG( "\n" ); for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { status = MGA_READ( MGA_STATUS ) & MGA_DMA_IDLE_MASK; if ( status == MGA_ENDPRDMASTS ) return 0; DRM_UDELAY( 1 ); } #if MGA_DMA_DEBUG DRM_ERROR( "failed! status=0x%08x\n", status ); #endif return DRM_ERR(EBUSY); }
static int nouveau_fbcon_sync(struct fb_info *info) { #if 0 struct nouveau_fbdev *nfbdev = info->par; struct drm_device *dev = nfbdev->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *chan = dev_priv->channel; int ret, i; if (!chan || !chan->accel_done || info->state != FBINFO_STATE_RUNNING || info->flags & FBINFO_HWACCEL_DISABLED) return 0; if (RING_SPACE(chan, 4)) { nouveau_fbcon_gpu_lockup(info); return 0; } BEGIN_RING(chan, 0, 0x0104, 1); OUT_RING(chan, 0); BEGIN_RING(chan, 0, 0x0100, 1); OUT_RING(chan, 0); nouveau_bo_wr32(chan->notifier_bo, chan->m2mf_ntfy + 3, 0xffffffff); FIRE_RING(chan); ret = -EBUSY; for (i = 0; i < 100000; i++) { if (!nouveau_bo_rd32(chan->notifier_bo, chan->m2mf_ntfy + 3)) { ret = 0; break; } DRM_UDELAY(1); } if (ret) { nouveau_fbcon_gpu_lockup(info); return 0; } chan->accel_done = false; #endif return 0; }
/** * cik_sdma_ring_test - simple async dma engine test * * @rdev: radeon_device pointer * @ring: radeon_ring structure holding ring information * * Test the DMA engine by writing using it to write an * value to memory. (CIK). * Returns 0 for success, error for failure. */ int cik_sdma_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) { unsigned i; int r; void __iomem *ptr = (void *)rdev->vram_scratch.ptr; u32 tmp; if (!ptr) { DRM_ERROR("invalid vram scratch pointer\n"); return -EINVAL; } tmp = 0xCAFEDEAD; writel(tmp, ptr); r = radeon_ring_lock(rdev, ring, 5); if (r) { DRM_ERROR("radeon: dma failed to lock ring %d (%d).\n", ring->idx, r); return r; } radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0)); radeon_ring_write(ring, rdev->vram_scratch.gpu_addr & 0xfffffffc); radeon_ring_write(ring, upper_32_bits(rdev->vram_scratch.gpu_addr)); radeon_ring_write(ring, 1); /* number of DWs to follow */ radeon_ring_write(ring, 0xDEADBEEF); radeon_ring_unlock_commit(rdev, ring); for (i = 0; i < rdev->usec_timeout; i++) { tmp = readl(ptr); if (tmp == 0xDEADBEEF) break; DRM_UDELAY(1); } if (i < rdev->usec_timeout) { DRM_INFO("ring test on %d succeeded in %d usecs\n", ring->idx, i); } else { DRM_ERROR("radeon: ring %d test failed (0x%08X)\n", ring->idx, tmp); r = -EINVAL; } return r; }
static int radeon_dp_link_train_finish(struct radeon_dp_link_train_info *dp_info) { DRM_UDELAY(400); /* disable the training pattern on the sink */ radeon_write_dpcd_reg(dp_info->radeon_connector, DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); /* disable the training pattern on the source */ if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) atombios_dig_encoder_setup(dp_info->encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE, 0); else radeon_dp_encoder_service(dp_info->rdev, ATOM_DP_ACTION_TRAINING_COMPLETE, dp_info->dp_clock, dp_info->enc_id, 0); return 0; }
static int savage_bci_wait_fifo_s4(drm_savage_private_t * dev_priv, unsigned int n) { uint32_t maxUsed = dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - n; uint32_t status; int i; for (i = 0; i < SAVAGE_DEFAULT_USEC_TIMEOUT; i++) { status = SAVAGE_READ(SAVAGE_ALT_STATUS_WORD0); if ((status & SAVAGE_FIFO_USED_MASK_S4) <= maxUsed) return 0; DRM_UDELAY(1); } #if SAVAGE_BCI_DEBUG DRM_ERROR("failed!\n"); DRM_INFO(" status=0x%08x\n", status); #endif return -EBUSY; }
int mga_do_wait_for_idle( drm_mga_private_t *dev_priv ) { u32 status = 0; int i; DRM_DEBUG( "\n" ); for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK; if ( status == MGA_ENDPRDMASTS ) { MGA_WRITE8( MGA_CRTC_INDEX, 0 ); return 0; } DRM_UDELAY( 1 ); } #if MGA_DMA_DEBUG DRM_ERROR( "failed!\n" ); DRM_INFO( " status=0x%08x\n", status ); #endif return DRM_ERR(EBUSY); }
static int savage_bci_wait_event_reg(drm_savage_private_t * dev_priv, uint16_t e) { uint32_t status; int i; for (i = 0; i < SAVAGE_EVENT_USEC_TIMEOUT; i++) { status = SAVAGE_READ(SAVAGE_STATUS_WORD1); if ((((status & 0xffff) - e) & 0xffff) <= 0x7fff || (status & 0xffff) == 0) return 0; DRM_UDELAY(1); } #if SAVAGE_BCI_DEBUG DRM_ERROR("failed!\n"); DRM_INFO(" status=0x%08x, e=0x%04x\n", status, e); #endif return -EBUSY; }
int psb_wait_for_register(struct drm_psb_private *dev_priv, uint32_t offset, uint32_t value, uint32_t enable, uint32_t loops, uint32_t interval) { uint32_t reg_value = 0; uint32_t poll_cnt = loops; while (poll_cnt) { reg_value = PSB_RMSVDX32(offset); if (value == (reg_value & enable)) /* All the bits are reset */ return 0; /* So exit */ /* Wait a bit */ DRM_UDELAY(interval); poll_cnt--; } DRM_ERROR("MSVDX: Timeout while waiting for register %08x:" " expecting %08x (mask %08x), got %08x\n", offset, value, enable, reg_value); return 1; }
/* * Waiting for events. * * The BIOSresets the event tag to 0 on mode changes. Therefore we * never emit 0 to the event tag. If we find a 0 event tag we know the * BIOS stomped on it and return success assuming that the BIOS waited * for engine idle. * * Note: if the Xserver uses the event tag it has to follow the same * rule. Otherwise there may be glitches every 2^16 events. */ static int savage_bci_wait_event_shadow(drm_savage_private_t * dev_priv, uint16_t e) { uint32_t status; int i; for (i = 0; i < SAVAGE_EVENT_USEC_TIMEOUT; i++) { DRM_MEMORYBARRIER(); status = dev_priv->status_ptr[1]; if ((((status & 0xffff) - e) & 0xffff) <= 0x7fff || (status & 0xffff) == 0) return 0; DRM_UDELAY(1); } #if SAVAGE_BCI_DEBUG DRM_ERROR("failed!\n"); DRM_INFO(" status=0x%08x, e=0x%04x\n", status, e); #endif return -EBUSY; }
int psb_wait_for_register (struct drm_psb_private *dev_priv, uint32_t ui32Offset, uint32_t ui32Value, uint32_t ui32Enable) { uint32_t ui32Temp; uint32_t ui32PollCount = 1000; while (ui32PollCount) { ui32Temp = PSB_RMSVDX32 (ui32Offset); if (ui32Value == (ui32Temp & ui32Enable)) /* All the bits are reset */ return 0; /* So exit */ /* Wait a bit */ DRM_UDELAY (100); ui32PollCount--; } PSB_DEBUG_GENERAL ("MSVDX: Timeout while waiting for register %08x: expecting %08x (mask %08x), got %08x\n", ui32Offset, ui32Value, ui32Enable, ui32Temp); return 1; }
u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) { struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); int i; /* Lock the graphics update lock */ tmp |= AVIVO_D1GRPH_UPDATE_LOCK; WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); /* update the scanout addresses */ if (radeon_crtc->crtc_id) { WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); } else { WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); } WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, (u32)crtc_base); WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, (u32)crtc_base); /* Wait for update_pending to go high. */ for (i = 0; i < rdev->usec_timeout; i++) { if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING) break; DRM_UDELAY(1); } DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); /* Unlock the lock, so double-buffering can take place inside vblank */ tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK; WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); /* Return current update_pending status: */ return RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING; }
static int radeon_do_wait_for_fifo(drm_radeon_private_t * dev_priv, int entries) { int i; dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; for (i = 0; i < dev_priv->usec_timeout; i++) { int slots = (RADEON_READ(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK); if (slots >= entries) return 0; DRM_UDELAY(1); } DRM_DEBUG("wait for fifo failed status : 0x%08X 0x%08X\n", RADEON_READ(RADEON_RBBM_STATUS), RADEON_READ(R300_VAP_CNTL_STATUS)); #if RADEON_FIFO_DEBUG DRM_ERROR("failed!\n"); radeon_status(dev_priv); #endif return -EBUSY; }
static int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector, u16 address, u8 *send, u8 send_bytes, u8 delay) { struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; int ret; u8 msg[20]; int msg_bytes = send_bytes + 4; u8 ack; unsigned retry; if (send_bytes > 16) return -1; msg[0] = address; msg[1] = address >> 8; msg[2] = AUX_NATIVE_WRITE << 4; msg[3] = (msg_bytes << 4) | (send_bytes - 1); memcpy(&msg[4], send, send_bytes); for (retry = 0; retry < 4; retry++) { ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_bytes, NULL, 0, delay, &ack); if (ret == -EBUSY) continue; else if (ret < 0) return ret; if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) return send_bytes; else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) DRM_UDELAY(400); else return -EIO; } return -EIO; }