aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2018-03-13 11:07:58 -0400
committerVille Syrjälä <ville.syrjala@linux.intel.com>2018-03-16 12:31:49 -0400
commit2f0e9d804935970a4ce0f58dd046b41881bfd8f3 (patch)
treee5b12b5b3bb171b37ec79ba10296bf64bbc690aa
parentdf550548c6339e0d032af4a7f9bd7200ab0c827b (diff)
drm: Make drm_mode_vrefresh() a bit more accurate
Do the refresh rate calculation with a single division. This gives us slightly more accurate results, especially for interlaced since we don't just double the final truncated result. We do lose one bit compared to the old way, so with an interlaced mode the new code can only handle ~2GHz instead of the ~4GHz the old code handeled. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20180313150759.27620-2-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/drm_modes.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 4157250140b0..f6b7c0e36a1a 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -773,24 +773,23 @@ EXPORT_SYMBOL(drm_mode_hsync);
773int drm_mode_vrefresh(const struct drm_display_mode *mode) 773int drm_mode_vrefresh(const struct drm_display_mode *mode)
774{ 774{
775 int refresh = 0; 775 int refresh = 0;
776 unsigned int calc_val;
777 776
778 if (mode->vrefresh > 0) 777 if (mode->vrefresh > 0)
779 refresh = mode->vrefresh; 778 refresh = mode->vrefresh;
780 else if (mode->htotal > 0 && mode->vtotal > 0) { 779 else if (mode->htotal > 0 && mode->vtotal > 0) {
781 int vtotal; 780 unsigned int num, den;
782 vtotal = mode->vtotal; 781
783 /* work out vrefresh the value will be x1000 */ 782 num = mode->clock * 1000;
784 calc_val = (mode->clock * 1000); 783 den = mode->htotal * mode->vtotal;
785 calc_val /= mode->htotal;
786 refresh = (calc_val + vtotal / 2) / vtotal;
787 784
788 if (mode->flags & DRM_MODE_FLAG_INTERLACE) 785 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
789 refresh *= 2; 786 num *= 2;
790 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 787 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
791 refresh /= 2; 788 den *= 2;
792 if (mode->vscan > 1) 789 if (mode->vscan > 1)
793 refresh /= mode->vscan; 790 den *= mode->vscan;
791
792 refresh = DIV_ROUND_CLOSEST(num, den);
794 } 793 }
795 return refresh; 794 return refresh;
796} 795}