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

Commit 38cff0b1 authored by Zhe Wang's avatar Zhe Wang Committed by Daniel Vetter
Browse files

drm/i915/skl: Gen9 Forcewake



Implement common forcewake functions shared by Gen9 features.

v2: Make the focewake_{get,put} functions static (Mika)
    Small coding style fix in the function definition (Damien)

Reviewed-by: default avatarMika Kuoppala <mika.kuoppala@intel.com>
Signed-off-by: Zhe Wang <zhe1.wang@intel.com> (v1)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> (v2)
Signed-off-by: default avatarDamien Lespiau <damien.lespiau@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent d21b795c
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -549,6 +549,7 @@ struct intel_uncore {

	unsigned fw_rendercount;
	unsigned fw_mediacount;
	unsigned fw_blittercount;

	struct timer_list force_wake_timer;
};
@@ -2979,7 +2980,9 @@ int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val);

#define FORCEWAKE_RENDER	(1 << 0)
#define FORCEWAKE_MEDIA		(1 << 1)
#define FORCEWAKE_ALL		(FORCEWAKE_RENDER | FORCEWAKE_MEDIA)
#define FORCEWAKE_BLITTER	(1 << 2)
#define FORCEWAKE_ALL		(FORCEWAKE_RENDER | FORCEWAKE_MEDIA | \
					FORCEWAKE_BLITTER)


#define I915_READ8(reg)		dev_priv->uncore.funcs.mmio_readb(dev_priv, (reg), true)
+6 −0
Original line number Diff line number Diff line
@@ -5833,6 +5833,12 @@ enum punit_power_well {
#define   VLV_GTLC_PW_MEDIA_STATUS_MASK		(1 << 5)
#define   VLV_GTLC_PW_RENDER_STATUS_MASK	(1 << 7)
#define  FORCEWAKE_MT				0xa188 /* multi-threaded */
#define  FORCEWAKE_MEDIA_GEN9			0xa270
#define  FORCEWAKE_RENDER_GEN9			0xa278
#define  FORCEWAKE_BLITTER_GEN9			0xa188
#define  FORCEWAKE_ACK_MEDIA_GEN9		0x0D88
#define  FORCEWAKE_ACK_RENDER_GEN9		0x0D84
#define  FORCEWAKE_ACK_BLITTER_GEN9		0x130044
#define   FORCEWAKE_KERNEL			0x1
#define   FORCEWAKE_USER			0x2
#define  FORCEWAKE_MT_ACK			0x130040
+174 −1
Original line number Diff line number Diff line
@@ -296,6 +296,154 @@ static void vlv_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
}

static void __gen9_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
{
	__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
			_MASKED_BIT_DISABLE(0xffff));

	__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
			_MASKED_BIT_DISABLE(0xffff));

	__raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
			_MASKED_BIT_DISABLE(0xffff));
}

static void
__gen9_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
{
	/* Check for Render Engine */
	if (FORCEWAKE_RENDER & fw_engine) {
		if (wait_for_atomic((__raw_i915_read32(dev_priv,
						FORCEWAKE_ACK_RENDER_GEN9) &
						FORCEWAKE_KERNEL) == 0,
					FORCEWAKE_ACK_TIMEOUT_MS))
			DRM_ERROR("Timed out: Render forcewake old ack to clear.\n");

		__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));

		if (wait_for_atomic((__raw_i915_read32(dev_priv,
						FORCEWAKE_ACK_RENDER_GEN9) &
						FORCEWAKE_KERNEL),
					FORCEWAKE_ACK_TIMEOUT_MS))
			DRM_ERROR("Timed out: waiting for Render to ack.\n");
	}

	/* Check for Media Engine */
	if (FORCEWAKE_MEDIA & fw_engine) {
		if (wait_for_atomic((__raw_i915_read32(dev_priv,
						FORCEWAKE_ACK_MEDIA_GEN9) &
						FORCEWAKE_KERNEL) == 0,
					FORCEWAKE_ACK_TIMEOUT_MS))
			DRM_ERROR("Timed out: Media forcewake old ack to clear.\n");

		__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));

		if (wait_for_atomic((__raw_i915_read32(dev_priv,
						FORCEWAKE_ACK_MEDIA_GEN9) &
						FORCEWAKE_KERNEL),
					FORCEWAKE_ACK_TIMEOUT_MS))
			DRM_ERROR("Timed out: waiting for Media to ack.\n");
	}

	/* Check for Blitter Engine */
	if (FORCEWAKE_BLITTER & fw_engine) {
		if (wait_for_atomic((__raw_i915_read32(dev_priv,
						FORCEWAKE_ACK_BLITTER_GEN9) &
						FORCEWAKE_KERNEL) == 0,
					FORCEWAKE_ACK_TIMEOUT_MS))
			DRM_ERROR("Timed out: Blitter forcewake old ack to clear.\n");

		__raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));

		if (wait_for_atomic((__raw_i915_read32(dev_priv,
						FORCEWAKE_ACK_BLITTER_GEN9) &
						FORCEWAKE_KERNEL),
					FORCEWAKE_ACK_TIMEOUT_MS))
			DRM_ERROR("Timed out: waiting for Blitter to ack.\n");
	}
}

