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

drm/msm/dpu: async commit support

In addition, moving to kms->flush_commit() lets us drop the only user
of kms->commit().

Signed-off-by: Rob Clark <robdclark@chromium.org>
Reviewed-by: Sean Paul <sean@poorly.run>

+34 -45
-13
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
··· 608 608 struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); 609 609 struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc); 610 610 struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state); 611 - int ret; 612 611 613 612 /* 614 613 * If no mixers has been allocated in dpu_crtc_atomic_check(), ··· 627 628 crtc->state->encoder_mask) 628 629 dpu_encoder_prepare_for_kickoff(encoder); 629 630 630 - /* wait for previous frame_event_done completion */ 631 - DPU_ATRACE_BEGIN("wait_for_frame_done_event"); 632 - ret = _dpu_crtc_wait_for_frame_done(crtc); 633 - DPU_ATRACE_END("wait_for_frame_done_event"); 634 - if (ret) { 635 - DPU_ERROR("crtc%d wait for frame done failed;frame_pending%d\n", 636 - crtc->base.id, 637 - atomic_read(&dpu_crtc->frame_pending)); 638 - goto end; 639 - } 640 - 641 631 if (atomic_inc_return(&dpu_crtc->frame_pending) == 1) { 642 632 /* acquire bandwidth and other resources */ 643 633 DPU_DEBUG("crtc%d first commit\n", crtc->base.id); ··· 640 652 drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) 641 653 dpu_encoder_kickoff(encoder); 642 654 643 - end: 644 655 reinit_completion(&dpu_crtc->frame_done_comp); 645 656 DPU_ATRACE_END("crtc_commit"); 646 657 }
+3 -4
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
··· 1680 1680 return line_time; 1681 1681 } 1682 1682 1683 - static int _dpu_encoder_wakeup_time(struct drm_encoder *drm_enc, 1684 - ktime_t *wakeup_time) 1683 + int dpu_encoder_vsync_time(struct drm_encoder *drm_enc, ktime_t *wakeup_time) 1685 1684 { 1686 1685 struct drm_display_mode *mode; 1687 1686 struct dpu_encoder_virt *dpu_enc; ··· 1767 1768 return; 1768 1769 } 1769 1770 1770 - if (_dpu_encoder_wakeup_time(&dpu_enc->base, &wakeup_time)) 1771 + if (dpu_encoder_vsync_time(&dpu_enc->base, &wakeup_time)) 1771 1772 return; 1772 1773 1773 1774 trace_dpu_enc_vsync_event_work(DRMID(&dpu_enc->base), wakeup_time); ··· 1841 1842 } 1842 1843 1843 1844 if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI && 1844 - !_dpu_encoder_wakeup_time(drm_enc, &wakeup_time)) { 1845 + !dpu_encoder_vsync_time(drm_enc, &wakeup_time)) { 1845 1846 trace_dpu_enc_early_kickoff(DRMID(drm_enc), 1846 1847 ktime_to_ms(wakeup_time)); 1847 1848 mod_timer(&dpu_enc->vsync_event_timer,
+5
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
··· 86 86 void dpu_encoder_kickoff(struct drm_encoder *encoder); 87 87 88 88 /** 89 + * dpu_encoder_wakeup_time - get the time of the next vsync 90 + */ 91 + int dpu_encoder_vsync_time(struct drm_encoder *drm_enc, ktime_t *wakeup_time); 92 + 93 + /** 89 94 * dpu_encoder_wait_for_event - Waits for encoder events 90 95 * @encoder: encoder pointer 91 96 * @event: event to wait for
+25 -21
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
··· 262 262 pm_runtime_put_sync(&dpu_kms->pdev->dev); 263 263 } 264 264 265 + static ktime_t dpu_kms_vsync_time(struct msm_kms *kms, struct drm_crtc *crtc) 266 + { 267 + struct drm_encoder *encoder; 268 + 269 + drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) { 270 + ktime_t vsync_time; 271 + 272 + if (dpu_encoder_vsync_time(encoder, &vsync_time) == 0) 273 + return vsync_time; 274 + } 275 + 276 + return ktime_get(); 277 + } 278 + 265 279 static void dpu_kms_prepare_commit(struct msm_kms *kms, 266 280 struct drm_atomic_state *state) 267 281 { ··· 307 293 308 294 static void dpu_kms_flush_commit(struct msm_kms *kms, unsigned crtc_mask) 309 295 { 310 - /* TODO */ 296 + struct dpu_kms *dpu_kms = to_dpu_kms(kms); 297 + struct drm_crtc *crtc; 298 + 299 + for_each_crtc_mask(dpu_kms->dev, crtc, crtc_mask) { 300 + if (!crtc->state->active) 301 + continue; 302 + 303 + trace_dpu_kms_commit(DRMID(crtc)); 304 + dpu_crtc_commit_kickoff(crtc); 305 + } 311 306 } 312 307 313 308 /* ··· 339 316 continue; 340 317 341 318 trace_dpu_kms_enc_enable(DRMID(crtc)); 342 - dpu_crtc_commit_kickoff(crtc); 343 - } 344 - } 345 - 346 - static void dpu_kms_commit(struct msm_kms *kms, struct drm_atomic_state *state) 347 - { 348 - struct drm_crtc *crtc; 349 - struct drm_crtc_state *crtc_state; 350 - int i; 351 - 352 - for_each_new_crtc_in_state(state, crtc, crtc_state, i) { 353 - /* If modeset is required, kickoff is run in encoder_enable */ 354 - if (drm_atomic_crtc_needs_modeset(crtc_state)) 355 - continue; 356 - 357 - if (crtc->state->active) { 358 - trace_dpu_kms_commit(DRMID(crtc)); 359 - dpu_crtc_commit_kickoff(crtc); 360 - } 361 319 } 362 320 } 363 321 ··· 699 695 .irq = dpu_irq, 700 696 .enable_commit = dpu_kms_enable_commit, 701 697 .disable_commit = dpu_kms_disable_commit, 698 + .vsync_time = dpu_kms_vsync_time, 702 699 .prepare_commit = dpu_kms_prepare_commit, 703 700 .flush_commit = dpu_kms_flush_commit, 704 - .commit = dpu_kms_commit, 705 701 .wait_flush = dpu_kms_wait_flush, 706 702 .complete_commit = dpu_kms_complete_commit, 707 703 .enable_vblank = dpu_kms_enable_vblank,
+1 -4
drivers/gpu/drm/msm/msm_atomic.c
··· 210 210 /* 211 211 * Flush hardware updates: 212 212 */ 213 - if (kms->funcs->commit) { 214 - DRM_DEBUG_ATOMIC("triggering commit\n"); 215 - kms->funcs->commit(kms, state); 216 - } 213 + DRM_DEBUG_ATOMIC("triggering commit\n"); 217 214 kms->funcs->flush_commit(kms, crtc_mask); 218 215 mutex_unlock(&kms->commit_lock); 219 216
-3
drivers/gpu/drm/msm/msm_kms.h
··· 80 80 */ 81 81 void (*flush_commit)(struct msm_kms *kms, unsigned crtc_mask); 82 82 83 - /* TODO remove ->commit(), use ->flush_commit() instead: */ 84 - void (*commit)(struct msm_kms *kms, struct drm_atomic_state *state); 85 - 86 83 /** 87 84 * Wait for any in-progress flush to complete on the specified 88 85 * crtcs. This should not block if there is no in-progress