Commit 6f19e7e5ae29b3df9061f9141ac138f60b8f416d
Exists in
master
and in
13 other branches
Merge tag 'drm-intel-fixes-2014-04-25' of git://anongit.freedesktop.org/drm-intel into drm-next
Fix regression with DVI and fix warns, and GM45 boot regression. * tag 'drm-intel-fixes-2014-04-25' of git://anongit.freedesktop.org/drm-intel: drm/i915: Move all ring resets before setting the HWS page drm/i915: Don't WARN nor handle unexpected hpd interrupts on gmch platforms drm/i915: Allow full PPGTT with param override drm/i915: Discard BIOS framebuffers too small to accommodate chosen mode drm/i915: get power domain in case the BIOS enabled eDP VDD drm/i915: Don't check gmch state on inherited configs drm/i915: Allow user modes to exceed DVI 165MHz limit
Showing 10 changed files Side-by-side Diff
- drivers/gpu/drm/i915/i915_gem_gtt.c
- drivers/gpu/drm/i915/i915_irq.c
- drivers/gpu/drm/i915/i915_reg.h
- drivers/gpu/drm/i915/intel_display.c
- drivers/gpu/drm/i915/intel_dp.c
- drivers/gpu/drm/i915/intel_drv.h
- drivers/gpu/drm/i915/intel_fbdev.c
- drivers/gpu/drm/i915/intel_hdmi.c
- drivers/gpu/drm/i915/intel_ringbuffer.c
- drivers/gpu/drm/i915/intel_ringbuffer.h
drivers/gpu/drm/i915/i915_gem_gtt.c
drivers/gpu/drm/i915/i915_irq.c
... | ... | @@ -1362,10 +1362,20 @@ |
1362 | 1362 | spin_lock(&dev_priv->irq_lock); |
1363 | 1363 | for (i = 1; i < HPD_NUM_PINS; i++) { |
1364 | 1364 | |
1365 | - WARN_ONCE(hpd[i] & hotplug_trigger && | |
1366 | - dev_priv->hpd_stats[i].hpd_mark == HPD_DISABLED, | |
1367 | - "Received HPD interrupt (0x%08x) on pin %d (0x%08x) although disabled\n", | |
1368 | - hotplug_trigger, i, hpd[i]); | |
1365 | + if (hpd[i] & hotplug_trigger && | |
1366 | + dev_priv->hpd_stats[i].hpd_mark == HPD_DISABLED) { | |
1367 | + /* | |
1368 | + * On GMCH platforms the interrupt mask bits only | |
1369 | + * prevent irq generation, not the setting of the | |
1370 | + * hotplug bits itself. So only WARN about unexpected | |
1371 | + * interrupts on saner platforms. | |
1372 | + */ | |
1373 | + WARN_ONCE(INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev), | |
1374 | + "Received HPD interrupt (0x%08x) on pin %d (0x%08x) although disabled\n", | |
1375 | + hotplug_trigger, i, hpd[i]); | |
1376 | + | |
1377 | + continue; | |
1378 | + } | |
1369 | 1379 | |
1370 | 1380 | if (!(hpd[i] & hotplug_trigger) || |
1371 | 1381 | dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED) |
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c
... | ... | @@ -9654,11 +9654,22 @@ |
9654 | 9654 | PIPE_CONF_CHECK_I(pipe_src_w); |
9655 | 9655 | PIPE_CONF_CHECK_I(pipe_src_h); |
9656 | 9656 | |
9657 | - PIPE_CONF_CHECK_I(gmch_pfit.control); | |
9658 | - /* pfit ratios are autocomputed by the hw on gen4+ */ | |
9659 | - if (INTEL_INFO(dev)->gen < 4) | |
9660 | - PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios); | |
9661 | - PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits); | |
9657 | + /* | |
9658 | + * FIXME: BIOS likes to set up a cloned config with lvds+external | |
9659 | + * screen. Since we don't yet re-compute the pipe config when moving | |
9660 | + * just the lvds port away to another pipe the sw tracking won't match. | |
9661 | + * | |
9662 | + * Proper atomic modesets with recomputed global state will fix this. | |
9663 | + * Until then just don't check gmch state for inherited modes. | |
9664 | + */ | |
9665 | + if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_INHERITED_MODE)) { | |
9666 | + PIPE_CONF_CHECK_I(gmch_pfit.control); | |
9667 | + /* pfit ratios are autocomputed by the hw on gen4+ */ | |
9668 | + if (INTEL_INFO(dev)->gen < 4) | |
9669 | + PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios); | |
9670 | + PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits); | |
9671 | + } | |
9672 | + | |
9662 | 9673 | PIPE_CONF_CHECK_I(pch_pfit.enabled); |
9663 | 9674 | if (current_config->pch_pfit.enabled) { |
9664 | 9675 | PIPE_CONF_CHECK_I(pch_pfit.pos); |
... | ... | @@ -11615,6 +11626,8 @@ |
11615 | 11626 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, |
11616 | 11627 | base.head) { |
11617 | 11628 | memset(&crtc->config, 0, sizeof(crtc->config)); |
11629 | + | |
11630 | + crtc->config.quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE; | |
11618 | 11631 | |
11619 | 11632 | crtc->active = dev_priv->display.get_pipe_config(crtc, |
11620 | 11633 | &crtc->config); |
drivers/gpu/drm/i915/intel_dp.c
... | ... | @@ -3619,7 +3619,8 @@ |
3619 | 3619 | { |
3620 | 3620 | struct drm_connector *connector = &intel_connector->base; |
3621 | 3621 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
3622 | - struct drm_device *dev = intel_dig_port->base.base.dev; | |
3622 | + struct intel_encoder *intel_encoder = &intel_dig_port->base; | |
3623 | + struct drm_device *dev = intel_encoder->base.dev; | |
3623 | 3624 | struct drm_i915_private *dev_priv = dev->dev_private; |
3624 | 3625 | struct drm_display_mode *fixed_mode = NULL; |
3625 | 3626 | bool has_dpcd; |
... | ... | @@ -3628,6 +3629,14 @@ |
3628 | 3629 | |
3629 | 3630 | if (!is_edp(intel_dp)) |
3630 | 3631 | return true; |
3632 | + | |
3633 | + /* The VDD bit needs a power domain reference, so if the bit is already | |
3634 | + * enabled when we boot, grab this reference. */ | |
3635 | + if (edp_have_panel_vdd(intel_dp)) { | |
3636 | + enum intel_display_power_domain power_domain; | |
3637 | + power_domain = intel_display_port_power_domain(intel_encoder); | |
3638 | + intel_display_power_get(dev_priv, power_domain); | |
3639 | + } | |
3631 | 3640 | |
3632 | 3641 | /* Cache DPCD and EDID for edp. */ |
3633 | 3642 | intel_edp_panel_vdd_on(intel_dp); |
drivers/gpu/drm/i915/intel_drv.h
... | ... | @@ -236,7 +236,8 @@ |
236 | 236 | * tracked with quirk flags so that fastboot and state checker can act |
237 | 237 | * accordingly. |
238 | 238 | */ |
239 | -#define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS (1<<0) /* unreliable sync mode.flags */ | |
239 | +#define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS (1<<0) /* unreliable sync mode.flags */ | |
240 | +#define PIPE_CONFIG_QUIRK_INHERITED_MODE (1<<1) /* mode inherited from firmware */ | |
240 | 241 | unsigned long quirks; |
241 | 242 | |
242 | 243 | /* User requested mode, only valid as a starting point to |
drivers/gpu/drm/i915/intel_fbdev.c
... | ... | @@ -132,6 +132,16 @@ |
132 | 132 | |
133 | 133 | mutex_lock(&dev->struct_mutex); |
134 | 134 | |
135 | + if (intel_fb && | |
136 | + (sizes->fb_width > intel_fb->base.width || | |
137 | + sizes->fb_height > intel_fb->base.height)) { | |
138 | + DRM_DEBUG_KMS("BIOS fb too small (%dx%d), we require (%dx%d)," | |
139 | + " releasing it\n", | |
140 | + intel_fb->base.width, intel_fb->base.height, | |
141 | + sizes->fb_width, sizes->fb_height); | |
142 | + drm_framebuffer_unreference(&intel_fb->base); | |
143 | + intel_fb = ifbdev->fb = NULL; | |
144 | + } | |
135 | 145 | if (!intel_fb || WARN_ON(!intel_fb->obj)) { |
136 | 146 | DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n"); |
137 | 147 | ret = intelfb_alloc(helper, sizes); |
drivers/gpu/drm/i915/intel_hdmi.c
... | ... | @@ -821,11 +821,11 @@ |
821 | 821 | } |
822 | 822 | } |
823 | 823 | |
824 | -static int hdmi_portclock_limit(struct intel_hdmi *hdmi) | |
824 | +static int hdmi_portclock_limit(struct intel_hdmi *hdmi, bool respect_dvi_limit) | |
825 | 825 | { |
826 | 826 | struct drm_device *dev = intel_hdmi_to_dev(hdmi); |
827 | 827 | |
828 | - if (!hdmi->has_hdmi_sink || IS_G4X(dev)) | |
828 | + if ((respect_dvi_limit && !hdmi->has_hdmi_sink) || IS_G4X(dev)) | |
829 | 829 | return 165000; |
830 | 830 | else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) |
831 | 831 | return 300000; |
... | ... | @@ -837,7 +837,8 @@ |
837 | 837 | intel_hdmi_mode_valid(struct drm_connector *connector, |
838 | 838 | struct drm_display_mode *mode) |
839 | 839 | { |
840 | - if (mode->clock > hdmi_portclock_limit(intel_attached_hdmi(connector))) | |
840 | + if (mode->clock > hdmi_portclock_limit(intel_attached_hdmi(connector), | |
841 | + true)) | |
841 | 842 | return MODE_CLOCK_HIGH; |
842 | 843 | if (mode->clock < 20000) |
843 | 844 | return MODE_CLOCK_LOW; |
... | ... | @@ -879,7 +880,7 @@ |
879 | 880 | struct drm_device *dev = encoder->base.dev; |
880 | 881 | struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; |
881 | 882 | int clock_12bpc = pipe_config->adjusted_mode.crtc_clock * 3 / 2; |
882 | - int portclock_limit = hdmi_portclock_limit(intel_hdmi); | |
883 | + int portclock_limit = hdmi_portclock_limit(intel_hdmi, false); | |
883 | 884 | int desired_bpp; |
884 | 885 | |
885 | 886 | if (intel_hdmi->color_range_auto) { |
drivers/gpu/drm/i915/intel_ringbuffer.c
... | ... | @@ -437,32 +437,41 @@ |
437 | 437 | I915_WRITE(HWS_PGA, addr); |
438 | 438 | } |
439 | 439 | |
440 | -static int init_ring_common(struct intel_ring_buffer *ring) | |
440 | +static bool stop_ring(struct intel_ring_buffer *ring) | |
441 | 441 | { |
442 | - struct drm_device *dev = ring->dev; | |
443 | - struct drm_i915_private *dev_priv = dev->dev_private; | |
444 | - struct drm_i915_gem_object *obj = ring->obj; | |
445 | - int ret = 0; | |
446 | - u32 head; | |
442 | + struct drm_i915_private *dev_priv = to_i915(ring->dev); | |
447 | 443 | |
448 | - gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); | |
444 | + if (!IS_GEN2(ring->dev)) { | |
445 | + I915_WRITE_MODE(ring, _MASKED_BIT_ENABLE(STOP_RING)); | |
446 | + if (wait_for_atomic((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000)) { | |
447 | + DRM_ERROR("%s :timed out trying to stop ring\n", ring->name); | |
448 | + return false; | |
449 | + } | |
450 | + } | |
449 | 451 | |
450 | - /* Stop the ring if it's running. */ | |
451 | 452 | I915_WRITE_CTL(ring, 0); |
452 | 453 | I915_WRITE_HEAD(ring, 0); |
453 | 454 | ring->write_tail(ring, 0); |
454 | - if (wait_for_atomic((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000)) | |
455 | - DRM_ERROR("%s :timed out trying to stop ring\n", ring->name); | |
456 | 455 | |
457 | - if (I915_NEED_GFX_HWS(dev)) | |
458 | - intel_ring_setup_status_page(ring); | |
459 | - else | |
460 | - ring_setup_phys_status_page(ring); | |
456 | + if (!IS_GEN2(ring->dev)) { | |
457 | + (void)I915_READ_CTL(ring); | |
458 | + I915_WRITE_MODE(ring, _MASKED_BIT_DISABLE(STOP_RING)); | |
459 | + } | |
461 | 460 | |
462 | - head = I915_READ_HEAD(ring) & HEAD_ADDR; | |
461 | + return (I915_READ_HEAD(ring) & HEAD_ADDR) == 0; | |
462 | +} | |
463 | 463 | |
464 | - /* G45 ring initialization fails to reset head to zero */ | |
465 | - if (head != 0) { | |
464 | +static int init_ring_common(struct intel_ring_buffer *ring) | |
465 | +{ | |
466 | + struct drm_device *dev = ring->dev; | |
467 | + struct drm_i915_private *dev_priv = dev->dev_private; | |
468 | + struct drm_i915_gem_object *obj = ring->obj; | |
469 | + int ret = 0; | |
470 | + | |
471 | + gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); | |
472 | + | |
473 | + if (!stop_ring(ring)) { | |
474 | + /* G45 ring initialization often fails to reset head to zero */ | |
466 | 475 | DRM_DEBUG_KMS("%s head not reset to zero " |
467 | 476 | "ctl %08x head %08x tail %08x start %08x\n", |
468 | 477 | ring->name, |
... | ... | @@ -471,9 +480,7 @@ |
471 | 480 | I915_READ_TAIL(ring), |
472 | 481 | I915_READ_START(ring)); |
473 | 482 | |
474 | - I915_WRITE_HEAD(ring, 0); | |
475 | - | |
476 | - if (I915_READ_HEAD(ring) & HEAD_ADDR) { | |
483 | + if (!stop_ring(ring)) { | |
477 | 484 | DRM_ERROR("failed to set %s head to zero " |
478 | 485 | "ctl %08x head %08x tail %08x start %08x\n", |
479 | 486 | ring->name, |
480 | 487 | |
... | ... | @@ -481,8 +488,15 @@ |
481 | 488 | I915_READ_HEAD(ring), |
482 | 489 | I915_READ_TAIL(ring), |
483 | 490 | I915_READ_START(ring)); |
491 | + ret = -EIO; | |
492 | + goto out; | |
484 | 493 | } |
485 | 494 | } |
495 | + | |
496 | + if (I915_NEED_GFX_HWS(dev)) | |
497 | + intel_ring_setup_status_page(ring); | |
498 | + else | |
499 | + ring_setup_phys_status_page(ring); | |
486 | 500 | |
487 | 501 | /* Initialize the ring. This must happen _after_ we've cleared the ring |
488 | 502 | * registers with the above sequence (the readback of the HEAD registers |
drivers/gpu/drm/i915/intel_ringbuffer.h
... | ... | @@ -34,6 +34,7 @@ |
34 | 34 | #define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val) |
35 | 35 | |
36 | 36 | #define I915_READ_MODE(ring) I915_READ(RING_MI_MODE((ring)->mmio_base)) |
37 | +#define I915_WRITE_MODE(ring, val) I915_WRITE(RING_MI_MODE((ring)->mmio_base), val) | |
37 | 38 | |
38 | 39 | enum intel_ring_hangcheck_action { |
39 | 40 | HANGCHECK_IDLE = 0, |