From 37327abdfbb4e2d7c9033f450de5e36e401d6efc Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 4 Sep 2013 18:25:28 +0300 Subject: drm/i915: Add explicit pipe src size to pipe config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather that mess about with hdisplay/vdisplay from requested_mode, add explicit pipe src size information to pipe config. Now requested_mode is only really relevant for dvo/sdvo output timings. For everything else either adjusted_mode or pipe src size should be used. In many places where we end up using pipe source size, we should actually use the primary plane size, but we don't currently store that information explicitly. As long as we treat primaries as full screen only, we can get away with this. Eventually when we move primaries over to drm_plane, we need to fix it all up. v2: Add a comment to explain what pipe_src_{w,h} are Add a note about primary planes to commit message Signed-off-by: Ville Syrjälä Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 56 ++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 29 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_panel.c') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 42114ecbae0e..c9dba46f52af 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -50,23 +50,22 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc, struct intel_crtc_config *pipe_config, int fitting_mode) { - struct drm_display_mode *mode, *adjusted_mode; + struct drm_display_mode *adjusted_mode; int x, y, width, height; - mode = &pipe_config->requested_mode; adjusted_mode = &pipe_config->adjusted_mode; x = y = width = height = 0; /* Native modes don't need fitting */ - if (adjusted_mode->hdisplay == mode->hdisplay && - adjusted_mode->vdisplay == mode->vdisplay) + if (adjusted_mode->hdisplay == pipe_config->pipe_src_w && + adjusted_mode->vdisplay == pipe_config->pipe_src_h) goto done; switch (fitting_mode) { case DRM_MODE_SCALE_CENTER: - width = mode->hdisplay; - height = mode->vdisplay; + width = pipe_config->pipe_src_w; + height = pipe_config->pipe_src_h; x = (adjusted_mode->hdisplay - width + 1)/2; y = (adjusted_mode->vdisplay - height + 1)/2; break; @@ -74,17 +73,17 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc, case DRM_MODE_SCALE_ASPECT: /* Scale but preserve the aspect ratio */ { - u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; - u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; + u32 scaled_width = adjusted_mode->hdisplay * pipe_config->pipe_src_h; + u32 scaled_height = pipe_config->pipe_src_w * adjusted_mode->vdisplay; if (scaled_width > scaled_height) { /* pillar */ - width = scaled_height / mode->vdisplay; + width = scaled_height / pipe_config->pipe_src_h; if (width & 1) width++; x = (adjusted_mode->hdisplay - width + 1) / 2; y = 0; height = adjusted_mode->vdisplay; } else if (scaled_width < scaled_height) { /* letter */ - height = scaled_width / mode->hdisplay; + height = scaled_width / pipe_config->pipe_src_w; if (height & 1) height++; y = (adjusted_mode->vdisplay - height + 1) / 2; @@ -176,14 +175,13 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, { struct drm_device *dev = intel_crtc->base.dev; u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; - struct drm_display_mode *mode, *adjusted_mode; + struct drm_display_mode *adjusted_mode; - mode = &pipe_config->requested_mode; adjusted_mode = &pipe_config->adjusted_mode; /* Native modes don't need fitting */ - if (adjusted_mode->hdisplay == mode->hdisplay && - adjusted_mode->vdisplay == mode->vdisplay) + if (adjusted_mode->hdisplay == pipe_config->pipe_src_w && + adjusted_mode->vdisplay == pipe_config->pipe_src_h) goto out; switch (fitting_mode) { @@ -192,16 +190,16 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, * For centered modes, we have to calculate border widths & * heights and modify the values programmed into the CRTC. */ - centre_horizontally(adjusted_mode, mode->hdisplay); - centre_vertically(adjusted_mode, mode->vdisplay); + centre_horizontally(adjusted_mode, pipe_config->pipe_src_w); + centre_vertically(adjusted_mode, pipe_config->pipe_src_h); border = LVDS_BORDER_ENABLE; break; case DRM_MODE_SCALE_ASPECT: /* Scale but preserve the aspect ratio */ if (INTEL_INFO(dev)->gen >= 4) { u32 scaled_width = adjusted_mode->hdisplay * - mode->vdisplay; - u32 scaled_height = mode->hdisplay * + pipe_config->pipe_src_h; + u32 scaled_height = pipe_config->pipe_src_w * adjusted_mode->vdisplay; /* 965+ is easy, it does everything in hw */ @@ -211,12 +209,12 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, else if (scaled_width < scaled_height) pfit_control |= PFIT_ENABLE | PFIT_SCALING_LETTER; - else if (adjusted_mode->hdisplay != mode->hdisplay) + else if (adjusted_mode->hdisplay != pipe_config->pipe_src_w) pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO; } else { u32 scaled_width = adjusted_mode->hdisplay * - mode->vdisplay; - u32 scaled_height = mode->hdisplay * + pipe_config->pipe_src_h; + u32 scaled_height = pipe_config->pipe_src_w * adjusted_mode->vdisplay; /* * For earlier chips we have to calculate the scaling @@ -226,11 +224,11 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, if (scaled_width > scaled_height) { /* pillar */ centre_horizontally(adjusted_mode, scaled_height / - mode->vdisplay); + pipe_config->pipe_src_h); border = LVDS_BORDER_ENABLE; - if (mode->vdisplay != adjusted_mode->vdisplay) { - u32 bits = panel_fitter_scaling(mode->vdisplay, adjusted_mode->vdisplay); + if (pipe_config->pipe_src_h != adjusted_mode->vdisplay) { + u32 bits = panel_fitter_scaling(pipe_config->pipe_src_h, adjusted_mode->vdisplay); pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | bits << PFIT_VERT_SCALE_SHIFT); pfit_control |= (PFIT_ENABLE | @@ -240,11 +238,11 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, } else if (scaled_width < scaled_height) { /* letter */ centre_vertically(adjusted_mode, scaled_width / - mode->hdisplay); + pipe_config->pipe_src_w); border = LVDS_BORDER_ENABLE; - if (mode->hdisplay != adjusted_mode->hdisplay) { - u32 bits = panel_fitter_scaling(mode->hdisplay, adjusted_mode->hdisplay); + if (pipe_config->pipe_src_w != adjusted_mode->hdisplay) { + u32 bits = panel_fitter_scaling(pipe_config->pipe_src_w, adjusted_mode->hdisplay); pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | bits << PFIT_VERT_SCALE_SHIFT); pfit_control |= (PFIT_ENABLE | @@ -265,8 +263,8 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, * Full scaling, even if it changes the aspect ratio. * Fortunately this is all done for us in hw. */ - if (mode->vdisplay != adjusted_mode->vdisplay || - mode->hdisplay != adjusted_mode->hdisplay) { + if (pipe_config->pipe_src_h != adjusted_mode->vdisplay || + pipe_config->pipe_src_w != adjusted_mode->hdisplay) { pfit_control |= PFIT_ENABLE; if (INTEL_INFO(dev)->gen >= 4) pfit_control |= PFIT_SCALING_AUTO; -- cgit From 9084e7d27671bc463c09ae6f0d6dfeea5f74f041 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 16 Sep 2013 23:43:45 +0200 Subject: drm/i915: re-layout intel_panel.c to obey 80 char limit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Especially intel_gmch_panel_fitting was shifting way too much over the right edge and also was way too long. So extract two helpers, one for gen4+ and one for gen2/3. Now the entire thing is again almost readable ... Spurred by checkpatch freaking out about a Ville's pipeconfig rework in intel_panel.c Otherwise just two lines that needed appropriate breaking. Not functional change in this patch. Cc: Ville Syrjälä Cc: Damien Lespiau Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 152 +++++++++++++++++++++---------------- 1 file changed, 88 insertions(+), 64 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_panel.c') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index c9dba46f52af..e36149d578fa 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -73,8 +73,10 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc, case DRM_MODE_SCALE_ASPECT: /* Scale but preserve the aspect ratio */ { - u32 scaled_width = adjusted_mode->hdisplay * pipe_config->pipe_src_h; - u32 scaled_height = pipe_config->pipe_src_w * adjusted_mode->vdisplay; + u32 scaled_width = adjusted_mode->hdisplay + * pipe_config->pipe_src_h; + u32 scaled_height = pipe_config->pipe_src_w + * adjusted_mode->vdisplay; if (scaled_width > scaled_height) { /* pillar */ width = scaled_height / pipe_config->pipe_src_h; if (width & 1) @@ -169,6 +171,83 @@ static inline u32 panel_fitter_scaling(u32 source, u32 target) return (FACTOR * ratio + FACTOR/2) / FACTOR; } +static void i965_scale_aspect(struct intel_crtc_config *pipe_config, + u32 *pfit_control) +{ + struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; + u32 scaled_width = adjusted_mode->hdisplay * + pipe_config->pipe_src_h; + u32 scaled_height = pipe_config->pipe_src_w * + adjusted_mode->vdisplay; + + /* 965+ is easy, it does everything in hw */ + if (scaled_width > scaled_height) + *pfit_control |= PFIT_ENABLE | + PFIT_SCALING_PILLAR; + else if (scaled_width < scaled_height) + *pfit_control |= PFIT_ENABLE | + PFIT_SCALING_LETTER; + else if (adjusted_mode->hdisplay != pipe_config->pipe_src_w) + *pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO; +} + +static void i9xx_scale_aspect(struct intel_crtc_config *pipe_config, + u32 *pfit_control, u32 *pfit_pgm_ratios, + u32 *border) +{ + struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; + u32 scaled_width = adjusted_mode->hdisplay * + pipe_config->pipe_src_h; + u32 scaled_height = pipe_config->pipe_src_w * + adjusted_mode->vdisplay; + u32 bits; + + /* + * For earlier chips we have to calculate the scaling + * ratio by hand and program it into the + * PFIT_PGM_RATIO register + */ + if (scaled_width > scaled_height) { /* pillar */ + centre_horizontally(adjusted_mode, + scaled_height / + pipe_config->pipe_src_h); + + *border = LVDS_BORDER_ENABLE; + if (pipe_config->pipe_src_h != adjusted_mode->vdisplay) { + bits = panel_fitter_scaling(pipe_config->pipe_src_h, + adjusted_mode->vdisplay); + + *pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | + bits << PFIT_VERT_SCALE_SHIFT); + *pfit_control |= (PFIT_ENABLE | + VERT_INTERP_BILINEAR | + HORIZ_INTERP_BILINEAR); + } + } else if (scaled_width < scaled_height) { /* letter */ + centre_vertically(adjusted_mode, + scaled_width / + pipe_config->pipe_src_w); + + *border = LVDS_BORDER_ENABLE; + if (pipe_config->pipe_src_w != adjusted_mode->hdisplay) { + bits = panel_fitter_scaling(pipe_config->pipe_src_w, + adjusted_mode->hdisplay); + + *pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | + bits << PFIT_VERT_SCALE_SHIFT); + *pfit_control |= (PFIT_ENABLE | + 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); + } +} + void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, struct intel_crtc_config *pipe_config, int fitting_mode) @@ -196,67 +275,11 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, break; case DRM_MODE_SCALE_ASPECT: /* Scale but preserve the aspect ratio */ - if (INTEL_INFO(dev)->gen >= 4) { - u32 scaled_width = adjusted_mode->hdisplay * - pipe_config->pipe_src_h; - u32 scaled_height = pipe_config->pipe_src_w * - adjusted_mode->vdisplay; - - /* 965+ is easy, it does everything in hw */ - if (scaled_width > scaled_height) - pfit_control |= PFIT_ENABLE | - PFIT_SCALING_PILLAR; - else if (scaled_width < scaled_height) - pfit_control |= PFIT_ENABLE | - PFIT_SCALING_LETTER; - else if (adjusted_mode->hdisplay != pipe_config->pipe_src_w) - pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO; - } else { - u32 scaled_width = adjusted_mode->hdisplay * - pipe_config->pipe_src_h; - u32 scaled_height = pipe_config->pipe_src_w * - adjusted_mode->vdisplay; - /* - * For earlier chips we have to calculate the scaling - * ratio by hand and program it into the - * PFIT_PGM_RATIO register - */ - if (scaled_width > scaled_height) { /* pillar */ - centre_horizontally(adjusted_mode, - scaled_height / - pipe_config->pipe_src_h); - - border = LVDS_BORDER_ENABLE; - if (pipe_config->pipe_src_h != adjusted_mode->vdisplay) { - u32 bits = panel_fitter_scaling(pipe_config->pipe_src_h, adjusted_mode->vdisplay); - pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | - bits << PFIT_VERT_SCALE_SHIFT); - pfit_control |= (PFIT_ENABLE | - VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); - } - } else if (scaled_width < scaled_height) { /* letter */ - centre_vertically(adjusted_mode, - scaled_width / - pipe_config->pipe_src_w); - - border = LVDS_BORDER_ENABLE; - if (pipe_config->pipe_src_w != adjusted_mode->hdisplay) { - u32 bits = panel_fitter_scaling(pipe_config->pipe_src_w, adjusted_mode->hdisplay); - pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | - bits << PFIT_VERT_SCALE_SHIFT); - pfit_control |= (PFIT_ENABLE | - 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); - } - } + if (INTEL_INFO(dev)->gen >= 4) + i965_scale_aspect(pipe_config, &pfit_control); + else + i9xx_scale_aspect(pipe_config, &pfit_control, + &pfit_pgm_ratios, &border); break; case DRM_MODE_SCALE_FULLSCREEN: /* @@ -438,7 +461,8 @@ static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level) I915_WRITE(BLC_PWM_CPU_CTL, val | level); } -static void intel_panel_actually_set_backlight(struct drm_device *dev, u32 level) +static void intel_panel_actually_set_backlight(struct drm_device *dev, + u32 level) { struct drm_i915_private *dev_priv = dev->dev_private; u32 tmp; -- cgit From 912e8b12eedb41c69717deda2b2a08e7292945fc Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Sep 2013 17:19:45 +0300 Subject: drm/i915: register backlight device also when backlight class is a module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ville and I were wondering why his laptop was missing the intel_backlight sysfs interface. Turns out we never register it when CONFIG_BACKLIGHT_CLASS_DEVICE=m. This has been broken ever since the i915 native backlight interface was added. CC: Ville Syrjälä Signed-off-by: Jani Nikula Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/intel_panel.c') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index e36149d578fa..0aaeb8b6d6ed 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -658,7 +658,7 @@ intel_panel_detect(struct drm_device *dev) } } -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE +#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) static int intel_panel_update_status(struct backlight_device *bd) { struct drm_device *dev = bl_get_data(bd); -- cgit