Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ea31bf69 authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/radeon: remove generic rptr/wptr functions (v2)



Fill in asic family specific versions rather than
using the generic version.  This lets us handle asic
specific differences more easily.  In this case, we
disable sw swapping of the rtpr writeback value on
r6xx+ since the hw does it for us.  Fixes bogus
rptr readback on BE systems.

v2: remove missed cpu_to_le32(), add comments

Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent e308b1d3
Loading
Loading
Loading
Loading
+39 −17
Original line number Diff line number Diff line
@@ -4015,15 +4015,43 @@ static int cik_cp_gfx_resume(struct radeon_device *rdev)
	return 0;
}

u32 cik_compute_ring_get_rptr(struct radeon_device *rdev,
u32 cik_gfx_get_rptr(struct radeon_device *rdev,
		     struct radeon_ring *ring)
{
	u32 rptr;

	if (rdev->wb.enabled)
		rptr = rdev->wb.wb[ring->rptr_offs/4];
	else
		rptr = RREG32(CP_RB0_RPTR);

	return rptr;
}

u32 cik_gfx_get_wptr(struct radeon_device *rdev,
		     struct radeon_ring *ring)
{
	u32 wptr;

	wptr = RREG32(CP_RB0_WPTR);

	return wptr;
}

void cik_gfx_set_wptr(struct radeon_device *rdev,
		      struct radeon_ring *ring)
{
	WREG32(CP_RB0_WPTR, ring->wptr);
	(void)RREG32(CP_RB0_WPTR);
}

u32 cik_compute_get_rptr(struct radeon_device *rdev,
			 struct radeon_ring *ring)
{
	u32 rptr;

	if (rdev->wb.enabled) {
		rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
		rptr = rdev->wb.wb[ring->rptr_offs/4];
	} else {
		mutex_lock(&rdev->srbm_mutex);
		cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
@@ -4035,13 +4063,14 @@ u32 cik_compute_ring_get_rptr(struct radeon_device *rdev,
	return rptr;
}

u32 cik_compute_ring_get_wptr(struct radeon_device *rdev,
u32 cik_compute_get_wptr(struct radeon_device *rdev,
			 struct radeon_ring *ring)
{
	u32 wptr;

	if (rdev->wb.enabled) {
		wptr = le32_to_cpu(rdev->wb.wb[ring->wptr_offs/4]);
		/* XXX check if swapping is necessary on BE */
		wptr = rdev->wb.wb[ring->wptr_offs/4];
	} else {
		mutex_lock(&rdev->srbm_mutex);
		cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
@@ -4053,10 +4082,11 @@ u32 cik_compute_ring_get_wptr(struct radeon_device *rdev,
	return wptr;
}

void cik_compute_ring_set_wptr(struct radeon_device *rdev,
void cik_compute_set_wptr(struct radeon_device *rdev,
			  struct radeon_ring *ring)
{
	rdev->wb.wb[ring->wptr_offs/4] = cpu_to_le32(ring->wptr);
	/* XXX check if swapping is necessary on BE */
	rdev->wb.wb[ring->wptr_offs/4] = ring->wptr;
	WDOORBELL32(ring->doorbell_index, ring->wptr);
}

@@ -7606,7 +7636,6 @@ static int cik_startup(struct radeon_device *rdev)

	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
			     CP_RB0_RPTR, CP_RB0_WPTR,
			     PACKET3(PACKET3_NOP, 0x3FFF));
	if (r)
		return r;
@@ -7615,7 +7644,6 @@ static int cik_startup(struct radeon_device *rdev)
	/* type-2 packets are deprecated on MEC, use type-3 instead */
	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET,
			     CP_HQD_PQ_RPTR, CP_HQD_PQ_WPTR,
			     PACKET3(PACKET3_NOP, 0x3FFF));
	if (r)
		return r;
@@ -7627,7 +7655,6 @@ static int cik_startup(struct radeon_device *rdev)
	/* type-2 packets are deprecated on MEC, use type-3 instead */
	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET,
			     CP_HQD_PQ_RPTR, CP_HQD_PQ_WPTR,
			     PACKET3(PACKET3_NOP, 0x3FFF));
	if (r)
		return r;
@@ -7639,16 +7666,12 @@ static int cik_startup(struct radeon_device *rdev)

	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
			     SDMA0_GFX_RB_RPTR + SDMA0_REGISTER_OFFSET,
			     SDMA0_GFX_RB_WPTR + SDMA0_REGISTER_OFFSET,
			     SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0));
	if (r)
		return r;

	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
	r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
			     SDMA0_GFX_RB_RPTR + SDMA1_REGISTER_OFFSET,
			     SDMA0_GFX_RB_WPTR + SDMA1_REGISTER_OFFSET,
			     SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0));
	if (r)
		return r;
@@ -7664,7 +7687,6 @@ static int cik_startup(struct radeon_device *rdev)
	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
	if (ring->ring_size) {
		r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
				     UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
				     RADEON_CP_PACKET2);
		if (!r)
			r = uvd_v1_0_init(rdev);
