drm/mgag200: Implement struct drm_crtc_funcs.get_vblank_timestamp
authorThomas Zimmermann <tzimmermann@suse.de>
Thu, 18 Jul 2024 10:44:17 +0000 (12:44 +0200)
committerThomas Zimmermann <tzimmermann@suse.de>
Fri, 19 Jul 2024 09:12:19 +0000 (11:12 +0200)
Implement struct drm_crtc_funcs.get_vblank_timestamp with the DRM
helper drm_crtc_vblank_helper_get_vblank_timestamp() with its helper
get_scanout_position. Read the scanout position from the MGAREG_VCOUNT
register.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240718104551.575912-8-tzimmermann@suse.de
drivers/gpu/drm/mgag200/mgag200_drv.h
drivers/gpu/drm/mgag200/mgag200_mode.c

index 829d32f50915681cce00cdbc9d673a99444e9496..8df3c84d2405e7dc42a326fee36f7cecbac18d00 100644 (file)
@@ -400,13 +400,18 @@ int mgag200_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_atomic_st
 void mgag200_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *old_state);
 void mgag200_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *old_state);
 void mgag200_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *old_state);
+bool mgag200_crtc_helper_get_scanout_position(struct drm_crtc *crtc, bool in_vblank_irq,
+                                             int *vpos, int *hpos,
+                                             ktime_t *stime, ktime_t *etime,
+                                             const struct drm_display_mode *mode);
 
 #define MGAG200_CRTC_HELPER_FUNCS \
        .mode_valid = mgag200_crtc_helper_mode_valid, \
        .atomic_check = mgag200_crtc_helper_atomic_check, \
        .atomic_flush = mgag200_crtc_helper_atomic_flush, \
        .atomic_enable = mgag200_crtc_helper_atomic_enable, \
-       .atomic_disable = mgag200_crtc_helper_atomic_disable
+       .atomic_disable = mgag200_crtc_helper_atomic_disable, \
+       .get_scanout_position = mgag200_crtc_helper_get_scanout_position
 
 void mgag200_crtc_reset(struct drm_crtc *crtc);
 struct drm_crtc_state *mgag200_crtc_atomic_duplicate_state(struct drm_crtc *crtc);
@@ -422,7 +427,8 @@ void mgag200_crtc_disable_vblank(struct drm_crtc *crtc);
        .atomic_duplicate_state = mgag200_crtc_atomic_duplicate_state, \
        .atomic_destroy_state = mgag200_crtc_atomic_destroy_state, \
        .enable_vblank = mgag200_crtc_enable_vblank, \
-       .disable_vblank = mgag200_crtc_disable_vblank
+       .disable_vblank = mgag200_crtc_disable_vblank, \
+       .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp
 
 void mgag200_set_mode_regs(struct mga_device *mdev, const struct drm_display_mode *mode,
                           bool set_vidrst);
index afabf693df64705cf8fbc7d7b9a0ac980473936b..dd125ef15559e0cf04b81d55f1474a2f9160782d 100644 (file)
@@ -714,6 +714,31 @@ void mgag200_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic
        mgag200_disable_display(mdev);
 }
 
+bool mgag200_crtc_helper_get_scanout_position(struct drm_crtc *crtc, bool in_vblank_irq,
+                                             int *vpos, int *hpos,
+                                             ktime_t *stime, ktime_t *etime,
+                                             const struct drm_display_mode *mode)
+{
+       struct mga_device *mdev = to_mga_device(crtc->dev);
+       u32 vcount;
+
+       if (stime)
+               *stime = ktime_get();
+
+       if (vpos) {
+               vcount = RREG32(MGAREG_VCOUNT);
+               *vpos = vcount & GENMASK(11, 0);
+       }
+
+       if (hpos)
+               *hpos = mode->htotal >> 1; // near middle of scanline on average
+
+       if (etime)
+               *etime = ktime_get();
+
+       return true;
+}
+
 void mgag200_crtc_reset(struct drm_crtc *crtc)
 {
        struct mgag200_crtc_state *mgag200_crtc_state;