[PATCH 65/71] drm/i915/chv: Don't do group access reads from TX lanes either

ville.syrjala
2014-04-09T10:32:51Z

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Like PCS, TX group reads return 0xffffffff. So we need to target each
lane separately if we want to use RMW cycles to update the registers.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
drivers/gpu/drm/i915/i915_reg.h | 11 +++++++++
drivers/gpu/drm/i915/intel_dp.c | 49 +++++++++++++++++++++++++--------------
drivers/gpu/drm/i915/intel_hdmi.c | 28 +++++++++++++---------
3 files changed, 59 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index ffed03e..b91232f 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -802,6 +802,17 @@ enum punit_power_well {
#define _TXLANE(ch, lane, offset) ((ch ? 0x2400 : 0) + \
(lane) * 0x200 + (offset))

+#define CHV_TX_DW0(ch, lane) _TXLANE(ch, lane, 0x80)
+#define CHV_TX_DW1(ch, lane) _TXLANE(ch, lane, 0x84)
+#define CHV_TX_DW2(ch, lane) _TXLANE(ch, lane, 0x88)
+#define CHV_TX_DW3(ch, lane) _TXLANE(ch, lane, 0x8c)
+#define CHV_TX_DW4(ch, lane) _TXLANE(ch, lane, 0x90)
+#define CHV_TX_DW5(ch, lane) _TXLANE(ch, lane, 0x94)
+#define CHV_TX_DW6(ch, lane) _TXLANE(ch, lane, 0x98)
+#define CHV_TX_DW7(ch, lane) _TXLANE(ch, lane, 0x9c)
+#define CHV_TX_DW8(ch, lane) _TXLANE(ch, lane, 0xa0)
+#define CHV_TX_DW9(ch, lane) _TXLANE(ch, lane, 0xa4)
+#define CHV_TX_DW10(ch, lane) _TXLANE(ch, lane, 0xa8)
#define CHV_TX_DW11(ch, lane) _TXLANE(ch, lane, 0xac)
#define DPIO_FRC_LATENCY_SHFIT (8)
#define CHV_TX_DW14(ch, lane) _TXLANE(ch, lane, 0xb8)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index cc7bccd3..4c54930 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2267,10 +2267,11 @@ static uint32_t intel_chv_signal_levels(struct intel_dp *intel_dp)
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
struct intel_crtc *intel_crtc = to_intel_crtc(dport->base.base.crtc);
- u32 deemph_reg_value, margin_reg_value, val, tx_dw2;
+ u32 deemph_reg_value, margin_reg_value, val;
uint8_t train_set = intel_dp->train_set[0];
enum dpio_channel ch = vlv_dport_to_channel(dport);
- int pipe = intel_crtc->pipe;
+ enum pipe pipe = intel_crtc->pipe;
+ int i;

switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
case DP_TRAIN_PRE_EMPHASIS_0:
@@ -2348,21 +2349,27 @@ static uint32_t intel_chv_signal_levels(struct intel_dp *intel_dp)
vlv_dpio_write(dev_priv, pipe, CHV_PCS_DW10(ch), 0);

/* Program swing deemph */
- val = vlv_dpio_read(dev_priv, pipe, VLV_TX_DW4(ch));
- val &= ~DPIO_SWING_DEEMPH9P5_MASK;
- val |= deemph_reg_value << DPIO_SWING_DEEMPH9P5_SHIFT;
- vlv_dpio_write(dev_priv, pipe, VLV_TX_DW4(ch), val);
+ for (i = 0; i < 4; i++) {
+ val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW4(ch, i));
+ val &= ~DPIO_SWING_DEEMPH9P5_MASK;
+ val |= deemph_reg_value << DPIO_SWING_DEEMPH9P5_SHIFT;
+ vlv_dpio_write(dev_priv, pipe, CHV_TX_DW4(ch, i), val);
+ }

/* Program swing margin */
- tx_dw2 = vlv_dpio_read(dev_priv, pipe, VLV_TX_DW2(ch));
- tx_dw2 &= ~DPIO_SWING_MARGIN_MASK;
- tx_dw2 |= margin_reg_value << DPIO_SWING_MARGIN_SHIFT;
- vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(ch), tx_dw2);
+ for (i = 0; i < 4; i++) {
+ val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i));
+ val &= ~DPIO_SWING_MARGIN_MASK;
+ val |= margin_reg_value << DPIO_SWING_MARGIN_SHIFT;
+ vlv_dpio_write(dev_priv, pipe, CHV_TX_DW2(ch, i), val);
+ }

