Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu/dce10: 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>

+6 -30
+6 -30
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
··· 262 262 * @crtc_id: crtc to cleanup pageflip on 263 263 * @crtc_base: new address of the crtc (GPU MC address) 264 264 * 265 - * Does the actual pageflip (evergreen+). 266 - * During vblank we take the crtc lock and wait for the update_pending 267 - * bit to go high, when it does, we release the lock, and allow the 268 - * double buffered update to take place. 269 - * Returns the current update pending status. 265 + * Triggers the actual pageflip by updating the primary 266 + * surface base address. 270 267 */ 271 268 static void dce_v10_0_page_flip(struct amdgpu_device *adev, 272 269 int crtc_id, u64 crtc_base) 273 270 { 274 271 struct amdgpu_crtc *amdgpu_crtc = adev->mode_info.crtcs[crtc_id]; 275 - u32 tmp = RREG32(mmGRPH_UPDATE + amdgpu_crtc->crtc_offset); 276 - int i; 277 272 278 - /* Lock the graphics update lock */ 279 - tmp = REG_SET_FIELD(tmp, GRPH_UPDATE, GRPH_UPDATE_LOCK, 1); 280 - WREG32(mmGRPH_UPDATE + amdgpu_crtc->crtc_offset, tmp); 281 - 282 - /* update the scanout addresses */ 283 - WREG32(mmGRPH_SECONDARY_SURFACE_ADDRESS_HIGH + amdgpu_crtc->crtc_offset, 284 - upper_32_bits(crtc_base)); 285 - WREG32(mmGRPH_SECONDARY_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset, 286 - lower_32_bits(crtc_base)); 287 - 273 + /* update the primary scanout address */ 288 274 WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + amdgpu_crtc->crtc_offset, 289 275 upper_32_bits(crtc_base)); 276 + /* writing to the low address triggers the update */ 290 277 WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset, 291 278 lower_32_bits(crtc_base)); 292 - 293 - /* Wait for update_pending to go high. */ 294 - for (i = 0; i < adev->usec_timeout; i++) { 295 - if (RREG32(mmGRPH_UPDATE + amdgpu_crtc->crtc_offset) & 296 - GRPH_UPDATE__GRPH_SURFACE_UPDATE_PENDING_MASK) 297 - break; 298 - udelay(1); 299 - } 300 - DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); 301 - 302 - /* Unlock the lock, so double-buffering can take place inside vblank */ 303 - tmp = REG_SET_FIELD(tmp, GRPH_UPDATE, GRPH_UPDATE_LOCK, 0); 304 - WREG32(mmGRPH_UPDATE + amdgpu_crtc->crtc_offset, tmp); 279 + /* post the write */ 280 + RREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset); 305 281 } 306 282 307 283 static int dce_v10_0_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc,