Merge v5.6-rc5 into drm-next
[linux-2.6-microblaze.git] / drivers / gpu / drm / msm / disp / mdp5 / mdp5_crtc.c
index e1cc541..998bef1 100644 (file)
@@ -405,6 +405,83 @@ static void mdp5_crtc_mode_set_nofb(struct drm_crtc *crtc)
        spin_unlock_irqrestore(&mdp5_crtc->lm_lock, flags);
 }
 
+static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc)
+{
+       struct drm_device *dev = crtc->dev;
+       struct drm_encoder *encoder;
+
+       drm_for_each_encoder(encoder, dev)
+               if (encoder->crtc == crtc)
+                       return encoder;
+
+       return NULL;
+}
+
+static bool mdp5_crtc_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)
+{
+       unsigned int pipe = crtc->index;
+       struct drm_encoder *encoder;
+       int line, vsw, vbp, vactive_start, vactive_end, vfp_end;
+
+
+       encoder = get_encoder_from_crtc(crtc);
+       if (!encoder) {
+               DRM_ERROR("no encoder found for crtc %d\n", pipe);
+               return false;
+       }
+
+       vsw = mode->crtc_vsync_end - mode->crtc_vsync_start;
+       vbp = mode->crtc_vtotal - mode->crtc_vsync_end;
+
+       /*
+        * the line counter is 1 at the start of the VSYNC pulse and VTOTAL at
+        * the end of VFP. Translate the porch values relative to the line
+        * counter positions.
+        */
+
+       vactive_start = vsw + vbp + 1;
+
+       vactive_end = vactive_start + mode->crtc_vdisplay;
+
+       /* last scan line before VSYNC */
+       vfp_end = mode->crtc_vtotal;
+
+       if (stime)
+               *stime = ktime_get();
+
+       line = mdp5_encoder_get_linecount(encoder);
+
+       if (line < vactive_start)
+               line -= vactive_start;
+       else if (line > vactive_end)
+               line = line - vfp_end - vactive_start;
+       else
+               line -= vactive_start;
+
+       *vpos = line;
+       *hpos = 0;
+
+       if (etime)
+               *etime = ktime_get();
+
+       return true;
+}
+
+static u32 mdp5_crtc_get_vblank_counter(struct drm_crtc *crtc)
+{
+       struct drm_encoder *encoder;
+
+       encoder = get_encoder_from_crtc(crtc);
+       if (!encoder)
+               return 0;
+
+       return mdp5_encoder_get_framecount(encoder);
+}
+
 static void mdp5_crtc_atomic_disable(struct drm_crtc *crtc,
                                     struct drm_crtc_state *old_state)
 {
@@ -1054,6 +1131,10 @@ static const struct drm_crtc_funcs mdp5_crtc_funcs = {
        .cursor_set = mdp5_crtc_cursor_set,
        .cursor_move = mdp5_crtc_cursor_move,
        .atomic_print_state = mdp5_crtc_atomic_print_state,
+       .get_vblank_counter = mdp5_crtc_get_vblank_counter,
+       .enable_vblank  = msm_crtc_enable_vblank,
+       .disable_vblank = msm_crtc_disable_vblank,
+       .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp,
 };
 
 static const struct drm_crtc_helper_funcs mdp5_crtc_helper_funcs = {
@@ -1063,6 +1144,7 @@ static const struct drm_crtc_helper_funcs mdp5_crtc_helper_funcs = {
        .atomic_flush = mdp5_crtc_atomic_flush,
        .atomic_enable = mdp5_crtc_atomic_enable,
        .atomic_disable = mdp5_crtc_atomic_disable,
+       .get_scanout_position = mdp5_crtc_get_scanout_position,
 };
 
 static void mdp5_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus)