Commit 08edb33c4e1b810011f21d7705811b7b9a0535f0
Exists in
master
and in
16 other branches
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
Showing 6 changed files Side-by-side Diff
drivers/gpu/drm/drm_pci.c
drivers/gpu/drm/exynos/exynos_drm_drv.c
... | ... | @@ -172,20 +172,24 @@ |
172 | 172 | |
173 | 173 | ret = exynos_drm_subdrv_open(dev, file); |
174 | 174 | if (ret) |
175 | - goto out; | |
175 | + goto err_file_priv_free; | |
176 | 176 | |
177 | 177 | anon_filp = anon_inode_getfile("exynos_gem", &exynos_drm_gem_fops, |
178 | 178 | NULL, 0); |
179 | 179 | if (IS_ERR(anon_filp)) { |
180 | 180 | ret = PTR_ERR(anon_filp); |
181 | - goto out; | |
181 | + goto err_subdrv_close; | |
182 | 182 | } |
183 | 183 | |
184 | 184 | anon_filp->f_mode = FMODE_READ | FMODE_WRITE; |
185 | 185 | file_priv->anon_filp = anon_filp; |
186 | 186 | |
187 | 187 | return ret; |
188 | -out: | |
188 | + | |
189 | +err_subdrv_close: | |
190 | + exynos_drm_subdrv_close(dev, file); | |
191 | + | |
192 | +err_file_priv_free: | |
189 | 193 | kfree(file_priv); |
190 | 194 | file->driver_priv = NULL; |
191 | 195 | return ret; |
drivers/gpu/drm/i915/i915_gem_stolen.c
... | ... | @@ -214,6 +214,13 @@ |
214 | 214 | struct drm_i915_private *dev_priv = dev->dev_private; |
215 | 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 | 224 | if (dev_priv->gtt.stolen_size == 0) |
218 | 225 | return 0; |
219 | 226 |
drivers/gpu/drm/i915/i915_irq.c
... | ... | @@ -618,33 +618,25 @@ |
618 | 618 | |
619 | 619 | /* raw reads, only for fast reads of display block, no need for forcewake etc. */ |
620 | 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 | |
623 | 622 | static bool ilk_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe) |
624 | 623 | { |
625 | 624 | struct drm_i915_private *dev_priv = dev->dev_private; |
626 | 625 | uint32_t status; |
626 | + int reg; | |
627 | 627 | |
628 | - if (INTEL_INFO(dev)->gen < 7) { | |
629 | - status = pipe == PIPE_A ? | |
630 | - DE_PIPEA_VBLANK : | |
631 | - DE_PIPEB_VBLANK; | |
628 | + if (INTEL_INFO(dev)->gen >= 8) { | |
629 | + status = GEN8_PIPE_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 | 634 | } else { |
633 | - switch (pipe) { | |
634 | - default: | |
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 | - } | |
635 | + status = DE_PIPE_VBLANK(pipe); | |
636 | + reg = DEISR; | |
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 | |
650 | 642 | static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, |
651 | 643 | |
... | ... | @@ -702,8 +694,29 @@ |
702 | 694 | else |
703 | 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)) { | |
706 | 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)) { | |
719 | + /* | |
707 | 720 | * The scanline counter increments at the leading edge |
708 | 721 | * of hsync, ie. it completely misses the active portion |
709 | 722 | * of the line. Fix up the counter at both edges of vblank |
710 | 723 | |
... | ... | @@ -2769,10 +2782,9 @@ |
2769 | 2782 | return; |
2770 | 2783 | |
2771 | 2784 | if (HAS_PCH_IBX(dev)) { |
2772 | - mask = SDE_GMBUS | SDE_AUX_MASK | SDE_TRANSB_FIFO_UNDER | | |
2773 | - SDE_TRANSA_FIFO_UNDER | SDE_POISON; | |
2785 | + mask = SDE_GMBUS | SDE_AUX_MASK | SDE_POISON; | |
2774 | 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 | 2789 | I915_WRITE(SERR_INT, I915_READ(SERR_INT)); |
2778 | 2790 | } |
2779 | 2791 | |
2780 | 2792 | |
2781 | 2793 | |
... | ... | @@ -2832,20 +2844,19 @@ |
2832 | 2844 | display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB | |
2833 | 2845 | DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB | |
2834 | 2846 | DE_PLANEB_FLIP_DONE_IVB | |
2835 | - DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB | | |
2836 | - DE_ERR_INT_IVB); | |
2847 | + DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB); | |
2837 | 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 | 2851 | I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT)); |
2841 | 2852 | } else { |
2842 | 2853 | display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | |
2843 | 2854 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE | |
2844 | 2855 | DE_AUX_CHANNEL_A | |
2845 | - DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN | | |
2846 | 2856 | DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE | |
2847 | 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 | 2862 | dev_priv->irq_mask = ~display_mask; |
2852 | 2863 | |
... | ... | @@ -2961,9 +2972,9 @@ |
2961 | 2972 | struct drm_device *dev = dev_priv->dev; |
2962 | 2973 | uint32_t de_pipe_masked = GEN8_PIPE_FLIP_DONE | |
2963 | 2974 | GEN8_PIPE_CDCLK_CRC_DONE | |
2964 | - GEN8_PIPE_FIFO_UNDERRUN | | |
2965 | 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 | 2978 | int pipe; |
2968 | 2979 | dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked; |
2969 | 2980 | dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked; |
drivers/gpu/drm/i915/intel_ddi.c
... | ... | @@ -1244,6 +1244,7 @@ |
1244 | 1244 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
1245 | 1245 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1246 | 1246 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); |
1247 | + ironlake_edp_panel_vdd_on(intel_dp); | |
1247 | 1248 | ironlake_edp_panel_off(intel_dp); |
1248 | 1249 | } |
1249 | 1250 |
drivers/gpu/drm/i915/intel_dp.c
... | ... | @@ -1249,17 +1249,24 @@ |
1249 | 1249 | |
1250 | 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 | 1254 | pp = ironlake_get_pp_control(intel_dp); |
1253 | 1255 | /* We need to switch off panel power _and_ force vdd, for otherwise some |
1254 | 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 | 1259 | pp_ctrl_reg = _pp_ctrl_reg(intel_dp); |
1258 | 1260 | |
1259 | 1261 | I915_WRITE(pp_ctrl_reg, pp); |
1260 | 1262 | POSTING_READ(pp_ctrl_reg); |
1261 | 1263 | |
1264 | + intel_dp->want_panel_vdd = false; | |
1265 | + | |
1262 | 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 | |
1265 | 1272 | void ironlake_edp_backlight_on(struct intel_dp *intel_dp) |
... | ... | @@ -1639,7 +1646,7 @@ |
1639 | 1646 | val |= EDP_PSR_LINK_DISABLE; |
1640 | 1647 | |
1641 | 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 | 1650 | max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | |
1644 | 1651 | idle_frames << EDP_PSR_IDLE_FRAME_SHIFT | |
1645 | 1652 | EDP_PSR_ENABLE); |
... | ... | @@ -1784,6 +1791,7 @@ |
1784 | 1791 | |
1785 | 1792 | /* Make sure the panel is off before trying to change the mode. But also |
1786 | 1793 | * ensure that we have vdd while we switch off the panel. */ |
1794 | + ironlake_edp_panel_vdd_on(intel_dp); | |
1787 | 1795 | ironlake_edp_backlight_off(intel_dp); |
1788 | 1796 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); |
1789 | 1797 | ironlake_edp_panel_off(intel_dp); |