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

Commit c8fe74ae authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~keithp/linux into drm-fixes

* 'drm-intel-fixes' of git://people.freedesktop.org/~keithp/linux: (24 commits)
  drm/i915: fixup forcewake spinlock fallout in drpc debugfs function
  drm/i915: debugfs: show semaphore registers also on gen7
  drm/i915: allow userspace forcewake references also on gen7
  drm/i915: Re-enable gen7 RC6 and GPU turbo after resume.
  drm/i915: Correct debugfs printout for RC1e.
  Revert "drm/i915: Work around gen7 BLT ring synchronization issues."
  drm/i915: rip out the HWSTAM missed irq workaround
  drm/i915: paper over missed irq issues with force wake voodoo
  drm/i915: Hold gt_lock across forcewake register reads
  drm/i915: Hold gt_lock during reset
  drm/i915: Move reset forcewake processing to gen6_do_reset
  drm/i915: protect force_wake_(get|put) with the gt_lock
  drm/i915: convert force_wake_get to func pointer in the gpu reset code
  drm/i915: sprite init failure on pre-SNB is not a failure
  drm/i915: VBT Parser cleanup for eDP block
  drm/i915: mask transcoder select bits before setting them on LVDS
  drm/i915: Add Clientron E830 to the ignore LVDS list
  CHROMIUM: i915: Add DMI override to skip CRT initialization on ZGB
  drm/i915: handle 3rd pipe
  drm/i915: simplify pipe checking
  ...