/* Disable unique transition scale */
- val = vlv_dpio_read(dev_priv, pipe, VLV_TX_DW3(ch));
- val &= ~DPIO_TX_UNIQ_TRANS_SCALE_EN;
- vlv_dpio_write(dev_priv, pipe, VLV_TX_DW3(ch), val);
+ for (i = 0; i < 4; i++) {
+ val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i));
+ val &= ~DPIO_TX_UNIQ_TRANS_SCALE_EN;
+ vlv_dpio_write(dev_priv, pipe, CHV_TX_DW3(ch, i), val);
+ }

if (((train_set & DP_TRAIN_PRE_EMPHASIS_MASK)
== DP_TRAIN_PRE_EMPHASIS_0) &&
@@ -2375,12 +2382,18 @@ static uint32_t intel_chv_signal_levels(struct intel_dp *intel_dp)
* For now, for this unique transition scale selection, set bit
* 27 for ch0 and ch1.
*/
- val = vlv_dpio_read(dev_priv, pipe, VLV_TX_DW3(ch));
- val |= DPIO_TX_UNIQ_TRANS_SCALE_EN;
- vlv_dpio_write(dev_priv, pipe, VLV_TX_DW3(ch), val);
+ for (i = 0; i < 4; i++) {
+ val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i));
+ val |= DPIO_TX_UNIQ_TRANS_SCALE_EN;
+ vlv_dpio_write(dev_priv, pipe, CHV_TX_DW3(ch, i), val);
+ }

- tx_dw2 |= (0x9a << DPIO_UNIQ_TRANS_SCALE_SHIFT);
- vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(ch), tx_dw2);
+ for (i = 0; i < 4; i++) {
+ val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i));
+ val &= ~(0xff << DPIO_UNIQ_TRANS_SCALE_SHIFT);
+ val |= (0x9a << DPIO_UNIQ_TRANS_SCALE_SHIFT);
+ vlv_dpio_write(dev_priv, pipe, CHV_TX_DW2(ch, i), val);
+ }
}

/* Start swing calculation */
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index c3896b0..e912554 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1287,20 +1287,26 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder)

/* FIXME: Program the support xxx V-dB */
/* Use 800mV-0dB */
- val = vlv_dpio_read(dev_priv, pipe, VLV_TX_DW4(ch));
- val &= ~DPIO_SWING_DEEMPH9P5_MASK;
- val |= 128 << DPIO_SWING_DEEMPH9P5_SHIFT;
- vlv_dpio_write(dev_priv, pipe, VLV_TX_DW4(ch), val);
+ for (i = 0; i < 4; i++) {
+ val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW4(ch, i));
+ val &= ~DPIO_SWING_DEEMPH9P5_MASK;
+ val |= 128 << DPIO_SWING_DEEMPH9P5_SHIFT;
+ vlv_dpio_write(dev_priv, pipe, CHV_TX_DW4(ch, i), val);
+ }

- val = vlv_dpio_read(dev_priv, pipe, VLV_TX_DW2(ch));
- val &= ~DPIO_SWING_MARGIN_MASK;
- val |= 102 << DPIO_SWING_MARGIN_SHIFT;
- vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(ch), val);
+ for (i = 0; i < 4; i++) {
+ val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i));
+ val &= ~DPIO_SWING_MARGIN_MASK;
+ val |= 102 << DPIO_SWING_MARGIN_SHIFT;
+ vlv_dpio_write(dev_priv, pipe, CHV_TX_DW2(ch, i), val);
+ }

/* Disable unique transition scale */
- val = vlv_dpio_read(dev_priv, pipe, VLV_TX_DW3(ch));
- val &= ~DPIO_TX_UNIQ_TRANS_SCALE_EN;
- vlv_dpio_write(dev_priv, pipe, VLV_TX_DW3(ch), val);
+ for (i = 0; i < 4; i++) {
+ val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i));
+ val &= ~DPIO_TX_UNIQ_TRANS_SCALE_EN;
+ vlv_dpio_write(dev_priv, pipe, CHV_TX_DW3(ch, i), val);
+ }

/* Additional steps for 1200mV-0dB */
#if 0
--
1.8.3.2