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

drm/tilcdc: Use standard drm_atomic_helper_commit

Gives us proper nonblocking support for free, and a pile of other
things. The tilcdc code is simply old enough that it was never
converted over, but was stuck forever with the copypasta from when it
was initially merged.

The riskiest thing with this conversion is maybe that there's an issue
with the vblank handling or vblank event handling, which will upset
the modern commit support in atomic helpers. But from a cursory review
drm_crtc_vblank_on/off is called in the right places, and the event
handling also seems to exist (albeit with much hand-rolling and
probably some races, could perhaps be converted over to
drm_crtc_arm_vblank_event without any real loss).

Motivated by me not having to hand-roll the dma-fence annotations for
this.

v2: Clear out crtc_state->event when we're handling the event, to
avoid upsetting the helpers (reported by Jyri).

v3: Also send out even whent the crtc is getting disabled. Tilcdc looks a
bit like conversion to simple display helpers would work out really
nice.

Tested-by: Jyri Sarha <jsarha@ti.com>
Reviewed-by: Jyri Sarha <jsarha@ti.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Jyri Sarha <jsarha@ti.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200708142050.530240-1-daniel.vetter@ffwll.ch

+19 -49
+13
drivers/gpu/drm/tilcdc/tilcdc_crtc.c
··· 537 537 tilcdc_crtc_disable(crtc); 538 538 } 539 539 540 + static void tilcdc_crtc_atomic_flush(struct drm_crtc *crtc, 541 + struct drm_crtc_state *old_state) 542 + { 543 + if (!crtc->state->event) 544 + return; 545 + 546 + spin_lock_irq(&crtc->dev->event_lock); 547 + drm_crtc_send_vblank_event(crtc, crtc->state->event); 548 + crtc->state->event = NULL; 549 + spin_unlock_irq(&crtc->dev->event_lock); 550 + } 551 + 540 552 void tilcdc_crtc_shutdown(struct drm_crtc *crtc) 541 553 { 542 554 tilcdc_crtc_off(crtc, true); ··· 834 822 .atomic_check = tilcdc_crtc_atomic_check, 835 823 .atomic_enable = tilcdc_crtc_atomic_enable, 836 824 .atomic_disable = tilcdc_crtc_atomic_disable, 825 + .atomic_flush = tilcdc_crtc_atomic_flush, 837 826 }; 838 827 839 828 void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc,
+1 -46
drivers/gpu/drm/tilcdc/tilcdc_drv.c
··· 87 87 return ret; 88 88 } 89 89 90 - static int tilcdc_commit(struct drm_device *dev, 91 - struct drm_atomic_state *state, 92 - bool async) 93 - { 94 - int ret; 95 - 96 - ret = drm_atomic_helper_prepare_planes(dev, state); 97 - if (ret) 98 - return ret; 99 - 100 - ret = drm_atomic_helper_swap_state(state, true); 101 - if (ret) { 102 - drm_atomic_helper_cleanup_planes(dev, state); 103 - return ret; 104 - } 105 - 106 - /* 107 - * Everything below can be run asynchronously without the need to grab 108 - * any modeset locks at all under one condition: It must be guaranteed 109 - * that the asynchronous work has either been cancelled (if the driver 110 - * supports it, which at least requires that the framebuffers get 111 - * cleaned up with drm_atomic_helper_cleanup_planes()) or completed 112 - * before the new state gets committed on the software side with 113 - * drm_atomic_helper_swap_state(). 114 - * 115 - * This scheme allows new atomic state updates to be prepared and 116 - * checked in parallel to the asynchronous completion of the previous 117 - * update. Which is important since compositors need to figure out the 118 - * composition of the next frame right after having submitted the 119 - * current layout. 120 - */ 121 - 122 - drm_atomic_helper_commit_modeset_disables(dev, state); 123 - 124 - drm_atomic_helper_commit_planes(dev, state, 0); 125 - 126 - drm_atomic_helper_commit_modeset_enables(dev, state); 127 - 128 - drm_atomic_helper_wait_for_vblanks(dev, state); 129 - 130 - drm_atomic_helper_cleanup_planes(dev, state); 131 - 132 - return 0; 133 - } 134 - 135 90 static const struct drm_mode_config_funcs mode_config_funcs = { 136 91 .fb_create = drm_gem_fb_create, 137 92 .atomic_check = tilcdc_atomic_check, 138 - .atomic_commit = tilcdc_commit, 93 + .atomic_commit = drm_atomic_helper_commit, 139 94 }; 140 95 141 96 static void modeset_init(struct drm_device *dev)
+5 -3
drivers/gpu/drm/tilcdc/tilcdc_plane.c
··· 83 83 if (WARN_ON(!state->fb || !state->crtc->state)) 84 84 return; 85 85 86 - tilcdc_crtc_update_fb(state->crtc, 87 - state->fb, 88 - state->crtc->state->event); 86 + if (tilcdc_crtc_update_fb(state->crtc, 87 + state->fb, 88 + state->crtc->state->event) == 0) { 89 + state->crtc->state->event = NULL; 90 + } 89 91 } 90 92 91 93 static const struct drm_plane_helper_funcs plane_helper_funcs = {