+69 −0
Original line number Diff line number Diff line
@@ -51,6 +51,75 @@ u32 cik_gpu_check_soft_reset(struct radeon_device *rdev);
 * buffers.
 */

/**
 * cik_sdma_get_rptr - get the current read pointer
 *
 * @rdev: radeon_device pointer
 * @ring: radeon ring pointer
 *
 * Get the current rptr from the hardware (CIK+).
 */
uint32_t cik_sdma_get_rptr(struct radeon_device *rdev,
			   struct radeon_ring *ring)
{
	u32 rptr, reg;

	if (rdev->wb.enabled) {
		rptr = rdev->wb.wb[ring->rptr_offs/4];
	} else {
		if (ring->idx == R600_RING_TYPE_DMA_INDEX)
			reg = SDMA0_GFX_RB_RPTR + SDMA0_REGISTER_OFFSET;
		else
			reg = SDMA0_GFX_RB_RPTR + SDMA1_REGISTER_OFFSET;

		rptr = RREG32(reg);
	}

	return (rptr & 0x3fffc) >> 2;
}

/**
 * cik_sdma_get_wptr - get the current write pointer
 *
 * @rdev: radeon_device pointer
 * @ring: radeon ring pointer
 *
 * Get the current wptr from the hardware (CIK+).
 */
uint32_t cik_sdma_get_wptr(struct radeon_device *rdev,
			   struct radeon_ring *ring)
{
	u32 reg;

	if (ring->idx == R600_RING_TYPE_DMA_INDEX)
		reg = SDMA0_GFX_RB_WPTR + SDMA0_REGISTER_OFFSET;
	else
		reg = SDMA0_GFX_RB_WPTR + SDMA1_REGISTER_OFFSET;

	return (RREG32(reg) & 0x3fffc) >> 2;
}

/**
 * cik_sdma_set_wptr - commit the write pointer
 *
 * @rdev: radeon_device pointer
 * @ring: radeon ring pointer
 *
 * Write the wptr back to the hardware (CIK+).
 */
void cik_sdma_set_wptr(struct radeon_device *rdev,
		       struct radeon_ring *ring)
{
	u32 reg;

	if (ring->idx == R600_RING_TYPE_DMA_INDEX)
		reg = SDMA0_GFX_RB_WPTR + SDMA0_REGISTER_OFFSET;
	else
		reg = SDMA0_GFX_RB_WPTR + SDMA1_REGISTER_OFFSET;

	WREG32(reg, (ring->wptr << 2) & 0x3fffc);
}

