forked from Minki/linux
drm/i915: Unduplicate CHV signal level code
The code for programming voltage swing and emphasis was duplicated between DP and HDMI code. Move that to a new file, intel_dpio_phy.c. v2: Keep the "Use 800mV-0dB" comment in the HDMI code. (Ville) Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Jim Bride <jim.bride@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1461761065-21195-3-git-send-email-ander.conselvan.de.oliveira@intel.com
This commit is contained in:
parent
d4d6279abe
commit
b7fa22d872
@ -59,6 +59,7 @@ i915-y += intel_audio.o \
|
||||
intel_bios.o \
|
||||
intel_color.o \
|
||||
intel_display.o \
|
||||
intel_dpio_phy.o \
|
||||
intel_dpll_mgr.o \
|
||||
intel_fbc.o \
|
||||
intel_fifo_underrun.o \
|
||||
|
@ -3589,6 +3589,11 @@ void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
|
||||
u32 vlv_flisdsi_read(struct drm_i915_private *dev_priv, u32 reg);
|
||||
void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
|
||||
|
||||
/* intel_dpio_phy.c */
|
||||
void chv_set_phy_signal_level(struct intel_encoder *encoder,
|
||||
u32 deemph_reg_value, u32 margin_reg_value,
|
||||
bool uniq_trans_scale);
|
||||
|
||||
int intel_gpu_freq(struct drm_i915_private *dev_priv, int val);
|
||||
int intel_freq_opcode(struct drm_i915_private *dev_priv, int val);
|
||||
|
||||
|
@ -3309,23 +3309,12 @@ static uint32_t vlv_signal_levels(struct intel_dp *intel_dp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool chv_need_uniq_trans_scale(uint8_t train_set)
|
||||
{
|
||||
return (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) == DP_TRAIN_PRE_EMPH_LEVEL_0 &&
|
||||
(train_set & DP_TRAIN_VOLTAGE_SWING_MASK) == DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
|
||||
}
|
||||
|
||||
static uint32_t chv_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);
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(dport->base.base.crtc);
|
||||
u32 deemph_reg_value, margin_reg_value, val;
|
||||
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
|
||||
u32 deemph_reg_value, margin_reg_value;
|
||||
bool uniq_trans_scale = false;
|
||||
uint8_t train_set = intel_dp->train_set[0];
|
||||
enum dpio_channel ch = vlv_dport_to_channel(dport);
|
||||
enum pipe pipe = intel_crtc->pipe;
|
||||
int i;
|
||||
|
||||
switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
|
||||
case DP_TRAIN_PRE_EMPH_LEVEL_0:
|
||||
@ -3345,7 +3334,7 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
|
||||
case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
|
||||
deemph_reg_value = 128;
|
||||
margin_reg_value = 154;
|
||||
/* FIXME extra to set for 1200 */
|
||||
uniq_trans_scale = true;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
@ -3397,88 +3386,8 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex_lock(&dev_priv->sb_lock);
|
||||
|
||||
/* Clear calc init */
|
||||
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
|
||||
val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
|
||||
val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
|
||||
val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
|
||||
vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
|
||||
|
||||
if (intel_crtc->config->lane_count > 2) {
|
||||
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
|
||||
val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
|
||||
val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
|
||||
val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
|
||||
vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
|
||||
}
|
||||
|
||||
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW9(ch));
|
||||
val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
|
||||
val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
|
||||
vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW9(ch), val);
|
||||
|
||||
if (intel_crtc->config->lane_count > 2) {
|
||||
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW9(ch));
|
||||
val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
|
||||
val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
|
||||
vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW9(ch), val);
|
||||
}
|
||||
|
||||
/* Program swing deemph */
|
||||
for (i = 0; i < intel_crtc->config->lane_count; 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 */
|
||||
for (i = 0; i < intel_crtc->config->lane_count; i++) {
|
||||
val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i));
|
||||
|
||||
val &= ~DPIO_SWING_MARGIN000_MASK;
|
||||
val |= margin_reg_value << DPIO_SWING_MARGIN000_SHIFT;
|
||||
|
||||
/*
|
||||
* Supposedly this value shouldn't matter when unique transition
|
||||
* scale is disabled, but in fact it does matter. Let's just
|
||||
* always program the same value and hope it's OK.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* The document said it needs to set bit 27 for ch0 and bit 26
|
||||
* for ch1. Might be a typo in the doc.
|
||||
* For now, for this unique transition scale selection, set bit
|
||||
* 27 for ch0 and ch1.
|
||||
*/
|
||||
for (i = 0; i < intel_crtc->config->lane_count; i++) {
|
||||
val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i));
|
||||
if (chv_need_uniq_trans_scale(train_set))
|
||||
val |= DPIO_TX_UNIQ_TRANS_SCALE_EN;
|
||||
else
|
||||
val &= ~DPIO_TX_UNIQ_TRANS_SCALE_EN;
|
||||
vlv_dpio_write(dev_priv, pipe, CHV_TX_DW3(ch, i), val);
|
||||
}
|
||||
|
||||
/* Start swing calculation */
|
||||
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
|
||||
val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
|
||||
vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
|
||||
|
||||
if (intel_crtc->config->lane_count > 2) {
|
||||
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
|
||||
val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
|
||||
vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
|
||||
}
|
||||
|
||||
mutex_unlock(&dev_priv->sb_lock);
|
||||
chv_set_phy_signal_level(encoder, deemph_reg_value,
|
||||
margin_reg_value, uniq_trans_scale);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
122
drivers/gpu/drm/i915/intel_dpio_phy.c
Normal file
122
drivers/gpu/drm/i915/intel_dpio_phy.c
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright © 2014-2016 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "intel_drv.h"
|
||||
|
||||
void chv_set_phy_signal_level(struct intel_encoder *encoder,
|
||||
u32 deemph_reg_value, u32 margin_reg_value,
|
||||
bool uniq_trans_scale)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(dport->base.base.crtc);
|
||||
enum dpio_channel ch = vlv_dport_to_channel(dport);
|
||||
enum pipe pipe = intel_crtc->pipe;
|
||||
u32 val;
|
||||
int i;
|
||||
|
||||
mutex_lock(&dev_priv->sb_lock);
|
||||
|
||||
/* Clear calc init */
|
||||
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
|
||||
val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
|
||||
val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
|
||||
val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
|
||||
vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
|
||||
|
||||
if (intel_crtc->config->lane_count > 2) {
|
||||
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
|
||||
val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
|
||||
val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
|
||||
val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
|
||||
vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
|
||||
}
|
||||
|
||||
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW9(ch));
|
||||
val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
|
||||
val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
|
||||
vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW9(ch), val);
|
||||
|
||||
if (intel_crtc->config->lane_count > 2) {
|
||||
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW9(ch));
|
||||
val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
|
||||
val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
|
||||
vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW9(ch), val);
|
||||
}
|
||||
|
||||
/* Program swing deemph */
|
||||
for (i = 0; i < intel_crtc->config->lane_count; 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 */
|
||||
for (i = 0; i < intel_crtc->config->lane_count; i++) {
|
||||
val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i));
|
||||
|
||||
val &= ~DPIO_SWING_MARGIN000_MASK;
|
||||
val |= margin_reg_value << DPIO_SWING_MARGIN000_SHIFT;
|
||||
|
||||
/*
|
||||
* Supposedly this value shouldn't matter when unique transition
|
||||
* scale is disabled, but in fact it does matter. Let's just
|
||||
* always program the same value and hope it's OK.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* The document said it needs to set bit 27 for ch0 and bit 26
|
||||
* for ch1. Might be a typo in the doc.
|
||||
* For now, for this unique transition scale selection, set bit
|
||||
* 27 for ch0 and ch1.
|
||||
*/
|
||||
for (i = 0; i < intel_crtc->config->lane_count; i++) {
|
||||
val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i));
|
||||
if (uniq_trans_scale)
|
||||
val |= DPIO_TX_UNIQ_TRANS_SCALE_EN;
|
||||
else
|
||||
val &= ~DPIO_TX_UNIQ_TRANS_SCALE_EN;
|
||||
vlv_dpio_write(dev_priv, pipe, CHV_TX_DW3(ch, i), val);
|
||||
}
|
||||
|
||||
/* Start swing calculation */
|
||||
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
|
||||
val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
|
||||
vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
|
||||
|
||||
if (intel_crtc->config->lane_count > 2) {
|
||||
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
|
||||
val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
|
||||
vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
|
||||
}
|
||||
|
||||
mutex_unlock(&dev_priv->sb_lock);
|
||||
|
||||
}
|
||||
|
@ -1921,77 +1921,11 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
|
||||
/* Deassert data lane reset */
|
||||
chv_data_lane_soft_reset(encoder, false);
|
||||
|
||||
/* Clear calc init */
|
||||
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
|
||||
val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
|
||||
val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
|
||||
val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
|
||||
vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
|
||||
|
||||
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
|
||||
val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3);
|
||||
val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK);
|
||||
val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5;
|
||||
vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
|
||||
|
||||
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW9(ch));
|
||||
val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
|
||||
val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
|
||||
vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW9(ch), val);
|
||||
|
||||
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW9(ch));
|
||||
val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK);
|
||||
val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000;
|
||||
vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW9(ch), val);
|
||||
mutex_unlock(&dev_priv->sb_lock);
|
||||
|
||||
/* FIXME: Program the support xxx V-dB */
|
||||
/* Use 800mV-0dB */
|
||||
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);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i));
|
||||
|
||||
val &= ~DPIO_SWING_MARGIN000_MASK;
|
||||
val |= 102 << DPIO_SWING_MARGIN000_SHIFT;
|
||||
|
||||
/*
|
||||
* Supposedly this value shouldn't matter when unique transition
|
||||
* scale is disabled, but in fact it does matter. Let's just
|
||||
* always program the same value and hope it's OK.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* The document said it needs to set bit 27 for ch0 and bit 26
|
||||
* for ch1. Might be a typo in the doc.
|
||||
* For now, for this unique transition scale selection, set bit
|
||||
* 27 for ch0 and ch1.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/* Start swing calculation */
|
||||
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
|
||||
val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
|
||||
vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val);
|
||||
|
||||
val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch));
|
||||
val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3;
|
||||
vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
|
||||
|
||||
mutex_unlock(&dev_priv->sb_lock);
|
||||
chv_set_phy_signal_level(encoder, 128, 102, false);
|
||||
|
||||
intel_hdmi->set_infoframes(&encoder->base,
|
||||
intel_crtc->config->has_hdmi_sink,
|
||||
|
Loading…
Reference in New Issue
Block a user