aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-03-21 01:32:28 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-03-21 01:32:28 -0400
commit08edb33c4e1b810011f21d7705811b7b9a0535f0 (patch)
tree60180e188c9c9dfc5055cbaf2e1eccaadcaa8e22
parent708f04d2abf4e90abee61d9ffb1f165038017ecf (diff)
parent004e5cf743086990e5fc04a14437b3966d7fa9a2 (diff)
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "Some final few intel fixes, all regressions, all stable cc, and one exynos oops fixer. The biggest is probably the intel display error irqs one, but it seems to fix a few crashes on startup, and one use after free in drm core" * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: drm/exynos: Fix (more) freeing issues in exynos_drm_drv.c drm/i915: Disable stolen memory when DMAR is active Revert "drm/i915: don't touch the VDD when disabling the panel" drm: Fix use-after-free in the shadow-attache exit code drm/i915: Don't enable display error interrupts from the start drm/i915: Fix scanline counter fixup on BDW drm/i915: Add a workaround for HSW scanline counter weirdness drm/i915: Fix PSR programming
-rw-r--r--drivers/gpu/drm/drm_pci.c2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c10
-rw-r--r--drivers/gpu/drm/i915/i915_gem_stolen.c7
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c71
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c1
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c12
6 files changed, 67 insertions, 36 deletions
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c
index 5736aaa7e86c..f7af69bcf3f4 100644
--- a/drivers/gpu/drm/drm_pci.c
+++ b/drivers/gpu/drm/drm_pci.c
@@ -468,8 +468,8 @@ void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver)
468 } else { 468 } else {
469 list_for_each_entry_safe(dev, tmp, &driver->legacy_dev_list, 469 list_for_each_entry_safe(dev, tmp, &driver->legacy_dev_list,
470 legacy_dev_list) { 470 legacy_dev_list) {
471 drm_put_dev(dev);
472 list_del(&dev->legacy_dev_list); 471 list_del(&dev->legacy_dev_list);
472 drm_put_dev(dev);
473 } 473 }
474 } 474 }
475 DRM_INFO("Module unloaded\n"); 475 DRM_INFO("Module unloaded\n");
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 215131ab1dd2..c204b4e3356e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -172,20 +172,24 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
172 172
173 ret = exynos_drm_subdrv_open(dev, file); 173 ret = exynos_drm_subdrv_open(dev, file);
174 if (ret) 174 if (ret)
175 goto out; 175 goto err_file_priv_free;
176 176
177 anon_filp = anon_inode_getfile("exynos_gem", &exynos_drm_gem_fops, 177 anon_filp = anon_inode_getfile("exynos_gem", &exynos_drm_gem_fops,
178 NULL, 0); 178 NULL, 0);
179 if (IS_ERR(anon_filp)) { 179 if (IS_ERR(anon_filp)) {
180 ret = PTR_ERR(anon_filp); 180 ret = PTR_ERR(anon_filp);
181 goto out; 181 goto err_subdrv_close;
182 } 182 }
183 183
184 anon_filp->f_mode = FMODE_READ | FMODE_WRITE; 184 anon_filp->f_mode = FMODE_READ | FMODE_WRITE;
185 file_priv->anon_filp = anon_filp; 185 file_priv->anon_filp = anon_filp;
186 186
187 return ret; 187 return ret;
188out: 188
189err_subdrv_close:
190 exynos_drm_subdrv_close(dev, file);
191
192err_file_priv_free:
189 kfree(file_priv); 193 kfree(file_priv);
190 file->driver_priv = NULL; 194 file->driver_priv = NULL;
191 return ret; 195 return ret;
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index d58b4e287e32..28d24caa49f3 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -214,6 +214,13 @@ int i915_gem_init_stolen(struct drm_device *dev)
214 struct drm_i915_private *dev_priv = dev->dev_private; 214 struct drm_i915_private *dev_priv = dev->dev_private;
215 int bios_reserved = 0; 215 int bios_reserved = 0;
216 216
217#ifdef CONFIG_INTEL_IOMMU
218 if (intel_iommu_gfx_mapped) {
219 DRM_INFO("DMAR active, disabling use of stolen memory\n");
220 return 0;
221 }
222#endif
223
217 if (dev_priv->gtt.stolen_size == 0) 224 if (dev_priv->gtt.stolen_size == 0)
218 return 0; 225 return 0;
219 226
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 9fec71175571..d554169ac592 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -618,33 +618,25 @@ static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
618 618
619/* raw reads, only for fast reads of display block, no need for forcewake etc. */ 619/* raw reads, only for fast reads of display block, no need for forcewake etc. */
620#define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + (reg__)) 620#define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + (reg__))
621#define __raw_i915_read16(dev_priv__, reg__) readw((dev_priv__)->regs + (reg__))
622 621
623static bool ilk_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe) 622static bool ilk_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe)
624{ 623{
625 struct drm_i915_private *dev_priv = dev->dev_private; 624 struct drm_i915_private *dev_priv = dev->dev_private;
626 uint32_t status; 625 uint32_t status;
627 626 int reg;
628 if (INTEL_INFO(dev)->gen < 7) { 627
629 status = pipe == PIPE_A ? 628 if (INTEL_INFO(dev)->gen >= 8) {
630 DE_PIPEA_VBLANK : 629 status = GEN8_PIPE_VBLANK;
631 DE_PIPEB_VBLANK; 630 reg = GEN8_DE_PIPE_ISR(pipe);
631 } else if (INTEL_INFO(dev)->gen >= 7) {
632 status = DE_PIPE_VBLANK_IVB(pipe);
633 reg = DEISR;
632 } else { 634 } else {
633 switch (pipe) { 635 status = DE_PIPE_VBLANK(pipe);
634 default: 636 reg = DEISR;
635 case PIPE_A:
636 status = DE_PIPEA_VBLANK_IVB;
637 break;
638 case PIPE_B:
639 status = DE_PIPEB_VBLANK_IVB;
640 break;
641 case PIPE_C:
642 status = DE_PIPEC_VBLANK_IVB;
643 break;
644 }
645 } 637 }
646 638
647 return __raw_i915_read32(dev_priv, DEISR) & status; 639 return __raw_i915_read32(dev_priv, reg) & status;
648} 640}
649 641
650static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, 642static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
@@ -702,7 +694,28 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
702 else 694 else
703 position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; 695 position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3;
704 696
705 if (HAS_PCH_SPLIT(dev)) { 697 if (HAS_DDI(dev)) {
698 /*
699 * On HSW HDMI outputs there seems to be a 2 line
700 * difference, whereas eDP has the normal 1 line
701 * difference that earlier platforms have. External
702 * DP is unknown. For now just check for the 2 line
703 * difference case on all output types on HSW+.
704 *
705 * This might misinterpret the scanline counter being
706 * one line too far along on eDP, but that's less
707 * dangerous than the alternative since that would lead
708 * the vblank timestamp code astray when it sees a
709 * scanline count before vblank_start during a vblank
710 * interrupt.
711 */
712 in_vbl = ilk_pipe_in_vblank_locked(dev, pipe);
713 if ((in_vbl && (position == vbl_start - 2 ||
714 position == vbl_start - 1)) ||
715 (!in_vbl && (position == vbl_end - 2 ||
716 position == vbl_end - 1)))
717 position = (position + 2) % vtotal;
718 } else if (HAS_PCH_SPLIT(dev)) {
706 /* 719 /*
707 * The scanline counter increments at the leading edge 720 * The scanline counter increments at the leading edge
708 * of hsync, ie. it completely misses the active portion 721 * of hsync, ie. it completely misses the active portion
@@ -2769,10 +2782,9 @@ static void ibx_irq_postinstall(struct drm_device *dev)
2769 return; 2782 return;
2770 2783
2771 if (HAS_PCH_IBX(dev)) { 2784 if (HAS_PCH_IBX(dev)) {
2772 mask = SDE_GMBUS | SDE_AUX_MASK | SDE_TRANSB_FIFO_UNDER | 2785 mask = SDE_GMBUS | SDE_AUX_MASK | SDE_POISON;
2773 SDE_TRANSA_FIFO_UNDER | SDE_POISON;
2774 } else { 2786 } else {
2775 mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT | SDE_ERROR_CPT; 2787 mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT;
2776 2788
2777 I915_WRITE(SERR_INT, I915_READ(SERR_INT)); 2789 I915_WRITE(SERR_INT, I915_READ(SERR_INT));
2778 } 2790 }
@@ -2832,20 +2844,19 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
2832 display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB | 2844 display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB |
2833 DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB | 2845 DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB |
2834 DE_PLANEB_FLIP_DONE_IVB | 2846 DE_PLANEB_FLIP_DONE_IVB |
2835 DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB | 2847 DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB);
2836 DE_ERR_INT_IVB);
2837 extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB | 2848 extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB |
2838 DE_PIPEA_VBLANK_IVB); 2849 DE_PIPEA_VBLANK_IVB | DE_ERR_INT_IVB);
2839 2850
2840 I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT)); 2851 I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT));
2841 } else { 2852 } else {
2842 display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | 2853 display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
2843 DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE | 2854 DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE |
2844 DE_AUX_CHANNEL_A | 2855 DE_AUX_CHANNEL_A |
2845 DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN |
2846 DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE | 2856 DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE |
2847 DE_POISON); 2857 DE_POISON);
2848 extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT; 2858 extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT |
2859 DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN;
2849 } 2860 }
2850 2861
2851 dev_priv->irq_mask = ~display_mask; 2862 dev_priv->irq_mask = ~display_mask;
@@ -2961,9 +2972,9 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
2961 struct drm_device *dev = dev_priv->dev; 2972 struct drm_device *dev = dev_priv->dev;
2962 uint32_t de_pipe_masked = GEN8_PIPE_FLIP_DONE | 2973 uint32_t de_pipe_masked = GEN8_PIPE_FLIP_DONE |
2963 GEN8_PIPE_CDCLK_CRC_DONE | 2974 GEN8_PIPE_CDCLK_CRC_DONE |
2964 GEN8_PIPE_FIFO_UNDERRUN |
2965 GEN8_DE_PIPE_IRQ_FAULT_ERRORS; 2975 GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
2966 uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK; 2976 uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK |
2977 GEN8_PIPE_FIFO_UNDERRUN;
2967 int pipe; 2978 int pipe;
2968 dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked; 2979 dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked;
2969 dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked; 2980 dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked;
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index e06b9e017d6b..234ac5f7bc5a 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1244,6 +1244,7 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
1244 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { 1244 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
1245 struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 1245 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1246 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); 1246 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
1247 ironlake_edp_panel_vdd_on(intel_dp);
1247 ironlake_edp_panel_off(intel_dp); 1248 ironlake_edp_panel_off(intel_dp);
1248 } 1249 }
1249 1250
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 57552eb386b0..2688f6d64bb9 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1249,17 +1249,24 @@ void ironlake_edp_panel_off(struct intel_dp *intel_dp)
1249 1249
1250 DRM_DEBUG_KMS("Turn eDP power off\n"); 1250 DRM_DEBUG_KMS("Turn eDP power off\n");
1251 1251
1252 WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n");
1253
1252 pp = ironlake_get_pp_control(intel_dp); 1254 pp = ironlake_get_pp_control(intel_dp);
1253 /* We need to switch off panel power _and_ force vdd, for otherwise some 1255 /* We need to switch off panel power _and_ force vdd, for otherwise some
1254 * panels get very unhappy and cease to work. */ 1256 * panels get very unhappy and cease to work. */
1255 pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_BLC_ENABLE); 1257 pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE);
1256 1258
1257 pp_ctrl_reg = _pp_ctrl_reg(intel_dp); 1259 pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
1258 1260
1259 I915_WRITE(pp_ctrl_reg, pp); 1261 I915_WRITE(pp_ctrl_reg, pp);
1260 POSTING_READ(pp_ctrl_reg); 1262 POSTING_READ(pp_ctrl_reg);
1261 1263
1264 intel_dp->want_panel_vdd = false;
1265
1262 ironlake_wait_panel_off(intel_dp); 1266 ironlake_wait_panel_off(intel_dp);
1267
1268 /* We got a reference when we enabled the VDD. */
1269 intel_runtime_pm_put(dev_priv);
1263} 1270}
1264 1271
1265void ironlake_edp_backlight_on(struct intel_dp *intel_dp) 1272void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
@@ -1639,7 +1646,7 @@ static void intel_edp_psr_enable_source(struct intel_dp *intel_dp)
1639 val |= EDP_PSR_LINK_DISABLE; 1646 val |= EDP_PSR_LINK_DISABLE;
1640 1647
1641 I915_WRITE(EDP_PSR_CTL(dev), val | 1648 I915_WRITE(EDP_PSR_CTL(dev), val |
1642 IS_BROADWELL(dev) ? 0 : link_entry_time | 1649 (IS_BROADWELL(dev) ? 0 : link_entry_time) |
1643 max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | 1650 max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT |
1644 idle_frames << EDP_PSR_IDLE_FRAME_SHIFT | 1651 idle_frames << EDP_PSR_IDLE_FRAME_SHIFT |
1645 EDP_PSR_ENABLE); 1652 EDP_PSR_ENABLE);
@@ -1784,6 +1791,7 @@ static void intel_disable_dp(struct intel_encoder *encoder)
1784 1791
1785 /* Make sure the panel is off before trying to change the mode. But also 1792 /* Make sure the panel is off before trying to change the mode. But also
1786 * ensure that we have vdd while we switch off the panel. */ 1793 * ensure that we have vdd while we switch off the panel. */
1794 ironlake_edp_panel_vdd_on(intel_dp);
1787 ironlake_edp_backlight_off(intel_dp); 1795 ironlake_edp_backlight_off(intel_dp);
1788 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); 1796 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
1789 ironlake_edp_panel_off(intel_dp); 1797 ironlake_edp_panel_off(intel_dp);