/**
 * cik_sdma_ring_ib_execute - Schedule an IB on the DMA engine
 *
+0 −3
Original line number Diff line number Diff line
@@ -5184,14 +5184,12 @@ static int evergreen_startup(struct radeon_device *rdev)

	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
			     R600_CP_RB_RPTR, R600_CP_RB_WPTR,
			     RADEON_CP_PACKET2);
	if (r)
		return r;

	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
			     DMA_RB_RPTR, DMA_RB_WPTR,
			     DMA_PACKET(DMA_PACKET_NOP, 0, 0));
	if (r)
		return r;
@@ -5209,7 +5207,6 @@ static int evergreen_startup(struct radeon_device *rdev)
	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
	if (ring->ring_size) {
		r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
				     UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
				     RADEON_CP_PACKET2);
		if (!r)
			r = uvd_v1_0_init(rdev);
+61 −8
Original line number Diff line number Diff line
@@ -1386,6 +1386,55 @@ static void cayman_cp_enable(struct radeon_device *rdev, bool enable)
	}
}

u32 cayman_gfx_get_rptr(struct radeon_device *rdev,
			struct radeon_ring *ring)
{
	u32 rptr;

	if (rdev->wb.enabled)
		rptr = rdev->wb.wb[ring->rptr_offs/4];
	else {
		if (ring->idx == RADEON_RING_TYPE_GFX_INDEX)
			rptr = RREG32(CP_RB0_RPTR);
		else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX)
			rptr = RREG32(CP_RB1_RPTR);
		else
			rptr = RREG32(CP_RB2_RPTR);
	}

	return rptr;
}

u32 cayman_gfx_get_wptr(struct radeon_device *rdev,
			struct radeon_ring *ring)
{
	u32 wptr;

	if (ring->idx == RADEON_RING_TYPE_GFX_INDEX)
		wptr = RREG32(CP_RB0_WPTR);
	else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX)
		wptr = RREG32(CP_RB1_WPTR);
	else
		wptr = RREG32(CP_RB2_WPTR);

	return wptr;
}

void cayman_gfx_set_wptr(struct radeon_device *rdev,
			 struct radeon_ring *ring)
{
	if (ring->idx == RADEON_RING_TYPE_GFX_INDEX) {
		WREG32(CP_RB0_WPTR, ring->wptr);
		(void)RREG32(CP_RB0_WPTR);
	} else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX) {
		WREG32(CP_RB1_WPTR, ring->wptr);
		(void)RREG32(CP_RB1_WPTR);
	} else {
		WREG32(CP_RB2_WPTR, ring->wptr);
		(void)RREG32(CP_RB2_WPTR);
	}
}

static int cayman_cp_load_microcode(struct radeon_device *rdev)
{
	const __be32 *fw_data;
@@ -1514,6 +1563,16 @@ static int cayman_cp_resume(struct radeon_device *rdev)
		CP_RB1_BASE,
		CP_RB2_BASE
	};
	static const unsigned cp_rb_rptr[] = {
		CP_RB0_RPTR,
		CP_RB1_RPTR,
		CP_RB2_RPTR
	};
	static const unsigned cp_rb_wptr[] = {
		CP_RB0_WPTR,
		CP_RB1_WPTR,
		CP_RB2_WPTR
	};
	struct radeon_ring *ring;
	int i, r;

@@ -1572,8 +1631,8 @@ static int cayman_cp_resume(struct radeon_device *rdev)
		WREG32_P(cp_rb_cntl[i], RB_RPTR_WR_ENA, ~RB_RPTR_WR_ENA);

		ring->rptr = ring->wptr = 0;
		WREG32(ring->rptr_reg, ring->rptr);
		WREG32(ring->wptr_reg, ring->wptr);
		WREG32(cp_rb_rptr[i], ring->rptr);
		WREG32(cp_rb_wptr[i], ring->wptr);

		mdelay(1);
		WREG32_P(cp_rb_cntl[i], 0, ~RB_RPTR_WR_ENA);
@@ -1953,23 +2012,18 @@ static int cayman_startup(struct radeon_device *rdev)
	evergreen_irq_set(rdev);

	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
			     CP_RB0_RPTR, CP_RB0_WPTR,
			     RADEON_CP_PACKET2);
	if (r)
		return r;

	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
			     DMA_RB_RPTR + DMA0_REGISTER_OFFSET,
			     DMA_RB_WPTR + DMA0_REGISTER_OFFSET,
			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
	if (r)
		return r;

	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
	r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
			     DMA_RB_RPTR + DMA1_REGISTER_OFFSET,
			     DMA_RB_WPTR + DMA1_REGISTER_OFFSET,
			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
	if (r)
		return r;
@@ -1988,7 +2042,6 @@ static int cayman_startup(struct radeon_device *rdev)
	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
	if (ring->ring_size) {
		r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
				     UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
				     RADEON_CP_PACKET2);
		if (!r)
			r = uvd_v1_0_init(rdev);
+69 −0
Original line number Diff line number Diff line
@@ -42,6 +42,75 @@ u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev);
 * Cayman and newer support two asynchronous DMA engines.
 */

/**
 * cayman_dma_get_rptr - get the current read pointer
 *
 * @rdev: radeon_device pointer
 * @ring: radeon ring pointer
 *
 * Get the current rptr from the hardware (cayman+).
 */
uint32_t cayman_dma_get_rptr(struct radeon_device *rdev,
			     struct radeon_ring *ring)
{
	u32 rptr, reg;

	if (rdev->wb.enabled) {
		rptr = rdev->wb.wb[ring->rptr_offs/4];
	} else {
		if (ring->idx == R600_RING_TYPE_DMA_INDEX)
			reg = DMA_RB_RPTR + DMA0_REGISTER_OFFSET;
		else
			reg = DMA_RB_RPTR + DMA1_REGISTER_OFFSET;

		rptr = RREG32(reg);
	}

	return (rptr & 0x3fffc) >> 2;
}

/**
 * cayman_dma_get_wptr - get the current write pointer
 *
 * @rdev: radeon_device pointer
 * @ring: radeon ring pointer
 *
 * Get the current wptr from the hardware (cayman+).
 */
uint32_t cayman_dma_get_wptr(struct radeon_device *rdev,
			   struct radeon_ring *ring)
{
	u32 reg;

	if (ring->idx == R600_RING_TYPE_DMA_INDEX)
		reg = DMA_RB_WPTR + DMA0_REGISTER_OFFSET;
	else
		reg = DMA_RB_WPTR + DMA1_REGISTER_OFFSET;

	return (RREG32(reg) & 0x3fffc) >> 2;
}

/**
 * cayman_dma_set_wptr - commit the write pointer
 *
 * @rdev: radeon_device pointer
 * @ring: radeon ring pointer
 *
 * Write the wptr back to the hardware (cayman+).
 */
void cayman_dma_set_wptr(struct radeon_device *rdev,
			 struct radeon_ring *ring)
{
	u32 reg;

	if (ring->idx == R600_RING_TYPE_DMA_INDEX)
		reg = DMA_RB_WPTR + DMA0_REGISTER_OFFSET;
	else
		reg = DMA_RB_WPTR + DMA1_REGISTER_OFFSET;

	WREG32(reg, (ring->wptr << 2) & 0x3fffc);
}

/**
 * cayman_dma_ring_ib_execute - Schedule an IB on the DMA engine
 *
Loading