From 7f4237c6dad7c959615b896d3c6c728c37943f4d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 9 Jan 2014 10:59:56 -0500 Subject: [PATCH 01/22] Revert "drm/radeon: disable CIK CP semaphores for now" This reverts commit 99b4f25122f43210278cde17a9d100906235a074. Semaphores work fine after further review and testing. Cc: 3.13 # 3.13 --- drivers/gpu/drm/radeon/cik.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index e7f6334138a1..dc6d5f58018d 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -3566,8 +3566,6 @@ bool cik_semaphore_ring_emit(struct radeon_device *rdev, struct radeon_semaphore *semaphore, bool emit_wait) { -/* TODO: figure out why semaphore cause lockups */ -#if 0 uint64_t addr = semaphore->gpu_addr; unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL; @@ -3576,9 +3574,6 @@ bool cik_semaphore_ring_emit(struct radeon_device *rdev, radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | sel); return true; -#else - return false; -#endif } /** From 8158eb9e32c4c98c7dd152207fd70f747ef81a9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 10 Jan 2014 16:05:05 +0100 Subject: [PATCH 02/22] drm/radeon: don't power gate paused UVD streams MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_pm.c | 4 ++++ drivers/gpu/drm/radeon/radeon_uvd.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 0b24c4c7dcf9..63c50493da56 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -924,6 +924,10 @@ void radeon_dpm_enable_uvd(struct radeon_device *rdev, bool enable) if (rdev->asic->dpm.powergate_uvd) { mutex_lock(&rdev->pm.mutex); + /* don't powergate anything if we + have active but pause streams */ + enable |= rdev->pm.dpm.sd > 0; + enable |= rdev->pm.dpm.hd > 0; /* enable/disable UVD */ radeon_dpm_powergate_uvd(rdev, !enable); mutex_unlock(&rdev->pm.mutex); diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index b9c0529b4a2e..4b5c1fcb515d 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -778,6 +778,8 @@ static void radeon_uvd_idle_work_handler(struct work_struct *work) if (radeon_fence_count_emitted(rdev, R600_RING_TYPE_UVD_INDEX) == 0) { if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) { + radeon_uvd_count_handles(rdev, &rdev->pm.dpm.sd, + &rdev->pm.dpm.hd); radeon_dpm_enable_uvd(rdev, false); } else { radeon_set_uvd_clocks(rdev, 0, 0); From 780f5dddaeb8e5950d8ecf2e7565a35bf5d5be36 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 9 Jan 2014 16:18:11 -0500 Subject: [PATCH 03/22] drm/radeon: consolidate cp hdp flushing code for CIK It's used in several places so move to a common shared function. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik.c | 55 ++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index dc6d5f58018d..c6e31b8f8983 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -3486,6 +3486,30 @@ int cik_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) return r; } +/** + * cik_hdp_flush_cp_ring_emit - emit an hdp flush on the cp + * + * @rdev: radeon_device pointer + * @ridx: radeon ring index + * + * Emits an hdp flush on the cp. + */ +static void cik_hdp_flush_cp_ring_emit(struct radeon_device *rdev, + int ridx) +{ + struct radeon_ring *ring = &rdev->ring[ridx]; + + /* We should be using the new WAIT_REG_MEM special op packet here + * but it causes the CP to hang + */ + radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); + radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | + WRITE_DATA_DST_SEL(0))); + radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); +} + /** * cik_fence_gfx_ring_emit - emit a fence on the gfx ring * @@ -3512,15 +3536,7 @@ void cik_fence_gfx_ring_emit(struct radeon_device *rdev, radeon_ring_write(ring, fence->seq); radeon_ring_write(ring, 0); /* HDP flush */ - /* We should be using the new WAIT_REG_MEM special op packet here - * but it causes the CP to hang - */ - radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); - radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | - WRITE_DATA_DST_SEL(0))); - radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 0); + cik_hdp_flush_cp_ring_emit(rdev, fence->ring); } /** @@ -3550,15 +3566,7 @@ void cik_fence_compute_ring_emit(struct radeon_device *rdev, radeon_ring_write(ring, fence->seq); radeon_ring_write(ring, 0); /* HDP flush */ - /* We should be using the new WAIT_REG_MEM special op packet here - * but it causes the CP to hang - */ - radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); - radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | - WRITE_DATA_DST_SEL(0))); - radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 0); + cik_hdp_flush_cp_ring_emit(rdev, fence->ring); } bool cik_semaphore_ring_emit(struct radeon_device *rdev, @@ -5553,16 +5561,7 @@ void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) radeon_ring_write(ring, VMID(0)); /* HDP flush */ - /* We should be using the WAIT_REG_MEM packet here like in - * cik_fence_ring_emit(), but it causes the CP to hang in this - * context... - */ - radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); - radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | - WRITE_DATA_DST_SEL(0))); - radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 0); + cik_hdp_flush_cp_ring_emit(rdev, ridx); /* bits 0-15 are the VM contexts0-15 */ radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); From ca113f6baeb314a66463c35565b4f7955c484000 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 9 Jan 2014 16:23:37 -0500 Subject: [PATCH 04/22] drm/radeon: consolidate sdma hdp flushing code for CIK It's used in several places so move to a common shared function. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik_sdma.c | 35 ++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index af520d4d362b..d7e51c06d597 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c @@ -156,6 +156,27 @@ void cik_sdma_ring_ib_execute(struct radeon_device *rdev, } +/** + * cik_sdma_hdp_flush_ring_emit - emit an hdp flush on the DMA ring + * + * @rdev: radeon_device pointer + * @ridx: radeon ring index + * + * Emit an hdp flush packet on the requested DMA ring. + */ +static void cik_sdma_hdp_flush_ring_emit(struct radeon_device *rdev, + int ridx) +{ + struct radeon_ring *ring = &rdev->ring[ridx]; + + /* We should be using the new POLL_REG_MEM special op packet here + * but it causes sDMA to hang sometimes + */ + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); + radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); + radeon_ring_write(ring, 0); +} + /** * cik_sdma_fence_ring_emit - emit a fence on the DMA ring * @@ -180,12 +201,7 @@ void cik_sdma_fence_ring_emit(struct radeon_device *rdev, /* generate an interrupt */ radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_TRAP, 0, 0)); /* flush HDP */ - /* We should be using the new POLL_REG_MEM special op packet here - * but it causes sDMA to hang sometimes - */ - radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); - radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); - radeon_ring_write(ring, 0); + cik_sdma_hdp_flush_ring_emit(rdev, fence->ring); } /** @@ -816,12 +832,7 @@ void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm radeon_ring_write(ring, VMID(0)); /* flush HDP */ - /* We should be using the new POLL_REG_MEM special op packet here - * but it causes sDMA to hang sometimes - */ - radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); - radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); - radeon_ring_write(ring, 0); + cik_sdma_hdp_flush_ring_emit(rdev, ridx); /* flush TLB */ radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); From da9e07e6f53eaac4e838bc8c987d87c5769be724 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 9 Jan 2014 16:35:39 -0500 Subject: [PATCH 05/22] drm/radeon/cik: use POLL_REG_MEM special op for sDMA HDP flush This is the preferred flushing method on CIK. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik_sdma.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index d7e51c06d597..9abea87a9213 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c @@ -168,13 +168,21 @@ static void cik_sdma_hdp_flush_ring_emit(struct radeon_device *rdev, int ridx) { struct radeon_ring *ring = &rdev->ring[ridx]; + u32 extra_bits = (SDMA_POLL_REG_MEM_EXTRA_OP(1) | + SDMA_POLL_REG_MEM_EXTRA_FUNC(3)); /* == */ + u32 ref_and_mask; - /* We should be using the new POLL_REG_MEM special op packet here - * but it causes sDMA to hang sometimes - */ - radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); - radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); - radeon_ring_write(ring, 0); + if (ridx == R600_RING_TYPE_DMA_INDEX) + ref_and_mask = SDMA0; + else + ref_and_mask = SDMA1; + + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, extra_bits)); + radeon_ring_write(ring, GPU_HDP_FLUSH_DONE); + radeon_ring_write(ring, GPU_HDP_FLUSH_REQ); + radeon_ring_write(ring, ref_and_mask); /* reference */ + radeon_ring_write(ring, ref_and_mask); /* mask */ + radeon_ring_write(ring, (0xfff << 16) | 10); /* retry count, poll interval */ } /** From 5d2590673f3e5c0c0ecf496fb48c73e3ee3ee573 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 9 Jan 2014 16:51:56 -0500 Subject: [PATCH 06/22] drm/radeon/cik: use WAIT_REG_MEM special op for CP HDP flush This is the preferred flushing method on CIK. Note, this only works on the PFP so the engine bit must be set. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik.c | 39 +++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index c6e31b8f8983..e8ec15dfe5f8 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -3498,16 +3498,37 @@ static void cik_hdp_flush_cp_ring_emit(struct radeon_device *rdev, int ridx) { struct radeon_ring *ring = &rdev->ring[ridx]; + u32 ref_and_mask; - /* We should be using the new WAIT_REG_MEM special op packet here - * but it causes the CP to hang - */ - radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); - radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | - WRITE_DATA_DST_SEL(0))); - radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 0); + switch (ring->idx) { + case CAYMAN_RING_TYPE_CP1_INDEX: + case CAYMAN_RING_TYPE_CP2_INDEX: + default: + switch (ring->me) { + case 0: + ref_and_mask = CP2 << ring->pipe; + break; + case 1: + ref_and_mask = CP6 << ring->pipe; + break; + default: + return; + } + break; + case RADEON_RING_TYPE_GFX_INDEX: + ref_and_mask = CP0; + break; + } + + radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5)); + radeon_ring_write(ring, (WAIT_REG_MEM_OPERATION(1) | /* write, wait, write */ + WAIT_REG_MEM_FUNCTION(3) | /* == */ + WAIT_REG_MEM_ENGINE(1))); /* pfp */ + radeon_ring_write(ring, GPU_HDP_FLUSH_REQ >> 2); + radeon_ring_write(ring, GPU_HDP_FLUSH_DONE >> 2); + radeon_ring_write(ring, ref_and_mask); + radeon_ring_write(ring, ref_and_mask); + radeon_ring_write(ring, 0x20); /* poll interval */ } /** From 919cf555c04e16dafb1fba56904eb23889a812c3 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sat, 11 Jan 2014 10:55:55 -0500 Subject: [PATCH 07/22] drm/radeon: disable dpm on BTC Still unstable on some boards. Bugs: https://bugs.freedesktop.org/show_bug.cgi?id=73053 https://bugzilla.kernel.org/show_bug.cgi?id=68571 Signed-off-by: Alex Deucher Cc: 3.13 # 3.13 --- drivers/gpu/drm/radeon/radeon_pm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 63c50493da56..4e7f8922ae62 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -1235,6 +1235,9 @@ int radeon_pm_init(struct radeon_device *rdev) case CHIP_RV670: case CHIP_RS780: case CHIP_RS880: + case CHIP_BARTS: + case CHIP_TURKS: + case CHIP_CAICOS: case CHIP_CAYMAN: /* DPM requires the RLC, RV770+ dGPU requires SMC */ if (!rdev->rlc_fw) @@ -1260,9 +1263,6 @@ int radeon_pm_init(struct radeon_device *rdev) case CHIP_PALM: case CHIP_SUMO: case CHIP_SUMO2: - case CHIP_BARTS: - case CHIP_TURKS: - case CHIP_CAICOS: case CHIP_ARUBA: case CHIP_TAHITI: case CHIP_PITCAIRN: From 6dfa09d7c9dd73fbcd9c7edbb4fa947637d4ed6e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 13 Jan 2014 10:18:03 -0500 Subject: [PATCH 08/22] drm/radeon/cik: use hw defaults for TC_CFG registers Use the hw power up values rather than 0. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index e8ec15dfe5f8..6ffe824624fb 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -5353,20 +5353,6 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev) WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT | WRITE_PROTECTION_FAULT_ENABLE_DEFAULT); - /* TC cache setup ??? */ - WREG32(TC_CFG_L1_LOAD_POLICY0, 0); - WREG32(TC_CFG_L1_LOAD_POLICY1, 0); - WREG32(TC_CFG_L1_STORE_POLICY, 0); - - WREG32(TC_CFG_L2_LOAD_POLICY0, 0); - WREG32(TC_CFG_L2_LOAD_POLICY1, 0); - WREG32(TC_CFG_L2_STORE_POLICY0, 0); - WREG32(TC_CFG_L2_STORE_POLICY1, 0); - WREG32(TC_CFG_L2_ATOMIC_POLICY, 0); - - WREG32(TC_CFG_L1_VOLATILE, 0); - WREG32(TC_CFG_L2_VOLATILE, 0); - if (rdev->family == CHIP_KAVERI) { u32 tmp = RREG32(CHUB_CONTROL); tmp &= ~BYPASS_VM; From d8e24525094200601236fa64a54cf73e3d682f2e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 13 Jan 2014 16:47:05 -0500 Subject: [PATCH 09/22] drm/radeon: disable ss on DP for DCE3.x Seems to cause problems with certain DP monitors. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=40699 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/atombios_crtc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 0b9621c9aeea..762b660af5aa 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -938,11 +938,14 @@ static bool atombios_crtc_prepare_pll(struct drm_crtc *crtc, struct drm_display_ radeon_atombios_get_ppll_ss_info(rdev, &radeon_crtc->ss, ATOM_DP_SS_ID1); - } else + } else { radeon_crtc->ss_enabled = radeon_atombios_get_ppll_ss_info(rdev, &radeon_crtc->ss, ATOM_DP_SS_ID1); + } + /* disable spread spectrum on DCE3 DP */ + radeon_crtc->ss_enabled = false; } break; case ATOM_ENCODER_MODE_LVDS: From 2138681bdde35f21b1faea26ec51a2ef1f9a9685 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 14 Jan 2014 10:29:59 -0500 Subject: [PATCH 10/22] drm/radeon/dp: bump i2c-over-aux retries to 7 As per the DP1.2 spec. Noticed while reviewing Thierry's drm/dp patches. Also bump native aux retries to 7 for consistency. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/atombios_dp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 37289f67f965..149e09aa7a03 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -161,7 +161,7 @@ static int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector, msg[3] = (msg_bytes << 4) | (send_bytes - 1); memcpy(&msg[4], send, send_bytes); - for (retry = 0; retry < 4; retry++) { + for (retry = 0; retry < 7; retry++) { ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_bytes, NULL, 0, delay, &ack); if (ret == -EBUSY) @@ -195,7 +195,7 @@ static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, msg[2] = DP_AUX_NATIVE_READ << 4; msg[3] = (msg_bytes << 4) | (recv_bytes - 1); - for (retry = 0; retry < 4; retry++) { + for (retry = 0; retry < 7; retry++) { ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_bytes, recv, recv_bytes, delay, &ack); if (ret == -EBUSY) @@ -274,7 +274,7 @@ int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, break; } - for (retry = 0; retry < 4; retry++) { + for (retry = 0; retry < 7; retry++) { ret = radeon_process_aux_ch(auxch, msg, msg_bytes, reply, reply_bytes, 0, &ack); if (ret == -EBUSY) From ab9f51c09f32351ccaaa6ab494edf07a16d3dd2a Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 14 Jan 2014 10:37:33 -0500 Subject: [PATCH 11/22] drm/radeon/dp: use usleep_range rather than udelay Based on common dp code proposed by Thierry Reding. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/atombios_dp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 149e09aa7a03..403ca00b8a55 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -172,7 +172,7 @@ static int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector, if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_ACK) return send_bytes; else if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_DEFER) - udelay(400); + usleep_range(400, 500); else return -EIO; } @@ -206,7 +206,7 @@ static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_ACK) return ret; else if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_DEFER) - udelay(400); + usleep_range(400, 500); else if (ret == 0) return -EPROTO; else @@ -295,7 +295,7 @@ int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, return -EREMOTEIO; case DP_AUX_NATIVE_REPLY_DEFER: DRM_DEBUG_KMS("aux_ch native defer\n"); - udelay(400); + usleep_range(500, 600); continue; default: DRM_ERROR("aux_ch invalid native reply 0x%02x\n", ack); @@ -312,7 +312,7 @@ int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, return -EREMOTEIO; case DP_AUX_I2C_REPLY_DEFER: DRM_DEBUG_KMS("aux_i2c defer\n"); - udelay(400); + usleep_range(400, 500); break; default: DRM_ERROR("aux_i2c invalid reply 0x%02x\n", ack); From d30df55b3ec069283408b6d3b013bcba52dd03dc Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 14 Jan 2014 10:45:51 -0500 Subject: [PATCH 12/22] drm/radeon/dp: sleep after powering up the display According to the DP 1.1 spec, the sink must power up within 1ms. Noticed while reviewing Thierry's drm/dp patches. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/atombios_dp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 403ca00b8a55..4ad7643fce5f 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -673,9 +673,11 @@ static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) u8 tmp; /* power up the sink */ - if (dp_info->dpcd[0] >= 0x11) + if (dp_info->dpcd[0] >= 0x11) { radeon_write_dpcd_reg(dp_info->radeon_connector, DP_SET_POWER, DP_SET_POWER_D0); + usleep_range(1000, 2000); + } /* possibly enable downspread on the sink */ if (dp_info->dpcd[3] & 0x1) From f5f1f897c892cbff6135cd743df9989ca7bc29e4 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 20 Jan 2014 18:20:29 -0500 Subject: [PATCH 13/22] drm/radeon: add query to fetch the max engine clock (v2) This is needed for reporting the max GPU engine clock in OpenCL. This just reports the max possible engine clock, it does not take into account current conditions that may limit that clock. v2: fix query number for merge with 3.13 Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_kms.c | 7 +++++++ drivers/gpu/drm/radeon/rv770_dpm.c | 14 ++++++-------- include/uapi/drm/radeon_drm.h | 2 ++ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 5bf50cec017e..9e3af24e1b05 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -470,6 +470,13 @@ static int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file DRM_DEBUG_KMS("BACKEND_ENABLED_MASK is si+ only!\n"); } break; + case RADEON_INFO_MAX_SCLK: + if ((rdev->pm.pm_method == PM_METHOD_DPM) && + rdev->pm.dpm_enabled) + *value = rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk * 10; + else + *value = rdev->pm.default_sclk * 10; + break; default: DRM_DEBUG_KMS("Invalid request %d\n", info->request); return -EINVAL; diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index b95267846ff2..cb730cddfb9a 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c @@ -2251,14 +2251,12 @@ static void rv7xx_parse_pplib_clock_info(struct radeon_device *rdev, pl->vddci = vddci; } - if (rdev->family >= CHIP_BARTS) { - if ((rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) == - ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE) { - rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk = pl->sclk; - rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.mclk = pl->mclk; - rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddc = pl->vddc; - rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddci = pl->vddci; - } + if ((rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) == + ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE) { + rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk = pl->sclk; + rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.mclk = pl->mclk; + rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddc = pl->vddc; + rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddci = pl->vddci; } } diff --git a/include/uapi/drm/radeon_drm.h b/include/uapi/drm/radeon_drm.h index fe421e8a431b..d9ea3a73afe2 100644 --- a/include/uapi/drm/radeon_drm.h +++ b/include/uapi/drm/radeon_drm.h @@ -985,6 +985,8 @@ struct drm_radeon_cs { #define RADEON_INFO_CIK_MACROTILE_MODE_ARRAY 0x18 /* query the number of render backends */ #define RADEON_INFO_SI_BACKEND_ENABLED_MASK 0x19 +/* max engine clock - needed for OpenCL */ +#define RADEON_INFO_MAX_SCLK 0x1a struct drm_radeon_info { From 18f8f52b9a8c293111c058f9d25bcd5e718b80b2 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 15 Jan 2014 13:41:31 -0500 Subject: [PATCH 14/22] drm/radeon: handle ss percentage divider properly It's either 100 or 1000 depending on the flags in the table. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/atombios_crtc.c | 8 +++++--- drivers/gpu/drm/radeon/radeon_atombios.c | 7 +++++++ drivers/gpu/drm/radeon/radeon_mode.h | 1 + 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 762b660af5aa..fd9daf4022a1 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1042,15 +1042,17 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode /* calculate ss amount and step size */ if (ASIC_IS_DCE4(rdev)) { u32 step_size; - u32 amount = (((fb_div * 10) + frac_fb_div) * radeon_crtc->ss.percentage) / 10000; + u32 amount = (((fb_div * 10) + frac_fb_div) * + (u32)radeon_crtc->ss.percentage) / + (100 * (u32)radeon_crtc->ss.percentage_divider); radeon_crtc->ss.amount = (amount / 10) & ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK; radeon_crtc->ss.amount |= ((amount - (amount / 10)) << ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) & ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK; if (radeon_crtc->ss.type & ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD) - step_size = (4 * amount * ref_div * (radeon_crtc->ss.rate * 2048)) / + step_size = (4 * amount * ref_div * ((u32)radeon_crtc->ss.rate * 2048)) / (125 * 25 * pll->reference_freq / 100); else - step_size = (2 * amount * ref_div * (radeon_crtc->ss.rate * 2048)) / + step_size = (2 * amount * ref_div * ((u32)radeon_crtc->ss.rate * 2048)) / (125 * 25 * pll->reference_freq / 100); radeon_crtc->ss.step = step_size; } diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 80a56ad40c52..61cff32b4012 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1511,6 +1511,7 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, le16_to_cpu(ss_assign->v1.usSpreadSpectrumPercentage); ss->type = ss_assign->v1.ucSpreadSpectrumMode; ss->rate = le16_to_cpu(ss_assign->v1.usSpreadRateInKhz); + ss->percentage_divider = 100; return true; } ss_assign = (union asic_ss_assignment *) @@ -1528,6 +1529,7 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, le16_to_cpu(ss_assign->v2.usSpreadSpectrumPercentage); ss->type = ss_assign->v2.ucSpreadSpectrumMode; ss->rate = le16_to_cpu(ss_assign->v2.usSpreadRateIn10Hz); + ss->percentage_divider = 100; if ((crev == 2) && ((id == ASIC_INTERNAL_ENGINE_SS) || (id == ASIC_INTERNAL_MEMORY_SS))) @@ -1549,6 +1551,11 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, le16_to_cpu(ss_assign->v3.usSpreadSpectrumPercentage); ss->type = ss_assign->v3.ucSpreadSpectrumMode; ss->rate = le16_to_cpu(ss_assign->v3.usSpreadRateIn10Hz); + if (ss_assign->v3.ucSpreadSpectrumMode & + SS_MODE_V3_PERCENTAGE_DIV_BY_1000_MASK) + ss->percentage_divider = 1000; + else + ss->percentage_divider = 100; if ((id == ASIC_INTERNAL_ENGINE_SS) || (id == ASIC_INTERNAL_MEMORY_SS)) ss->rate /= 100; diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 28bba631b80c..7c53fb1cc46d 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -291,6 +291,7 @@ struct radeon_tv_regs { struct radeon_atom_ss { uint16_t percentage; + uint16_t percentage_divider; uint8_t type; uint16_t step; uint8_t delay; From c4756baa4a8ba75b812506818cbc81178650d3c1 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 15 Jan 2014 13:59:47 -0500 Subject: [PATCH 15/22] drm/radeon: bail early from enable ss in certain cases If the ss percentage is 0 or we are using external ss, just bail when enabling ss. We disable it explicitly earlier in the modeset already. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/atombios_crtc.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index fd9daf4022a1..4cf678306c9c 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -423,7 +423,17 @@ static void atombios_crtc_program_ss(struct radeon_device *rdev, int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); union atom_enable_ss args; - if (!enable) { + if (enable) { + /* Don't mess with SS if percentage is 0 or external ss. + * SS is already disabled previously, and disabling it + * again can cause display problems if the pll is already + * programmed. + */ + if (ss->percentage == 0) + return; + if (ss->type & ATOM_EXTERNAL_SS_MASK) + return; + } else { for (i = 0; i < rdev->num_crtc; i++) { if (rdev->mode_info.crtcs[i] && rdev->mode_info.crtcs[i]->enabled && @@ -459,8 +469,6 @@ static void atombios_crtc_program_ss(struct radeon_device *rdev, args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step); args.v3.ucEnable = enable; - if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK) || ASIC_IS_DCE61(rdev)) - args.v3.ucEnable = ATOM_DISABLE; } else if (ASIC_IS_DCE4(rdev)) { args.v2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); args.v2.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK; @@ -480,8 +488,6 @@ static void atombios_crtc_program_ss(struct radeon_device *rdev, args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step); args.v2.ucEnable = enable; - if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK) || ASIC_IS_DCE41(rdev)) - args.v2.ucEnable = ATOM_DISABLE; } else if (ASIC_IS_DCE3(rdev)) { args.v1.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); args.v1.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK; @@ -503,8 +509,7 @@ static void atombios_crtc_program_ss(struct radeon_device *rdev, args.lvds_ss_2.ucSpreadSpectrumRange = ss->range; args.lvds_ss_2.ucEnable = enable; } else { - if ((enable == ATOM_DISABLE) || (ss->percentage == 0) || - (ss->type & ATOM_EXTERNAL_SS_MASK)) { + if (enable == ATOM_DISABLE) { atombios_disable_ss(rdev, pll_id); return; } From aa34dba8fb9cdcf3f7f8203abce493036b348fdb Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 16 Jan 2014 10:39:17 -0500 Subject: [PATCH 16/22] drm/radeon: write gfx pg bases even when gfx pg is disabled For consistency. These buffers aren't used when pg is disabled. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/si.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 22d3517ed6ad..07ce58716e44 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -5488,6 +5488,9 @@ static void si_init_pg(struct radeon_device *rdev) si_init_ao_cu_mask(rdev); if (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_PG) { si_init_gfx_cgpg(rdev); + } else { + WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8); + WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8); } si_enable_dma_pg(rdev, true); si_enable_gfx_cgpg(rdev, true); From d526fbdd0fd0e5d78cd2e01a5387ee83431da7fb Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 16 Jan 2014 10:53:50 -0500 Subject: [PATCH 17/22] drm/radeon: fix endian handling in radeon_atom_init_mc_reg_table Need to swap the data for big endian. Notcied by sylware in IRC. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_atombios.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 61cff32b4012..00bca1bd5745 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -3874,16 +3874,18 @@ int radeon_atom_init_mc_reg_table(struct radeon_device *rdev, ((u8 *)format + sizeof(ATOM_INIT_REG_INDEX_FORMAT)); } reg_table->last = i; - while ((*(u32 *)reg_data != END_OF_REG_DATA_BLOCK) && + while ((le32_to_cpu(*(u32 *)reg_data) != END_OF_REG_DATA_BLOCK) && (num_ranges < VBIOS_MAX_AC_TIMING_ENTRIES)) { - t_mem_id = (u8)((*(u32 *)reg_data & MEM_ID_MASK) >> MEM_ID_SHIFT); + t_mem_id = (u8)((le32_to_cpu(*(u32 *)reg_data) & MEM_ID_MASK) + >> MEM_ID_SHIFT); if (module_index == t_mem_id) { reg_table->mc_reg_table_entry[num_ranges].mclk_max = - (u32)((*(u32 *)reg_data & CLOCK_RANGE_MASK) >> CLOCK_RANGE_SHIFT); + (u32)((le32_to_cpu(*(u32 *)reg_data) & CLOCK_RANGE_MASK) + >> CLOCK_RANGE_SHIFT); for (i = 0, j = 1; i < reg_table->last; i++) { if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_FROM_TABLE) { reg_table->mc_reg_table_entry[num_ranges].mc_data[i] = - (u32)*((u32 *)reg_data + j); + (u32)le32_to_cpu(*((u32 *)reg_data + j)); j++; } else if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_EQU_PREV) { reg_table->mc_reg_table_entry[num_ranges].mc_data[i] = @@ -3895,7 +3897,7 @@ int radeon_atom_init_mc_reg_table(struct radeon_device *rdev, reg_data = (ATOM_MEMORY_SETTING_DATA_BLOCK *) ((u8 *)reg_data + le16_to_cpu(reg_block->usRegDataBlkSize)); } - if (*(u32 *)reg_data != END_OF_REG_DATA_BLOCK) + if (le32_to_cpu(*(u32 *)reg_data) != END_OF_REG_DATA_BLOCK) return -EINVAL; reg_table->num_entries = num_ranges; } else From 8097d94116d0c17e774ba4c8256e774018dc2a46 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 7 Jan 2014 13:51:51 -0500 Subject: [PATCH 18/22] drm/radeon/dpm: disable mclk switching on desktop RV770 Mclk switching doesn't seem to work reliably on these cards. Most RV770 boards specify the same mclk for all performance levels anyway so in most cases, this has no affect. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=73067 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/rv770_dpm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index cb730cddfb9a..80c595aba359 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c @@ -2536,6 +2536,12 @@ bool rv770_dpm_vblank_too_short(struct radeon_device *rdev) (rdev->pdev->subsystem_device == 0x1c42)) switch_limit = 200; + /* RV770 */ + /* mclk switching doesn't seem to work reliably on desktop RV770s */ + if ((rdev->family == CHIP_RV770) && + !(rdev->flags & RADEON_IS_MOBILITY)) + switch_limit = 0xffffffff; /* disable mclk switching */ + if (vblank_time < switch_limit) return true; else From 10e9ffae463396c5a25fdfe8a48d7c98a87f6b85 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 16 Jan 2014 18:02:59 -0500 Subject: [PATCH 19/22] drm/radeon: fix surface sync in fence on cayman (v2) We need to set the engine bit to select the ME and also set the full cache bit. Should help stability on TN and cayman. V2: fix up surface sync in ib execute as well Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/ni.c | 16 +++++++--------- drivers/gpu/drm/radeon/nid.h | 1 + 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index af45b23675ee..647b1d0fa62c 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1331,13 +1331,12 @@ void cayman_fence_ring_emit(struct radeon_device *rdev, { struct radeon_ring *ring = &rdev->ring[fence->ring]; u64 addr = rdev->fence_drv[fence->ring].gpu_addr; + u32 cp_coher_cntl = PACKET3_FULL_CACHE_ENA | PACKET3_TC_ACTION_ENA | + PACKET3_SH_ACTION_ENA; /* flush read cache over gart for this vmid */ - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(ring, 0); radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA); + radeon_ring_write(ring, PACKET3_ENGINE_ME | cp_coher_cntl); radeon_ring_write(ring, 0xFFFFFFFF); radeon_ring_write(ring, 0); radeon_ring_write(ring, 10); /* poll interval */ @@ -1353,6 +1352,8 @@ void cayman_fence_ring_emit(struct radeon_device *rdev, void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) { struct radeon_ring *ring = &rdev->ring[ib->ring]; + u32 cp_coher_cntl = PACKET3_FULL_CACHE_ENA | PACKET3_TC_ACTION_ENA | + PACKET3_SH_ACTION_ENA; /* set to DX10/11 mode */ radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); @@ -1377,14 +1378,11 @@ void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) (ib->vm ? (ib->vm->id << 24) : 0)); /* flush read cache over gart for this vmid */ - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(ring, ib->vm ? ib->vm->id : 0); radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA); + radeon_ring_write(ring, PACKET3_ENGINE_ME | cp_coher_cntl); radeon_ring_write(ring, 0xFFFFFFFF); radeon_ring_write(ring, 0); - radeon_ring_write(ring, 10); /* poll interval */ + radeon_ring_write(ring, ((ib->vm ? ib->vm->id : 0) << 24) | 10); /* poll interval */ } static void cayman_cp_enable(struct radeon_device *rdev, bool enable) diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h index 22421bc80c0d..d996033c243e 100644 --- a/drivers/gpu/drm/radeon/nid.h +++ b/drivers/gpu/drm/radeon/nid.h @@ -1154,6 +1154,7 @@ # define PACKET3_DB_ACTION_ENA (1 << 26) # define PACKET3_SH_ACTION_ENA (1 << 27) # define PACKET3_SX_ACTION_ENA (1 << 28) +# define PACKET3_ENGINE_ME (1 << 31) #define PACKET3_ME_INITIALIZE 0x44 #define PACKET3_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) #define PACKET3_COND_WRITE 0x45 From d45b964a22cad962d3ede1eba8d24f5cee7b2a92 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 16 Jan 2014 18:11:47 -0500 Subject: [PATCH 20/22] drm/radeon: set the full cache bit for fences on r7xx+ Needed to properly flush the read caches for fences. Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/r600.c | 13 +++++++------ drivers/gpu/drm/radeon/r600d.h | 1 + 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index ad99bae2e85c..3dce370adc1b 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2706,14 +2706,17 @@ void r600_fence_ring_emit(struct radeon_device *rdev, struct radeon_fence *fence) { struct radeon_ring *ring = &rdev->ring[fence->ring]; + u32 cp_coher_cntl = PACKET3_TC_ACTION_ENA | PACKET3_VC_ACTION_ENA | + PACKET3_SH_ACTION_ENA; + + if (rdev->family >= CHIP_RV770) + cp_coher_cntl |= PACKET3_FULL_CACHE_ENA; if (rdev->wb.use_event) { u64 addr = rdev->fence_drv[fence->ring].gpu_addr; /* flush read cache over gart */ radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | - PACKET3_VC_ACTION_ENA | - PACKET3_SH_ACTION_ENA); + radeon_ring_write(ring, cp_coher_cntl); radeon_ring_write(ring, 0xFFFFFFFF); radeon_ring_write(ring, 0); radeon_ring_write(ring, 10); /* poll interval */ @@ -2727,9 +2730,7 @@ void r600_fence_ring_emit(struct radeon_device *rdev, } else { /* flush read cache over gart */ radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | - PACKET3_VC_ACTION_ENA | - PACKET3_SH_ACTION_ENA); + radeon_ring_write(ring, cp_coher_cntl); radeon_ring_write(ring, 0xFFFFFFFF); radeon_ring_write(ring, 0); radeon_ring_write(ring, 10); /* poll interval */ diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 3fca4b9c65ad..37455f65107f 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -1582,6 +1582,7 @@ # define PACKET3_CP_DMA_CMD_DAIC (1 << 29) #define PACKET3_SURFACE_SYNC 0x43 # define PACKET3_CB0_DEST_BASE_ENA (1 << 6) +# define PACKET3_FULL_CACHE_ENA (1 << 20) /* r7xx+ only */ # define PACKET3_TC_ACTION_ENA (1 << 23) # define PACKET3_VC_ACTION_ENA (1 << 24) # define PACKET3_CB_ACTION_ENA (1 << 25) From 407b6dfd9afa30cf963fa99bca91870e47965612 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 17 Jan 2014 12:34:55 -0500 Subject: [PATCH 21/22] drm/radeon: fix minor typos in si_dpm.c Copy/paste typos from the ni code. Should not have any functional change. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/si_dpm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 512919b0156a..36a5da4791ce 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -2395,7 +2395,7 @@ static int si_populate_sq_ramping_values(struct radeon_device *rdev, if (SISLANDS_DPM2_SQ_RAMP_STI_SIZE > (STI_SIZE_MASK >> STI_SIZE_SHIFT)) enable_sq_ramping = false; - if (NISLANDS_DPM2_SQ_RAMP_LTI_RATIO <= (LTI_RATIO_MASK >> LTI_RATIO_SHIFT)) + if (SISLANDS_DPM2_SQ_RAMP_LTI_RATIO <= (LTI_RATIO_MASK >> LTI_RATIO_SHIFT)) enable_sq_ramping = false; for (i = 0; i < state->performance_level_count; i++) { @@ -5413,7 +5413,7 @@ static void si_populate_mc_reg_addresses(struct radeon_device *rdev, for (i = 0, j = 0; j < si_pi->mc_reg_table.last; j++) { if (si_pi->mc_reg_table.valid_flag & (1 << j)) { - if (i >= SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE) + if (i >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE) break; mc_reg_table->address[i].s0 = cpu_to_be16(si_pi->mc_reg_table.mc_reg_address[j].s0); From 5d029339bb8ce69aeb68280c3de67d3cea456146 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 20 Jan 2014 11:25:35 -0500 Subject: [PATCH 22/22] drm/radeon: add UVD support for OLAND It seems this got dropped when we merged UVD support last year. Add this back now. Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/radeon_uvd.c | 1 + drivers/gpu/drm/radeon/uvd_v2_2.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 4b5c1fcb515d..6781fee1eaad 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -91,6 +91,7 @@ int radeon_uvd_init(struct radeon_device *rdev) case CHIP_VERDE: case CHIP_PITCAIRN: case CHIP_ARUBA: + case CHIP_OLAND: fw_name = FIRMWARE_TAHITI; break; diff --git a/drivers/gpu/drm/radeon/uvd_v2_2.c b/drivers/gpu/drm/radeon/uvd_v2_2.c index b19ef4951085..824550db3fed 100644 --- a/drivers/gpu/drm/radeon/uvd_v2_2.c +++ b/drivers/gpu/drm/radeon/uvd_v2_2.c @@ -153,6 +153,7 @@ int uvd_v2_2_resume(struct radeon_device *rdev) chip_id = 0x01000015; break; case CHIP_PITCAIRN: + case CHIP_OLAND: chip_id = 0x01000016; break; case CHIP_ARUBA: