@@ -50,11 +50,40 @@ void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc)
50
50
scrtc -> event = NULL ;
51
51
if (event ) {
52
52
drm_crtc_send_vblank_event (& scrtc -> base , event );
53
+ wake_up (& scrtc -> flip_wait );
53
54
drm_crtc_vblank_put (& scrtc -> base );
54
55
}
55
56
spin_unlock_irqrestore (& dev -> event_lock , flags );
56
57
}
57
58
59
+ static bool shmob_drm_crtc_page_flip_pending (struct shmob_drm_crtc * scrtc )
60
+ {
61
+ struct drm_device * dev = scrtc -> base .dev ;
62
+ unsigned long flags ;
63
+ bool pending ;
64
+
65
+ spin_lock_irqsave (& dev -> event_lock , flags );
66
+ pending = scrtc -> event != NULL ;
67
+ spin_unlock_irqrestore (& dev -> event_lock , flags );
68
+
69
+ return pending ;
70
+ }
71
+
72
+ static void shmob_drm_crtc_wait_page_flip (struct shmob_drm_crtc * scrtc )
73
+ {
74
+ struct drm_crtc * crtc = & scrtc -> base ;
75
+ struct shmob_drm_device * sdev = to_shmob_device (crtc -> dev );
76
+
77
+ if (wait_event_timeout (scrtc -> flip_wait ,
78
+ !shmob_drm_crtc_page_flip_pending (scrtc ),
79
+ msecs_to_jiffies (50 )))
80
+ return ;
81
+
82
+ dev_warn (sdev -> dev , "page flip timeout\n" );
83
+
84
+ shmob_drm_crtc_finish_page_flip (scrtc );
85
+ }
86
+
58
87
/* -----------------------------------------------------------------------------
59
88
* CRTC
60
89
*/
@@ -253,6 +282,12 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
253
282
if (!scrtc -> started )
254
283
return ;
255
284
285
+ /*
286
+ * Wait for page flip completion before stopping the CRTC as userspace
287
+ * expects page flips to eventually complete.
288
+ */
289
+ shmob_drm_crtc_wait_page_flip (scrtc );
290
+
256
291
/* Stop the LCDC. */
257
292
shmob_drm_crtc_start_stop (scrtc , false);
258
293
@@ -463,6 +498,8 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
463
498
unsigned int i ;
464
499
int ret ;
465
500
501
+ init_waitqueue_head (& sdev -> crtc .flip_wait );
502
+
466
503
sdev -> crtc .dpms = DRM_MODE_DPMS_OFF ;
467
504
468
505
primary = shmob_drm_plane_create (sdev , DRM_PLANE_TYPE_PRIMARY , 0 );
0 commit comments