Rev 3480 | Rev 4104 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3480 | Rev 3746 | ||
---|---|---|---|
Line 24... | Line 24... | ||
24 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
24 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
25 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
25 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
26 | * |
26 | * |
27 | */ |
27 | */ |
Line 28... | Line 28... | ||
28 | 28 | ||
Line 29... | Line 29... | ||
29 | #define pr_fmt(fmt) ": " fmt |
29 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
30 | 30 | ||
31 | #include |
31 | #include |
32 | #include |
32 | #include |
33 | #include |
33 | #include |
34 | #include "i915_drv.h" |
34 | #include "i915_drv.h" |
Line -... | Line 35... | ||
- | 35 | #include "i915_trace.h" |
|
- | 36 | #include "intel_drv.h" |
|
- | 37 | ||
- | 38 | static const u32 hpd_ibx[] = { |
|
- | 39 | [HPD_CRT] = SDE_CRT_HOTPLUG, |
|
- | 40 | [HPD_SDVO_B] = SDE_SDVOB_HOTPLUG, |
|
- | 41 | [HPD_PORT_B] = SDE_PORTB_HOTPLUG, |
|
- | 42 | [HPD_PORT_C] = SDE_PORTC_HOTPLUG, |
|
- | 43 | [HPD_PORT_D] = SDE_PORTD_HOTPLUG |
|
- | 44 | }; |
|
- | 45 | ||
- | 46 | static const u32 hpd_cpt[] = { |
|
- | 47 | [HPD_CRT] = SDE_CRT_HOTPLUG_CPT, |
|
- | 48 | [HPD_SDVO_B] = SDE_SDVOB_HOTPLUG_CPT, |
|
- | 49 | [HPD_PORT_B] = SDE_PORTB_HOTPLUG_CPT, |
|
- | 50 | [HPD_PORT_C] = SDE_PORTC_HOTPLUG_CPT, |
|
- | 51 | [HPD_PORT_D] = SDE_PORTD_HOTPLUG_CPT |
|
- | 52 | }; |
|
- | 53 | ||
- | 54 | static const u32 hpd_mask_i915[] = { |
|
- | 55 | [HPD_CRT] = CRT_HOTPLUG_INT_EN, |
|
- | 56 | [HPD_SDVO_B] = SDVOB_HOTPLUG_INT_EN, |
|
- | 57 | [HPD_SDVO_C] = SDVOC_HOTPLUG_INT_EN, |
|
- | 58 | [HPD_PORT_B] = PORTB_HOTPLUG_INT_EN, |
|
- | 59 | [HPD_PORT_C] = PORTC_HOTPLUG_INT_EN, |
|
- | 60 | [HPD_PORT_D] = PORTD_HOTPLUG_INT_EN |
|
- | 61 | }; |
|
- | 62 | ||
- | 63 | static const u32 hpd_status_gen4[] = { |
|
- | 64 | [HPD_CRT] = CRT_HOTPLUG_INT_STATUS, |
|
- | 65 | [HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_G4X, |
|
- | 66 | [HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_G4X, |
|
- | 67 | [HPD_PORT_B] = PORTB_HOTPLUG_INT_STATUS, |
|
- | 68 | [HPD_PORT_C] = PORTC_HOTPLUG_INT_STATUS, |
|
- | 69 | [HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS |
|
- | 70 | }; |
|
- | 71 | ||
- | 72 | static const u32 hpd_status_i965[] = { |
|
- | 73 | [HPD_CRT] = CRT_HOTPLUG_INT_STATUS, |
|
- | 74 | [HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_I965, |
|
- | 75 | [HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_I965, |
|
- | 76 | [HPD_PORT_B] = PORTB_HOTPLUG_INT_STATUS, |
|
- | 77 | [HPD_PORT_C] = PORTC_HOTPLUG_INT_STATUS, |
|
- | 78 | [HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS |
|
- | 79 | }; |
|
- | 80 | ||
- | 81 | static const u32 hpd_status_i915[] = { /* i915 and valleyview are the same */ |
|
- | 82 | [HPD_CRT] = CRT_HOTPLUG_INT_STATUS, |
|
- | 83 | [HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_I915, |
|
- | 84 | [HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_I915, |
|
- | 85 | [HPD_PORT_B] = PORTB_HOTPLUG_INT_STATUS, |
|
- | 86 | [HPD_PORT_C] = PORTC_HOTPLUG_INT_STATUS, |
|
- | 87 | [HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS |
|
- | 88 | }; |
|
Line 35... | Line 89... | ||
35 | #include "i915_trace.h" |
89 | |
36 | #include "intel_drv.h" |
90 | static void ibx_hpd_irq_setup(struct drm_device *dev); |
Line 56... | Line 110... | ||
56 | I915_WRITE(DEIMR, dev_priv->irq_mask); |
110 | I915_WRITE(DEIMR, dev_priv->irq_mask); |
57 | POSTING_READ(DEIMR); |
111 | POSTING_READ(DEIMR); |
58 | } |
112 | } |
59 | } |
113 | } |
Line 60... | Line 114... | ||
60 | 114 | ||
61 | static inline void |
115 | static void |
62 | ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask) |
116 | ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask) |
63 | { |
117 | { |
64 | if ((dev_priv->irq_mask & mask) != mask) { |
118 | if ((dev_priv->irq_mask & mask) != mask) { |
65 | dev_priv->irq_mask |= mask; |
119 | dev_priv->irq_mask |= mask; |
Line 69... | Line 123... | ||
69 | } |
123 | } |
Line 70... | Line 124... | ||
70 | 124 | ||
71 | void |
125 | void |
72 | i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) |
126 | i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) |
73 | { |
- | |
74 | if ((dev_priv->pipestat[pipe] & mask) != mask) { |
127 | { |
- | 128 | u32 reg = PIPESTAT(pipe); |
|
- | 129 | u32 pipestat = I915_READ(reg) & 0x7fff0000; |
|
- | 130 | ||
- | 131 | if ((pipestat & mask) == mask) |
|
Line 75... | Line -... | ||
75 | u32 reg = PIPESTAT(pipe); |
- | |
76 | 132 | return; |
|
- | 133 | ||
77 | dev_priv->pipestat[pipe] |= mask; |
134 | /* Enable the interrupt, clear any pending status */ |
78 | /* Enable the interrupt, clear any pending status */ |
135 | pipestat |= mask | (mask >> 16); |
79 | I915_WRITE(reg, dev_priv->pipestat[pipe] | (mask >> 16)); |
136 | I915_WRITE(reg, pipestat); |
80 | POSTING_READ(reg); |
- | |
Line 81... | Line 137... | ||
81 | } |
137 | POSTING_READ(reg); |
82 | } |
138 | } |
83 | 139 | ||
84 | void |
- | |
85 | i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) |
140 | void |
- | 141 | i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) |
|
- | 142 | { |
|
- | 143 | u32 reg = PIPESTAT(pipe); |
|
- | 144 | u32 pipestat = I915_READ(reg) & 0x7fff0000; |
|
Line 86... | Line 145... | ||
86 | { |
145 | |
87 | if ((dev_priv->pipestat[pipe] & mask) != 0) { |
146 | if ((pipestat & mask) == 0) |
88 | u32 reg = PIPESTAT(pipe); |
147 | return; |
89 | 148 | ||
90 | dev_priv->pipestat[pipe] &= ~mask; |
- | |
Line 91... | Line 149... | ||
91 | I915_WRITE(reg, dev_priv->pipestat[pipe]); |
149 | pipestat &= ~mask; |
92 | POSTING_READ(reg); |
150 | I915_WRITE(reg, pipestat); |
93 | } |
151 | POSTING_READ(reg); |
94 | } |
152 | } |
Line 188... | Line 246... | ||
188 | } |
246 | } |
Line 189... | Line 247... | ||
189 | 247 | ||
190 | return I915_READ(reg); |
248 | return I915_READ(reg); |
Line -... | Line 249... | ||
- | 249 | } |
|
- | 250 | ||
- | 251 | static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, |
|
- | 252 | int *vpos, int *hpos) |
|
- | 253 | { |
|
- | 254 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
|
- | 255 | u32 vbl = 0, position = 0; |
|
- | 256 | int vbl_start, vbl_end, htotal, vtotal; |
|
- | 257 | bool in_vbl = true; |
|
- | 258 | int ret = 0; |
|
- | 259 | enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, |
|
- | 260 | pipe); |
|
- | 261 | ||
- | 262 | if (!i915_pipe_enabled(dev, pipe)) { |
|
- | 263 | DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled " |
|
- | 264 | "pipe %c\n", pipe_name(pipe)); |
|
- | 265 | return 0; |
|
- | 266 | } |
|
- | 267 | ||
- | 268 | /* Get vtotal. */ |
|
- | 269 | vtotal = 1 + ((I915_READ(VTOTAL(cpu_transcoder)) >> 16) & 0x1fff); |
|
- | 270 | ||
- | 271 | if (INTEL_INFO(dev)->gen >= 4) { |
|
- | 272 | /* No obvious pixelcount register. Only query vertical |
|
- | 273 | * scanout position from Display scan line register. |
|
- | 274 | */ |
|
- | 275 | position = I915_READ(PIPEDSL(pipe)); |
|
- | 276 | ||
- | 277 | /* Decode into vertical scanout position. Don't have |
|
- | 278 | * horizontal scanout position. |
|
- | 279 | */ |
|
- | 280 | *vpos = position & 0x1fff; |
|
- | 281 | *hpos = 0; |
|
- | 282 | } else { |
|
- | 283 | /* Have access to pixelcount since start of frame. |
|
- | 284 | * We can split this into vertical and horizontal |
|
- | 285 | * scanout position. |
|
- | 286 | */ |
|
- | 287 | position = (I915_READ(PIPEFRAMEPIXEL(pipe)) & PIPE_PIXEL_MASK) >> PIPE_PIXEL_SHIFT; |
|
- | 288 | ||
- | 289 | htotal = 1 + ((I915_READ(HTOTAL(cpu_transcoder)) >> 16) & 0x1fff); |
|
- | 290 | *vpos = position / htotal; |
|
- | 291 | *hpos = position - (*vpos * htotal); |
|
- | 292 | } |
|
- | 293 | ||
- | 294 | /* Query vblank area. */ |
|
- | 295 | vbl = I915_READ(VBLANK(cpu_transcoder)); |
|
- | 296 | ||
- | 297 | /* Test position against vblank region. */ |
|
- | 298 | vbl_start = vbl & 0x1fff; |
|
- | 299 | vbl_end = (vbl >> 16) & 0x1fff; |
|
- | 300 | ||
- | 301 | if ((*vpos < vbl_start) || (*vpos > vbl_end)) |
|
- | 302 | in_vbl = false; |
|
- | 303 | ||
- | 304 | /* Inside "upper part" of vblank area? Apply corrective offset: */ |
|
- | 305 | if (in_vbl && (*vpos >= vbl_start)) |
|
- | 306 | *vpos = *vpos - vtotal; |
|
- | 307 | ||
- | 308 | /* Readouts valid? */ |
|
- | 309 | if (vbl > 0) |
|
- | 310 | ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; |
|
- | 311 | ||
- | 312 | /* In vblank? */ |
|
- | 313 | if (in_vbl) |
|
- | 314 | ret |= DRM_SCANOUTPOS_INVBL; |
|
- | 315 | ||
- | 316 | return ret; |
|
- | 317 | } |
|
- | 318 | ||
- | 319 | static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe, |
|
- | 320 | int *max_error, |
|
- | 321 | struct timeval *vblank_time, |
|
- | 322 | unsigned flags) |
|
- | 323 | { |
|
- | 324 | struct drm_crtc *crtc; |
|
- | 325 | ||
- | 326 | if (pipe < 0 || pipe >= INTEL_INFO(dev)->num_pipes) { |
|
- | 327 | DRM_ERROR("Invalid crtc %d\n", pipe); |
|
- | 328 | return -EINVAL; |
|
- | 329 | } |
|
- | 330 | ||
- | 331 | /* Get drm_crtc to timestamp: */ |
|
- | 332 | crtc = intel_get_crtc_for_pipe(dev, pipe); |
|
- | 333 | if (crtc == NULL) { |
|
- | 334 | DRM_ERROR("Invalid crtc %d\n", pipe); |
|
- | 335 | return -EINVAL; |
|
- | 336 | } |
|
- | 337 | ||
- | 338 | if (!crtc->enabled) { |
|
- | 339 | DRM_DEBUG_KMS("crtc %d is disabled\n", pipe); |
|
- | 340 | return -EBUSY; |
|
- | 341 | } |
|
- | 342 | ||
- | 343 | /* Helper routine in DRM core does all the work: */ |
|
- | 344 | return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, |
|
- | 345 | vblank_time, flags, |
|
- | 346 | crtc); |
|
191 | } |
347 | } |
192 | 348 | ||
193 | /* |
349 | /* |
- | 350 | * Handle hotplug events outside the interrupt handler proper. |
|
- | 351 | */ |
|
194 | * Handle hotplug events outside the interrupt handler proper. |
352 | #define I915_REENABLE_HOTPLUG_DELAY (2*60*1000) |
195 | */ |
353 | |
196 | static void i915_hotplug_work_func(struct work_struct *work) |
354 | static void i915_hotplug_work_func(struct work_struct *work) |
197 | { |
355 | { |
198 | drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, |
356 | drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, |
199 | hotplug_work); |
357 | hotplug_work); |
- | 358 | struct drm_device *dev = dev_priv->dev; |
|
200 | struct drm_device *dev = dev_priv->dev; |
359 | struct drm_mode_config *mode_config = &dev->mode_config; |
- | 360 | struct intel_connector *intel_connector; |
|
- | 361 | struct intel_encoder *intel_encoder; |
|
- | 362 | struct drm_connector *connector; |
|
Line 201... | Line 363... | ||
201 | struct drm_mode_config *mode_config = &dev->mode_config; |
363 | unsigned long irqflags; |
202 | struct intel_encoder *encoder; |
364 | bool hpd_disabled = false; |
203 | 365 | ||
Line 204... | Line 366... | ||
204 | /* HPD irq before everything is fully set up. */ |
366 | /* HPD irq before everything is fully set up. */ |
205 | if (!dev_priv->enable_hotplug_processing) |
367 | if (!dev_priv->enable_hotplug_processing) |
Line -... | Line 368... | ||
- | 368 | return; |
|
- | 369 | ||
- | 370 | mutex_lock(&mode_config->mutex); |
|
- | 371 | DRM_DEBUG_KMS("running encoder hotplug functions\n"); |
|
- | 372 | ||
- | 373 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
|
- | 374 | list_for_each_entry(connector, &mode_config->connector_list, head) { |
|
- | 375 | intel_connector = to_intel_connector(connector); |
|
- | 376 | intel_encoder = intel_connector->encoder; |
|
- | 377 | if (intel_encoder->hpd_pin > HPD_NONE && |
|
- | 378 | dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark == HPD_MARK_DISABLED && |
|
- | 379 | connector->polled == DRM_CONNECTOR_POLL_HPD) { |
|
- | 380 | DRM_INFO("HPD interrupt storm detected on connector %s: " |
|
- | 381 | "switching from hotplug detection to polling\n", |
|
- | 382 | drm_get_connector_name(connector)); |
|
- | 383 | dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark = HPD_DISABLED; |
|
- | 384 | connector->polled = DRM_CONNECTOR_POLL_CONNECT |
|
- | 385 | | DRM_CONNECTOR_POLL_DISCONNECT; |
|
- | 386 | hpd_disabled = true; |
|
- | 387 | } |
|
- | 388 | } |
|
- | 389 | /* if there were no outputs to poll, poll was disabled, |
|
- | 390 | * therefore make sure it's enabled when disabling HPD on |
|
- | 391 | * some connectors */ |
|
- | 392 | if (hpd_disabled) { |
|
- | 393 | drm_kms_helper_poll_enable(dev); |
|
- | 394 | // mod_timer(&dev_priv->hotplug_reenable_timer, |
|
206 | return; |
395 | // jiffies + msecs_to_jiffies(I915_REENABLE_HOTPLUG_DELAY)); |
207 | 396 | } |
|
208 | mutex_lock(&mode_config->mutex); |
397 | |
Line 209... | Line 398... | ||
209 | DRM_DEBUG_KMS("running encoder hotplug functions\n"); |
398 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
Line 210... | Line 399... | ||
210 | 399 | ||
211 | list_for_each_entry(encoder, &mode_config->encoder_list, base.head) |
400 | list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head) |
212 | if (encoder->hot_plug) |
401 | if (intel_encoder->hot_plug) |
Line -... | Line 402... | ||
- | 402 | intel_encoder->hot_plug(intel_encoder); |
|
- | 403 | ||
- | 404 | mutex_unlock(&mode_config->mutex); |
|
- | 405 | ||
- | 406 | /* Just fire off a uevent and let userspace tell us what to do */ |
|
- | 407 | drm_helper_hpd_irq_event(dev); |
|
- | 408 | } |
|
- | 409 | ||
- | 410 | static void ironlake_handle_rps_change(struct drm_device *dev) |
|
- | 411 | { |
|
- | 412 | drm_i915_private_t *dev_priv = dev->dev_private; |
|
- | 413 | u32 busy_up, busy_down, max_avg, min_avg; |
|
- | 414 | u8 new_delay; |
|
- | 415 | unsigned long flags; |
|
- | 416 | ||
- | 417 | spin_lock_irqsave(&mchdev_lock, flags); |
|
- | 418 | ||
- | 419 | I915_WRITE16(MEMINTRSTS, I915_READ(MEMINTRSTS)); |
|
- | 420 | ||
- | 421 | new_delay = dev_priv->ips.cur_delay; |
|
- | 422 | ||
- | 423 | I915_WRITE16(MEMINTRSTS, MEMINT_EVAL_CHG); |
|
- | 424 | busy_up = I915_READ(RCPREVBSYTUPAVG); |
|
- | 425 | busy_down = I915_READ(RCPREVBSYTDNAVG); |
|
- | 426 | max_avg = I915_READ(RCBMAXAVG); |
|
- | 427 | min_avg = I915_READ(RCBMINAVG); |
|
- | 428 | ||
- | 429 | /* Handle RCS change request from hw */ |
|
- | 430 | if (busy_up > max_avg) { |
|
- | 431 | if (dev_priv->ips.cur_delay != dev_priv->ips.max_delay) |
|
- | 432 | new_delay = dev_priv->ips.cur_delay - 1; |
|
- | 433 | if (new_delay < dev_priv->ips.max_delay) |
|
- | 434 | new_delay = dev_priv->ips.max_delay; |
|
- | 435 | } else if (busy_down < min_avg) { |
|
- | 436 | if (dev_priv->ips.cur_delay != dev_priv->ips.min_delay) |
|
- | 437 | new_delay = dev_priv->ips.cur_delay + 1; |
|
- | 438 | if (new_delay > dev_priv->ips.min_delay) |
|
- | 439 | new_delay = dev_priv->ips.min_delay; |
|
- | 440 | } |
|
- | 441 | ||
213 | encoder->hot_plug(encoder); |
442 | if (ironlake_set_drps(dev, new_delay)) |
214 | 443 | dev_priv->ips.cur_delay = new_delay; |
|
215 | mutex_unlock(&mode_config->mutex); |
444 | |
216 | 445 | spin_unlock_irqrestore(&mchdev_lock, flags); |
|
Line 357... | Line 586... | ||
357 | 586 | ||
358 | static void snb_gt_irq_handler(struct drm_device *dev, |
587 | static void snb_gt_irq_handler(struct drm_device *dev, |
359 | struct drm_i915_private *dev_priv, |
588 | struct drm_i915_private *dev_priv, |
360 | u32 gt_iir) |
589 | u32 gt_iir) |
361 | { |
- | |
Line 362... | Line 590... | ||
362 | // printf("%s\n", __FUNCTION__); |
590 | { |
363 | 591 | ||
364 | if (gt_iir & (GEN6_RENDER_USER_INTERRUPT | |
592 | if (gt_iir & (GEN6_RENDER_USER_INTERRUPT | |
365 | GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT)) |
593 | GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT)) |
Line 402... | Line 630... | ||
402 | spin_unlock_irqrestore(&dev_priv->rps.lock, flags); |
630 | spin_unlock_irqrestore(&dev_priv->rps.lock, flags); |
Line 403... | Line 631... | ||
403 | 631 | ||
404 | // queue_work(dev_priv->wq, &dev_priv->rps.work); |
632 | // queue_work(dev_priv->wq, &dev_priv->rps.work); |
Line -... | Line 633... | ||
- | 633 | } |
|
- | 634 | ||
- | 635 | #define HPD_STORM_DETECT_PERIOD 1000 |
|
- | 636 | #define HPD_STORM_THRESHOLD 5 |
|
- | 637 | ||
- | 638 | static inline bool hotplug_irq_storm_detect(struct drm_device *dev, |
|
- | 639 | u32 hotplug_trigger, |
|
- | 640 | const u32 *hpd) |
|
- | 641 | { |
|
- | 642 | drm_i915_private_t *dev_priv = dev->dev_private; |
|
- | 643 | unsigned long irqflags; |
|
- | 644 | int i; |
|
- | 645 | bool ret = false; |
|
- | 646 | ||
- | 647 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
|
- | 648 | ||
- | 649 | for (i = 1; i < HPD_NUM_PINS; i++) { |
|
- | 650 | ||
- | 651 | if (!(hpd[i] & hotplug_trigger) || |
|
- | 652 | dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED) |
|
- | 653 | continue; |
|
- | 654 | ||
- | 655 | // if (!time_in_range(GetTimerTicks(), dev_priv->hpd_stats[i].hpd_last_jiffies, |
|
- | 656 | // dev_priv->hpd_stats[i].hpd_last_jiffies |
|
- | 657 | // + msecs_to_jiffies(HPD_STORM_DETECT_PERIOD))) { |
|
- | 658 | // dev_priv->hpd_stats[i].hpd_last_jiffies = GetTimerTicks; |
|
- | 659 | // dev_priv->hpd_stats[i].hpd_cnt = 0; |
|
- | 660 | // } else if (dev_priv->hpd_stats[i].hpd_cnt > HPD_STORM_THRESHOLD) { |
|
- | 661 | // dev_priv->hpd_stats[i].hpd_mark = HPD_MARK_DISABLED; |
|
- | 662 | // DRM_DEBUG_KMS("HPD interrupt storm detected on PIN %d\n", i); |
|
- | 663 | // ret = true; |
|
- | 664 | // } else { |
|
- | 665 | dev_priv->hpd_stats[i].hpd_cnt++; |
|
- | 666 | // } |
|
- | 667 | } |
|
- | 668 | ||
- | 669 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
|
- | 670 | ||
- | 671 | return ret; |
|
405 | } |
672 | } |
406 | 673 | ||
407 | static void gmbus_irq_handler(struct drm_device *dev) |
674 | static void gmbus_irq_handler(struct drm_device *dev) |
Line 408... | Line 675... | ||
408 | { |
675 | { |
Line 472... | Line 739... | ||
472 | #endif |
739 | #endif |
Line 473... | Line 740... | ||
473 | 740 | ||
474 | /* Consume port. Then clear IIR or we'll miss events */ |
741 | /* Consume port. Then clear IIR or we'll miss events */ |
475 | if (iir & I915_DISPLAY_PORT_INTERRUPT) { |
742 | if (iir & I915_DISPLAY_PORT_INTERRUPT) { |
- | 743 | u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); |
|
Line 476... | Line 744... | ||
476 | u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); |
744 | u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_I915; |
477 | 745 | ||
- | 746 | DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", |
|
478 | DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", |
747 | hotplug_status); |
- | 748 | if (hotplug_trigger) { |
|
479 | hotplug_status); |
749 | if (hotplug_irq_storm_detect(dev, hotplug_trigger, hpd_status_i915)) |
480 | if (hotplug_status & dev_priv->hotplug_supported_mask) |
750 | i915_hpd_irq_setup(dev); |
481 | queue_work(dev_priv->wq, |
751 | queue_work(dev_priv->wq, |
482 | &dev_priv->hotplug_work); |
752 | &dev_priv->hotplug_work); |
483 | 753 | } |
|
484 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); |
754 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); |
Line 485... | Line 755... | ||
485 | I915_READ(PORT_HOTPLUG_STAT); |
755 | I915_READ(PORT_HOTPLUG_STAT); |
Line 502... | Line 772... | ||
502 | 772 | ||
503 | static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir) |
773 | static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir) |
504 | { |
774 | { |
505 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
775 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
- | 776 | int pipe; |
|
Line 506... | Line 777... | ||
506 | int pipe; |
777 | u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK; |
- | 778 | ||
- | 779 | if (hotplug_trigger) { |
|
507 | 780 | if (hotplug_irq_storm_detect(dev, hotplug_trigger, hpd_ibx)) |
|
508 | if (pch_iir & SDE_HOTPLUG_MASK) |
781 | ibx_hpd_irq_setup(dev); |
509 | queue_work(dev_priv->wq, &dev_priv->hotplug_work); |
782 | queue_work(dev_priv->wq, &dev_priv->hotplug_work); |
510 | 783 | } |
|
511 | if (pch_iir & SDE_AUDIO_POWER_MASK) |
784 | if (pch_iir & SDE_AUDIO_POWER_MASK) |
512 | DRM_DEBUG_DRIVER("PCH audio power change on port %d\n", |
785 | DRM_DEBUG_DRIVER("PCH audio power change on port %d\n", |
Line 548... | Line 821... | ||
548 | 821 | ||
549 | static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) |
822 | static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) |
550 | { |
823 | { |
551 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
824 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
- | 825 | int pipe; |
|
Line 552... | Line 826... | ||
552 | int pipe; |
826 | u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT; |
- | 827 | ||
- | 828 | if (hotplug_trigger) { |
|
553 | 829 | if (hotplug_irq_storm_detect(dev, hotplug_trigger, hpd_cpt)) |
|
554 | if (pch_iir & SDE_HOTPLUG_MASK_CPT) |
830 | ibx_hpd_irq_setup(dev); |
555 | queue_work(dev_priv->wq, &dev_priv->hotplug_work); |
831 | queue_work(dev_priv->wq, &dev_priv->hotplug_work); |
556 | 832 | } |
|
557 | if (pch_iir & SDE_AUDIO_POWER_MASK_CPT) |
833 | if (pch_iir & SDE_AUDIO_POWER_MASK_CPT) |
558 | DRM_DEBUG_DRIVER("PCH audio power change on port %d\n", |
834 | DRM_DEBUG_DRIVER("PCH audio power change on port %d\n", |
Line 580... | Line 856... | ||
580 | 856 | ||
581 | static irqreturn_t ivybridge_irq_handler(int irq, void *arg) |
857 | static irqreturn_t ivybridge_irq_handler(int irq, void *arg) |
582 | { |
858 | { |
583 | struct drm_device *dev = (struct drm_device *) arg; |
859 | struct drm_device *dev = (struct drm_device *) arg; |
584 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
860 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
585 | u32 de_iir, gt_iir, de_ier, pm_iir, sde_ier; |
861 | u32 de_iir, gt_iir, de_ier, pm_iir, sde_ier = 0; |
586 | irqreturn_t ret = IRQ_NONE; |
862 | irqreturn_t ret = IRQ_NONE; |
Line 587... | Line 863... | ||
587 | int i; |
863 | int i; |
Line 595... | Line 871... | ||
595 | /* Disable south interrupts. We'll only write to SDEIIR once, so further |
871 | /* Disable south interrupts. We'll only write to SDEIIR once, so further |
596 | * interrupts will will be stored on its back queue, and then we'll be |
872 | * interrupts will will be stored on its back queue, and then we'll be |
597 | * able to process them after we restore SDEIER (as soon as we restore |
873 | * able to process them after we restore SDEIER (as soon as we restore |
598 | * it, we'll get an interrupt if SDEIIR still has something to process |
874 | * it, we'll get an interrupt if SDEIIR still has something to process |
599 | * due to its back queue). */ |
875 | * due to its back queue). */ |
- | 876 | if (!HAS_PCH_NOP(dev)) { |
|
600 | sde_ier = I915_READ(SDEIER); |
877 | sde_ier = I915_READ(SDEIER); |
601 | I915_WRITE(SDEIER, 0); |
878 | I915_WRITE(SDEIER, 0); |
602 | POSTING_READ(SDEIER); |
879 | POSTING_READ(SDEIER); |
- | 880 | } |
|
Line 603... | Line 881... | ||
603 | 881 | ||
604 | gt_iir = I915_READ(GTIIR); |
882 | gt_iir = I915_READ(GTIIR); |
605 | if (gt_iir) { |
883 | if (gt_iir) { |
606 | snb_gt_irq_handler(dev, dev_priv, gt_iir); |
884 | snb_gt_irq_handler(dev, dev_priv, gt_iir); |
Line 624... | Line 902... | ||
624 | intel_finish_page_flip_plane(dev, i); |
902 | intel_finish_page_flip_plane(dev, i); |
625 | } |
903 | } |
626 | } |
904 | } |
627 | #endif |
905 | #endif |
628 | /* check event from PCH */ |
906 | /* check event from PCH */ |
629 | if (de_iir & DE_PCH_EVENT_IVB) { |
907 | if (!HAS_PCH_NOP(dev) && (de_iir & DE_PCH_EVENT_IVB)) { |
630 | u32 pch_iir = I915_READ(SDEIIR); |
908 | u32 pch_iir = I915_READ(SDEIIR); |
Line 631... | Line 909... | ||
631 | 909 | ||
Line 632... | Line 910... | ||
632 | cpt_irq_handler(dev, pch_iir); |
910 | cpt_irq_handler(dev, pch_iir); |
Line 647... | Line 925... | ||
647 | ret = IRQ_HANDLED; |
925 | ret = IRQ_HANDLED; |
648 | } |
926 | } |
Line 649... | Line 927... | ||
649 | 927 | ||
650 | I915_WRITE(DEIER, de_ier); |
928 | I915_WRITE(DEIER, de_ier); |
- | 929 | POSTING_READ(DEIER); |
|
651 | POSTING_READ(DEIER); |
930 | if (!HAS_PCH_NOP(dev)) { |
652 | I915_WRITE(SDEIER, sde_ier); |
931 | I915_WRITE(SDEIER, sde_ier); |
- | 932 | POSTING_READ(SDEIER); |
|
Line 653... | Line 933... | ||
653 | POSTING_READ(SDEIER); |
933 | } |
654 | 934 | ||
Line 655... | Line 935... | ||
655 | return ret; |
935 | return ret; |
Line 790... | Line 1070... | ||
790 | } |
1070 | } |
791 | } |
1071 | } |
Line 792... | Line 1072... | ||
792 | 1072 | ||
793 | #ifdef CONFIG_DEBUG_FS |
1073 | #ifdef CONFIG_DEBUG_FS |
794 | static struct drm_i915_error_object * |
1074 | static struct drm_i915_error_object * |
795 | i915_error_object_create(struct drm_i915_private *dev_priv, |
1075 | i915_error_object_create_sized(struct drm_i915_private *dev_priv, |
- | 1076 | struct drm_i915_gem_object *src, |
|
796 | struct drm_i915_gem_object *src) |
1077 | const int num_pages) |
797 | { |
1078 | { |
798 | struct drm_i915_error_object *dst; |
1079 | struct drm_i915_error_object *dst; |
799 | int i, count; |
1080 | int i; |
Line 800... | Line 1081... | ||
800 | u32 reloc_offset; |
1081 | u32 reloc_offset; |
801 | 1082 | ||
Line 802... | Line -... | ||
802 | if (src == NULL || src->pages == NULL) |
- | |
803 | return NULL; |
- | |
804 | 1083 | if (src == NULL || src->pages == NULL) |
|
805 | count = src->base.size / PAGE_SIZE; |
1084 | return NULL; |
806 | 1085 | ||
Line 807... | Line 1086... | ||
807 | dst = kmalloc(sizeof(*dst) + count * sizeof(u32 *), GFP_ATOMIC); |
1086 | dst = kmalloc(sizeof(*dst) + num_pages * sizeof(u32 *), GFP_ATOMIC); |
808 | if (dst == NULL) |
1087 | if (dst == NULL) |
809 | return NULL; |
1088 | return NULL; |
810 | 1089 | ||
Line 811... | Line 1090... | ||
811 | reloc_offset = src->gtt_offset; |
1090 | reloc_offset = src->gtt_offset; |
812 | for (i = 0; i < count; i++) { |
1091 | for (i = 0; i < num_pages; i++) { |
Line 857... | Line 1136... | ||
857 | 1136 | ||
Line 858... | Line 1137... | ||
858 | dst->pages[i] = d; |
1137 | dst->pages[i] = d; |
859 | 1138 | ||
860 | reloc_offset += PAGE_SIZE; |
1139 | reloc_offset += PAGE_SIZE; |
861 | } |
1140 | } |
Line 862... | Line 1141... | ||
862 | dst->page_count = count; |
1141 | dst->page_count = num_pages; |
Line 863... | Line 1142... | ||
863 | dst->gtt_offset = src->gtt_offset; |
1142 | dst->gtt_offset = src->gtt_offset; |
864 | 1143 | ||
865 | return dst; |
1144 | return dst; |
866 | 1145 | ||
867 | unwind: |
1146 | unwind: |
868 | while (i--) |
1147 | while (i--) |
- | 1148 | kfree(dst->pages[i]); |
|
- | 1149 | kfree(dst); |
|
- | 1150 | return NULL; |
|
Line 869... | Line 1151... | ||
869 | kfree(dst->pages[i]); |
1151 | } |
870 | kfree(dst); |
1152 | #define i915_error_object_create(dev_priv, src) \ |
871 | return NULL; |
1153 | i915_error_object_create_sized((dev_priv), (src), \ |
872 | } |
1154 | (src)->base.size>>PAGE_SHIFT) |
Line 966... | Line 1248... | ||
966 | 1248 | ||
967 | /* Fences */ |
1249 | /* Fences */ |
968 | switch (INTEL_INFO(dev)->gen) { |
1250 | switch (INTEL_INFO(dev)->gen) { |
969 | case 7: |
1251 | case 7: |
970 | case 6: |
1252 | case 6: |
971 | for (i = 0; i < 16; i++) |
1253 | for (i = 0; i < dev_priv->num_fence_regs; i++) |
972 | error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); |
1254 | error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); |
973 | break; |
1255 | break; |
974 | case 5: |
1256 | case 5: |
975 | case 4: |
1257 | case 4: |
Line 1074... | Line 1356... | ||
1074 | 1356 | ||
1075 | error->cpu_ring_head[ring->id] = ring->head; |
1357 | error->cpu_ring_head[ring->id] = ring->head; |
1076 | error->cpu_ring_tail[ring->id] = ring->tail; |
1358 | error->cpu_ring_tail[ring->id] = ring->tail; |
Line -... | Line 1359... | ||
- | 1359 | } |
|
- | 1360 | ||
- | 1361 | ||
- | 1362 | static void i915_gem_record_active_context(struct intel_ring_buffer *ring, |
|
- | 1363 | struct drm_i915_error_state *error, |
|
- | 1364 | struct drm_i915_error_ring *ering) |
|
- | 1365 | { |
|
- | 1366 | struct drm_i915_private *dev_priv = ring->dev->dev_private; |
|
- | 1367 | struct drm_i915_gem_object *obj; |
|
- | 1368 | ||
- | 1369 | /* Currently render ring is the only HW context user */ |
|
- | 1370 | if (ring->id != RCS || !error->ccid) |
|
- | 1371 | return; |
|
- | 1372 | ||
- | 1373 | list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) { |
|
- | 1374 | if ((error->ccid & PAGE_MASK) == obj->gtt_offset) { |
|
- | 1375 | ering->ctx = i915_error_object_create_sized(dev_priv, |
|
- | 1376 | obj, 1); |
|
- | 1377 | } |
|
- | 1378 | } |
|
1077 | } |
1379 | } |
1078 | 1380 | ||
1079 | static void i915_gem_record_rings(struct drm_device *dev, |
1381 | static void i915_gem_record_rings(struct drm_device *dev, |
1080 | struct drm_i915_error_state *error) |
1382 | struct drm_i915_error_state *error) |
1081 | { |
1383 | { |
Line 1091... | Line 1393... | ||
1091 | i915_error_first_batchbuffer(dev_priv, ring); |
1393 | i915_error_first_batchbuffer(dev_priv, ring); |
Line 1092... | Line 1394... | ||
1092 | 1394 | ||
1093 | error->ring[i].ringbuffer = |
1395 | error->ring[i].ringbuffer = |
Line -... | Line 1396... | ||
- | 1396 | i915_error_object_create(dev_priv, ring->obj); |
|
- | 1397 | ||
- | 1398 | ||
1094 | i915_error_object_create(dev_priv, ring->obj); |
1399 | i915_gem_record_active_context(ring, error, &error->ring[i]); |
1095 | 1400 | ||
1096 | count = 0; |
1401 | count = 0; |
Line 1097... | Line 1402... | ||
1097 | list_for_each_entry(request, &ring->request_list, list) |
1402 | list_for_each_entry(request, &ring->request_list, list) |
Line 1153... | Line 1458... | ||
1153 | dev->primary->index); |
1458 | dev->primary->index); |
Line 1154... | Line 1459... | ||
1154 | 1459 | ||
1155 | kref_init(&error->ref); |
1460 | kref_init(&error->ref); |
1156 | error->eir = I915_READ(EIR); |
1461 | error->eir = I915_READ(EIR); |
- | 1462 | error->pgtbl_er = I915_READ(PGTBL_ER); |
|
1157 | error->pgtbl_er = I915_READ(PGTBL_ER); |
1463 | if (HAS_HW_CONTEXTS(dev)) |
Line 1158... | Line 1464... | ||
1158 | error->ccid = I915_READ(CCID); |
1464 | error->ccid = I915_READ(CCID); |
1159 | 1465 | ||
1160 | if (HAS_PCH_SPLIT(dev)) |
1466 | if (HAS_PCH_SPLIT(dev)) |
Line 1174... | Line 1480... | ||
1174 | else if (INTEL_INFO(dev)->gen >= 7) |
1480 | else if (INTEL_INFO(dev)->gen >= 7) |
1175 | error->forcewake = I915_READ(FORCEWAKE_MT); |
1481 | error->forcewake = I915_READ(FORCEWAKE_MT); |
1176 | else if (INTEL_INFO(dev)->gen == 6) |
1482 | else if (INTEL_INFO(dev)->gen == 6) |
1177 | error->forcewake = I915_READ(FORCEWAKE); |
1483 | error->forcewake = I915_READ(FORCEWAKE); |
Line -... | Line 1484... | ||
- | 1484 | ||
1178 | 1485 | if (!HAS_PCH_SPLIT(dev)) |
|
1179 | for_each_pipe(pipe) |
1486 | for_each_pipe(pipe) |
Line 1180... | Line 1487... | ||
1180 | error->pipestat[pipe] = I915_READ(PIPESTAT(pipe)); |
1487 | error->pipestat[pipe] = I915_READ(PIPESTAT(pipe)); |
1181 | 1488 | ||
Line 1388... | Line 1695... | ||
1388 | } |
1695 | } |
Line 1389... | Line 1696... | ||
1389 | 1696 | ||
Line 1390... | Line 1697... | ||
1390 | #if 0 |
1697 | #if 0 |
1391 | 1698 | ||
1392 | 1699 | ||
1393 | static void i915_pageflip_stall_check(struct drm_device *dev, int pipe) |
1700 | static void __always_unused i915_pageflip_stall_check(struct drm_device *dev, int pipe) |
1394 | { |
1701 | { |
1395 | drm_i915_private_t *dev_priv = dev->dev_private; |
1702 | drm_i915_private_t *dev_priv = dev->dev_private; |
Line 1603... | Line 1910... | ||
1603 | /* and GT */ |
1910 | /* and GT */ |
1604 | I915_WRITE(GTIMR, 0xffffffff); |
1911 | I915_WRITE(GTIMR, 0xffffffff); |
1605 | I915_WRITE(GTIER, 0x0); |
1912 | I915_WRITE(GTIER, 0x0); |
1606 | POSTING_READ(GTIER); |
1913 | POSTING_READ(GTIER); |
Line -... | Line 1914... | ||
- | 1914 | ||
- | 1915 | if (HAS_PCH_NOP(dev)) |
|
- | 1916 | return; |
|
1607 | 1917 | ||
1608 | /* south display irq */ |
1918 | /* south display irq */ |
- | 1919 | I915_WRITE(SDEIMR, 0xffffffff); |
|
- | 1920 | /* |
|
- | 1921 | * SDEIER is also touched by the interrupt handler to work around missed |
|
- | 1922 | * PCH interrupts. Hence we can't update it after the interrupt handler |
|
- | 1923 | * is enabled - instead we unconditionally enable all PCH interrupt |
|
- | 1924 | * sources here, but then only unmask them as needed with SDEIMR. |
|
1609 | I915_WRITE(SDEIMR, 0xffffffff); |
1925 | */ |
1610 | I915_WRITE(SDEIER, 0x0); |
1926 | I915_WRITE(SDEIER, 0xffffffff); |
1611 | POSTING_READ(SDEIER); |
1927 | POSTING_READ(SDEIER); |
Line 1612... | Line 1928... | ||
1612 | } |
1928 | } |
1613 | 1929 | ||
Line 1641... | Line 1957... | ||
1641 | I915_WRITE(VLV_IMR, 0xffffffff); |
1957 | I915_WRITE(VLV_IMR, 0xffffffff); |
1642 | I915_WRITE(VLV_IER, 0x0); |
1958 | I915_WRITE(VLV_IER, 0x0); |
1643 | POSTING_READ(VLV_IER); |
1959 | POSTING_READ(VLV_IER); |
1644 | } |
1960 | } |
Line -... | Line 1961... | ||
- | 1961 | ||
- | 1962 | static void ibx_hpd_irq_setup(struct drm_device *dev) |
|
- | 1963 | { |
|
- | 1964 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
|
- | 1965 | struct drm_mode_config *mode_config = &dev->mode_config; |
|
- | 1966 | struct intel_encoder *intel_encoder; |
|
- | 1967 | u32 mask = ~I915_READ(SDEIMR); |
|
- | 1968 | u32 hotplug; |
|
- | 1969 | ||
- | 1970 | if (HAS_PCH_IBX(dev)) { |
|
- | 1971 | mask &= ~SDE_HOTPLUG_MASK; |
|
- | 1972 | list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head) |
|
- | 1973 | if (dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark == HPD_ENABLED) |
|
- | 1974 | mask |= hpd_ibx[intel_encoder->hpd_pin]; |
|
- | 1975 | } else { |
|
- | 1976 | mask &= ~SDE_HOTPLUG_MASK_CPT; |
|
- | 1977 | list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head) |
|
- | 1978 | if (dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark == HPD_ENABLED) |
|
- | 1979 | mask |= hpd_cpt[intel_encoder->hpd_pin]; |
|
- | 1980 | } |
|
- | 1981 | ||
- | 1982 | I915_WRITE(SDEIMR, ~mask); |
|
1645 | 1983 | ||
1646 | /* |
1984 | /* |
1647 | * Enable digital hotplug on the PCH, and configure the DP short pulse |
1985 | * Enable digital hotplug on the PCH, and configure the DP short pulse |
1648 | * duration to 2ms (which is the minimum in the Display Port spec) |
1986 | * duration to 2ms (which is the minimum in the Display Port spec) |
1649 | * |
1987 | * |
1650 | * This register is the same on all known PCH chips. |
1988 | * This register is the same on all known PCH chips. |
1651 | */ |
- | |
1652 | - | ||
1653 | static void ibx_enable_hotplug(struct drm_device *dev) |
- | |
1654 | { |
- | |
1655 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
- | |
1656 | u32 hotplug; |
- | |
1657 | 1989 | */ |
|
1658 | hotplug = I915_READ(PCH_PORT_HOTPLUG); |
1990 | hotplug = I915_READ(PCH_PORT_HOTPLUG); |
1659 | hotplug &= ~(PORTD_PULSE_DURATION_MASK|PORTC_PULSE_DURATION_MASK|PORTB_PULSE_DURATION_MASK); |
1991 | hotplug &= ~(PORTD_PULSE_DURATION_MASK|PORTC_PULSE_DURATION_MASK|PORTB_PULSE_DURATION_MASK); |
1660 | hotplug |= PORTD_HOTPLUG_ENABLE | PORTD_PULSE_DURATION_2ms; |
1992 | hotplug |= PORTD_HOTPLUG_ENABLE | PORTD_PULSE_DURATION_2ms; |
1661 | hotplug |= PORTC_HOTPLUG_ENABLE | PORTC_PULSE_DURATION_2ms; |
1993 | hotplug |= PORTC_HOTPLUG_ENABLE | PORTC_PULSE_DURATION_2ms; |
Line 1667... | Line 1999... | ||
1667 | { |
1999 | { |
1668 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2000 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1669 | u32 mask; |
2001 | u32 mask; |
Line 1670... | Line 2002... | ||
1670 | 2002 | ||
1671 | if (HAS_PCH_IBX(dev)) |
2003 | if (HAS_PCH_IBX(dev)) |
1672 | mask = SDE_HOTPLUG_MASK | |
- | |
1673 | SDE_GMBUS | |
- | |
1674 | SDE_AUX_MASK; |
2004 | mask = SDE_GMBUS | SDE_AUX_MASK; |
1675 | else |
2005 | else |
- | 2006 | mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT; |
|
1676 | mask = SDE_HOTPLUG_MASK_CPT | |
2007 | |
1677 | SDE_GMBUS_CPT | |
2008 | if (HAS_PCH_NOP(dev)) |
Line 1678... | Line 2009... | ||
1678 | SDE_AUX_MASK_CPT; |
2009 | return; |
1679 | 2010 | ||
1680 | I915_WRITE(SDEIIR, I915_READ(SDEIIR)); |
- | |
1681 | I915_WRITE(SDEIMR, ~mask); |
- | |
1682 | I915_WRITE(SDEIER, mask); |
- | |
1683 | POSTING_READ(SDEIER); |
- | |
1684 | 2011 | I915_WRITE(SDEIIR, I915_READ(SDEIIR)); |
|
Line 1685... | Line 2012... | ||
1685 | ibx_enable_hotplug(dev); |
2012 | I915_WRITE(SDEIMR, ~mask); |
1686 | } |
2013 | } |
1687 | 2014 | ||
Line 1791... | Line 2118... | ||
1791 | */ |
2118 | */ |
1792 | dev_priv->irq_mask = (~enable_mask) | |
2119 | dev_priv->irq_mask = (~enable_mask) | |
1793 | I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | |
2120 | I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | |
1794 | I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; |
2121 | I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; |
Line 1795... | Line -... | ||
1795 | - | ||
1796 | dev_priv->pipestat[0] = 0; |
- | |
1797 | dev_priv->pipestat[1] = 0; |
- | |
1798 | 2122 | ||
1799 | /* Hack for broken MSIs on VLV */ |
2123 | /* Hack for broken MSIs on VLV */ |
1800 | // pci_write_config_dword(dev_priv->dev->pdev, 0x94, 0xfee00000); |
2124 | // pci_write_config_dword(dev_priv->dev->pdev, 0x94, 0xfee00000); |
1801 | // pci_read_config_word(dev->pdev, 0x98, &msid); |
2125 | // pci_read_config_word(dev->pdev, 0x98, &msid); |
1802 | // msid &= 0xff; /* mask out delivery bits */ |
2126 | // msid &= 0xff; /* mask out delivery bits */ |
Line 1837... | Line 2161... | ||
1837 | I915_WRITE(VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE); |
2161 | I915_WRITE(VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE); |
Line 1838... | Line 2162... | ||
1838 | 2162 | ||
1839 | return 0; |
2163 | return 0; |
Line 1840... | Line -... | ||
1840 | } |
- | |
1841 | - | ||
1842 | static void valleyview_hpd_irq_setup(struct drm_device *dev) |
- | |
1843 | { |
- | |
1844 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
- | |
1845 | u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); |
- | |
1846 | - | ||
1847 | /* Note HDMI and DP share bits */ |
- | |
1848 | if (dev_priv->hotplug_supported_mask & PORTB_HOTPLUG_INT_STATUS) |
- | |
1849 | hotplug_en |= PORTB_HOTPLUG_INT_EN; |
- | |
1850 | if (dev_priv->hotplug_supported_mask & PORTC_HOTPLUG_INT_STATUS) |
- | |
1851 | hotplug_en |= PORTC_HOTPLUG_INT_EN; |
- | |
1852 | if (dev_priv->hotplug_supported_mask & PORTD_HOTPLUG_INT_STATUS) |
- | |
1853 | hotplug_en |= PORTD_HOTPLUG_INT_EN; |
- | |
1854 | if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_I915) |
- | |
1855 | hotplug_en |= SDVOC_HOTPLUG_INT_EN; |
- | |
1856 | if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_I915) |
- | |
1857 | hotplug_en |= SDVOB_HOTPLUG_INT_EN; |
- | |
1858 | if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) { |
- | |
1859 | hotplug_en |= CRT_HOTPLUG_INT_EN; |
- | |
1860 | hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; |
- | |
1861 | } |
- | |
1862 | - | ||
1863 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); |
- | |
1864 | } |
2164 | } |
1865 | 2165 | ||
1866 | static void valleyview_irq_uninstall(struct drm_device *dev) |
2166 | static void valleyview_irq_uninstall(struct drm_device *dev) |
1867 | { |
2167 | { |
Line 1900... | Line 2200... | ||
1900 | 2200 | ||
1901 | I915_WRITE(GTIMR, 0xffffffff); |
2201 | I915_WRITE(GTIMR, 0xffffffff); |
1902 | I915_WRITE(GTIER, 0x0); |
2202 | I915_WRITE(GTIER, 0x0); |
Line -... | Line 2203... | ||
- | 2203 | I915_WRITE(GTIIR, I915_READ(GTIIR)); |
|
- | 2204 | ||
- | 2205 | if (HAS_PCH_NOP(dev)) |
|
1903 | I915_WRITE(GTIIR, I915_READ(GTIIR)); |
2206 | return; |
1904 | 2207 | ||
1905 | I915_WRITE(SDEIMR, 0xffffffff); |
2208 | I915_WRITE(SDEIMR, 0xffffffff); |
1906 | I915_WRITE(SDEIER, 0x0); |
2209 | I915_WRITE(SDEIER, 0x0); |
Line 1925... | Line 2228... | ||
1925 | 2228 | ||
1926 | static int i8xx_irq_postinstall(struct drm_device *dev) |
2229 | static int i8xx_irq_postinstall(struct drm_device *dev) |
1927 | { |
2230 | { |
Line 1928... | Line -... | ||
1928 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
- | |
1929 | - | ||
1930 | dev_priv->pipestat[0] = 0; |
- | |
1931 | dev_priv->pipestat[1] = 0; |
2231 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1932 | 2232 | ||
Line 1933... | Line 2233... | ||
1933 | I915_WRITE16(EMR, |
2233 | I915_WRITE16(EMR, |
1934 | ~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH)); |
2234 | ~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH)); |
Line 1950... | Line 2250... | ||
1950 | POSTING_READ16(IER); |
2250 | POSTING_READ16(IER); |
Line 1951... | Line 2251... | ||
1951 | 2251 | ||
1952 | return 0; |
2252 | return 0; |
Line -... | Line 2253... | ||
- | 2253 | } |
|
- | 2254 | ||
- | 2255 | /* |
|
- | 2256 | * Returns true when a page flip has completed. |
|
- | 2257 | */ |
|
- | 2258 | static bool i8xx_handle_vblank(struct drm_device *dev, |
|
- | 2259 | int pipe, u16 iir) |
|
- | 2260 | { |
|
- | 2261 | drm_i915_private_t *dev_priv = dev->dev_private; |
|
- | 2262 | u16 flip_pending = DISPLAY_PLANE_FLIP_PENDING(pipe); |
|
- | 2263 | ||
- | 2264 | // if (!drm_handle_vblank(dev, pipe)) |
|
- | 2265 | return false; |
|
- | 2266 | ||
- | 2267 | if ((iir & flip_pending) == 0) |
|
- | 2268 | return false; |
|
- | 2269 | ||
- | 2270 | // intel_prepare_page_flip(dev, pipe); |
|
- | 2271 | ||
- | 2272 | /* We detect FlipDone by looking for the change in PendingFlip from '1' |
|
- | 2273 | * to '0' on the following vblank, i.e. IIR has the Pendingflip |
|
- | 2274 | * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence |
|
- | 2275 | * the flip is completed (no longer pending). Since this doesn't raise |
|
- | 2276 | * an interrupt per se, we watch for the change at vblank. |
|
- | 2277 | */ |
|
- | 2278 | if (I915_READ16(ISR) & flip_pending) |
|
- | 2279 | return false; |
|
- | 2280 | ||
- | 2281 | intel_finish_page_flip(dev, pipe); |
|
- | 2282 | ||
- | 2283 | return true; |
|
1953 | } |
2284 | } |
1954 | 2285 | ||
1955 | static irqreturn_t i8xx_irq_handler(int irq, void *arg) |
2286 | static irqreturn_t i8xx_irq_handler(int irq, void *arg) |
1956 | { |
2287 | { |
1957 | struct drm_device *dev = (struct drm_device *) arg; |
2288 | struct drm_device *dev = (struct drm_device *) arg; |
Line 2005... | Line 2336... | ||
2005 | 2336 | ||
2006 | if (iir & I915_USER_INTERRUPT) |
2337 | if (iir & I915_USER_INTERRUPT) |
Line 2007... | Line 2338... | ||
2007 | notify_ring(dev, &dev_priv->ring[RCS]); |
2338 | notify_ring(dev, &dev_priv->ring[RCS]); |
2008 | 2339 | ||
2009 | if (pipe_stats[0] & PIPE_VBLANK_INTERRUPT_STATUS && |
- | |
2010 | drm_handle_vblank(dev, 0)) { |
- | |
2011 | if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) { |
- | |
2012 | intel_prepare_page_flip(dev, 0); |
2340 | if (pipe_stats[0] & PIPE_VBLANK_INTERRUPT_STATUS && |
2013 | intel_finish_page_flip(dev, 0); |
- | |
2014 | flip_mask &= ~I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT; |
- | |
Line 2015... | Line 2341... | ||
2015 | } |
2341 | i8xx_handle_vblank(dev, 0, iir)) |
2016 | } |
2342 | flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(0); |
2017 | - | ||
2018 | if (pipe_stats[1] & PIPE_VBLANK_INTERRUPT_STATUS && |
- | |
2019 | drm_handle_vblank(dev, 1)) { |
- | |
2020 | if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT) { |
2343 | |
2021 | intel_prepare_page_flip(dev, 1); |
- | |
2022 | intel_finish_page_flip(dev, 1); |
- | |
Line 2023... | Line 2344... | ||
2023 | flip_mask &= ~I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; |
2344 | if (pipe_stats[1] & PIPE_VBLANK_INTERRUPT_STATUS && |
2024 | } |
2345 | i8xx_handle_vblank(dev, 1, iir)) |
Line 2025... | Line 2346... | ||
2025 | } |
2346 | flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(1); |
Line 2070... | Line 2391... | ||
2070 | static int i915_irq_postinstall(struct drm_device *dev) |
2391 | static int i915_irq_postinstall(struct drm_device *dev) |
2071 | { |
2392 | { |
2072 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2393 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2073 | u32 enable_mask; |
2394 | u32 enable_mask; |
Line 2074... | Line -... | ||
2074 | - | ||
2075 | dev_priv->pipestat[0] = 0; |
- | |
2076 | dev_priv->pipestat[1] = 0; |
- | |
2077 | 2395 | ||
Line 2078... | Line 2396... | ||
2078 | I915_WRITE(EMR, ~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH)); |
2396 | I915_WRITE(EMR, ~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH)); |
2079 | 2397 | ||
2080 | /* Unmask the interrupts that we always want on. */ |
2398 | /* Unmask the interrupts that we always want on. */ |
Line 2110... | Line 2428... | ||
2110 | // intel_opregion_enable_asle(dev); |
2428 | // intel_opregion_enable_asle(dev); |
Line 2111... | Line 2429... | ||
2111 | 2429 | ||
2112 | return 0; |
2430 | return 0; |
Line -... | Line 2431... | ||
- | 2431 | } |
|
- | 2432 | ||
- | 2433 | /* |
|
2113 | } |
2434 | * Returns true when a page flip has completed. |
- | 2435 | */ |
|
2114 | 2436 | static bool i915_handle_vblank(struct drm_device *dev, |
|
2115 | static void i915_hpd_irq_setup(struct drm_device *dev) |
2437 | int plane, int pipe, u32 iir) |
2116 | { |
2438 | { |
Line 2117... | Line 2439... | ||
2117 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2439 | drm_i915_private_t *dev_priv = dev->dev_private; |
2118 | u32 hotplug_en; |
2440 | u32 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane); |
Line 2119... | Line -... | ||
2119 | - | ||
2120 | if (I915_HAS_HOTPLUG(dev)) { |
- | |
2121 | hotplug_en = I915_READ(PORT_HOTPLUG_EN); |
- | |
2122 | 2441 | ||
2123 | if (dev_priv->hotplug_supported_mask & PORTB_HOTPLUG_INT_STATUS) |
- | |
2124 | hotplug_en |= PORTB_HOTPLUG_INT_EN; |
- | |
2125 | if (dev_priv->hotplug_supported_mask & PORTC_HOTPLUG_INT_STATUS) |
- | |
2126 | hotplug_en |= PORTC_HOTPLUG_INT_EN; |
- | |
2127 | if (dev_priv->hotplug_supported_mask & PORTD_HOTPLUG_INT_STATUS) |
- | |
2128 | hotplug_en |= PORTD_HOTPLUG_INT_EN; |
- | |
2129 | if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_I915) |
- | |
2130 | hotplug_en |= SDVOC_HOTPLUG_INT_EN; |
2442 | // if (!drm_handle_vblank(dev, pipe)) |
2131 | if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_I915) |
- | |
2132 | hotplug_en |= SDVOB_HOTPLUG_INT_EN; |
- | |
Line 2133... | Line 2443... | ||
2133 | if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) { |
2443 | return false; |
Line -... | Line 2444... | ||
- | 2444 | ||
- | 2445 | if ((iir & flip_pending) == 0) |
|
- | 2446 | return false; |
|
- | 2447 | ||
- | 2448 | // intel_prepare_page_flip(dev, plane); |
|
- | 2449 | ||
2134 | hotplug_en |= CRT_HOTPLUG_INT_EN; |
2450 | /* We detect FlipDone by looking for the change in PendingFlip from '1' |
- | 2451 | * to '0' on the following vblank, i.e. IIR has the Pendingflip |
|
- | 2452 | * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence |
|
- | 2453 | * the flip is completed (no longer pending). Since this doesn't raise |
|
2135 | hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; |
2454 | * an interrupt per se, we watch for the change at vblank. |
- | 2455 | */ |
|
2136 | } |
2456 | if (I915_READ(ISR) & flip_pending) |
Line 2137... | Line 2457... | ||
2137 | 2457 | return false; |
|
2138 | /* Ignore TV since it's buggy */ |
2458 | |
2139 | 2459 | intel_finish_page_flip(dev, pipe); |
|
Line 2148... | Line 2468... | ||
2148 | u32 iir, new_iir, pipe_stats[I915_MAX_PIPES]; |
2468 | u32 iir, new_iir, pipe_stats[I915_MAX_PIPES]; |
2149 | unsigned long irqflags; |
2469 | unsigned long irqflags; |
2150 | u32 flip_mask = |
2470 | u32 flip_mask = |
2151 | I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | |
2471 | I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | |
2152 | I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; |
2472 | I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; |
2153 | u32 flip[2] = { |
- | |
2154 | I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT, |
- | |
2155 | I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT |
- | |
2156 | }; |
- | |
2157 | int pipe, ret = IRQ_NONE; |
2473 | int pipe, ret = IRQ_NONE; |
Line 2158... | Line 2474... | ||
2158 | 2474 | ||
Line 2159... | Line 2475... | ||
2159 | atomic_inc(&dev_priv->irq_received); |
2475 | atomic_inc(&dev_priv->irq_received); |
Line 2192... | Line 2508... | ||
2192 | 2508 | ||
2193 | /* Consume port. Then clear IIR or we'll miss events */ |
2509 | /* Consume port. Then clear IIR or we'll miss events */ |
2194 | if ((I915_HAS_HOTPLUG(dev)) && |
2510 | if ((I915_HAS_HOTPLUG(dev)) && |
2195 | (iir & I915_DISPLAY_PORT_INTERRUPT)) { |
2511 | (iir & I915_DISPLAY_PORT_INTERRUPT)) { |
- | 2512 | u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); |
|
Line 2196... | Line 2513... | ||
2196 | u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); |
2513 | u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_I915; |
2197 | 2514 | ||
- | 2515 | DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", |
|
2198 | DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", |
2516 | hotplug_status); |
- | 2517 | if (hotplug_trigger) { |
|
2199 | hotplug_status); |
2518 | if (hotplug_irq_storm_detect(dev, hotplug_trigger, hpd_status_i915)) |
2200 | if (hotplug_status & dev_priv->hotplug_supported_mask) |
2519 | i915_hpd_irq_setup(dev); |
2201 | queue_work(dev_priv->wq, |
2520 | queue_work(dev_priv->wq, |
2202 | &dev_priv->hotplug_work); |
2521 | &dev_priv->hotplug_work); |
2203 | 2522 | } |
|
2204 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); |
2523 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); |
Line 2205... | Line 2524... | ||
2205 | POSTING_READ(PORT_HOTPLUG_STAT); |
2524 | POSTING_READ(PORT_HOTPLUG_STAT); |
Line 2213... | Line 2532... | ||
2213 | 2532 | ||
2214 | for_each_pipe(pipe) { |
2533 | for_each_pipe(pipe) { |
2215 | int plane = pipe; |
2534 | int plane = pipe; |
2216 | if (IS_MOBILE(dev)) |
2535 | if (IS_MOBILE(dev)) |
- | 2536 | plane = !plane; |
|
2217 | plane = !plane; |
2537 | |
2218 | if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS /* && |
2538 | if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS && |
2219 | drm_handle_vblank(dev, pipe) */) { |
- | |
2220 | if (iir & flip[plane]) { |
- | |
2221 | // intel_prepare_page_flip(dev, plane); |
- | |
2222 | // intel_finish_page_flip(dev, pipe); |
2539 | i915_handle_vblank(dev, plane, pipe, iir)) |
2223 | flip_mask &= ~flip[plane]; |
- | |
2224 | } |
- | |
Line 2225... | Line 2540... | ||
2225 | } |
2540 | flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(plane); |
2226 | 2541 | ||
2227 | if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) |
2542 | if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) |
Line 2309... | Line 2624... | ||
2309 | I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | |
2624 | I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | |
2310 | I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT | |
2625 | I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT | |
2311 | I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); |
2626 | I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); |
Line 2312... | Line 2627... | ||
2312 | 2627 | ||
- | 2628 | enable_mask = ~dev_priv->irq_mask; |
|
- | 2629 | enable_mask &= ~(I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | |
|
2313 | enable_mask = ~dev_priv->irq_mask; |
2630 | I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT); |
Line 2314... | Line 2631... | ||
2314 | enable_mask |= I915_USER_INTERRUPT; |
2631 | enable_mask |= I915_USER_INTERRUPT; |
2315 | 2632 | ||
Line 2316... | Line -... | ||
2316 | if (IS_G4X(dev)) |
- | |
2317 | enable_mask |= I915_BSD_USER_INTERRUPT; |
- | |
2318 | 2633 | if (IS_G4X(dev)) |
|
Line 2319... | Line 2634... | ||
2319 | dev_priv->pipestat[0] = 0; |
2634 | enable_mask |= I915_BSD_USER_INTERRUPT; |
2320 | dev_priv->pipestat[1] = 0; |
2635 | |
2321 | i915_enable_pipestat(dev_priv, 0, PIPE_GMBUS_EVENT_ENABLE); |
2636 | i915_enable_pipestat(dev_priv, 0, PIPE_GMBUS_EVENT_ENABLE); |
Line 2345... | Line 2660... | ||
2345 | // intel_opregion_enable_asle(dev); |
2660 | // intel_opregion_enable_asle(dev); |
Line 2346... | Line 2661... | ||
2346 | 2661 | ||
2347 | return 0; |
2662 | return 0; |
Line 2348... | Line 2663... | ||
2348 | } |
2663 | } |
2349 | 2664 | ||
2350 | static void i965_hpd_irq_setup(struct drm_device *dev) |
2665 | static void i915_hpd_irq_setup(struct drm_device *dev) |
- | 2666 | { |
|
- | 2667 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
|
2351 | { |
2668 | struct drm_mode_config *mode_config = &dev->mode_config; |
Line -... | Line 2669... | ||
- | 2669 | struct intel_encoder *intel_encoder; |
|
- | 2670 | u32 hotplug_en; |
|
- | 2671 | ||
2352 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2672 | if (I915_HAS_HOTPLUG(dev)) { |
2353 | u32 hotplug_en; |
- | |
2354 | - | ||
2355 | /* Note HDMI and DP share hotplug bits */ |
- | |
2356 | hotplug_en = 0; |
- | |
2357 | if (dev_priv->hotplug_supported_mask & PORTB_HOTPLUG_INT_STATUS) |
- | |
2358 | hotplug_en |= PORTB_HOTPLUG_INT_EN; |
2673 | hotplug_en = I915_READ(PORT_HOTPLUG_EN); |
2359 | if (dev_priv->hotplug_supported_mask & PORTC_HOTPLUG_INT_STATUS) |
- | |
2360 | hotplug_en |= PORTC_HOTPLUG_INT_EN; |
- | |
2361 | if (dev_priv->hotplug_supported_mask & PORTD_HOTPLUG_INT_STATUS) |
- | |
2362 | hotplug_en |= PORTD_HOTPLUG_INT_EN; |
- | |
2363 | if (IS_G4X(dev)) { |
- | |
2364 | if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_G4X) |
- | |
2365 | hotplug_en |= SDVOC_HOTPLUG_INT_EN; |
- | |
2366 | if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_G4X) |
2674 | hotplug_en &= ~HOTPLUG_INT_EN_MASK; |
2367 | hotplug_en |= SDVOB_HOTPLUG_INT_EN; |
- | |
2368 | } else { |
2675 | /* Note HDMI and DP share hotplug bits */ |
2369 | if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_I965) |
2676 | /* enable bits are the same for all generations */ |
2370 | hotplug_en |= SDVOC_HOTPLUG_INT_EN; |
- | |
2371 | if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_I965) |
- | |
2372 | hotplug_en |= SDVOB_HOTPLUG_INT_EN; |
- | |
2373 | } |
- | |
2374 | if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) { |
2677 | list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head) |
2375 | hotplug_en |= CRT_HOTPLUG_INT_EN; |
2678 | if (dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark == HPD_ENABLED) |
2376 | 2679 | hotplug_en |= hpd_mask_i915[intel_encoder->hpd_pin]; |
|
2377 | /* Programming the CRT detection parameters tends |
2680 | /* Programming the CRT detection parameters tends |
2378 | to generate a spurious hotplug event about three |
2681 | to generate a spurious hotplug event about three |
2379 | seconds later. So just do it once. |
2682 | seconds later. So just do it once. |
- | 2683 | */ |
|
2380 | */ |
2684 | if (IS_G4X(dev)) |
2381 | if (IS_G4X(dev)) |
- | |
Line 2382... | Line 2685... | ||
2382 | hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64; |
2685 | hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64; |
2383 | hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; |
- | |
2384 | } |
2686 | hotplug_en &= ~CRT_HOTPLUG_VOLTAGE_COMPARE_MASK; |
2385 | 2687 | hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; |
|
- | 2688 | ||
Line 2386... | Line 2689... | ||
2386 | /* Ignore TV since it's buggy */ |
2689 | /* Ignore TV since it's buggy */ |
2387 | 2690 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); |
|
2388 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); |
2691 | } |
2389 | } |
2692 | } |
2390 | 2693 | ||
2391 | static irqreturn_t i965_irq_handler(int irq, void *arg) |
2694 | static irqreturn_t i965_irq_handler(int irq, void *arg) |
2392 | { |
2695 | { |
2393 | struct drm_device *dev = (struct drm_device *) arg; |
2696 | struct drm_device *dev = (struct drm_device *) arg; |
2394 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2697 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
- | 2698 | u32 iir, new_iir; |
|
- | 2699 | u32 pipe_stats[I915_MAX_PIPES]; |
|
- | 2700 | unsigned long irqflags; |
|
Line 2395... | Line 2701... | ||
2395 | u32 iir, new_iir; |
2701 | int irq_received; |
Line 2396... | Line 2702... | ||
2396 | u32 pipe_stats[I915_MAX_PIPES]; |
2702 | int ret = IRQ_NONE, pipe; |
Line 2397... | Line 2703... | ||
2397 | unsigned long irqflags; |
2703 | u32 flip_mask = |
2398 | int irq_received; |
2704 | I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | |
Line 2399... | Line 2705... | ||
2399 | int ret = IRQ_NONE, pipe; |
2705 | I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; |
Line 2400... | Line 2706... | ||
2400 | 2706 | ||
2401 | atomic_inc(&dev_priv->irq_received); |
2707 | atomic_inc(&dev_priv->irq_received); |
2402 | 2708 | ||
2403 | iir = I915_READ(IIR); |
2709 | iir = I915_READ(IIR); |
Line 2439... | Line 2745... | ||
2439 | ret = IRQ_HANDLED; |
2745 | ret = IRQ_HANDLED; |
Line 2440... | Line 2746... | ||
2440 | 2746 | ||
2441 | /* Consume port. Then clear IIR or we'll miss events */ |
2747 | /* Consume port. Then clear IIR or we'll miss events */ |
2442 | if (iir & I915_DISPLAY_PORT_INTERRUPT) { |
2748 | if (iir & I915_DISPLAY_PORT_INTERRUPT) { |
- | 2749 | u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); |
|
- | 2750 | u32 hotplug_trigger = hotplug_status & (IS_G4X(dev) ? |
|
- | 2751 | HOTPLUG_INT_STATUS_G4X : |
|
Line 2443... | Line 2752... | ||
2443 | u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); |
2752 | HOTPLUG_INT_STATUS_I965); |
2444 | 2753 | ||
- | 2754 | DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", |
|
2445 | DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", |
2755 | hotplug_status); |
- | 2756 | if (hotplug_trigger) { |
|
- | 2757 | if (hotplug_irq_storm_detect(dev, hotplug_trigger, |
|
2446 | hotplug_status); |
2758 | IS_G4X(dev) ? hpd_status_gen4 : hpd_status_i965)) |
2447 | if (hotplug_status & dev_priv->hotplug_supported_mask) |
2759 | i915_hpd_irq_setup(dev); |
2448 | queue_work(dev_priv->wq, |
2760 | queue_work(dev_priv->wq, |
2449 | &dev_priv->hotplug_work); |
2761 | &dev_priv->hotplug_work); |
2450 | 2762 | } |
|
2451 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); |
2763 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); |
Line 2452... | Line 2764... | ||
2452 | I915_READ(PORT_HOTPLUG_STAT); |
2764 | I915_READ(PORT_HOTPLUG_STAT); |
2453 | } |
2765 | } |
Line 2454... | Line 2766... | ||
2454 | 2766 | ||
2455 | I915_WRITE(IIR, iir); |
2767 | I915_WRITE(IIR, iir & ~flip_mask); |
2456 | new_iir = I915_READ(IIR); /* Flush posted writes */ |
2768 | new_iir = I915_READ(IIR); /* Flush posted writes */ |
2457 | 2769 | ||
Line 2458... | Line -... | ||
2458 | if (iir & I915_USER_INTERRUPT) |
- | |
2459 | notify_ring(dev, &dev_priv->ring[RCS]); |
- | |
2460 | if (iir & I915_BSD_USER_INTERRUPT) |
- | |
2461 | notify_ring(dev, &dev_priv->ring[VCS]); |
- | |
2462 | - | ||
2463 | // if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) |
- | |
2464 | // intel_prepare_page_flip(dev, 0); |
2770 | if (iir & I915_USER_INTERRUPT) |
2465 | 2771 | notify_ring(dev, &dev_priv->ring[RCS]); |
|
2466 | // if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT) |
2772 | if (iir & I915_BSD_USER_INTERRUPT) |
2467 | // intel_prepare_page_flip(dev, 1); |
2773 | notify_ring(dev, &dev_priv->ring[VCS]); |
2468 | - | ||
2469 | for_each_pipe(pipe) { |
- | |
Line 2470... | Line 2774... | ||
2470 | // if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS && |
2774 | |
2471 | // drm_handle_vblank(dev, pipe)) { |
2775 | for_each_pipe(pipe) { |
2472 | // i915_pageflip_stall_check(dev, pipe); |
2776 | if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS && |
Line 2542... | Line 2846... | ||
2542 | 2846 | ||
2543 | if (IS_VALLEYVIEW(dev)) { |
2847 | if (IS_VALLEYVIEW(dev)) { |
2544 | dev->driver->irq_handler = valleyview_irq_handler; |
2848 | dev->driver->irq_handler = valleyview_irq_handler; |
2545 | dev->driver->irq_preinstall = valleyview_irq_preinstall; |
2849 | dev->driver->irq_preinstall = valleyview_irq_preinstall; |
2546 | dev->driver->irq_postinstall = valleyview_irq_postinstall; |
2850 | dev->driver->irq_postinstall = valleyview_irq_postinstall; |
2547 | dev_priv->display.hpd_irq_setup = valleyview_hpd_irq_setup; |
2851 | dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; |
2548 | } else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { |
2852 | } else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { |
2549 | /* Share pre & uninstall handlers with ILK/SNB */ |
2853 | /* Share pre & uninstall handlers with ILK/SNB */ |
2550 | dev->driver->irq_handler = ivybridge_irq_handler; |
2854 | dev->driver->irq_handler = ivybridge_irq_handler; |
2551 | dev->driver->irq_preinstall = ironlake_irq_preinstall; |
2855 | dev->driver->irq_preinstall = ironlake_irq_preinstall; |
- | 2856 | dev->driver->irq_postinstall = ivybridge_irq_postinstall; |
|
2552 | dev->driver->irq_postinstall = ivybridge_irq_postinstall; |
2857 | dev_priv->display.hpd_irq_setup = ibx_hpd_irq_setup; |
2553 | } else if (HAS_PCH_SPLIT(dev)) { |
2858 | } else if (HAS_PCH_SPLIT(dev)) { |
2554 | dev->driver->irq_handler = ironlake_irq_handler; |
2859 | dev->driver->irq_handler = ironlake_irq_handler; |
2555 | dev->driver->irq_preinstall = ironlake_irq_preinstall; |
2860 | dev->driver->irq_preinstall = ironlake_irq_preinstall; |
- | 2861 | dev->driver->irq_postinstall = ironlake_irq_postinstall; |
|
2556 | dev->driver->irq_postinstall = ironlake_irq_postinstall; |
2862 | dev_priv->display.hpd_irq_setup = ibx_hpd_irq_setup; |
2557 | } else { |
2863 | } else { |
2558 | if (INTEL_INFO(dev)->gen == 2) { |
2864 | if (INTEL_INFO(dev)->gen == 2) { |
2559 | } else if (INTEL_INFO(dev)->gen == 3) { |
2865 | } else if (INTEL_INFO(dev)->gen == 3) { |
2560 | dev->driver->irq_preinstall = i915_irq_preinstall; |
2866 | dev->driver->irq_preinstall = i915_irq_preinstall; |
Line 2563... | Line 2869... | ||
2563 | dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; |
2869 | dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; |
2564 | } else { |
2870 | } else { |
2565 | dev->driver->irq_preinstall = i965_irq_preinstall; |
2871 | dev->driver->irq_preinstall = i965_irq_preinstall; |
2566 | dev->driver->irq_postinstall = i965_irq_postinstall; |
2872 | dev->driver->irq_postinstall = i965_irq_postinstall; |
2567 | dev->driver->irq_handler = i965_irq_handler; |
2873 | dev->driver->irq_handler = i965_irq_handler; |
2568 | dev_priv->display.hpd_irq_setup = i965_hpd_irq_setup; |
2874 | dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; |
2569 | } |
2875 | } |
2570 | } |
2876 | } |
2571 | } |
2877 | } |
Line 2572... | Line 2878... | ||
2572 | 2878 | ||
2573 | void intel_hpd_init(struct drm_device *dev) |
2879 | void intel_hpd_init(struct drm_device *dev) |
2574 | { |
2880 | { |
- | 2881 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 2882 | struct drm_mode_config *mode_config = &dev->mode_config; |
|
- | 2883 | struct drm_connector *connector; |
|
Line -... | Line 2884... | ||
- | 2884 | int i; |
|
- | 2885 | ||
- | 2886 | for (i = 1; i < HPD_NUM_PINS; i++) { |
|
- | 2887 | dev_priv->hpd_stats[i].hpd_cnt = 0; |
|
- | 2888 | dev_priv->hpd_stats[i].hpd_mark = HPD_ENABLED; |
|
- | 2889 | } |
|
- | 2890 | list_for_each_entry(connector, &mode_config->connector_list, head) { |
|
- | 2891 | struct intel_connector *intel_connector = to_intel_connector(connector); |
|
- | 2892 | connector->polled = intel_connector->polled; |
|
- | 2893 | if (!connector->polled && I915_HAS_HOTPLUG(dev) && intel_connector->encoder->hpd_pin > HPD_NONE) |
|
2575 | struct drm_i915_private *dev_priv = dev->dev_private; |
2894 | connector->polled = DRM_CONNECTOR_POLL_HPD; |
2576 | 2895 | } |
|
2577 | if (dev_priv->display.hpd_irq_setup) |
2896 | if (dev_priv->display.hpd_irq_setup) |