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

Commit ce055fe3 authored by Alex Deucher's avatar Alex Deucher
Browse files

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: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarJammy Zhou <Jammy.Zhou@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 0eaaacab
Loading
Loading
Loading
Loading
+5 −29
Original line number Diff line number Diff line
@@ -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_base: new address of the crtc (GPU MC address)
 *
 * Does the actual pageflip (evergreen+).
 * During vblank we take the crtc lock and wait for the update_pending
 * 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.
 * Triggers the actual pageflip by updating the primary
 * surface base address.
 */
static void dce_v11_0_page_flip(struct amdgpu_device *adev,
			      int crtc_id, u64 crtc_base)
{
	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 */
	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,
	       upper_32_bits(crtc_base));
	/* writing to the low address triggers the update */
	WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset,
	       lower_32_bits(crtc_base));

	/* Wait for update_pending to go high. */
	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);	
	/* post the write */
	RREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset);
}

static int dce_v11_0_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc,