Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 08edb33c authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents 708f04d2 004e5cf7
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -468,8 +468,8 @@ void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver)
	} else {
		list_for_each_entry_safe(dev, tmp, &driver->legacy_dev_list,
					 legacy_dev_list) {
			drm_put_dev(dev);
			list_del(&dev->legacy_dev_list);
			drm_put_dev(dev);
		}
	}
	DRM_INFO("Module unloaded\n");
+7 −3
Original line number Diff line number Diff line
@@ -172,20 +172,24 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)

	ret = exynos_drm_subdrv_open(dev, file);
	if (ret)
		goto out;
		goto err_file_priv_free;

	anon_filp = anon_inode_getfile("exynos_gem", &exynos_drm_gem_fops,
					NULL, 0);
	if (IS_ERR(anon_filp)) {
		ret = PTR_ERR(anon_filp);
		goto out;
		goto err_subdrv_close;
	}

	anon_filp->f_mode = FMODE_READ | FMODE_WRITE;
	file_priv->anon_filp = anon_filp;

	return ret;
out:

err_subdrv_close:
	exynos_drm_subdrv_close(dev, file);

err_file_priv_free:
	kfree(file_priv);
	file->driver_priv = NULL;
	return ret;
+7 −0
Original line number Diff line number Diff line
@@ -214,6 +214,13 @@ int i915_gem_init_stolen(struct drm_device *dev)
	struct drm_i915_private *dev_priv = dev->dev_private;
	int bios_reserved = 0;

#ifdef CONFIG_INTEL_IOMMU
	if (intel_iommu_gfx_mapped) {
		DRM_INFO("DMAR active, disabling use of stolen memory\n");
		return 0;
	}
#endif

	if (dev_priv->gtt.stolen_size == 0)
		return 0;

+41 −30
Original line number Diff line number Diff line
@@ -618,33 +618,25 @@ static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)

/* raw reads, only for fast reads of display block, no need for forcewake etc. */
#define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + (reg__))
#define __raw_i915_read16(dev_priv__, reg__) readw((dev_priv__)->regs + (reg__))

static bool ilk_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	uint32_t status;

	if (INTEL_INFO(dev)->gen < 7) {
		status = pipe == PIPE_A ?
			DE_PIPEA_VBLANK :
			DE_PIPEB_VBLANK;
	int reg;

	if (INTEL_INFO(dev)->gen >= 8) {
		status = GEN8_PIPE_VBLANK;
		reg = GEN8_DE_PIPE_ISR(pipe);
	} else if (INTEL_INFO(dev)->gen >= 7) {
		status = DE_PIPE_VBLANK_IVB(pipe);
		reg = DEISR;
	} else {
		switch (pipe) {
		default:
		case PIPE_A:
			status = DE_PIPEA_VBLANK_IVB;
			break;
		case PIPE_B:
			status = DE_PIPEB_VBLANK_IVB;
			break;
		case PIPE_C:
			status = DE_PIPEC_VBLANK_IVB;
			break;
		}
		status = DE_PIPE_VBLANK(pipe);
		reg = DEISR;
	}

	return __raw_i915_read32(dev_priv, DEISR) & status;
	return __raw_i915_read32(dev_priv, reg) & status;
}

static 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,
		else
			position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3;

		if (HAS_PCH_SPLIT(dev)) {
		if (HAS_DDI(dev)) {
			/*
			 * On HSW HDMI outputs there seems to be a 2 line
			 * difference, whereas eDP has the normal 1 line
			 * difference that earlier platforms have. External
			 * DP is unknown. For now just check for the 2 line
			 * difference case on all output types on HSW+.
			 *
			 * This might misinterpret the scanline counter being
			 * one line too far along on eDP, but that's less
			 * dangerous than the alternative since that would lead
			 * the vblank timestamp code astray when it sees a
			 * scanline count before vblank_start during a vblank
			 * interrupt.
			 */
			in_vbl = ilk_pipe_in_vblank_locked(dev, pipe);
			if ((in_vbl && (position == vbl_start - 2 ||
					position == vbl_start - 1)) ||
			    (!in_vbl && (position == vbl_end - 2 ||
					 position == vbl_end - 1)))
				position = (position + 2) % vtotal;
		} else if (HAS_PCH_SPLIT(dev)) {
			/*
			 * The scanline counter increments at the leading edge
			 * of hsync, ie. it completely misses the active portion
@@ -2769,10 +2782,9 @@ static void ibx_irq_postinstall(struct drm_device *dev)
		return;

	if (HAS_PCH_IBX(dev)) {
		mask = SDE_GMBUS | SDE_AUX_MASK | SDE_TRANSB_FIFO_UNDER |
		       SDE_TRANSA_FIFO_UNDER | SDE_POISON;
		mask = SDE_GMBUS | SDE_AUX_MASK | SDE_POISON;
	} else {
		mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT | SDE_ERROR_CPT;
		mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT;

		I915_WRITE(SERR_INT, I915_READ(SERR_INT));
	}
@@ -2832,20 +2844,19 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
		display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB |
				DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB |
				DE_PLANEB_FLIP_DONE_IVB |
				DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB |
				DE_ERR_INT_IVB);
				DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB);
		extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB |
			      DE_PIPEA_VBLANK_IVB);
			      DE_PIPEA_VBLANK_IVB | DE_ERR_INT_IVB);

		I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT));
	} else {
		display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
				DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE |
				DE_AUX_CHANNEL_A |
				DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN |
				DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE |
				DE_POISON);
		extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT;
		extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT |
				DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN;
	}

	dev_priv->irq_mask = ~display_mask;
@@ -2961,9 +2972,9 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
	struct drm_device *dev = dev_priv->dev;
	uint32_t de_pipe_masked = GEN8_PIPE_FLIP_DONE |
		GEN8_PIPE_CDCLK_CRC_DONE |
		GEN8_PIPE_FIFO_UNDERRUN |
		GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
	uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK;
	uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK |
		GEN8_PIPE_FIFO_UNDERRUN;
	int pipe;
	dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked;
	dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked;
+1 −0
Original line number Diff line number Diff line
@@ -1244,6 +1244,7 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
	if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
		ironlake_edp_panel_vdd_on(intel_dp);
		ironlake_edp_panel_off(intel_dp);
	}

Loading