* [PATCH] drm/i915: Enable aspect/centering panel fitting for Ironlake. @ 2010-08-04 14:04 Chris Wilson 2010-08-05 1:11 ` Zhenyu Wang 0 siblings, 1 reply; 8+ messages in thread From: Chris Wilson @ 2010-08-04 14:04 UTC (permalink / raw) To: intel-gfx Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> --- drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/intel_display.c | 16 +++---- drivers/gpu/drm/i915/intel_lvds.c | 70 ++++++++++++++++++++++++++++++++-- 3 files changed, 75 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ad8dab5..6da15d8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -610,6 +610,8 @@ typedef struct drm_i915_private { struct sdvo_device_mapping sdvo_mappings[2]; /* indicate whether the LVDS_BORDER should be enabled or not */ unsigned int lvds_border_bits; + /* Panel fitter placement and size for Ironlake+ */ + u32 pch_pf_pos, pch_pf_size; struct drm_crtc *plane_to_crtc_mapping[2]; struct drm_crtc *pipe_to_crtc_mapping[2]; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 07f893f..9b5fab4 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1914,15 +1914,13 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) /* Enable panel fitting for LVDS */ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) || HAS_eDP || intel_pch_has_edp(crtc)) { - temp = I915_READ(pf_ctl_reg); - I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); - - /* currently full aspect */ - I915_WRITE(pf_win_pos, 0); - - I915_WRITE(pf_win_size, - (dev_priv->panel_fixed_mode->hdisplay << 16) | - (dev_priv->panel_fixed_mode->vdisplay)); + if (dev_priv->pch_pf_size) { + temp = I915_READ(pf_ctl_reg); + I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); + I915_WRITE(pf_win_pos, dev_priv->pch_pf_pos); + I915_WRITE(pf_win_size, dev_priv->pch_pf_size); + } else + I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); } /* Enable CPU pipe */ diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 312ac30..abbe32e 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -218,6 +218,68 @@ static inline u32 panel_fitter_scaling(u32 source, u32 target) return (FACTOR * ratio + FACTOR/2) / FACTOR; } +static bool +intel_pch_lvds_mode_fixup(struct intel_lvds *intel_lvds, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct drm_device *dev = intel_lvds->base.enc.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode; + int x, y, width, height; + + x = y = width = height = 0; + + /* Native modes don't need fitting */ + if (adjusted_mode->hdisplay == mode->hdisplay && + adjusted_mode->vdisplay == mode->vdisplay) + goto done; + + switch (intel_lvds->fitting_mode) { + case DRM_MODE_SCALE_CENTER: + width = mode->hdisplay; + height = mode->vdisplay; + x = (fixed_mode->hdisplay - width + 1)/2; + y = (fixed_mode->vdisplay - height + 1)/2; + break; + + case DRM_MODE_SCALE_ASPECT: + /* Scale but preserve the aspect ratio */ + { + u32 scaled_width = fixed_mode->hdisplay * mode->vdisplay; + u32 scaled_height = mode->hdisplay * fixed_mode->vdisplay; + if (scaled_width > scaled_height) { /* pillar */ + width = scaled_height / mode->vdisplay; + x = (fixed_mode->hdisplay - width + 1) / 2; + y = 0; + height = fixed_mode->vdisplay; + } else if (scaled_width < scaled_height) { /* letter */ + height = scaled_width / mode->hdisplay; + y = (fixed_mode->vdisplay - height + 1) / 2; + x = 0; + width = fixed_mode->hdisplay; + } else { + x = y = 0; + width = fixed_mode->hdisplay; + height = fixed_mode->vdisplay; + } + } + break; + + default: + case DRM_MODE_SCALE_FULLSCREEN: + x = y = 0; + width = fixed_mode->hdisplay; + height = fixed_mode->vdisplay; + break; + } + +done: + dev_priv->pch_pf_pos = (x << 16) | y; + dev_priv->pch_pf_size = (width << 16) | height; + return true; +} + static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) @@ -267,6 +329,10 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, adjusted_mode->clock = dev_priv->panel_fixed_mode->clock; drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); + if (HAS_PCH_SPLIT(dev)) + return intel_pch_lvds_mode_fixup(intel_lvds, + mode, adjusted_mode); + /* Make sure pre-965s set dither correctly */ if (!IS_I965G(dev)) { if (dev_priv->panel_wants_dither || dev_priv->lvds_dither) @@ -278,10 +344,6 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, adjusted_mode->vdisplay == mode->vdisplay) goto out; - /* full screen scale for now */ - if (HAS_PCH_SPLIT(dev)) - goto out; - /* 965+ wants fuzzy fitting */ if (IS_I965G(dev)) pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | -- 1.7.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] drm/i915: Enable aspect/centering panel fitting for Ironlake. 2010-08-04 14:04 [PATCH] drm/i915: Enable aspect/centering panel fitting for Ironlake Chris Wilson @ 2010-08-05 1:11 ` Zhenyu Wang 2010-08-05 8:05 ` Chris Wilson 0 siblings, 1 reply; 8+ messages in thread From: Zhenyu Wang @ 2010-08-05 1:11 UTC (permalink / raw) To: Chris Wilson; +Cc: intel-gfx [-- Attachment #1.1: Type: text/plain, Size: 2232 bytes --] On 2010.08.04 15:04:01 +0100, Chris Wilson wrote: > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> > --- > drivers/gpu/drm/i915/i915_drv.h | 2 + > drivers/gpu/drm/i915/intel_display.c | 16 +++---- > drivers/gpu/drm/i915/intel_lvds.c | 70 ++++++++++++++++++++++++++++++++-- > 3 files changed, 75 insertions(+), 13 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index ad8dab5..6da15d8 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -610,6 +610,8 @@ typedef struct drm_i915_private { > struct sdvo_device_mapping sdvo_mappings[2]; > /* indicate whether the LVDS_BORDER should be enabled or not */ > unsigned int lvds_border_bits; > + /* Panel fitter placement and size for Ironlake+ */ > + u32 pch_pf_pos, pch_pf_size; > > struct drm_crtc *plane_to_crtc_mapping[2]; > struct drm_crtc *pipe_to_crtc_mapping[2]; > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > index 07f893f..9b5fab4 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -1914,15 +1914,13 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) > /* Enable panel fitting for LVDS */ > if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) > || HAS_eDP || intel_pch_has_edp(crtc)) { > - temp = I915_READ(pf_ctl_reg); > - I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); > - > - /* currently full aspect */ > - I915_WRITE(pf_win_pos, 0); > - > - I915_WRITE(pf_win_size, > - (dev_priv->panel_fixed_mode->hdisplay << 16) | > - (dev_priv->panel_fixed_mode->vdisplay)); > + if (dev_priv->pch_pf_size) { > + temp = I915_READ(pf_ctl_reg); > + I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); > + I915_WRITE(pf_win_pos, dev_priv->pch_pf_pos); > + I915_WRITE(pf_win_size, dev_priv->pch_pf_size); > + } else > + I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); > } So this breaks panel fitting setting on eDP... -- Open Source Technology Center, Intel ltd. $gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827 [-- Attachment #1.2: Digital signature --] [-- Type: application/pgp-signature, Size: 198 bytes --] [-- Attachment #2: Type: text/plain, Size: 159 bytes --] _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] drm/i915: Enable aspect/centering panel fitting for Ironlake. 2010-08-05 1:11 ` Zhenyu Wang @ 2010-08-05 8:05 ` Chris Wilson 2010-08-05 9:01 ` Zhenyu Wang 0 siblings, 1 reply; 8+ messages in thread From: Chris Wilson @ 2010-08-05 8:05 UTC (permalink / raw) To: Zhenyu Wang; +Cc: intel-gfx On Thu, 5 Aug 2010 09:11:26 +0800, Zhenyu Wang <zhenyuw@linux.intel.com> wrote: > On 2010.08.04 15:04:01 +0100, Chris Wilson wrote: > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > > index 07f893f..9b5fab4 100644 > > --- a/drivers/gpu/drm/i915/intel_display.c > > +++ b/drivers/gpu/drm/i915/intel_display.c > > @@ -1914,15 +1914,13 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) > > /* Enable panel fitting for LVDS */ > > if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) > > || HAS_eDP || intel_pch_has_edp(crtc)) { > > - temp = I915_READ(pf_ctl_reg); > > - I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); > > - > > - /* currently full aspect */ > > - I915_WRITE(pf_win_pos, 0); > > - > > - I915_WRITE(pf_win_size, > > - (dev_priv->panel_fixed_mode->hdisplay << 16) | > > - (dev_priv->panel_fixed_mode->vdisplay)); > > + if (dev_priv->pch_pf_size) { > > + temp = I915_READ(pf_ctl_reg); > > + I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); > > + I915_WRITE(pf_win_pos, dev_priv->pch_pf_pos); > > + I915_WRITE(pf_win_size, dev_priv->pch_pf_size); > > + } else > > + I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); > > } > > So this breaks panel fitting setting on eDP... Please illuminate the poor ignorant fool (that's me) what the requirements for eDP are. Even better in patch form. ;-) Does eDP require panel fitting always? -- Chris Wilson, Intel Open Source Technology Centre ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] drm/i915: Enable aspect/centering panel fitting for Ironlake. 2010-08-05 8:05 ` Chris Wilson @ 2010-08-05 9:01 ` Zhenyu Wang 2010-08-05 9:31 ` Chris Wilson 2010-08-05 10:25 ` Chris Wilson 0 siblings, 2 replies; 8+ messages in thread From: Zhenyu Wang @ 2010-08-05 9:01 UTC (permalink / raw) To: Chris Wilson; +Cc: intel-gfx [-- Attachment #1.1: Type: text/plain, Size: 526 bytes --] On 2010.08.05 09:05:15 +0100, Chris Wilson wrote: > > Please illuminate the poor ignorant fool (that's me) what the requirements > for eDP are. Even better in patch form. ;-) > > Does eDP require panel fitting always? yeah, you can see recently added panel fitting support for eDP, it should be same as LVDS actually. I think if you duplicate intel_pch_lvds_mode_fixup() for eDP, that should also work. ;) -- Open Source Technology Center, Intel ltd. $gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827 [-- Attachment #1.2: Digital signature --] [-- Type: application/pgp-signature, Size: 198 bytes --] [-- Attachment #2: Type: text/plain, Size: 159 bytes --] _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] drm/i915: Enable aspect/centering panel fitting for Ironlake. 2010-08-05 9:01 ` Zhenyu Wang @ 2010-08-05 9:31 ` Chris Wilson 2010-08-05 10:25 ` Chris Wilson 1 sibling, 0 replies; 8+ messages in thread From: Chris Wilson @ 2010-08-05 9:31 UTC (permalink / raw) To: Zhenyu Wang; +Cc: intel-gfx On Thu, 5 Aug 2010 17:01:07 +0800, Zhenyu Wang <zhenyuw@linux.intel.com> wrote: > yeah, you can see recently added panel fitting support for eDP, it > should be same as LVDS actually. I think if you duplicate > intel_pch_lvds_mode_fixup() for eDP, that should also work. ;) Ah, I'd missed that eDP panel fitting support had been merged. Thanks. I'll take another look and see which bits can be reused. -- Chris Wilson, Intel Open Source Technology Centre ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] drm/i915: Enable aspect/centering panel fitting for Ironlake. 2010-08-05 9:01 ` Zhenyu Wang 2010-08-05 9:31 ` Chris Wilson @ 2010-08-05 10:25 ` Chris Wilson 2010-08-06 1:00 ` Zhenyu Wang 1 sibling, 1 reply; 8+ messages in thread From: Chris Wilson @ 2010-08-05 10:25 UTC (permalink / raw) To: intel-gfx [-- Attachment #1: Type: text/plain, Size: 11373 bytes --] v2: Hook in DP paths to keep FULLSCREEN panel fitting on eDP. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Zhenyu Wang <zhenyuw@linux.intel.com> --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/intel_display.c | 16 ++--- drivers/gpu/drm/i915/intel_dp.c | 20 ++----- drivers/gpu/drm/i915/intel_drv.h | 7 ++ drivers/gpu/drm/i915/intel_lvds.c | 32 +++------- drivers/gpu/drm/i915/intel_panel.c | 111 ++++++++++++++++++++++++++++++++++ 7 files changed, 143 insertions(+), 46 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_panel.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 384fd45..5c8e534 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -19,6 +19,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ intel_hdmi.o \ intel_sdvo.o \ intel_modes.o \ + intel_panel.o \ intel_i2c.o \ intel_fb.o \ intel_tv.o \ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ad8dab5..6da15d8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -610,6 +610,8 @@ typedef struct drm_i915_private { struct sdvo_device_mapping sdvo_mappings[2]; /* indicate whether the LVDS_BORDER should be enabled or not */ unsigned int lvds_border_bits; + /* Panel fitter placement and size for Ironlake+ */ + u32 pch_pf_pos, pch_pf_size; struct drm_crtc *plane_to_crtc_mapping[2]; struct drm_crtc *pipe_to_crtc_mapping[2]; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 07f893f..9b5fab4 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1914,15 +1914,13 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) /* Enable panel fitting for LVDS */ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) || HAS_eDP || intel_pch_has_edp(crtc)) { - temp = I915_READ(pf_ctl_reg); - I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); - - /* currently full aspect */ - I915_WRITE(pf_win_pos, 0); - - I915_WRITE(pf_win_size, - (dev_priv->panel_fixed_mode->hdisplay << 16) | - (dev_priv->panel_fixed_mode->vdisplay)); + if (dev_priv->pch_pf_size) { + temp = I915_READ(pf_ctl_reg); + I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); + I915_WRITE(pf_win_pos, dev_priv->pch_pf_pos); + I915_WRITE(pf_win_size, dev_priv->pch_pf_size); + } else + I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); } /* Enable CPU pipe */ diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c4c5868..cee5d9c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -523,21 +523,9 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) && dev_priv->panel_fixed_mode) { - struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode; - - adjusted_mode->hdisplay = fixed_mode->hdisplay; - adjusted_mode->hsync_start = fixed_mode->hsync_start; - adjusted_mode->hsync_end = fixed_mode->hsync_end; - adjusted_mode->htotal = fixed_mode->htotal; - - adjusted_mode->vdisplay = fixed_mode->vdisplay; - adjusted_mode->vsync_start = fixed_mode->vsync_start; - adjusted_mode->vsync_end = fixed_mode->vsync_end; - adjusted_mode->vtotal = fixed_mode->vtotal; - - adjusted_mode->clock = fixed_mode->clock; - drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); - + intel_fixed_panel_mode(dev_priv->panel_fixed_mode, adjusted_mode); + intel_pch_panel_fitting(dev, DRM_MODE_SCALE_FULLSCREEN, + mode, adjusted_mode); /* * the mode->clock is used to calculate the Data&Link M/N * of the pipe. For the eDP the fixed clock should be used. @@ -572,8 +560,10 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, "count %d clock %d\n", intel_dp->link_bw, intel_dp->lane_count, adjusted_mode->clock); + return true; } + return false; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a44b8cb..c552b06 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -186,6 +186,13 @@ extern bool intel_dpd_is_edp(struct drm_device *dev); extern void intel_edp_link_config (struct intel_encoder *, int *, int *); +extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, + struct drm_display_mode *adjusted_mode); +extern void intel_pch_panel_fitting(struct drm_device *dev, + int fitting_mode, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); + extern int intel_panel_fitter_pipe (struct drm_device *dev); extern void intel_crtc_load_lut(struct drm_crtc *crtc); extern void intel_encoder_prepare (struct drm_encoder *encoder); diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 312ac30..cb5821e 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -246,26 +246,20 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, /* If we don't have a panel mode, there is nothing we can do */ if (dev_priv->panel_fixed_mode == NULL) return true; + /* * We have timings from the BIOS for the panel, put them in * to the adjusted mode. The CRTC will be set up for this mode, * with the panel scaling set up to source from the H/VDisplay * of the original mode. */ - adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay; - adjusted_mode->hsync_start = - dev_priv->panel_fixed_mode->hsync_start; - adjusted_mode->hsync_end = - dev_priv->panel_fixed_mode->hsync_end; - adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal; - adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay; - adjusted_mode->vsync_start = - dev_priv->panel_fixed_mode->vsync_start; - adjusted_mode->vsync_end = - dev_priv->panel_fixed_mode->vsync_end; - adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal; - adjusted_mode->clock = dev_priv->panel_fixed_mode->clock; - drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); + intel_fixed_panel_mode(dev_priv->panel_fixed_mode, adjusted_mode); + + if (HAS_PCH_SPLIT(dev)) { + intel_pch_panel_fitting(dev, intel_lvds->fitting_mode, + mode, adjusted_mode); + return true; + } /* Make sure pre-965s set dither correctly */ if (!IS_I965G(dev)) { @@ -278,10 +272,6 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, adjusted_mode->vdisplay == mode->vdisplay) goto out; - /* full screen scale for now */ - if (HAS_PCH_SPLIT(dev)) - goto out; - /* 965+ wants fuzzy fitting */ if (IS_I965G(dev)) pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | @@ -293,10 +283,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, * to register description and PRM. * Change the value here to see the borders for debugging */ - if (!HAS_PCH_SPLIT(dev)) { - I915_WRITE(BCLRPAT_A, 0); - I915_WRITE(BCLRPAT_B, 0); - } + I915_WRITE(BCLRPAT_A, 0); + I915_WRITE(BCLRPAT_B, 0); switch (intel_lvds->fitting_mode) { case DRM_MODE_SCALE_CENTER: diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c new file mode 100644 index 0000000..e7f5299 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -0,0 +1,111 @@ +/* + * Copyright © 2006-2010 Intel Corporation + * Copyright (c) 2006 Dave Airlie <airlied@linux.ie> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Eric Anholt <eric@anholt.net> + * Dave Airlie <airlied@linux.ie> + * Jesse Barnes <jesse.barnes@intel.com> + * Chris Wilson <chris@chris-wilson.co.uk> + */ + +#include "intel_drv.h" + +void +intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, + struct drm_display_mode *adjusted_mode) +{ + adjusted_mode->hdisplay = fixed_mode->hdisplay; + adjusted_mode->hsync_start = fixed_mode->hsync_start; + adjusted_mode->hsync_end = fixed_mode->hsync_end; + adjusted_mode->htotal = fixed_mode->htotal; + + adjusted_mode->vdisplay = fixed_mode->vdisplay; + adjusted_mode->vsync_start = fixed_mode->vsync_start; + adjusted_mode->vsync_end = fixed_mode->vsync_end; + adjusted_mode->vtotal = fixed_mode->vtotal; + + adjusted_mode->clock = fixed_mode->clock; + + drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); +} + +/* adjusted_mode has been preset to be the panel's fixed mode */ +void +intel_pch_panel_fitting(struct drm_device *dev, + int fitting_mode, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int x, y, width, height; + + x = y = width = height = 0; + + /* Native modes don't need fitting */ + if (adjusted_mode->hdisplay == mode->hdisplay && + adjusted_mode->vdisplay == mode->vdisplay) + goto done; + + switch (fitting_mode) { + case DRM_MODE_SCALE_CENTER: + width = mode->hdisplay; + height = mode->vdisplay; + x = (adjusted_mode->hdisplay - width + 1)/2; + y = (adjusted_mode->vdisplay - height + 1)/2; + break; + + 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; + if (scaled_width > scaled_height) { /* pillar */ + width = scaled_height / mode->vdisplay; + 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; + y = (adjusted_mode->vdisplay - height + 1) / 2; + x = 0; + width = adjusted_mode->hdisplay; + } else { + x = y = 0; + width = adjusted_mode->hdisplay; + height = adjusted_mode->vdisplay; + } + } + break; + + default: + case DRM_MODE_SCALE_FULLSCREEN: + x = y = 0; + width = adjusted_mode->hdisplay; + height = adjusted_mode->vdisplay; + break; + } + +done: + dev_priv->pch_pf_pos = (x << 16) | y; + dev_priv->pch_pf_size = (width << 16) | height; +} -- 1.7.1 [-- Attachment #2: Type: text/plain, Size: 159 bytes --] _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] drm/i915: Enable aspect/centering panel fitting for Ironlake. 2010-08-05 10:25 ` Chris Wilson @ 2010-08-06 1:00 ` Zhenyu Wang 0 siblings, 0 replies; 8+ messages in thread From: Zhenyu Wang @ 2010-08-06 1:00 UTC (permalink / raw) To: Chris Wilson; +Cc: intel-gfx [-- Attachment #1.1: Type: text/plain, Size: 303 bytes --] On 2010.08.05 11:25:26 +0100, Chris Wilson wrote: > v2: Hook in DP paths to keep FULLSCREEN panel fitting on eDP. > Looks fine to me. Reviewed-by: Zhenyu Wang <zhenyuw@linux.intel.com> -- Open Source Technology Center, Intel ltd. $gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827 [-- Attachment #1.2: Digital signature --] [-- Type: application/pgp-signature, Size: 198 bytes --] [-- Attachment #2: Type: text/plain, Size: 159 bytes --] _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] drm/i915: Enable aspect/centering panel fitting for Ironlake. @ 2010-07-21 17:41 Chris Wilson 0 siblings, 0 replies; 8+ messages in thread From: Chris Wilson @ 2010-07-21 17:41 UTC (permalink / raw) To: intel-gfx Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> --- drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/intel_display.c | 16 +++---- drivers/gpu/drm/i915/intel_lvds.c | 70 ++++++++++++++++++++++++++++++++-- 3 files changed, 75 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 57d24f8..0e7bf85 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -599,6 +599,8 @@ typedef struct drm_i915_private { struct sdvo_device_mapping sdvo_mappings[2]; /* indicate whether the LVDS_BORDER should be enabled or not */ unsigned int lvds_border_bits; + /* Panel fitter placement and size for Ironlake+ */ + u32 pch_pf_pos, pch_pf_size; struct drm_crtc *plane_to_crtc_mapping[2]; struct drm_crtc *pipe_to_crtc_mapping[2]; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d56184c..d476752 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1918,15 +1918,13 @@ static int ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) /* Enable panel fitting for LVDS */ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { - temp = I915_READ(pf_ctl_reg); - I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); - - /* currently full aspect */ - I915_WRITE(pf_win_pos, 0); - - I915_WRITE(pf_win_size, - (dev_priv->panel_fixed_mode->hdisplay << 16) | - (dev_priv->panel_fixed_mode->vdisplay)); + if (dev_priv->pch_pf_size) { + temp = I915_READ(pf_ctl_reg); + I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); + I915_WRITE(pf_win_pos, dev_priv->pch_pf_pos); + I915_WRITE(pf_win_size, dev_priv->pch_pf_size); + } else + I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); } /* Enable CPU pipe */ diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 6b399e0..56d233d 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -215,6 +215,68 @@ static inline u32 panel_fitter_scaling(u32 source, u32 target) return (FACTOR * ratio + FACTOR/2) / FACTOR; } +static bool +intel_pch_lvds_mode_fixup(struct intel_lvds *intel_lvds, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct drm_device *dev = intel_lvds->base.enc.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode; + int x, y, width, height; + + x = y = width = height = 0; + + /* Native modes don't need fitting */ + if (adjusted_mode->hdisplay == mode->hdisplay && + adjusted_mode->vdisplay == mode->vdisplay) + goto done; + + switch (intel_lvds->fitting_mode) { + case DRM_MODE_SCALE_CENTER: + width = mode->hdisplay; + height = mode->vdisplay; + x = (fixed_mode->hdisplay - width + 1)/2; + y = (fixed_mode->vdisplay - height + 1)/2; + break; + + case DRM_MODE_SCALE_ASPECT: + /* Scale but preserve the aspect ratio */ + { + u32 scaled_width = fixed_mode->hdisplay * mode->vdisplay; + u32 scaled_height = mode->hdisplay * fixed_mode->vdisplay; + if (scaled_width > scaled_height) { /* pillar */ + width = scaled_height / mode->vdisplay; + x = (fixed_mode->hdisplay - width + 1) / 2; + y = 0; + height = fixed_mode->vdisplay; + } else if (scaled_width < scaled_height) { /* letter */ + height = scaled_width / mode->hdisplay; + y = (fixed_mode->vdisplay - height + 1) / 2; + x = 0; + width = fixed_mode->hdisplay; + } else { + x = y = 0; + width = fixed_mode->hdisplay; + height = fixed_mode->vdisplay; + } + } + break; + + default: + case DRM_MODE_SCALE_FULLSCREEN: + x = y = 0; + width = fixed_mode->hdisplay; + height = fixed_mode->vdisplay; + break; + } + +done: + dev_priv->pch_pf_pos = (x << 16) | y; + dev_priv->pch_pf_size = (width << 16) | height; + return true; +} + static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) @@ -264,6 +326,10 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, adjusted_mode->clock = dev_priv->panel_fixed_mode->clock; drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); + if (HAS_PCH_SPLIT(dev)) + return intel_pch_lvds_mode_fixup(intel_lvds, + mode, adjusted_mode); + /* Make sure pre-965s set dither correctly */ if (!IS_I965G(dev)) { if (dev_priv->panel_wants_dither || dev_priv->lvds_dither) @@ -275,10 +341,6 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, adjusted_mode->vdisplay == mode->vdisplay) goto out; - /* full screen scale for now */ - if (HAS_PCH_SPLIT(dev)) - goto out; - /* 965+ wants fuzzy fitting */ if (IS_I965G(dev)) pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | -- 1.7.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-08-06 1:01 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-08-04 14:04 [PATCH] drm/i915: Enable aspect/centering panel fitting for Ironlake Chris Wilson 2010-08-05 1:11 ` Zhenyu Wang 2010-08-05 8:05 ` Chris Wilson 2010-08-05 9:01 ` Zhenyu Wang 2010-08-05 9:31 ` Chris Wilson 2010-08-05 10:25 ` Chris Wilson 2010-08-06 1:00 ` Zhenyu Wang -- strict thread matches above, loose matches on Subject: below -- 2010-07-21 17:41 Chris Wilson
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.