Den 25.08.2016 08:30, skrev Daniel Vetter: > On Wed, Aug 24, 2016 at 08:38:37PM +0200, Noralf Trønnes wrote: >> Den 23.08.2016 08:25, skrev Daniel Vetter: >>> Our update function is hooked to the single plane, which might not get >>> called for crtc-only updates. Which is surprising, so fix this by >>> always adding the plane. >>> >>> While at it document how&when the event should be sent out better in >>> the kerneldoc. >>> >>> Cc: Noralf Trønnes <noralf at tronnes.org> >>> Cc: andrea.merello at gmail.com >>> Tested-and-Reported-by: andrea.merello at gmail.com >>> Signed-off-by: Daniel Vetter <daniel.vetter at intel.com> >>> --- >>> I'm not entirely sure we really want to put the responsibility for >>> this onto driver. Plan B) would be to remove the kerneldoc I added >>> here and call the right function from drm_simple_kms_plane_atomic_update. >>> That way simple drivers don't need to deal with that detail, and in >>> general those drivers don't care that much about the miniscule >>> possible race a generic implementation would cause. What do you >>> suggest as the best approach? >> If the driver is responsible, a helper like this would be nice: >> >> void drm_simple_display_pipe_handle_vblank_event(struct >> drm_simple_display_pipe *pipe) >> { >> struct drm_crtc *crtc = &pipe->crtc; >> >> if (crtc->state && crtc->state->event) { >> spin_lock_irq(&crtc->dev->event_lock); >> drm_crtc_send_vblank_event(crtc, crtc->state->event); >> spin_unlock_irq(&crtc->dev->event_lock); >> crtc->state->event = NULL; > For a generic version we probably want to automatically switch to > drm_crtc_arm_vblank_event, if vblank support is available. That can be > checked by looking at drm_device->num_crtcs. > >> } >> } >> >> Then if the update() callback is not set, drm_simple_kms_plane_atomic_update >> calls this, and if it is set, then the driver has to do it or something >> similar. >> >> It is difficult to predict what future drivers will need. >> Unless there are drivers on the horizon that will need to handle the >> event themselves, I suggest that we follow your plan B. If the need arises, >> we just add a one-liner to all drivers that has the update() callback set. > Hm yeah. What about merging this patch here for now (would need your > formal reviewed-by), and then later on when we have 2-3 simple drivers > using this we can reconsider? Since I dont have hw for any of them I can't > do this myself. > >> Noralf. >> >> Sidenote: >> When I converted simpledrm I had problems with flip_done timeouts. >> In the end I had to check for the event in disable/enable/update. >> Trying it again now, it's enough to do it in update(). >> Not sure what has changed. > Trying again with this patch, or without? Since this patch here is meant > to exactly the problem that you need to handle the event in too many > places. If it's fixed with just latest drm-misc, that would be surprising > ...
I have updated Raspian so I could use xorg to test with, and indeed without this patch and without sending vblank event in disable and enable, the flip_done timeout showed up. modetest -v didn't trigger it. With this patch I only have to send the vblank event in update(). Reviewed-by: Noralf Trønnes <noralf at tronnes.org> > -Daniel > >>> -Daniel >>> --- >>> drivers/gpu/drm/drm_simple_kms_helper.c | 7 +++++++ >>> include/drm/drm_simple_kms_helper.h | 6 ++++++ >>> 2 files changed, 13 insertions(+) >>> >>> diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c >>> b/drivers/gpu/drm/drm_simple_kms_helper.c >>> index bada17166512..447631018426 100644 >>> --- a/drivers/gpu/drm/drm_simple_kms_helper.c >>> +++ b/drivers/gpu/drm/drm_simple_kms_helper.c >>> @@ -34,6 +34,12 @@ static const struct drm_encoder_funcs >>> drm_simple_kms_encoder_funcs = { >>> .destroy = drm_encoder_cleanup, >>> }; >>> +static int drm_simple_kms_crtc_check(struct drm_crtc *crtc, >>> + struct drm_crtc_state *state) >>> +{ >>> + return drm_atomic_add_affected_planes(state->state, crtc); >>> +} >>> + >>> static void drm_simple_kms_crtc_enable(struct drm_crtc *crtc) >>> { >>> struct drm_simple_display_pipe *pipe; >>> @@ -57,6 +63,7 @@ static void drm_simple_kms_crtc_disable(struct drm_crtc >>> *crtc) >>> } >>> static const struct drm_crtc_helper_funcs >>> drm_simple_kms_crtc_helper_funcs = { >>> + .atomic_check = drm_simple_kms_crtc_check, >>> .disable = drm_simple_kms_crtc_disable, >>> .enable = drm_simple_kms_crtc_enable, >>> }; >>> diff --git a/include/drm/drm_simple_kms_helper.h >>> b/include/drm/drm_simple_kms_helper.h >>> index 269039722f91..826946ca2b82 100644 >>> --- a/include/drm/drm_simple_kms_helper.h >>> +++ b/include/drm/drm_simple_kms_helper.h >>> @@ -60,6 +60,12 @@ struct drm_simple_display_pipe_funcs { >>> * >>> * This function is called when the underlying plane state is updated. >>> * This hook is optional. >>> + * >>> + * This is the function drivers should submit the >>> + * &drm_pending_vblank_event from. Using either >>> + * drm_crtc_arm_vblank_event(), when the driver supports vblank >>> + * interrupt handling, or drm_crtc_send_vblank_event() directly in case >>> + * the hardware lacks vblank support entirely. >>> */ >>> void (*update)(struct drm_simple_display_pipe *pipe, >>> struct drm_plane_state *plane_state);