aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2011-08-03 15:59:20 -0400
committerKeith Packard <keithp@keithp.com>2011-08-09 13:26:24 -0400
commit13d83a672e9bbd52ae82c2f611dfd845a957e8b4 (patch)
treeba82ed032944fb58e3c721ac3a5d3031e5d4a8f5 /drivers/gpu
parentda64c6fc4aba6f02aa800db72411f459a9f86809 (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.c119
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
5100static 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
5100static int ironlake_crtc_mode_set(struct drm_crtc *crtc, 5175static 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)