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

Commit 72a9987e authored by Michel Dänzer's avatar Michel Dänzer Committed by Alex Deucher
Browse files

drm/radeon: Always flush the HDP cache before submitting a CS to the GPU



This ensures the GPU sees all previous CPU writes to VRAM, which makes it
safe:

* For userspace to stream data from CPU to GPU via VRAM instead of GTT
* For IBs to be stored in VRAM instead of GTT
* For ring buffers to be stored in VRAM instead of GTT, if the HPD flush
  is performed via MMIO

Signed-off-by: default avatarMichel Dänzer <michel.daenzer@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 124764f1
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -3890,8 +3890,6 @@ void cik_fence_gfx_ring_emit(struct radeon_device *rdev,
	radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | DATA_SEL(1) | INT_SEL(2));
	radeon_ring_write(ring, fence->seq);
	radeon_ring_write(ring, 0);
	/* HDP flush */
	cik_hdp_flush_cp_ring_emit(rdev, fence->ring);
}

/**
@@ -3920,8 +3918,6 @@ void cik_fence_compute_ring_emit(struct radeon_device *rdev,
	radeon_ring_write(ring, upper_32_bits(addr));
	radeon_ring_write(ring, fence->seq);
	radeon_ring_write(ring, 0);
	/* HDP flush */
	cik_hdp_flush_cp_ring_emit(rdev, fence->ring);
}

bool cik_semaphore_ring_emit(struct radeon_device *rdev,
+15 −5
Original line number Diff line number Diff line
@@ -837,11 +837,7 @@ void r100_fence_ring_emit(struct radeon_device *rdev,
	/* Wait until IDLE & CLEAN */
	radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0));
	radeon_ring_write(ring, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
	radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0));
	radeon_ring_write(ring, rdev->config.r100.hdp_cntl |
				RADEON_HDP_READ_BUFFER_INVALIDATE);
	radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0));
	radeon_ring_write(ring, rdev->config.r100.hdp_cntl);
	r100_ring_hdp_flush(rdev, ring);
	/* Emit fence sequence & fire IRQ */
	radeon_ring_write(ring, PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 0));
	radeon_ring_write(ring, fence->seq);
@@ -1060,6 +1056,20 @@ void r100_gfx_set_wptr(struct radeon_device *rdev,
	(void)RREG32(RADEON_CP_RB_WPTR);
}

/**
 * r100_ring_hdp_flush - flush Host Data Path via the ring buffer
 * rdev: radeon device structure
 * ring: ring buffer struct for emitting packets
 */
void r100_ring_hdp_flush(struct radeon_device *rdev, struct radeon_ring *ring)
{
	radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0));
	radeon_ring_write(ring, rdev->config.r100.hdp_cntl |
				RADEON_HDP_READ_BUFFER_INVALIDATE);
	radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0));
	radeon_ring_write(ring, rdev->config.r100.hdp_cntl);
}

static void r100_cp_load_microcode(struct radeon_device *rdev)
{
	const __be32 *fw_data;
+1 −0
Original line number Diff line number Diff line
@@ -1749,6 +1749,7 @@ struct radeon_asic_ring {
	/* command emmit functions */
	void (*ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib);
	void (*emit_fence)(struct radeon_device *rdev, struct radeon_fence *fence);
	void (*hdp_flush)(struct radeon_device *rdev, struct radeon_ring *ring);
	bool (*emit_semaphore)(struct radeon_device *rdev, struct radeon_ring *cp,
			       struct radeon_semaphore *semaphore, bool emit_wait);
	void (*vm_flush)(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
+4 −2
Original line number Diff line number Diff line
@@ -185,6 +185,7 @@ static struct radeon_asic_ring r100_gfx_ring = {
	.get_rptr = &r100_gfx_get_rptr,
	.get_wptr = &r100_gfx_get_wptr,
	.set_wptr = &r100_gfx_set_wptr,
	.hdp_flush = &r100_ring_hdp_flush,
};

static struct radeon_asic r100_asic = {
@@ -331,6 +332,7 @@ static struct radeon_asic_ring r300_gfx_ring = {
	.get_rptr = &r100_gfx_get_rptr,
	.get_wptr = &r100_gfx_get_wptr,
	.set_wptr = &r100_gfx_set_wptr,
	.hdp_flush = &r100_ring_hdp_flush,
};

static struct radeon_asic r300_asic = {
@@ -1987,7 +1989,7 @@ static struct radeon_asic ci_asic = {
	.resume = &cik_resume,
	.asic_reset = &cik_asic_reset,
	.vga_set_state = &r600_vga_set_state,
	.mmio_hdp_flush = NULL,
	.mmio_hdp_flush = &r600_mmio_hdp_flush,
	.gui_idle = &r600_gui_idle,
	.mc_wait_for_idle = &evergreen_mc_wait_for_idle,
	.get_xclk = &cik_get_xclk,
@@ -2091,7 +2093,7 @@ static struct radeon_asic kv_asic = {
	.resume = &cik_resume,
	.asic_reset = &cik_asic_reset,
	.vga_set_state = &r600_vga_set_state,
	.mmio_hdp_flush = NULL,
	.mmio_hdp_flush = &r600_mmio_hdp_flush,
	.gui_idle = &r600_gui_idle,
	.mc_wait_for_idle = &evergreen_mc_wait_for_idle,
	.get_xclk = &cik_get_xclk,
+2 −1
Original line number Diff line number Diff line
@@ -148,7 +148,8 @@ u32 r100_gfx_get_wptr(struct radeon_device *rdev,
		      struct radeon_ring *ring);
void r100_gfx_set_wptr(struct radeon_device *rdev,
		       struct radeon_ring *ring);

void r100_ring_hdp_flush(struct radeon_device *rdev,
			 struct radeon_ring *ring);
/*
 * r200,rv250,rs300,rv280
 */
Loading