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

Commit 542a6b20 authored by Mika Kuoppala's avatar Mika Kuoppala Committed by Daniel Vetter
Browse files

drm/i915/chv: calculate rc6 residency correctly

The register to read cz count is different from vlv. Also
the counts returned from CCK_CTL1 for BSW are (ticks in 30ns - 1).
czcount_30ns of value 1 is a special case for 320Mhz.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=80703


Suggested-by: default avatarDeepak S <deepak.s@linux.intel.com>
Cc: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: default avatarMika Kuoppala <mika.kuoppala@intel.com>
Tested-by: default avatarGuo Jinxian <jinxianx.guo@intel.com>
Reviewed-by: default avatarDeepak S <deepak.s@linux.intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent d4ef41ce
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2281,7 +2281,7 @@ enum punit_power_well {
/* Same as Haswell, but 72064 bytes now. */
#define GEN8_CXT_TOTAL_SIZE		(18 * PAGE_SIZE)


#define CHV_CLK_CTL1			0x101100
#define VLV_CLK_CTL2			0x101104
#define   CLK_CTL2_CZCOUNT_30NS_SHIFT	28

+31 −8
Original line number Diff line number Diff line
@@ -47,22 +47,45 @@ static u32 calc_residency(struct drm_device *dev, const u32 reg)

	intel_runtime_pm_get(dev_priv);

	/* On VLV, residency time is in CZ units rather than 1.28us */
	/* On VLV and CHV, residency time is in CZ units rather than 1.28us */
	if (IS_VALLEYVIEW(dev)) {
		u32 clkctl2;
		u32 reg, czcount_30ns;

		clkctl2 = I915_READ(VLV_CLK_CTL2) >>
			CLK_CTL2_CZCOUNT_30NS_SHIFT;
		if (!clkctl2) {
			WARN(!clkctl2, "bogus CZ count value");
		if (IS_CHERRYVIEW(dev))
			reg = CHV_CLK_CTL1;
		else
			reg = VLV_CLK_CTL2;

		czcount_30ns = I915_READ(reg) >> CLK_CTL2_CZCOUNT_30NS_SHIFT;

		if (!czcount_30ns) {
			WARN(!czcount_30ns, "bogus CZ count value");
			ret = 0;
			goto out;
		}
		units = DIV_ROUND_UP_ULL(30ULL * bias, (u64)clkctl2);

		units = 0;
		div = 1000000ULL;

		if (IS_CHERRYVIEW(dev)) {
			/* Special case for 320Mhz */
			if (czcount_30ns == 1) {
				div = 10000000ULL;
				units = 3125ULL;
			} else {
				/* chv counts are one less */
				czcount_30ns += 1;
			}
		}

		if (units == 0)
			units = DIV_ROUND_UP_ULL(30ULL * bias,
						 (u64)czcount_30ns);

		if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH)
			units <<= 8;

		div = 1000000ULL * bias;
		div = div * bias;
	}

	raw_time = I915_READ(reg) * units;