drm/vblank: drop the mode argument from drm_calc_vbltimestamp_from_scanoutpos
[linux-2.6-microblaze.git] / drivers / gpu / drm / drm_irq.c
index fba6a84..89f0928 100644 (file)
@@ -684,6 +684,7 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
 
        vblank->linedur_ns  = linedur_ns;
        vblank->framedur_ns = framedur_ns;
+       vblank->hwmode = *mode;
 
        DRM_DEBUG("crtc %u: hwmode: htotal %d, vtotal %d, vdisplay %d\n",
                  crtc->base.id, mode->crtc_htotal,
@@ -704,7 +705,6 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants);
  *     True when called from drm_crtc_handle_vblank().  Some drivers
  *     need to apply some workarounds for gpu-specific vblank irq quirks
  *     if flag is set.
- * @mode: mode which defines the scanout timings
  *
  * Implements calculation of exact vblank timestamps from given drm_display_mode
  * timings and current video scanout position of a CRTC. This can be called from
@@ -724,6 +724,13 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants);
  * returns as no operation if a doublescan or interlaced video mode is
  * active. Higher level code is expected to handle this.
  *
+ * This function can be used to implement the &drm_driver.get_vblank_timestamp
+ * directly, if the driver implements the &drm_driver.get_scanout_position hook.
+ *
+ * Note that atomic drivers must call drm_calc_timestamping_constants() before
+ * enabling a CRTC. The atomic helpers already take care of that in
+ * drm_atomic_helper_update_legacy_modeset_state().
+ *
  * Returns:
  *
  * Returns true on success, and false on failure, i.e. when no accurate
@@ -733,17 +740,23 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
                                           unsigned int pipe,
                                           int *max_error,
                                           struct timeval *vblank_time,
-                                          bool in_vblank_irq,
-                                          const struct drm_display_mode *mode)
+                                          bool in_vblank_irq)
 {
        struct timeval tv_etime;
        ktime_t stime, etime;
-       unsigned int vbl_status;
+       bool vbl_status;
+       struct drm_crtc *crtc;
+       const struct drm_display_mode *mode;
+       struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
        int vpos, hpos, i;
        int delta_ns, duration_ns;
-       unsigned flags = in_vblank_irq ? DRM_CALLED_FROM_VBLIRQ : 0;
 
-       if (pipe >= dev->num_crtcs) {
+       if (!drm_core_check_feature(dev, DRIVER_MODESET))
+               return false;
+
+       crtc = drm_crtc_from_index(dev, pipe);
+
+       if (pipe >= dev->num_crtcs || !crtc) {
                DRM_ERROR("Invalid crtc %u\n", pipe);
                return false;
        }
@@ -754,6 +767,11 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
                return false;
        }
 
+       if (drm_drv_uses_atomic_modeset(dev))
+               mode = &vblank->hwmode;
+       else
+               mode = &crtc->hwmode;
+
        /* If mode timing undefined, just return as no-op:
         * Happens during initial modesetting of a crtc.
         */
@@ -774,15 +792,16 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
                 * Get vertical and horizontal scanout position vpos, hpos,
                 * and bounding timestamps stime, etime, pre/post query.
                 */
-               vbl_status = dev->driver->get_scanout_position(dev, pipe, flags,
+               vbl_status = dev->driver->get_scanout_position(dev, pipe,
+                                                              in_vblank_irq,
                                                               &vpos, &hpos,
                                                               &stime, &etime,
                                                               mode);
 
                /* Return as no-op if scanout query unsupported or failed. */
-               if (!(vbl_status & DRM_SCANOUTPOS_VALID)) {
-                       DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n",
-                                 pipe, vbl_status);
+               if (!vbl_status) {
+                       DRM_DEBUG("crtc %u : scanoutpos query failed.\n",
+                                 pipe);
                        return false;
                }
 
@@ -821,8 +840,8 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
        etime = ktime_sub_ns(etime, delta_ns);
        *vblank_time = ktime_to_timeval(etime);
 
-       DRM_DEBUG_VBL("crtc %u : v 0x%x p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n",
-                     pipe, vbl_status, hpos, vpos,
+       DRM_DEBUG_VBL("crtc %u : v p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n",
+                     pipe, hpos, vpos,
                      (long)tv_etime.tv_sec, (long)tv_etime.tv_usec,
                      (long)vblank_time->tv_sec, (long)vblank_time->tv_usec,
                      duration_ns/1000, i);