From da0f600c8e6c17aac5ab96dafa2eb0de9934ed4b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 4 Apr 2016 16:55:04 +0100 Subject: [PATCH] nn-panel-fitter --- drivers/gpu/drm/i915/intel_panel.c | 46 +++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 8c8996f..d44aa78 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -234,15 +234,25 @@ static void i965_scale_aspect(struct intel_crtc_state *pipe_config, /* 965+ is easy, it does everything in hw */ if (scaled_width > scaled_height) - *pfit_control |= PFIT_ENABLE | - PFIT_SCALING_PILLAR; + *pfit_control |= PFIT_ENABLE | PFIT_SCALING_PILLAR; else if (scaled_width < scaled_height) - *pfit_control |= PFIT_ENABLE | - PFIT_SCALING_LETTER; + *pfit_control |= PFIT_ENABLE | PFIT_SCALING_LETTER; else if (adjusted_mode->crtc_hdisplay != pipe_config->pipe_src_w) *pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO; } +static bool pixel_exact_x(const struct intel_crtc_state *pc) +{ + const struct drm_display_mode *mode = &pc->base.adjusted_mode; + return (mode->crtc_hdisplay % pc->pipe_src_w) == 0; +} + +static bool pixel_exact_y(const struct intel_crtc_state *pc) +{ + const struct drm_display_mode *mode = &pc->base.adjusted_mode; + return (mode->crtc_vdisplay % pc->pipe_src_h) == 0; +} + static void i9xx_scale_aspect(struct intel_crtc_state *pipe_config, u32 *pfit_control, u32 *pfit_pgm_ratios, u32 *border) @@ -271,9 +281,9 @@ static void i9xx_scale_aspect(struct intel_crtc_state *pipe_config, *pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | bits << PFIT_VERT_SCALE_SHIFT); - *pfit_control |= (PFIT_ENABLE | - VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); + *pfit_control |= + PFIT_ENABLE | + (pixel_exact_y(pipe_config) ? 0 : VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR); } } else if (scaled_width < scaled_height) { /* letter */ centre_vertically(adjusted_mode, @@ -287,16 +297,16 @@ static void i9xx_scale_aspect(struct intel_crtc_state *pipe_config, *pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | bits << PFIT_VERT_SCALE_SHIFT); - *pfit_control |= (PFIT_ENABLE | - VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); + *pfit_control |= + PFIT_ENABLE | + (pixel_exact_x(pipe_config) ? 0 : VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR); } } else { /* Aspects match, Let hw scale both directions */ - *pfit_control |= (PFIT_ENABLE | - VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | - VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); + *pfit_control |= + PFIT_ENABLE | VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | + (pixel_exact_y(pipe_config) ? 0 : VERT_INTERP_BILINEAR) | + (pixel_exact_x(pipe_config) ? 0 : HORIZ_INTERP_BILINEAR); } } @@ -342,10 +352,10 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, if (INTEL_INFO(dev)->gen >= 4) pfit_control |= PFIT_SCALING_AUTO; else - pfit_control |= (VERT_AUTO_SCALE | - VERT_INTERP_BILINEAR | - HORIZ_AUTO_SCALE | - HORIZ_INTERP_BILINEAR); + pfit_control |= + VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | + (pixel_exact_y(pipe_config) ? 0 : VERT_INTERP_BILINEAR) | + (pixel_exact_x(pipe_config) ? 0 : HORIZ_INTERP_BILINEAR); } break; default: -- 1.9.1