linux/drivers/gpu/drm/amd/display/amdgpu_dm
Mario Kleiner 2b5aed9ac3 drm/amd/display: Fix pageflip event race condition for DCN.
Commit '16f17eda8bad ("drm/amd/display: Send vblank and user
events at vsartup for DCN")' introduces a new way of pageflip
completion handling for DCN, and some trouble.

The current implementation introduces a race condition, which
can cause pageflip completion events to be sent out one vblank
too early, thereby confusing userspace and causing flicker:

prepare_flip_isr():

1. Pageflip programming takes the ddev->event_lock.
2. Sets acrtc->pflip_status == AMDGPU_FLIP_SUBMITTED
3. Releases ddev->event_lock.

--> Deadline for surface address regs double-buffering passes on
    target pipe.

4. dc_commit_updates_for_stream() MMIO programs the new pageflip
   into hw, but too late for current vblank.

=> pflip_status == AMDGPU_FLIP_SUBMITTED, but flip won't complete
   in current vblank due to missing the double-buffering deadline
   by a tiny bit.

5. VSTARTUP trigger point in vblank is reached, VSTARTUP irq fires,
   dm_dcn_crtc_high_irq() gets called.

6. Detects pflip_status == AMDGPU_FLIP_SUBMITTED and assumes the
   pageflip has been completed/will complete in this vblank and
   sends out pageflip completion event to userspace and resets
   pflip_status = AMDGPU_FLIP_NONE.

=> Flip completion event sent out one vblank too early.

This behaviour has been observed during my testing with measurement
hardware a couple of time.

The commit message says that the extra flip event code was added to
dm_dcn_crtc_high_irq() to prevent missing to send out pageflip events
in case the pflip irq doesn't fire, because the "DCH HUBP" component
is clock gated and doesn't fire pflip irqs in that state. Also that
this clock gating may happen if no planes are active. This suggests
that the problem addressed by that commit can't happen if planes
are active.

The proposed solution is therefore to only execute the extra pflip
completion code iff the count of active planes is zero and otherwise
leave pflip completion handling to the pflip irq handler, for a
more race-free experience.

Note that i don't know if this fixes the problem the original commit
tried to address, as i don't know what the test scenario was. It
does fix the observed too early pageflip events though and points
out the problem introduced.

Fixes: 16f17eda8b ("drm/amd/display: Send vblank and user events at vsartup for DCN")
Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2020-03-25 17:00:11 -04:00
..
amdgpu_dm_color.c drm/amd/display: Free gamma after calculating legacy transfer function 2019-10-25 16:50:07 -04:00
amdgpu_dm_crc.c drm/amd/display: Added pixel dynamic expansion control. 2019-10-10 19:24:26 -05:00
amdgpu_dm_crc.h drm/amd/display: Split out DC programming for CRC capture 2019-08-21 22:18:25 -05:00
amdgpu_dm_debugfs.c drm/amd/display: move dpcd debugfs members setup 2020-02-26 14:21:13 -05:00
amdgpu_dm_debugfs.h amdgpu_dm: no need to check return value of debugfs_create functions 2019-06-13 13:59:49 -05:00
amdgpu_dm_hdcp.c drm/amd/display: determine is mst hdcp based on stream instead of sink signal 2020-03-09 13:49:06 -04:00
amdgpu_dm_hdcp.h drm/amd/display: Add sysfs interface for set/get srm 2020-02-06 15:04:36 -05:00
amdgpu_dm_helpers.c drm/amd/display: update connector->display_info after read edid 2020-03-19 00:03:03 -04:00
amdgpu_dm_irq.c drm/amd: use list_for_each_entry for list iteration. 2020-01-07 12:04:16 -05:00
amdgpu_dm_irq.h
amdgpu_dm_mst_types.c drm-misc-next for 5.7: 2020-03-19 11:01:58 +10:00
amdgpu_dm_mst_types.h drm/amdgpu/display: protect new DSC code with CONFIG_DRM_AMD_DC_DCN 2020-01-09 18:07:48 -05:00
amdgpu_dm_pp_smu.c drm/amd/display: add default clocks if not able to fetch them 2019-11-26 12:19:08 -05:00
amdgpu_dm_services.c drm/amd: drop use of drmP.h in display/ 2019-06-10 23:00:20 +02:00
amdgpu_dm_trace.h drm/amd/display: Add tracing to dc 2018-12-05 17:49:49 -05:00
amdgpu_dm.c drm/amd/display: Fix pageflip event race condition for DCN. 2020-03-25 17:00:11 -04:00
amdgpu_dm.h drm/amd/display: update connector->display_info after read edid 2020-03-19 00:03:03 -04:00
Makefile drm/amd/display: Create amdgpu_dm_hdcp 2019-10-03 09:10:58 -05:00