[Intel-gfx] [PATCH 2/2] drm/i915: Refactor panel fitting on the LVDS.

2010-07-17 Thread Chris Wilson
Move the common routines into separate functions to not only increase
readability, but also throwaway surplus code.

In doing so, we review the calculation of the aspect preserving scaling
and avoid the use of fixed-point until we need to calculate the accurate
scale factor.

1 files changed, 128 insertions(+), 194 deletions(-)

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
Cc: Jesse Barnes jbar...@virtuousgeek.org
---
 drivers/gpu/drm/i915/intel_lvds.c |  322 +++--
 1 files changed, 128 insertions(+), 194 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_lvds.c 
b/drivers/gpu/drm/i915/intel_lvds.c
index 6ef9388..eab6a3a 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -156,31 +156,92 @@ static int intel_lvds_mode_valid(struct drm_connector 
*connector,
return MODE_OK;
 }
 
+static void
+centre_horizontally(struct drm_display_mode *mode,
+   int width)
+{
+   u32 border, sync_pos, blank_width, sync_width;
+
+   sync_width = mode-crtc_hsync_end - mode-crtc_hsync_start;
+   blank_width = mode-crtc_hblank_end - mode-crtc_hblank_start;
+
+   border = (mode-hdisplay - width) / 2;
+
+   if (mode-hdisplay  1) /* odd resolutions */
+   border++;
+
+   /* keep the border be even */
+   if (border  1)
+   border++;
+
+   mode-crtc_hdisplay = width;
+   mode-crtc_hblank_start = width + border;
+   /* keep the hblank width constant */
+   mode-crtc_hblank_end =
+   mode-crtc_hblank_start + blank_width;
+
+   /* get the hsync start pos relative to hblank start */
+   sync_pos = (blank_width - sync_width) / 2;
+   /* keep the hsync_pos be even */
+   if (sync_pos  1)
+   sync_pos++;
+
+   /* keep hsync width constant */
+   mode-crtc_hsync_start = mode-crtc_hblank_start + sync_pos;
+   mode-crtc_hsync_end = mode-crtc_hsync_start + sync_width;
+}
+
+static void
+centre_vertically(struct drm_display_mode *mode,
+ int height)
+{
+   u32 border, sync_pos, blank_width, sync_width;
+
+   sync_width = mode-crtc_vsync_end - mode-crtc_vsync_start;
+   blank_width = mode-crtc_vblank_end - mode-crtc_vblank_start;
+
+   border = (mode-vdisplay - height) / 2;
+
+   if (mode-vdisplay  1)
+   border++;
+
+   mode-crtc_vdisplay = height;
+   mode-crtc_vblank_start = height + border;
+   /* keep the vblank width constant */
+   mode-crtc_vblank_end = mode-crtc_vblank_start + blank_width;
+
+   /* get the vsync start pos relative to vblank start */
+   sync_pos = (blank_width - sync_width) / 2;
+
+   /* keep the vsync width constant */
+   mode-crtc_vsync_start = mode-crtc_vblank_start + sync_pos;
+   mode-crtc_vsync_end = mode-crtc_vsync_start + sync_width;
+}
+
+static inline u32 panel_fitter_scaling(u32 source, u32 target)
+{
+   /*
+* Floating point operation is not supported. So the FACTOR
+* is defined, which can avoid the floating point computation
+* when calculating the panel ratio.
+*/
+#define ACCURACY 12
+#define FACTOR (1  ACCURACY)
+   u32 ratio = source * FACTOR / target;
+   return (FACTOR * (ratio + FACTOR/2)) / FACTOR;
+}
+
 static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
  struct drm_display_mode *mode,
  struct drm_display_mode *adjusted_mode)
 {
-   /*
-* float point operation is not supported . So the PANEL_RATIO_FACTOR
-* is defined, which can avoid the float point computation when
-* calculating the panel ratio.
-*/
-#define PANEL_RATIO_FACTOR 8192
struct drm_device *dev = encoder-dev;
struct drm_i915_private *dev_priv = dev-dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder-crtc);
struct drm_encoder *tmp_encoder;
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_lvds_priv *lvds_priv = intel_encoder-dev_priv;
-   u32 pfit_control = 0, pfit_pgm_ratios = 0;
-   int left_border = 0, right_border = 0, top_border = 0;
-   int bottom_border = 0;
-   bool border = 0;
-   int panel_ratio, desired_ratio, vert_scale, horiz_scale;
-   int horiz_ratio, vert_ratio;
-   u32 hsync_width, vsync_width;
-   u32 hblank_width, vblank_width;
-   u32 hsync_pos, vsync_pos;
+   u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
 
/* Should never happen!! */
if (!IS_I965G(dev)  intel_crtc-pipe == 0) {
@@ -228,11 +289,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder 
*encoder,
 
/* Native modes don't need fitting */
if (adjusted_mode-hdisplay == mode-hdisplay 
-   adjusted_mode-vdisplay == mode-vdisplay) {
-   pfit_pgm_ratios = 0;
-   border = 0;
+ 

Re: [Intel-gfx] [PATCH 2/2] drm/i915: Refactor panel fitting on the LVDS.

2010-07-17 Thread Jesse Barnes
On Sat, 17 Jul 2010 13:38:44 +0100
Chris Wilson ch...@chris-wilson.co.uk wrote:

 Move the common routines into separate functions to not only increase
 readability, but also throwaway surplus code.
 
 In doing so, we review the calculation of the aspect preserving
 scaling and avoid the use of fixed-point until we need to calculate
 the accurate scale factor.
 
 1 files changed, 128 insertions(+), 194 deletions(-)

Nice cleanups, that function was getting too big...  misc nitpicks
below.

 + /* keep the border be even */
 + if (border  1)
 + border++;

May as well fix the comment here or combine it with the above.  There
are a few other comments like this elsewhere too.

While you're in there it would also be cool to write a small CRTC mode
verification function that checks the htotal/vtotal/etc against the
constraints documented in the manual (e.g. sync before end, active
divisible by 2 in ganged mode, etc).  If you're feeling adventurous
anyway. :)

Other than that:

Reviewed-by: Jesse Barnes jbar...@virtuousgeek.org

-- 
Jesse Barnes, Intel Open Source Technology Center
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx