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

Commit dd06f88c authored by Ville Syrjälä's avatar Ville Syrjälä Committed by Daniel Vetter
Browse files

drm/i915: Refactor vlv/chv GPU frequency divider setup



The divider used in the GPU frequency calculations is compatible between
vlv and chv. vlv just wants doubled values compared to chv.

Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarDeepak <S&lt;deepak.s@linux.intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent ce611ef8
Loading
Loading
Loading
Loading
+35 −69
Original line number Diff line number Diff line
@@ -7206,99 +7206,65 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val)
	return 0;
}

static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)
static int vlv_gpu_freq_div(unsigned int czclk_freq)
{
	int div;

	/* 4 x czclk */
	switch (dev_priv->mem_freq) {
	case 800:
		div = 10;
		break;
	case 1066:
		div = 12;
		break;
	case 1333:
		div = 16;
		break;
	switch (czclk_freq) {
	case 200:
		return 10;
	case 267:
		return 12;
	case 320:
	case 333:
	case 400:
		return 16;
	default:
		return -1;
	}
}

	return DIV_ROUND_CLOSEST(dev_priv->mem_freq * (val + 6 - 0xbd), 4 * div);
static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)
{
	int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->mem_freq, 4);

	div = vlv_gpu_freq_div(czclk_freq);
	if (div < 0)
		return div;

	return DIV_ROUND_CLOSEST(czclk_freq * (val + 6 - 0xbd), div);
}

static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val)
{
	int mul;
	int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->mem_freq, 4);

	/* 4 x czclk */
	switch (dev_priv->mem_freq) {
	case 800:
		mul = 10;
		break;
	case 1066:
		mul = 12;
		break;
	case 1333:
		mul = 16;
		break;
	default:
		return -1;
	}
	mul = vlv_gpu_freq_div(czclk_freq);
	if (mul < 0)
		return mul;

	return DIV_ROUND_CLOSEST(4 * mul * val, dev_priv->mem_freq) + 0xbd - 6;
	return DIV_ROUND_CLOSEST(mul * val, czclk_freq) + 0xbd - 6;
}

static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val)
{
	int div, freq;

	switch (dev_priv->rps.cz_freq) {
	case 200:
		div = 5;
		break;
	case 267:
		div = 6;
		break;
	case 320:
	case 333:
	case 400:
		div = 8;
		break;
	default:
		return -1;
	}
	int div, czclk_freq = dev_priv->rps.cz_freq;

	freq = (DIV_ROUND_CLOSEST((dev_priv->rps.cz_freq * val), 2 * div) / 2);
	div = vlv_gpu_freq_div(czclk_freq) / 2;
	if (div < 0)
		return div;

	return freq;
	return DIV_ROUND_CLOSEST(czclk_freq * val, 2 * div) / 2;
}

static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val)
{
	int mul, opcode;
	int mul, czclk_freq = dev_priv->rps.cz_freq;

	switch (dev_priv->rps.cz_freq) {
	case 200:
		mul = 5;
		break;
	case 267:
		mul = 6;
		break;
	case 320:
	case 333:
	case 400:
		mul = 8;
		break;
	default:
		return -1;
	}
	mul = vlv_gpu_freq_div(czclk_freq) / 2;
	if (mul < 0)
		return mul;

	/* CHV needs even values */
	opcode = (DIV_ROUND_CLOSEST((val * 2 * mul), dev_priv->rps.cz_freq) * 2);

	return opcode;
	return DIV_ROUND_CLOSEST(val * 2 * mul, czclk_freq) * 2;
}

int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val)