diff options
author | Adam Jackson <ajax@redhat.com> | 2010-04-12 11:38:44 -0400 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2010-04-18 16:57:44 -0700 |
commit | 77ffb5979de59efd1a6b280b10d647b09285bee0 (patch) | |
tree | a3a2293c9e944900c59d9b56b778d90c4f766f99 /drivers/gpu/drm | |
parent | 7f8a85698f5c8a981641ec0bdf9926768786db9d (diff) |
drm/i915/pch: Use minimal number of FDI lanes (v2)
This should be a small power savings. Tested on Lenovo T410 (Ironlake), LVDS
VGA and DisplayPort, up to 1920x1200R.
v2: Add Sandybridge support, fix obvious math error.
Acked-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 26 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 1 |
2 files changed, 21 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9fdea06f3e7..58668c407f6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1507,7 +1507,8 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) /* enable CPU FDI TX and PCH FDI RX */ temp = I915_READ(fdi_tx_reg); temp |= FDI_TX_ENABLE; - temp |= FDI_DP_PORT_WIDTH_X4; /* default */ + temp &= ~(7 << 19); + temp |= (intel_crtc->fdi_lanes - 1) << 19; temp &= ~FDI_LINK_TRAIN_NONE; temp |= FDI_LINK_TRAIN_PATTERN_1; I915_WRITE(fdi_tx_reg, temp); @@ -1607,7 +1608,8 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc) /* enable CPU FDI TX and PCH FDI RX */ temp = I915_READ(fdi_tx_reg); temp |= FDI_TX_ENABLE; - temp |= FDI_DP_PORT_WIDTH_X4; /* default */ + temp &= ~(7 << 19); + temp |= (intel_crtc->fdi_lanes - 1) << 19; temp &= ~FDI_LINK_TRAIN_NONE; temp |= FDI_LINK_TRAIN_PATTERN_1; temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; @@ -1769,8 +1771,9 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) */ temp &= ~(0x7 << 16); temp |= (pipe_bpc << 11); - I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE | - FDI_DP_PORT_WIDTH_X4); /* default 4 lanes */ + temp &= ~(7 << 19); + temp |= (intel_crtc->fdi_lanes - 1) << 19; + I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE); I915_READ(fdi_rx_reg); udelay(200); @@ -3368,7 +3371,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, /* FDI link */ if (HAS_PCH_SPLIT(dev)) { - int lane, link_bw, bpp; + int lane = 0, link_bw, bpp; /* eDP doesn't require FDI link, so just set DP M/N according to current link config */ if (is_edp) { @@ -3382,7 +3385,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, target_clock = mode->clock; else target_clock = adjusted_mode->clock; - lane = 4; link_bw = 270000; } @@ -3434,6 +3436,18 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, bpp = 24; } + if (!lane) { + /* + * Account for spread spectrum to avoid + * oversubscribing the link. Max center spread + * is 2.5%; use 5% for safety's sake. + */ + u32 bps = target_clock * bpp * 21 / 20; + lane = bps / (link_bw * 8) + 1; + } + + intel_crtc->fdi_lanes = lane; + ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n); } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 8a64c154b42..1ee4717f431 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -152,6 +152,7 @@ struct intel_crtc { bool lowfreq_avail; struct intel_overlay *overlay; struct intel_unpin_work *unpin_work; + int fdi_lanes; }; #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) |