drm/amdgpu/dce11: optimize pageflip

Taking the grph update lock is only necessary when
updating the the secondary address (for single pipe stereo).

Reviewed-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Jammy Zhou <Jammy.Zhou@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Alex Deucher 2015-10-22 14:17:21 -04:00
parent 0eaaacab03
commit ce055fe332

View File

@ -252,46 +252,22 @@ static u32 dce_v11_0_vblank_get_counter(struct amdgpu_device *adev, int crtc)
* @crtc_id: crtc to cleanup pageflip on * @crtc_id: crtc to cleanup pageflip on
* @crtc_base: new address of the crtc (GPU MC address) * @crtc_base: new address of the crtc (GPU MC address)
* *
* Does the actual pageflip (evergreen+). * Triggers the actual pageflip by updating the primary
* During vblank we take the crtc lock and wait for the update_pending * surface base address.
* bit to go high, when it does, we release the lock, and allow the
* double buffered update to take place.
* Returns the current update pending status.
*/ */
static void dce_v11_0_page_flip(struct amdgpu_device *adev, static void dce_v11_0_page_flip(struct amdgpu_device *adev,
int crtc_id, u64 crtc_base) int crtc_id, u64 crtc_base)
{ {
struct amdgpu_crtc *amdgpu_crtc = adev->mode_info.crtcs[crtc_id]; struct amdgpu_crtc *amdgpu_crtc = adev->mode_info.crtcs[crtc_id];
u32 tmp = RREG32(mmGRPH_UPDATE + amdgpu_crtc->crtc_offset);
int i;
/* Lock the graphics update lock */
tmp = REG_SET_FIELD(tmp, GRPH_UPDATE, GRPH_UPDATE_LOCK, 1);
WREG32(mmGRPH_UPDATE + amdgpu_crtc->crtc_offset, tmp);
/* update the scanout addresses */ /* update the scanout addresses */
WREG32(mmGRPH_SECONDARY_SURFACE_ADDRESS_HIGH + amdgpu_crtc->crtc_offset,
upper_32_bits(crtc_base));
WREG32(mmGRPH_SECONDARY_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset,
lower_32_bits(crtc_base));
WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + amdgpu_crtc->crtc_offset, WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + amdgpu_crtc->crtc_offset,
upper_32_bits(crtc_base)); upper_32_bits(crtc_base));
/* writing to the low address triggers the update */
WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset, WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset,
lower_32_bits(crtc_base)); lower_32_bits(crtc_base));
/* post the write */
/* Wait for update_pending to go high. */ RREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset);
for (i = 0; i < adev->usec_timeout; i++) {
if (RREG32(mmGRPH_UPDATE + amdgpu_crtc->crtc_offset) &
GRPH_UPDATE__GRPH_SURFACE_UPDATE_PENDING_MASK)
break;
udelay(1);
}
DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
/* Unlock the lock, so double-buffering can take place inside vblank */
tmp = REG_SET_FIELD(tmp, GRPH_UPDATE, GRPH_UPDATE_LOCK, 0);
WREG32(mmGRPH_UPDATE + amdgpu_crtc->crtc_offset, tmp);
} }
static int dce_v11_0_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc, static int dce_v11_0_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc,