From 863981e96738983919de841ec669e157e6bdaeb0 Mon Sep 17 00:00:00 2001 From: André Fabian Silva Delgado Date: Sun, 11 Sep 2016 04:34:46 -0300 Subject: Linux-libre 4.7.1-gnu --- drivers/gpu/drm/radeon/rv770.c | 106 ++++++++++++++++++++++++++++++----------- 1 file changed, 77 insertions(+), 29 deletions(-) (limited to 'drivers/gpu/drm/radeon/rv770.c') diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 01ee96acb..1c120a4c3 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -801,7 +801,7 @@ u32 rv770_get_xclk(struct radeon_device *rdev) return reference_clock; } -void rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) +void rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base, bool async) { struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); @@ -812,6 +812,8 @@ void rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); /* update the scanout addresses */ + WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, + async ? AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN : 0); 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)); @@ -1681,6 +1683,73 @@ static int rv770_mc_init(struct radeon_device *rdev) return 0; } +static void rv770_uvd_init(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_uvd) + return; + + r = radeon_uvd_init(rdev); + if (r) { + dev_err(rdev->dev, "failed UVD (%d) init.\n", r); + /* + * At this point rdev->uvd.vcpu_bo is NULL which trickles down + * to early fails uvd_v2_2_resume() and thus nothing happens + * there. So it is pointless to try to go through that code + * hence why we disable uvd here. + */ + rdev->has_uvd = 0; + return; + } + rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096); +} + +static void rv770_uvd_start(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_uvd) + return; + + r = uvd_v2_2_resume(rdev); + if (r) { + dev_err(rdev->dev, "failed UVD resume (%d).\n", r); + goto error; + } + r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX); + if (r) { + dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r); + goto error; + } + return; + +error: + rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; +} + +static void rv770_uvd_resume(struct radeon_device *rdev) +{ + struct radeon_ring *ring; + int r; + + if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size) + return; + + ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, RADEON_CP_PACKET2); + if (r) { + dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r); + return; + } + r = uvd_v1_0_init(rdev); + if (r) { + dev_err(rdev->dev, "failed initializing UVD (%d).\n", r); + return; + } +} + static int rv770_startup(struct radeon_device *rdev) { struct radeon_ring *ring; @@ -1723,16 +1792,7 @@ static int rv770_startup(struct radeon_device *rdev) return r; } - r = uvd_v2_2_resume(rdev); - if (!r) { - r = radeon_fence_driver_start_ring(rdev, - R600_RING_TYPE_UVD_INDEX); - if (r) - dev_err(rdev->dev, "UVD fences init error (%d).\n", r); - } - - if (r) - rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; + rv770_uvd_start(rdev); /* Enable IRQ */ if (!rdev->irq.installed) { @@ -1772,16 +1832,7 @@ static int rv770_startup(struct radeon_device *rdev) if (r) return r; - ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; - if (ring->ring_size) { - r = radeon_ring_init(rdev, ring, ring->ring_size, 0, - RADEON_CP_PACKET2); - if (!r) - r = uvd_v1_0_init(rdev); - - if (r) - DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); - } + rv770_uvd_resume(rdev); r = radeon_ib_pool_init(rdev); if (r) { @@ -1831,8 +1882,10 @@ int rv770_suspend(struct radeon_device *rdev) { radeon_pm_suspend(rdev); radeon_audio_fini(rdev); - uvd_v1_0_fini(rdev); - radeon_uvd_suspend(rdev); + if (rdev->has_uvd) { + uvd_v1_0_fini(rdev); + radeon_uvd_suspend(rdev); + } r700_cp_stop(rdev); r600_dma_stop(rdev); r600_irq_suspend(rdev); @@ -1917,12 +1970,7 @@ int rv770_init(struct radeon_device *rdev) rdev->ring[R600_RING_TYPE_DMA_INDEX].ring_obj = NULL; r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX], 64 * 1024); - r = radeon_uvd_init(rdev); - if (!r) { - rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL; - r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], - 4096); - } + rv770_uvd_init(rdev); rdev->ih.ring_obj = NULL; r600_ih_ring_init(rdev, 64 * 1024); -- cgit v1.2.3-54-g00ecf