static void
__gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
{
	/* Check for Render Engine */
	if (FORCEWAKE_RENDER & fw_engine)
		__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));

	/* Check for Media Engine */
	if (FORCEWAKE_MEDIA & fw_engine)
		__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));

	/* Check for Blitter Engine */
	if (FORCEWAKE_BLITTER & fw_engine)
		__raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
}

static void
gen9_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
{
	unsigned long irqflags;

	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);

	if (FORCEWAKE_RENDER & fw_engine) {
		if (dev_priv->uncore.fw_rendercount++ == 0)
			dev_priv->uncore.funcs.force_wake_get(dev_priv,
							FORCEWAKE_RENDER);
	}

	if (FORCEWAKE_MEDIA & fw_engine) {
		if (dev_priv->uncore.fw_mediacount++ == 0)
			dev_priv->uncore.funcs.force_wake_get(dev_priv,
							FORCEWAKE_MEDIA);
	}

	if (FORCEWAKE_BLITTER & fw_engine) {
		if (dev_priv->uncore.fw_blittercount++ == 0)
			dev_priv->uncore.funcs.force_wake_get(dev_priv,
							FORCEWAKE_BLITTER);
	}

	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
}

static void
gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
{
	unsigned long irqflags;

	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);

	if (FORCEWAKE_RENDER & fw_engine) {
		WARN_ON(dev_priv->uncore.fw_rendercount == 0);
		if (--dev_priv->uncore.fw_rendercount == 0)
			dev_priv->uncore.funcs.force_wake_put(dev_priv,
							FORCEWAKE_RENDER);
	}

	if (FORCEWAKE_MEDIA & fw_engine) {
		WARN_ON(dev_priv->uncore.fw_mediacount == 0);
		if (--dev_priv->uncore.fw_mediacount == 0)
			dev_priv->uncore.funcs.force_wake_put(dev_priv,
							FORCEWAKE_MEDIA);
	}

	if (FORCEWAKE_BLITTER & fw_engine) {
		WARN_ON(dev_priv->uncore.fw_blittercount == 0);
		if (--dev_priv->uncore.fw_blittercount == 0)
			dev_priv->uncore.funcs.force_wake_put(dev_priv,
							FORCEWAKE_BLITTER);
	}

	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
}

static void gen6_force_wake_timer(unsigned long arg)
{
	struct drm_i915_private *dev_priv = (void *)arg;
@@ -334,6 +482,9 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
	if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev))
		__gen7_gt_force_wake_mt_reset(dev_priv);

	if (IS_GEN9(dev))
		__gen9_gt_force_wake_mt_reset(dev_priv);

	if (restore) { /* If reset with a user forcewake, try to restore */
		unsigned fw = 0;

@@ -343,6 +494,15 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)

			if (dev_priv->uncore.fw_mediacount)
				fw |= FORCEWAKE_MEDIA;
		} else if (IS_GEN9(dev)) {
			if (dev_priv->uncore.fw_rendercount)
				fw |= FORCEWAKE_RENDER;

			if (dev_priv->uncore.fw_mediacount)
				fw |= FORCEWAKE_MEDIA;

			if (dev_priv->uncore.fw_blittercount)
				fw |= FORCEWAKE_BLITTER;
		} else {
			if (dev_priv->uncore.forcewake_count)
				fw = FORCEWAKE_ALL;
@@ -414,6 +574,10 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)

	intel_runtime_pm_get(dev_priv);

	/* Redirect to Gen9 specific routine */
	if (IS_GEN9(dev_priv->dev))
		return gen9_force_wake_get(dev_priv, fw_engine);

	/* Redirect to VLV specific routine */
	if (IS_VALLEYVIEW(dev_priv->dev))
		return vlv_force_wake_get(dev_priv, fw_engine);
@@ -435,6 +599,12 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
	if (!dev_priv->uncore.funcs.force_wake_put)
		return;

	/* Redirect to Gen9 specific routine */
	if (IS_GEN9(dev_priv->dev)) {
		gen9_force_wake_put(dev_priv, fw_engine);
		goto out;
	}

	/* Redirect to VLV specific routine */
	if (IS_VALLEYVIEW(dev_priv->dev)) {
		vlv_force_wake_put(dev_priv, fw_engine);
@@ -855,7 +1025,10 @@ void intel_uncore_init(struct drm_device *dev)

	__intel_uncore_early_sanitize(dev, false);

	if (IS_VALLEYVIEW(dev)) {
	if (IS_GEN9(dev)) {
		dev_priv->uncore.funcs.force_wake_get = __gen9_force_wake_get;
		dev_priv->uncore.funcs.force_wake_put = __gen9_force_wake_put;
	} else if (IS_VALLEYVIEW(dev)) {
		dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get;
		dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put;
	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {