Commit 5e884f60 authored by Alex Deucher's avatar Alex Deucher

drm/radeon: restructure UVD code to handle UVD PG (v2)

When we PG (powergate) UVD, we need to re-initialize it
before we can use it again.

v2: rebase on UVD stop fixes
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 9e9d9762
...@@ -69,6 +69,7 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev); ...@@ -69,6 +69,7 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev);
static void cik_program_aspm(struct radeon_device *rdev); static void cik_program_aspm(struct radeon_device *rdev);
static void cik_init_pg(struct radeon_device *rdev); static void cik_init_pg(struct radeon_device *rdev);
static void cik_init_cg(struct radeon_device *rdev); static void cik_init_cg(struct radeon_device *rdev);
static void cik_uvd_resume(struct radeon_device *rdev);
/* get temperature in millidegrees */ /* get temperature in millidegrees */
int ci_get_temp(struct radeon_device *rdev) int ci_get_temp(struct radeon_device *rdev)
...@@ -7619,8 +7620,9 @@ static int cik_startup(struct radeon_device *rdev) ...@@ -7619,8 +7620,9 @@ static int cik_startup(struct radeon_device *rdev)
return r; return r;
} }
r = cik_uvd_resume(rdev); r = radeon_uvd_resume(rdev);
if (!r) { if (!r) {
cik_uvd_resume(rdev);
r = radeon_fence_driver_start_ring(rdev, r = radeon_fence_driver_start_ring(rdev,
R600_RING_TYPE_UVD_INDEX); R600_RING_TYPE_UVD_INDEX);
if (r) if (r)
...@@ -7708,7 +7710,7 @@ static int cik_startup(struct radeon_device *rdev) ...@@ -7708,7 +7710,7 @@ static int cik_startup(struct radeon_device *rdev)
UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
0, 0xfffff, RADEON_CP_PACKET2); 0, 0xfffff, RADEON_CP_PACKET2);
if (!r) if (!r)
r = r600_uvd_init(rdev); r = r600_uvd_init(rdev, true);
if (r) if (r)
DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
} }
...@@ -8598,15 +8600,10 @@ int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) ...@@ -8598,15 +8600,10 @@ int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
return r; return r;
} }
int cik_uvd_resume(struct radeon_device *rdev) static void cik_uvd_resume(struct radeon_device *rdev)
{ {
uint64_t addr; uint64_t addr;
uint32_t size; uint32_t size;
int r;
r = radeon_uvd_resume(rdev);
if (r)
return r;
/* programm the VCPU memory controller bits 0-27 */ /* programm the VCPU memory controller bits 0-27 */
addr = rdev->uvd.gpu_addr >> 3; addr = rdev->uvd.gpu_addr >> 3;
...@@ -8632,7 +8629,6 @@ int cik_uvd_resume(struct radeon_device *rdev) ...@@ -8632,7 +8629,6 @@ int cik_uvd_resume(struct radeon_device *rdev)
addr = (rdev->uvd.gpu_addr >> 32) & 0xFF; addr = (rdev->uvd.gpu_addr >> 32) & 0xFF;
WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31)); WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));
return 0;
} }
static void cik_pcie_gen3_enable(struct radeon_device *rdev) static void cik_pcie_gen3_enable(struct radeon_device *rdev)
......
...@@ -5296,7 +5296,7 @@ static int evergreen_startup(struct radeon_device *rdev) ...@@ -5296,7 +5296,7 @@ static int evergreen_startup(struct radeon_device *rdev)
UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
0, 0xfffff, RADEON_CP_PACKET2); 0, 0xfffff, RADEON_CP_PACKET2);
if (!r) if (!r)
r = r600_uvd_init(rdev); r = r600_uvd_init(rdev, true);
if (r) if (r)
DRM_ERROR("radeon: error initializing UVD (%d).\n", r); DRM_ERROR("radeon: error initializing UVD (%d).\n", r);
......
...@@ -2230,7 +2230,7 @@ static int cayman_startup(struct radeon_device *rdev) ...@@ -2230,7 +2230,7 @@ static int cayman_startup(struct radeon_device *rdev)
UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
0, 0xfffff, RADEON_CP_PACKET2); 0, 0xfffff, RADEON_CP_PACKET2);
if (!r) if (!r)
r = r600_uvd_init(rdev); r = r600_uvd_init(rdev, true);
if (r) if (r)
DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
} }
......
...@@ -2623,7 +2623,7 @@ void r600_dma_fini(struct radeon_device *rdev) ...@@ -2623,7 +2623,7 @@ void r600_dma_fini(struct radeon_device *rdev)
/* /*
* UVD * UVD
*/ */
int r600_uvd_rbc_start(struct radeon_device *rdev) static int r600_uvd_rbc_start(struct radeon_device *rdev, bool ring_test)
{ {
struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
uint64_t rptr_addr; uint64_t rptr_addr;
...@@ -2664,6 +2664,7 @@ int r600_uvd_rbc_start(struct radeon_device *rdev) ...@@ -2664,6 +2664,7 @@ int r600_uvd_rbc_start(struct radeon_device *rdev)
rb_bufsz = (0x1 << 8) | rb_bufsz; rb_bufsz = (0x1 << 8) | rb_bufsz;
WREG32(UVD_RBC_RB_CNTL, rb_bufsz); WREG32(UVD_RBC_RB_CNTL, rb_bufsz);
if (ring_test) {
ring->ready = true; ring->ready = true;
r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring); r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring);
if (r) { if (r) {
...@@ -2697,14 +2698,13 @@ int r600_uvd_rbc_start(struct radeon_device *rdev) ...@@ -2697,14 +2698,13 @@ int r600_uvd_rbc_start(struct radeon_device *rdev)
radeon_ring_write(ring, 3); radeon_ring_write(ring, 3);
radeon_ring_unlock_commit(rdev, ring); radeon_ring_unlock_commit(rdev, ring);
}
return 0; return 0;
} }
void r600_uvd_stop(struct radeon_device *rdev) void r600_do_uvd_stop(struct radeon_device *rdev)
{ {
struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
/* force RBC into idle state */ /* force RBC into idle state */
WREG32(UVD_RBC_RB_CNTL, 0x11010101); WREG32(UVD_RBC_RB_CNTL, 0x11010101);
...@@ -2723,11 +2723,17 @@ void r600_uvd_stop(struct radeon_device *rdev) ...@@ -2723,11 +2723,17 @@ void r600_uvd_stop(struct radeon_device *rdev)
/* Unstall UMC and register bus */ /* Unstall UMC and register bus */
WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8)); WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3)); WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
}
void r600_uvd_stop(struct radeon_device *rdev)
{
struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
r600_do_uvd_stop(rdev);
ring->ready = false; ring->ready = false;
} }
int r600_uvd_init(struct radeon_device *rdev) int r600_uvd_init(struct radeon_device *rdev, bool ring_test)
{ {
int i, j, r; int i, j, r;
/* disable byte swapping */ /* disable byte swapping */
...@@ -2815,17 +2821,17 @@ int r600_uvd_init(struct radeon_device *rdev) ...@@ -2815,17 +2821,17 @@ int r600_uvd_init(struct radeon_device *rdev)
if (r) { if (r) {
DRM_ERROR("UVD not responding, giving up!!!\n"); DRM_ERROR("UVD not responding, giving up!!!\n");
radeon_set_uvd_clocks(rdev, 0, 0); goto done;
return r;
} }
/* enable interupt */ /* enable interupt */
WREG32_P(UVD_MASTINT_EN, 3<<1, ~(3 << 1)); WREG32_P(UVD_MASTINT_EN, 3<<1, ~(3 << 1));
r = r600_uvd_rbc_start(rdev); r = r600_uvd_rbc_start(rdev, ring_test);
if (!r) if (!r)
DRM_INFO("UVD initialized successfully.\n"); DRM_INFO("UVD initialized successfully.\n");
done:
/* lower clocks again */ /* lower clocks again */
radeon_set_uvd_clocks(rdev, 0, 0); radeon_set_uvd_clocks(rdev, 0, 0);
......
...@@ -424,8 +424,7 @@ void rs780_dpm_debugfs_print_current_performance_level(struct radeon_device *rde ...@@ -424,8 +424,7 @@ void rs780_dpm_debugfs_print_current_performance_level(struct radeon_device *rde
struct seq_file *m); struct seq_file *m);
/* uvd */ /* uvd */
int r600_uvd_init(struct radeon_device *rdev); int r600_uvd_init(struct radeon_device *rdev, bool ring_test);
int r600_uvd_rbc_start(struct radeon_device *rdev);
void r600_uvd_stop(struct radeon_device *rdev); void r600_uvd_stop(struct radeon_device *rdev);
int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
void r600_uvd_fence_emit(struct radeon_device *rdev, void r600_uvd_fence_emit(struct radeon_device *rdev,
...@@ -696,7 +695,6 @@ u32 cik_get_xclk(struct radeon_device *rdev); ...@@ -696,7 +695,6 @@ u32 cik_get_xclk(struct radeon_device *rdev);
uint32_t cik_pciep_rreg(struct radeon_device *rdev, uint32_t reg); uint32_t cik_pciep_rreg(struct radeon_device *rdev, uint32_t reg);
void cik_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); void cik_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
int cik_uvd_resume(struct radeon_device *rdev);
void cik_sdma_fence_ring_emit(struct radeon_device *rdev, void cik_sdma_fence_ring_emit(struct radeon_device *rdev,
struct radeon_fence *fence); struct radeon_fence *fence);
void cik_sdma_semaphore_ring_emit(struct radeon_device *rdev, void cik_sdma_semaphore_ring_emit(struct radeon_device *rdev,
......
...@@ -1928,7 +1928,7 @@ static int rv770_startup(struct radeon_device *rdev) ...@@ -1928,7 +1928,7 @@ static int rv770_startup(struct radeon_device *rdev)
UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
0, 0xfffff, RADEON_CP_PACKET2); 0, 0xfffff, RADEON_CP_PACKET2);
if (!r) if (!r)
r = r600_uvd_init(rdev); r = r600_uvd_init(rdev, true);
if (r) if (r)
DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
......
...@@ -6421,7 +6421,7 @@ static int si_startup(struct radeon_device *rdev) ...@@ -6421,7 +6421,7 @@ static int si_startup(struct radeon_device *rdev)
UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
0, 0xfffff, RADEON_CP_PACKET2); 0, 0xfffff, RADEON_CP_PACKET2);
if (!r) if (!r)
r = r600_uvd_init(rdev); r = r600_uvd_init(rdev, true);
if (r) if (r)
DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment