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

Commit e2fa6fba authored by Pallavi G's avatar Pallavi G Committed by Daniel Vetter
Browse files

drm/i915/dp: program VSwing and Preemphasis control settings on VLV v2



Program few Tx buffer Swing control settings through DPIO.

v2: fix up codingstyle (Daniel)
    call from set_signal_levels (Ville, Daniel)
    use proper port numbers (Jesse)

Signed-off-by: default avatarPallavi G <pallavi.g@intel.com>
Signed-off-by: default avatarYogesh M <yogesh.mohan.marimuthu@intel.com>
Signed-off-by: default avatarGajanan Bhat <gajanan.bhat@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> (v2 changes)
[danvet: Reorder if-ladder to avoid two IS_VLV checks.]
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 598fac6b
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -450,8 +450,7 @@ u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg)
	return I915_READ(DPIO_DATA);
}

static void intel_dpio_write(struct drm_i915_private *dev_priv, int reg,
			     u32 val)
void intel_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val)
{
	WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));

+125 −3
Original line number Diff line number Diff line
@@ -1461,7 +1461,9 @@ intel_dp_voltage_max(struct intel_dp *intel_dp)
{
	struct drm_device *dev = intel_dp_to_dev(intel_dp);

	if (IS_GEN7(dev) && is_cpu_edp(intel_dp))
	if (IS_VALLEYVIEW(dev))
		return DP_TRAIN_VOLTAGE_SWING_1200;
	else if (IS_GEN7(dev) && is_cpu_edp(intel_dp))
		return DP_TRAIN_VOLTAGE_SWING_800;
	else if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp))
		return DP_TRAIN_VOLTAGE_SWING_1200;
@@ -1486,7 +1488,19 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
		default:
			return DP_TRAIN_PRE_EMPHASIS_0;
		}
	} else if (IS_GEN7(dev) && is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) {
	} else if (IS_VALLEYVIEW(dev)) {
		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
		case DP_TRAIN_VOLTAGE_SWING_400:
			return DP_TRAIN_PRE_EMPHASIS_9_5;
		case DP_TRAIN_VOLTAGE_SWING_600:
			return DP_TRAIN_PRE_EMPHASIS_6;
		case DP_TRAIN_VOLTAGE_SWING_800:
			return DP_TRAIN_PRE_EMPHASIS_3_5;
		case DP_TRAIN_VOLTAGE_SWING_1200:
		default:
			return DP_TRAIN_PRE_EMPHASIS_0;
		}
	} else if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) {
		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
		case DP_TRAIN_VOLTAGE_SWING_400:
			return DP_TRAIN_PRE_EMPHASIS_6;
@@ -1511,6 +1525,111 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
	}
}

static uint32_t intel_vlv_signal_levels(struct intel_dp *intel_dp)
{
	struct drm_device *dev = intel_dp_to_dev(intel_dp);
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
	unsigned long demph_reg_value, preemph_reg_value,
		uniqtranscale_reg_value;
	uint8_t train_set = intel_dp->train_set[0];
	int port;

	if (dport->port == PORT_B)
		port = 0;
	else if (dport->port == PORT_C)
		port = 1;
	else
		BUG();

	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
	case DP_TRAIN_PRE_EMPHASIS_0:
		preemph_reg_value = 0x0004000;
		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
		case DP_TRAIN_VOLTAGE_SWING_400:
			demph_reg_value = 0x2B405555;
			uniqtranscale_reg_value = 0x552AB83A;
			break;
		case DP_TRAIN_VOLTAGE_SWING_600:
			demph_reg_value = 0x2B404040;
			uniqtranscale_reg_value = 0x5548B83A;
			break;
		case DP_TRAIN_VOLTAGE_SWING_800:
			demph_reg_value = 0x2B245555;
			uniqtranscale_reg_value = 0x5560B83A;
			break;
		case DP_TRAIN_VOLTAGE_SWING_1200:
			demph_reg_value = 0x2B405555;
			uniqtranscale_reg_value = 0x5598DA3A;
			break;
		default:
			return 0;
		}
		break;
	case DP_TRAIN_PRE_EMPHASIS_3_5:
		preemph_reg_value = 0x0002000;
		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
		case DP_TRAIN_VOLTAGE_SWING_400:
			demph_reg_value = 0x2B404040;
			uniqtranscale_reg_value = 0x5552B83A;
			break;
		case DP_TRAIN_VOLTAGE_SWING_600:
			demph_reg_value = 0x2B404848;
			uniqtranscale_reg_value = 0x5580B83A;
			break;
		case DP_TRAIN_VOLTAGE_SWING_800:
			demph_reg_value = 0x2B404040;
			uniqtranscale_reg_value = 0x55ADDA3A;
			break;
		default:
			return 0;
		}
		break;
	case DP_TRAIN_PRE_EMPHASIS_6:
		preemph_reg_value = 0x0000000;
		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
		case DP_TRAIN_VOLTAGE_SWING_400:
			demph_reg_value = 0x2B305555;
			uniqtranscale_reg_value = 0x5570B83A;
			break;
		case DP_TRAIN_VOLTAGE_SWING_600:
			demph_reg_value = 0x2B2B4040;
			uniqtranscale_reg_value = 0x55ADDA3A;
			break;
		default:
			return 0;
		}
		break;
	case DP_TRAIN_PRE_EMPHASIS_9_5:
		preemph_reg_value = 0x0006000;
		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
		case DP_TRAIN_VOLTAGE_SWING_400:
			demph_reg_value = 0x1B405555;
			uniqtranscale_reg_value = 0x55ADDA3A;
			break;
		default:
			return 0;
		}
		break;
	default:
		return 0;
	}

	/* eDP is only on port C */
	mutex_lock(&dev_priv->dpio_lock);
	intel_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), 0x00000000);
	intel_dpio_write(dev_priv, DPIO_TX_SWING_CTL4(port), demph_reg_value);
	intel_dpio_write(dev_priv, DPIO_TX_SWING_CTL2(port),
			 uniqtranscale_reg_value);
	intel_dpio_write(dev_priv, DPIO_TX_SWING_CTL3(port), 0x0C782040);
	intel_dpio_write(dev_priv, DPIO_PCS_STAGGER0(port), 0x00030000);
	intel_dpio_write(dev_priv, DPIO_PCS_CTL_OVER1(port), preemph_reg_value);
	intel_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), 0x80000000);
	mutex_unlock(&dev_priv->dpio_lock);

	return 0;
}

static void
intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
{
@@ -1685,7 +1804,10 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
	if (HAS_DDI(dev)) {
		signal_levels = intel_hsw_signal_levels(train_set);
		mask = DDI_BUF_EMP_MASK;
	} else if (IS_GEN7(dev) && is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) {
	} else if (IS_VALLEYVIEW(dev)) {
		signal_levels = intel_vlv_signal_levels(intel_dp);
		mask = 0;
	} else if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) {
		signal_levels = intel_gen7_edp_signal_levels(train_set);
		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
	} else if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) {
+2 −0
Original line number Diff line number Diff line
@@ -689,6 +689,8 @@ extern int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
				     struct drm_file *file_priv);

extern u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg);
extern void intel_dpio_write(struct drm_i915_private *dev_priv, int reg,
			     u32 val);

/* Power-related functions, located in intel_pm.c */
extern void intel_init_pm(struct drm_device *dev);