summaryrefslogtreecommitdiff
path: root/src/drmmode_display.c
diff options
context:
space:
mode:
authorMichel Dänzer <michel.daenzer@amd.com>2017-08-14 12:23:04 +0900
committerMichel Dänzer <michel@daenzer.net>2017-08-17 15:24:22 +0900
commit99f1d7a474af3683fe1a66f50c0bb8935478ff0a (patch)
treebfbfa730d273cf70975fb3eee83eb8f51ce5e6ae /src/drmmode_display.c
parent49cc61ab970ee28d4509b4e2dd0a57165136889f (diff)
Create drmmode_wait_vblank helper
Allows cleaning up the code considerably. v2: * Fix "drmWaiVBlank" typo, add blank line for readability (Slava Abramov) * Rename in/out sequence parameters to "target_seq" and "result_seq", hopefully that will be clearer. Reviewed-by: Alex Deucher <alexander.deucher@amd.com> # v1
Diffstat (limited to 'src/drmmode_display.c')
-rw-r--r--src/drmmode_display.c63
1 files changed, 42 insertions, 21 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 46a579ff..d86f8300 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -243,6 +243,41 @@ drmmode_ConvertToKMode(ScrnInfoPtr scrn,
}
/*
+ * Utility helper for drmWaitVBlank
+ */
+Bool
+drmmode_wait_vblank(xf86CrtcPtr crtc, drmVBlankSeqType type,
+ uint32_t target_seq, unsigned long signal, uint64_t *ust,
+ uint32_t *result_seq)
+{
+ int crtc_id = drmmode_get_crtc_id(crtc);
+ ScrnInfoPtr scrn = crtc->scrn;
+ RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
+ drmVBlank vbl;
+
+ if (crtc_id == 1)
+ type |= DRM_VBLANK_SECONDARY;
+ else if (crtc_id > 1)
+ type |= (crtc_id << DRM_VBLANK_HIGH_CRTC_SHIFT) &
+ DRM_VBLANK_HIGH_CRTC_MASK;
+
+ vbl.request.type = type;
+ vbl.request.sequence = target_seq;
+ vbl.request.signal = signal;
+
+ if (drmWaitVBlank(pRADEONEnt->fd, &vbl) != 0)
+ return FALSE;
+
+ if (ust)
+ *ust = (uint64_t)vbl.reply.tval_sec * 1000000 +
+ vbl.reply.tval_usec;
+ if (result_seq)
+ *result_seq = vbl.reply.sequence;
+
+ return TRUE;
+}
+
+/*
* Retrieves present time in microseconds that is compatible
* with units used by vblank timestamps. Depending on the kernel
* version and DRM kernel module configuration, the vblank
@@ -272,23 +307,15 @@ int drmmode_get_current_ust(int drm_fd, CARD64 *ust)
int drmmode_crtc_get_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc)
{
ScrnInfoPtr scrn = crtc->scrn;
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
- drmVBlank vbl;
- int ret;
-
- vbl.request.type = DRM_VBLANK_RELATIVE;
- vbl.request.type |= radeon_populate_vbl_request_type(crtc);
- vbl.request.sequence = 0;
+ uint32_t seq;
- ret = drmWaitVBlank(pRADEONEnt->fd, &vbl);
- if (ret) {
+ if (!drmmode_wait_vblank(crtc, DRM_VBLANK_RELATIVE, 0, 0, ust, &seq)) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"get vblank counter failed: %s\n", strerror(errno));
- return ret;
+ return -1;
}
- *ust = ((CARD64)vbl.reply.tval_sec * 1000000) + vbl.reply.tval_usec;
- *msc = vbl.reply.sequence;
+ *msc = seq;
return Success;
}
@@ -305,7 +332,7 @@ drmmode_do_crtc_dpms(xf86CrtcPtr crtc, int mode)
drmmode_crtc->pending_dpms_mode = mode;
if (drmmode_crtc->dpms_mode == DPMSModeOn && mode != DPMSModeOn) {
- drmVBlank vbl;
+ uint32_t seq;
/* Wait for any pending flip to finish */
if (drmmode_crtc->flip_pending)
@@ -315,20 +342,14 @@ drmmode_do_crtc_dpms(xf86CrtcPtr crtc, int mode)
* On->Off transition: record the last vblank time,
* sequence number and frame period.
*/
- vbl.request.type = DRM_VBLANK_RELATIVE;
- vbl.request.type |= radeon_populate_vbl_request_type(crtc);
- vbl.request.sequence = 0;
- ret = drmWaitVBlank(pRADEONEnt->fd, &vbl);
- if (ret)
+ if (!drmmode_wait_vblank(crtc, DRM_VBLANK_RELATIVE, 0, 0, &ust,
+ &seq))
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"%s cannot get last vblank counter\n",
__func__);
else {
- CARD64 seq = (CARD64)vbl.reply.sequence;
CARD64 nominal_frame_rate, pix_in_frame;
- ust = ((CARD64)vbl.reply.tval_sec * 1000000) +
- vbl.reply.tval_usec;
drmmode_crtc->dpms_last_ust = ust;
drmmode_crtc->dpms_last_seq = seq;
nominal_frame_rate = crtc->mode.Clock;