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

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

+7 -31
+7 -31
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
··· 211 211 * @crtc_id: crtc to cleanup pageflip on 212 212 * @crtc_base: new address of the crtc (GPU MC address) 213 213 * 214 - * Does the actual pageflip (evergreen+). 215 - * During vblank we take the crtc lock and wait for the update_pending 216 - * bit to go high, when it does, we release the lock, and allow the 217 - * double buffered update to take place. 218 - * Returns the current update pending status. 214 + * Triggers the actual pageflip by updating the primary 215 + * surface base address. 219 216 */ 220 217 static void dce_v8_0_page_flip(struct amdgpu_device *adev, 221 218 int crtc_id, u64 crtc_base) 222 219 { 223 220 struct amdgpu_crtc *amdgpu_crtc = adev->mode_info.crtcs[crtc_id]; 224 - u32 tmp = RREG32(mmGRPH_UPDATE + amdgpu_crtc->crtc_offset); 225 - int i; 226 221 227 - /* Lock the graphics update lock */ 228 - tmp |= GRPH_UPDATE__GRPH_UPDATE_LOCK_MASK; 229 - WREG32(mmGRPH_UPDATE + amdgpu_crtc->crtc_offset, tmp); 230 - 231 - /* update the scanout addresses */ 232 - WREG32(mmGRPH_SECONDARY_SURFACE_ADDRESS_HIGH + amdgpu_crtc->crtc_offset, 233 - upper_32_bits(crtc_base)); 234 - WREG32(mmGRPH_SECONDARY_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset, 235 - (u32)crtc_base); 236 - 222 + /* update the primary scanout addresses */ 237 223 WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + amdgpu_crtc->crtc_offset, 238 224 upper_32_bits(crtc_base)); 225 + /* writing to the low address triggers the update */ 239 226 WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset, 240 - (u32)crtc_base); 241 - 242 - /* Wait for update_pending to go high. */ 243 - for (i = 0; i < adev->usec_timeout; i++) { 244 - if (RREG32(mmGRPH_UPDATE + amdgpu_crtc->crtc_offset) & 245 - GRPH_UPDATE__GRPH_SURFACE_UPDATE_PENDING_MASK) 246 - break; 247 - udelay(1); 248 - } 249 - DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); 250 - 251 - /* Unlock the lock, so double-buffering can take place inside vblank */ 252 - tmp &= ~GRPH_UPDATE__GRPH_UPDATE_LOCK_MASK; 253 - WREG32(mmGRPH_UPDATE + amdgpu_crtc->crtc_offset, tmp); 227 + lower_32_bits(crtc_base)); 228 + /* post the write */ 229 + RREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset); 254 230 } 255 231 256 232 static int dce_v8_0_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc,