diff options
-rw-r--r-- | drivers/gpu/drm/i915/intel_crt.c | 95 |
1 files changed, 57 insertions, 38 deletions
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index e38bc6769180..8df574316063 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -34,8 +34,17 @@ | |||
34 | #include "i915_drm.h" | 34 | #include "i915_drm.h" |
35 | #include "i915_drv.h" | 35 | #include "i915_drv.h" |
36 | 36 | ||
37 | /* Here's the desired hotplug mode */ | ||
38 | #define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 | \ | ||
39 | ADPA_CRT_HOTPLUG_WARMUP_10MS | \ | ||
40 | ADPA_CRT_HOTPLUG_SAMPLE_4S | \ | ||
41 | ADPA_CRT_HOTPLUG_VOLTAGE_50 | \ | ||
42 | ADPA_CRT_HOTPLUG_VOLREF_325MV | \ | ||
43 | ADPA_CRT_HOTPLUG_ENABLE) | ||
44 | |||
37 | struct intel_crt { | 45 | struct intel_crt { |
38 | struct intel_encoder base; | 46 | struct intel_encoder base; |
47 | bool force_hotplug_required; | ||
39 | }; | 48 | }; |
40 | 49 | ||
41 | static struct intel_crt *intel_attached_crt(struct drm_connector *connector) | 50 | static struct intel_crt *intel_attached_crt(struct drm_connector *connector) |
@@ -139,7 +148,7 @@ static void intel_crt_mode_set(struct drm_encoder *encoder, | |||
139 | dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK); | 148 | dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK); |
140 | } | 149 | } |
141 | 150 | ||
142 | adpa = 0; | 151 | adpa = ADPA_HOTPLUG_BITS; |
143 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 152 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
144 | adpa |= ADPA_HSYNC_ACTIVE_HIGH; | 153 | adpa |= ADPA_HSYNC_ACTIVE_HIGH; |
145 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) | 154 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) |
@@ -167,53 +176,44 @@ static void intel_crt_mode_set(struct drm_encoder *encoder, | |||
167 | static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) | 176 | static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) |
168 | { | 177 | { |
169 | struct drm_device *dev = connector->dev; | 178 | struct drm_device *dev = connector->dev; |
179 | struct intel_crt *crt = intel_attached_crt(connector); | ||
170 | struct drm_i915_private *dev_priv = dev->dev_private; | 180 | struct drm_i915_private *dev_priv = dev->dev_private; |
171 | u32 adpa, temp; | 181 | u32 adpa; |
172 | bool ret; | 182 | bool ret; |
173 | bool turn_off_dac = false; | ||
174 | 183 | ||
175 | temp = adpa = I915_READ(PCH_ADPA); | 184 | /* The first time through, trigger an explicit detection cycle */ |
185 | if (crt->force_hotplug_required) { | ||
186 | bool turn_off_dac = HAS_PCH_SPLIT(dev); | ||
187 | u32 save_adpa; | ||
176 | 188 | ||
177 | if (HAS_PCH_SPLIT(dev)) | 189 | crt->force_hotplug_required = 0; |
178 | turn_off_dac = true; | 190 | |
179 | 191 | save_adpa = adpa = I915_READ(PCH_ADPA); | |
180 | adpa &= ~ADPA_CRT_HOTPLUG_MASK; | 192 | DRM_DEBUG_KMS("trigger hotplug detect cycle: adpa=0x%x\n", adpa); |
181 | if (turn_off_dac) | 193 | |
182 | adpa &= ~ADPA_DAC_ENABLE; | 194 | adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER; |
183 | 195 | if (turn_off_dac) | |
184 | /* disable HPD first */ | 196 | adpa &= ~ADPA_DAC_ENABLE; |
185 | I915_WRITE(PCH_ADPA, adpa); | 197 | |
186 | (void)I915_READ(PCH_ADPA); | 198 | I915_WRITE(PCH_ADPA, adpa); |
187 | 199 | ||
188 | adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | | 200 | if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, |
189 | ADPA_CRT_HOTPLUG_WARMUP_10MS | | 201 | 1000)) |
190 | ADPA_CRT_HOTPLUG_SAMPLE_4S | | 202 | DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); |
191 | ADPA_CRT_HOTPLUG_VOLTAGE_50 | /* default */ | 203 | |
192 | ADPA_CRT_HOTPLUG_VOLREF_325MV | | 204 | if (turn_off_dac) { |
193 | ADPA_CRT_HOTPLUG_ENABLE | | 205 | I915_WRITE(PCH_ADPA, save_adpa); |
194 | ADPA_CRT_HOTPLUG_FORCE_TRIGGER); | 206 | POSTING_READ(PCH_ADPA); |
195 | 207 | } | |
196 | DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa); | ||
197 | I915_WRITE(PCH_ADPA, adpa); | ||
198 | |||
199 | if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, | ||
200 | 1000)) | ||
201 | DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); | ||
202 | |||
203 | if (turn_off_dac) { | ||
204 | /* Make sure hotplug is enabled */ | ||
205 | I915_WRITE(PCH_ADPA, temp | ADPA_CRT_HOTPLUG_ENABLE); | ||
206 | (void)I915_READ(PCH_ADPA); | ||
207 | } | 208 | } |
208 | 209 | ||
209 | /* Check the status to see if both blue and green are on now */ | 210 | /* Check the status to see if both blue and green are on now */ |
210 | adpa = I915_READ(PCH_ADPA); | 211 | adpa = I915_READ(PCH_ADPA); |
211 | adpa &= ADPA_CRT_HOTPLUG_MONITOR_MASK; | 212 | if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0) |
212 | if ((adpa == ADPA_CRT_HOTPLUG_MONITOR_COLOR) || | ||
213 | (adpa == ADPA_CRT_HOTPLUG_MONITOR_MONO)) | ||
214 | ret = true; | 213 | ret = true; |
215 | else | 214 | else |
216 | ret = false; | 215 | ret = false; |
216 | DRM_DEBUG_KMS("ironlake hotplug adpa=0x%x, result %d\n", adpa, ret); | ||
217 | 217 | ||
218 | return ret; | 218 | return ret; |
219 | } | 219 | } |
@@ -452,8 +452,10 @@ intel_crt_detect(struct drm_connector *connector, bool force) | |||
452 | if (intel_crt_detect_hotplug(connector)) { | 452 | if (intel_crt_detect_hotplug(connector)) { |
453 | DRM_DEBUG_KMS("CRT detected via hotplug\n"); | 453 | DRM_DEBUG_KMS("CRT detected via hotplug\n"); |
454 | return connector_status_connected; | 454 | return connector_status_connected; |
455 | } else | 455 | } else { |
456 | DRM_DEBUG_KMS("CRT not detected via hotplug\n"); | ||
456 | return connector_status_disconnected; | 457 | return connector_status_disconnected; |
458 | } | ||
457 | } | 459 | } |
458 | 460 | ||
459 | if (intel_crt_detect_ddc(crt)) | 461 | if (intel_crt_detect_ddc(crt)) |
@@ -587,5 +589,22 @@ void intel_crt_init(struct drm_device *dev) | |||
587 | else | 589 | else |
588 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | 590 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; |
589 | 591 | ||
592 | /* | ||
593 | * Configure the automatic hotplug detection stuff | ||
594 | */ | ||
595 | crt->force_hotplug_required = 0; | ||
596 | if (HAS_PCH_SPLIT(dev)) { | ||
597 | u32 adpa; | ||
598 | |||
599 | adpa = I915_READ(PCH_ADPA); | ||
600 | adpa &= ~ADPA_CRT_HOTPLUG_MASK; | ||
601 | adpa |= ADPA_HOTPLUG_BITS; | ||
602 | I915_WRITE(PCH_ADPA, adpa); | ||
603 | POSTING_READ(PCH_ADPA); | ||
604 | |||
605 | DRM_DEBUG_KMS("pch crt adpa set to 0x%x\n", adpa); | ||
606 | crt->force_hotplug_required = 1; | ||
607 | } | ||
608 | |||
590 | dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS; | 609 | dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS; |
591 | } | 610 | } |