parents 9f1feed2 93b525dc
Loading
Loading
Loading
Loading
+20 −11
Original line number Diff line number Diff line
@@ -121,11 +121,11 @@ static const char *cache_level_str(int type)
static void
describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
{
	seq_printf(m, "%p: %s%s %8zd %04x %04x %d %d%s%s%s",
	seq_printf(m, "%p: %s%s %8zdKiB %04x %04x %d %d%s%s%s",
		   &obj->base,
		   get_pin_flag(obj),
		   get_tiling_flag(obj),
		   obj->base.size,
		   obj->base.size / 1024,
		   obj->base.read_domains,
		   obj->base.write_domain,
		   obj->last_rendering_seqno,
@@ -653,7 +653,7 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data)
	seq_printf(m, "  Size :    %08x\n", ring->size);
	seq_printf(m, "  Active :  %08x\n", intel_ring_get_active_head(ring));
	seq_printf(m, "  NOPID :   %08x\n", I915_READ_NOPID(ring));
	if (IS_GEN6(dev)) {
	if (IS_GEN6(dev) || IS_GEN7(dev)) {
		seq_printf(m, "  Sync 0 :   %08x\n", I915_READ_SYNC_0(ring));
		seq_printf(m, "  Sync 1 :   %08x\n", I915_READ_SYNC_1(ring));
	}
@@ -1075,6 +1075,7 @@ static int gen6_drpc_info(struct seq_file *m)
	struct drm_device *dev = node->minor->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	u32 rpmodectl1, gt_core_status, rcctl1;
	unsigned forcewake_count;
	int count=0, ret;


@@ -1082,9 +1083,13 @@ static int gen6_drpc_info(struct seq_file *m)
	if (ret)
		return ret;

	if (atomic_read(&dev_priv->forcewake_count)) {
		seq_printf(m, "RC information inaccurate because userspace "
			      "holds a reference \n");
	spin_lock_irq(&dev_priv->gt_lock);
	forcewake_count = dev_priv->forcewake_count;
	spin_unlock_irq(&dev_priv->gt_lock);

	if (forcewake_count) {
		seq_printf(m, "RC information inaccurate because somebody "
			      "holds a forcewake reference \n");
	} else {
		/* NB: we cannot use forcewake, else we read the wrong values */
		while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1))
@@ -1106,7 +1111,7 @@ static int gen6_drpc_info(struct seq_file *m)
	seq_printf(m, "SW control enabled: %s\n",
		   yesno((rpmodectl1 & GEN6_RP_MEDIA_MODE_MASK) ==
			  GEN6_RP_MEDIA_SW_MODE));
	seq_printf(m, "RC6 Enabled: %s\n",
	seq_printf(m, "RC1e Enabled: %s\n",
		   yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE));
	seq_printf(m, "RC6 Enabled: %s\n",
		   yesno(rcctl1 & GEN6_RC_CTL_RC6_ENABLE));
@@ -1398,9 +1403,13 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
	struct drm_info_node *node = (struct drm_info_node *) m->private;
	struct drm_device *dev = node->minor->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	unsigned forcewake_count;

	spin_lock_irq(&dev_priv->gt_lock);
	forcewake_count = dev_priv->forcewake_count;
	spin_unlock_irq(&dev_priv->gt_lock);

	seq_printf(m, "forcewake count = %d\n",
		   atomic_read(&dev_priv->forcewake_count));
	seq_printf(m, "forcewake count = %u\n", forcewake_count);

	return 0;
}
@@ -1665,7 +1674,7 @@ static int i915_forcewake_open(struct inode *inode, struct file *file)
	struct drm_i915_private *dev_priv = dev->dev_private;
	int ret;

	if (!IS_GEN6(dev))
	if (INTEL_INFO(dev)->gen < 6)
		return 0;

	ret = mutex_lock_interruptible(&dev->struct_mutex);
@@ -1682,7 +1691,7 @@ int i915_forcewake_release(struct inode *inode, struct file *file)
	struct drm_device *dev = inode->i_private;
	struct drm_i915_private *dev_priv = dev->dev_private;

	if (!IS_GEN6(dev))
	if (INTEL_INFO(dev)->gen < 6)
		return 0;

	/*
+1 −0
Original line number Diff line number Diff line
@@ -2045,6 +2045,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
	if (!IS_I945G(dev) && !IS_I945GM(dev))
		pci_enable_msi(dev->pdev);

	spin_lock_init(&dev_priv->gt_lock);
	spin_lock_init(&dev_priv->irq_lock);
	spin_lock_init(&dev_priv->error_lock);
	spin_lock_init(&dev_priv->rps_lock);
+44 −12
Original line number Diff line number Diff line
@@ -368,11 +368,12 @@ void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
 */
void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
{
	WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
	unsigned long irqflags;

	/* Forcewake is atomic in case we get in here without the lock */
	if (atomic_add_return(1, &dev_priv->forcewake_count) == 1)
	spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
	if (dev_priv->forcewake_count++ == 0)
		dev_priv->display.force_wake_get(dev_priv);
	spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
}

void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
@@ -392,10 +393,12 @@ void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
 */
void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
{
	WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
	unsigned long irqflags;

	if (atomic_dec_and_test(&dev_priv->forcewake_count))
	spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
	if (--dev_priv->forcewake_count == 0)
		dev_priv->display.force_wake_put(dev_priv);
	spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
}

void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
@@ -597,9 +600,36 @@ static int ironlake_do_reset(struct drm_device *dev, u8 flags)
static int gen6_do_reset(struct drm_device *dev, u8 flags)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	int	ret;
	unsigned long irqflags;

	/* Hold gt_lock across reset to prevent any register access
	 * with forcewake not set correctly
	 */
	spin_lock_irqsave(&dev_priv->gt_lock, irqflags);

	/* Reset the chip */

	/* GEN6_GDRST is not in the gt power well, no need to check
	 * for fifo space for the write or forcewake the chip for
	 * the read
	 */
	I915_WRITE_NOTRACE(GEN6_GDRST, GEN6_GRDOM_FULL);

	I915_WRITE(GEN6_GDRST, GEN6_GRDOM_FULL);
	return wait_for((I915_READ(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500);
	/* Spin waiting for the device to ack the reset request */
	ret = wait_for((I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500);

	/* If reset with a user forcewake, try to restore, otherwise turn it off */
	if (dev_priv->forcewake_count)
		dev_priv->display.force_wake_get(dev_priv);
	else
		dev_priv->display.force_wake_put(dev_priv);

	/* Restore fifo count */
	dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);

	spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
	return ret;
}

/**
@@ -643,9 +673,6 @@ int i915_reset(struct drm_device *dev, u8 flags)
	case 7:
	case 6:
		ret = gen6_do_reset(dev, flags);
		/* If reset with a user forcewake, try to restore */
		if (atomic_read(&dev_priv->forcewake_count))
			__gen6_gt_force_wake_get(dev_priv);
		break;
	case 5:
		ret = ironlake_do_reset(dev, flags);
@@ -927,9 +954,14 @@ MODULE_LICENSE("GPL and additional rights");
u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
	u##x val = 0; \
	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
		gen6_gt_force_wake_get(dev_priv); \
		unsigned long irqflags; \
		spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \
		if (dev_priv->forcewake_count == 0) \
			dev_priv->display.force_wake_get(dev_priv); \
		val = read##y(dev_priv->regs + reg); \
		gen6_gt_force_wake_put(dev_priv); \
		if (dev_priv->forcewake_count == 0) \
			dev_priv->display.force_wake_put(dev_priv); \
		spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \
	} else { \
		val = read##y(dev_priv->regs + reg); \
	} \
+7 −3
Original line number Diff line number Diff line
@@ -288,7 +288,13 @@ typedef struct drm_i915_private {
	int relative_constants_mode;

	void __iomem *regs;
	u32 gt_fifo_count;
	/** gt_fifo_count and the subsequent register write are synchronized
	 * with dev->struct_mutex. */
	unsigned gt_fifo_count;
	/** forcewake_count is protected by gt_lock */
	unsigned forcewake_count;
	/** gt_lock is also taken in irq contexts. */
	struct spinlock gt_lock;

	struct intel_gmbus {
		struct i2c_adapter adapter;
@@ -741,8 +747,6 @@ typedef struct drm_i915_private {

	struct drm_property *broadcast_rgb_property;
	struct drm_property *force_audio_property;

	atomic_t forcewake_count;
} drm_i915_private_t;

enum i915_cache_level {
+2 −1
Original line number Diff line number Diff line
@@ -1751,7 +1751,8 @@ static void ironlake_irq_preinstall(struct drm_device *dev)
		INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work);

	I915_WRITE(HWSTAM, 0xeffe);
	if (IS_GEN6(dev) || IS_GEN7(dev)) {

	if (IS_GEN6(dev)) {
		/* Workaround stalls observed on Sandy Bridge GPUs by
		 * making the blitter command streamer generate a
		 * write to the Hardware Status Page for
Loading