diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2011-08-03 15:59:20 -0400 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2011-08-09 13:26:24 -0400 |
commit | 13d83a672e9bbd52ae82c2f611dfd845a957e8b4 (patch) | |
tree | ba82ed032944fb58e3c721ac3a5d3031e5d4a8f5 /drivers/gpu | |
parent | da64c6fc4aba6f02aa800db72411f459a9f86809 (diff) |
drm/i915: split out PCH refclk update code
We ought to be calling this from our DPMS routines as well as global
state may change and we need to enable/disable clocks. So split out the
code in preparation for further changes.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 119 |
1 files changed, 76 insertions, 43 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f6f18c72068f..ee1d701317f7 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -5097,6 +5097,81 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
5097 | return ret; | 5097 | return ret; |
5098 | } | 5098 | } |
5099 | 5099 | ||
5100 | static void ironlake_update_pch_refclk(struct drm_device *dev) | ||
5101 | { | ||
5102 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5103 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
5104 | struct drm_crtc *crtc; | ||
5105 | struct intel_encoder *encoder; | ||
5106 | struct intel_encoder *has_edp_encoder = NULL; | ||
5107 | u32 temp; | ||
5108 | bool has_lvds = false; | ||
5109 | |||
5110 | /* We need to take the global config into account */ | ||
5111 | list_for_each_entry(crtc, &mode_config->crtc_list, head) { | ||
5112 | if (!crtc->enabled) | ||
5113 | continue; | ||
5114 | |||
5115 | list_for_each_entry(encoder, &mode_config->encoder_list, | ||
5116 | base.head) { | ||
5117 | if (encoder->base.crtc != crtc) | ||
5118 | continue; | ||
5119 | |||
5120 | switch (encoder->type) { | ||
5121 | case INTEL_OUTPUT_LVDS: | ||
5122 | has_lvds = true; | ||
5123 | case INTEL_OUTPUT_EDP: | ||
5124 | has_edp_encoder = encoder; | ||
5125 | break; | ||
5126 | } | ||
5127 | } | ||
5128 | } | ||
5129 | |||
5130 | /* Ironlake: try to setup display ref clock before DPLL | ||
5131 | * enabling. This is only under driver's control after | ||
5132 | * PCH B stepping, previous chipset stepping should be | ||
5133 | * ignoring this setting. | ||
5134 | */ | ||
5135 | temp = I915_READ(PCH_DREF_CONTROL); | ||
5136 | /* Always enable nonspread source */ | ||
5137 | temp &= ~DREF_NONSPREAD_SOURCE_MASK; | ||
5138 | temp |= DREF_NONSPREAD_SOURCE_ENABLE; | ||
5139 | temp &= ~DREF_SSC_SOURCE_MASK; | ||
5140 | temp |= DREF_SSC_SOURCE_ENABLE; | ||
5141 | I915_WRITE(PCH_DREF_CONTROL, temp); | ||
5142 | |||
5143 | POSTING_READ(PCH_DREF_CONTROL); | ||
5144 | udelay(200); | ||
5145 | |||
5146 | if (has_edp_encoder) { | ||
5147 | if (intel_panel_use_ssc(dev_priv)) { | ||
5148 | temp |= DREF_SSC1_ENABLE; | ||
5149 | I915_WRITE(PCH_DREF_CONTROL, temp); | ||
5150 | |||
5151 | POSTING_READ(PCH_DREF_CONTROL); | ||
5152 | udelay(200); | ||
5153 | } | ||
5154 | temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; | ||
5155 | |||
5156 | /* Enable CPU source on CPU attached eDP */ | ||
5157 | if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) { | ||
5158 | if (intel_panel_use_ssc(dev_priv)) | ||
5159 | temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; | ||
5160 | else | ||
5161 | temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; | ||
5162 | } else { | ||
5163 | /* Enable SSC on PCH eDP if needed */ | ||
5164 | if (intel_panel_use_ssc(dev_priv)) { | ||
5165 | DRM_ERROR("enabling SSC on PCH\n"); | ||
5166 | temp |= DREF_SUPERSPREAD_SOURCE_ENABLE; | ||
5167 | } | ||
5168 | } | ||
5169 | I915_WRITE(PCH_DREF_CONTROL, temp); | ||
5170 | POSTING_READ(PCH_DREF_CONTROL); | ||
5171 | udelay(200); | ||
5172 | } | ||
5173 | } | ||
5174 | |||
5100 | static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | 5175 | static int ironlake_crtc_mode_set(struct drm_crtc *crtc, |
5101 | struct drm_display_mode *mode, | 5176 | struct drm_display_mode *mode, |
5102 | struct drm_display_mode *adjusted_mode, | 5177 | struct drm_display_mode *adjusted_mode, |
@@ -5292,49 +5367,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
5292 | ironlake_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw, | 5367 | ironlake_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw, |
5293 | &m_n); | 5368 | &m_n); |
5294 | 5369 | ||
5295 | /* Ironlake: try to setup display ref clock before DPLL | 5370 | ironlake_update_pch_refclk(dev); |
5296 | * enabling. This is only under driver's control after | ||
5297 | * PCH B stepping, previous chipset stepping should be | ||
5298 | * ignoring this setting. | ||
5299 | */ | ||
5300 | temp = I915_READ(PCH_DREF_CONTROL); | ||
5301 | /* Always enable nonspread source */ | ||
5302 | temp &= ~DREF_NONSPREAD_SOURCE_MASK; | ||
5303 | temp |= DREF_NONSPREAD_SOURCE_ENABLE; | ||
5304 | temp &= ~DREF_SSC_SOURCE_MASK; | ||
5305 | temp |= DREF_SSC_SOURCE_ENABLE; | ||
5306 | I915_WRITE(PCH_DREF_CONTROL, temp); | ||
5307 | |||
5308 | POSTING_READ(PCH_DREF_CONTROL); | ||
5309 | udelay(200); | ||
5310 | |||
5311 | if (has_edp_encoder) { | ||
5312 | if (intel_panel_use_ssc(dev_priv)) { | ||
5313 | temp |= DREF_SSC1_ENABLE; | ||
5314 | I915_WRITE(PCH_DREF_CONTROL, temp); | ||
5315 | |||
5316 | POSTING_READ(PCH_DREF_CONTROL); | ||
5317 | udelay(200); | ||
5318 | } | ||
5319 | temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; | ||
5320 | |||
5321 | /* Enable CPU source on CPU attached eDP */ | ||
5322 | if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) { | ||
5323 | if (intel_panel_use_ssc(dev_priv)) | ||
5324 | temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; | ||
5325 | else | ||
5326 | temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; | ||
5327 | } else { | ||
5328 | /* Enable SSC on PCH eDP if needed */ | ||
5329 | if (intel_panel_use_ssc(dev_priv)) { | ||
5330 | DRM_ERROR("enabling SSC on PCH\n"); | ||
5331 | temp |= DREF_SUPERSPREAD_SOURCE_ENABLE; | ||
5332 | } | ||
5333 | } | ||
5334 | I915_WRITE(PCH_DREF_CONTROL, temp); | ||
5335 | POSTING_READ(PCH_DREF_CONTROL); | ||
5336 | udelay(200); | ||
5337 | } | ||
5338 | 5371 | ||
5339 | fp = clock.n << 16 | clock.m1 << 8 | clock.m2; | 5372 | fp = clock.n << 16 | clock.m1 << 8 | clock.m2; |
5340 | if (has_reduced_clock) | 5373 | if (has_reduced_clock) |