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

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>

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