diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-11-01 05:50:22 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-11-01 13:24:53 -0400 |
commit | 8d2f24ca1f19e1e5ca6b941a3f6488f9ccae5390 (patch) | |
tree | 37aabe0afe812fb8ad704eaa8b913c9cbdc6e4f1 | |
parent | 8409360381ebaaab82c7ab502665a29423fcdfc2 (diff) |
drm/i915: scramble reset support for DP port CRC on vlv
They've moved the DC balance reset bit around. Again I don't think we
need it, but better safe than sorry and maybe HDMI port CRC will prove
useful for checking infoframes or hdmi audio.
v2: Apply the suggestions from Damien's review.
Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 881251611512..82c58eb1aa66 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -2026,6 +2026,9 @@ static int vlv_pipe_crc_ctl_reg(struct drm_device *dev, | |||
2026 | enum intel_pipe_crc_source *source, | 2026 | enum intel_pipe_crc_source *source, |
2027 | uint32_t *val) | 2027 | uint32_t *val) |
2028 | { | 2028 | { |
2029 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2030 | bool need_stable_symbols = false; | ||
2031 | |||
2029 | if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) { | 2032 | if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) { |
2030 | int ret = i9xx_pipe_crc_auto_source(dev, pipe, source); | 2033 | int ret = i9xx_pipe_crc_auto_source(dev, pipe, source); |
2031 | if (ret) | 2034 | if (ret) |
@@ -2038,9 +2041,11 @@ static int vlv_pipe_crc_ctl_reg(struct drm_device *dev, | |||
2038 | break; | 2041 | break; |
2039 | case INTEL_PIPE_CRC_SOURCE_DP_B: | 2042 | case INTEL_PIPE_CRC_SOURCE_DP_B: |
2040 | *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_B_VLV; | 2043 | *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_B_VLV; |
2044 | need_stable_symbols = true; | ||
2041 | break; | 2045 | break; |
2042 | case INTEL_PIPE_CRC_SOURCE_DP_C: | 2046 | case INTEL_PIPE_CRC_SOURCE_DP_C: |
2043 | *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_C_VLV; | 2047 | *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_C_VLV; |
2048 | need_stable_symbols = true; | ||
2044 | break; | 2049 | break; |
2045 | case INTEL_PIPE_CRC_SOURCE_NONE: | 2050 | case INTEL_PIPE_CRC_SOURCE_NONE: |
2046 | *val = 0; | 2051 | *val = 0; |
@@ -2049,6 +2054,29 @@ static int vlv_pipe_crc_ctl_reg(struct drm_device *dev, | |||
2049 | return -EINVAL; | 2054 | return -EINVAL; |
2050 | } | 2055 | } |
2051 | 2056 | ||
2057 | /* | ||
2058 | * When the pipe CRC tap point is after the transcoders we need | ||
2059 | * to tweak symbol-level features to produce a deterministic series of | ||
2060 | * symbols for a given frame. We need to reset those features only once | ||
2061 | * a frame (instead of every nth symbol): | ||
2062 | * - DC-balance: used to ensure a better clock recovery from the data | ||
2063 | * link (SDVO) | ||
2064 | * - DisplayPort scrambling: used for EMI reduction | ||
2065 | */ | ||
2066 | if (need_stable_symbols) { | ||
2067 | uint32_t tmp = I915_READ(PORT_DFT2_G4X); | ||
2068 | |||
2069 | WARN_ON(!IS_G4X(dev)); | ||
2070 | |||
2071 | tmp |= DC_BALANCE_RESET_VLV; | ||
2072 | if (pipe == PIPE_A) | ||
2073 | tmp |= PIPE_A_SCRAMBLE_RESET; | ||
2074 | else | ||
2075 | tmp |= PIPE_B_SCRAMBLE_RESET; | ||
2076 | |||
2077 | I915_WRITE(PORT_DFT2_G4X, tmp); | ||
2078 | } | ||
2079 | |||
2052 | return 0; | 2080 | return 0; |
2053 | } | 2081 | } |
2054 | 2082 | ||
@@ -2128,6 +2156,22 @@ static int i9xx_pipe_crc_ctl_reg(struct drm_device *dev, | |||
2128 | return 0; | 2156 | return 0; |
2129 | } | 2157 | } |
2130 | 2158 | ||
2159 | static void vlv_undo_pipe_scramble_reset(struct drm_device *dev, | ||
2160 | enum pipe pipe) | ||
2161 | { | ||
2162 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2163 | uint32_t tmp = I915_READ(PORT_DFT2_G4X); | ||
2164 | |||
2165 | if (pipe == PIPE_A) | ||
2166 | tmp &= ~PIPE_A_SCRAMBLE_RESET; | ||
2167 | else | ||
2168 | tmp &= ~PIPE_B_SCRAMBLE_RESET; | ||
2169 | if (!(tmp & PIPE_SCRAMBLE_RESET_MASK)) | ||
2170 | tmp &= ~DC_BALANCE_RESET_VLV; | ||
2171 | I915_WRITE(PORT_DFT2_G4X, tmp); | ||
2172 | |||
2173 | } | ||
2174 | |||
2131 | static void g4x_undo_pipe_scramble_reset(struct drm_device *dev, | 2175 | static void g4x_undo_pipe_scramble_reset(struct drm_device *dev, |
2132 | enum pipe pipe) | 2176 | enum pipe pipe) |
2133 | { | 2177 | { |
@@ -2267,6 +2311,8 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe, | |||
2267 | 2311 | ||
2268 | if (IS_G4X(dev)) | 2312 | if (IS_G4X(dev)) |
2269 | g4x_undo_pipe_scramble_reset(dev, pipe); | 2313 | g4x_undo_pipe_scramble_reset(dev, pipe); |
2314 | else if (IS_VALLEYVIEW(dev)) | ||
2315 | vlv_undo_pipe_scramble_reset(dev, pipe); | ||
2270 | } | 2316 | } |
2271 | 2317 | ||
2272 | return 0; | 2318 | return 0; |