84,7 → 84,8 |
* in either FDI or DP modes only, as HDMI connections will work with both |
* of those |
*/ |
void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, bool use_fdi_mode) |
static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, |
bool use_fdi_mode) |
{ |
struct drm_i915_private *dev_priv = dev->dev_private; |
u32 reg; |
114,17 → 115,18 |
{ |
int port; |
|
if (IS_HASWELL(dev)) { |
if (!HAS_DDI(dev)) |
return; |
|
for (port = PORT_A; port < PORT_E; port++) |
intel_prepare_ddi_buffers(dev, port, false); |
|
/* DDI E is the suggested one to work in FDI mode, so program is as such by |
* default. It will have to be re-programmed in case a digital DP output |
* will be detected on it |
/* DDI E is the suggested one to work in FDI mode, so program is as such |
* by default. It will have to be re-programmed in case a digital DP |
* output will be detected on it |
*/ |
intel_prepare_ddi_buffers(dev, PORT_E, true); |
} |
} |
|
static const long hsw_ddi_buf_ctl_values[] = { |
DDI_BUF_EMP_400MV_0DB_HSW, |
178,10 → 180,8 |
FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90); |
|
/* Enable the PCH Receiver FDI PLL */ |
rx_ctl_val = FDI_RX_PLL_ENABLE | FDI_RX_ENHANCE_FRAME_ENABLE | |
((intel_crtc->fdi_lanes - 1) << 19); |
if (dev_priv->fdi_rx_polarity_reversed) |
rx_ctl_val |= FDI_RX_POLARITY_REVERSED_LPT; |
rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE | |
FDI_RX_PLL_ENABLE | ((intel_crtc->fdi_lanes - 1) << 19); |
I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
POSTING_READ(_FDI_RXA_CTL); |
udelay(220); |
203,7 → 203,10 |
DP_TP_CTL_LINK_TRAIN_PAT1 | |
DP_TP_CTL_ENABLE); |
|
/* Configure and enable DDI_BUF_CTL for DDI E with next voltage */ |
/* Configure and enable DDI_BUF_CTL for DDI E with next voltage. |
* DDI E does not support port reversal, the functionality is |
* achieved on the PCH side in FDI_RX_CTL, so no need to set the |
* port reversal bit */ |
I915_WRITE(DDI_BUF_CTL(PORT_E), |
DDI_BUF_CTL_ENABLE | |
((intel_crtc->fdi_lanes - 1) << 1) | |
675,10 → 678,14 |
DRM_DEBUG_KMS("Preparing DDI mode for Haswell on port %c, pipe %c\n", |
port_name(port), pipe_name(pipe)); |
|
intel_crtc->eld_vld = false; |
if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
struct intel_digital_port *intel_dig_port = |
enc_to_dig_port(encoder); |
|
intel_dp->DP = DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW; |
intel_dp->DP = intel_dig_port->port_reversal | |
DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW; |
switch (intel_dp->lane_count) { |
case 1: |
intel_dp->DP |= DDI_PORT_WIDTH_X1; |
985,7 → 992,13 |
if (cpu_transcoder == TRANSCODER_EDP) { |
switch (pipe) { |
case PIPE_A: |
/* Can only use the always-on power well for eDP when |
* not using the panel fitter, and when not using motion |
* blur mitigation (which we don't support). */ |
if (dev_priv->pch_pf_size) |
temp |= TRANS_DDI_EDP_INPUT_A_ONOFF; |
else |
temp |= TRANS_DDI_EDP_INPUT_A_ON; |
break; |
case PIPE_B: |
temp |= TRANS_DDI_EDP_INPUT_B_ONOFF; |
1069,7 → 1082,7 |
if (port == PORT_A) |
cpu_transcoder = TRANSCODER_EDP; |
else |
cpu_transcoder = pipe; |
cpu_transcoder = (enum transcoder) pipe; |
|
tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); |
|
1285,28 → 1298,48 |
static void intel_enable_ddi(struct intel_encoder *intel_encoder) |
{ |
struct drm_encoder *encoder = &intel_encoder->base; |
struct drm_crtc *crtc = encoder->crtc; |
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
int pipe = intel_crtc->pipe; |
struct drm_device *dev = encoder->dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
enum port port = intel_ddi_get_encoder_port(intel_encoder); |
int type = intel_encoder->type; |
uint32_t tmp; |
|
if (type == INTEL_OUTPUT_HDMI) { |
struct intel_digital_port *intel_dig_port = |
enc_to_dig_port(encoder); |
|
/* In HDMI/DVI mode, the port width, and swing/emphasis values |
* are ignored so nothing special needs to be done besides |
* enabling the port. |
*/ |
I915_WRITE(DDI_BUF_CTL(port), DDI_BUF_CTL_ENABLE); |
I915_WRITE(DDI_BUF_CTL(port), |
intel_dig_port->port_reversal | DDI_BUF_CTL_ENABLE); |
} else if (type == INTEL_OUTPUT_EDP) { |
struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
|
ironlake_edp_backlight_on(intel_dp); |
} |
|
if (intel_crtc->eld_vld) { |
tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); |
tmp |= ((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4)); |
I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); |
} |
} |
|
static void intel_disable_ddi(struct intel_encoder *intel_encoder) |
{ |
struct drm_encoder *encoder = &intel_encoder->base; |
struct drm_crtc *crtc = encoder->crtc; |
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
int pipe = intel_crtc->pipe; |
int type = intel_encoder->type; |
struct drm_device *dev = encoder->dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
uint32_t tmp; |
|
if (type == INTEL_OUTPUT_EDP) { |
struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1313,6 → 1346,10 |
|
ironlake_edp_backlight_off(intel_dp); |
} |
|
tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); |
tmp &= ~((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4)); |
I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); |
} |
|
int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) |
1354,8 → 1391,8 |
struct intel_dp *intel_dp = &intel_dig_port->dp; |
struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
enum port port = intel_dig_port->port; |
bool wait; |
uint32_t val; |
bool wait = false; |
|
if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) { |
val = I915_READ(DDI_BUF_CTL(port)); |
1452,11 → 1489,11 |
static const struct drm_encoder_helper_funcs intel_ddi_helper_funcs = { |
.mode_fixup = intel_ddi_mode_fixup, |
.mode_set = intel_ddi_mode_set, |
.disable = intel_encoder_noop, |
}; |
|
void intel_ddi_init(struct drm_device *dev, enum port port) |
{ |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_digital_port *intel_dig_port; |
struct intel_encoder *intel_encoder; |
struct drm_encoder *encoder; |
1497,6 → 1534,8 |
intel_encoder->get_hw_state = intel_ddi_get_hw_state; |
|
intel_dig_port->port = port; |
intel_dig_port->port_reversal = I915_READ(DDI_BUF_CTL(port)) & |
DDI_BUF_PORT_REVERSAL; |
if (hdmi_connector) |
intel_dig_port->hdmi.sdvox_reg = DDI_BUF_CTL(port); |
else |