Commit 3d2011cf authored by Mahesh Kumar's avatar Mahesh Kumar Committed by Jani Nikula

drm/i915/icl: remove port A/E lane sharing limitation.

Platforms before Gen11 were sharing lanes between port-A & port-E.
This limitation is no more there.

Changes since V1:
 - optimize the code (Shashank/Jani)
 - create helper function to get max lanes (ville)
Changes since V2:
 - Include BIOS fail fix-up in same helper function (ville)
Changes since V3:
 - remove confusing if/else (jani)
 - group intel_encoder initialization
Signed-off-by: default avatarMahesh Kumar <mahesh1.kumar@intel.com>
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180206060855.30026-1-mahesh1.kumar@intel.com
parent 1f267a57
...@@ -2842,39 +2842,45 @@ static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dport) ...@@ -2842,39 +2842,45 @@ static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dport)
return false; return false;
} }
static int
intel_ddi_max_lanes(struct intel_digital_port *intel_dport)
{
struct drm_i915_private *dev_priv = to_i915(intel_dport->base.base.dev);
enum port port = intel_dport->base.port;
int max_lanes = 4;
if (INTEL_GEN(dev_priv) >= 11)
return max_lanes;
if (port == PORT_A || port == PORT_E) {
if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES)
max_lanes = port == PORT_A ? 4 : 0;
else
/* Both A and E share 2 lanes */
max_lanes = 2;
}
/*
* Some BIOS might fail to set this bit on port A if eDP
* wasn't lit up at boot. Force this bit set when needed
* so we use the proper lane count for our calculations.
*/
if (intel_ddi_a_force_4_lanes(intel_dport)) {
DRM_DEBUG_KMS("Forcing DDI_A_4_LANES for port A\n");
intel_dport->saved_port_bits |= DDI_A_4_LANES;
max_lanes = 4;
}
return max_lanes;
}
void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
{ {
struct intel_digital_port *intel_dig_port; struct intel_digital_port *intel_dig_port;
struct intel_encoder *intel_encoder; struct intel_encoder *intel_encoder;
struct drm_encoder *encoder; struct drm_encoder *encoder;
bool init_hdmi, init_dp, init_lspcon = false; bool init_hdmi, init_dp, init_lspcon = false;
int max_lanes;
if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {
switch (port) {
case PORT_A:
max_lanes = 4;
break;
case PORT_E:
max_lanes = 0;
break;
default:
max_lanes = 4;
break;
}
} else {
switch (port) {
case PORT_A:
max_lanes = 2;
break;
case PORT_E:
max_lanes = 2;
break;
default:
max_lanes = 4;
break;
}
}
init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi || init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
dev_priv->vbt.ddi_port_info[port].supports_hdmi); dev_priv->vbt.ddi_port_info[port].supports_hdmi);
...@@ -2920,10 +2926,17 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) ...@@ -2920,10 +2926,17 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
intel_encoder->get_config = intel_ddi_get_config; intel_encoder->get_config = intel_ddi_get_config;
intel_encoder->suspend = intel_dp_encoder_suspend; intel_encoder->suspend = intel_dp_encoder_suspend;
intel_encoder->get_power_domains = intel_ddi_get_power_domains; intel_encoder->get_power_domains = intel_ddi_get_power_domains;
intel_encoder->type = INTEL_OUTPUT_DDI;
intel_encoder->power_domain = intel_port_to_power_domain(port);
intel_encoder->port = port;
intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
intel_encoder->cloneable = 0;
intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
(DDI_BUF_PORT_REVERSAL | (DDI_BUF_PORT_REVERSAL |
DDI_A_4_LANES); DDI_A_4_LANES);
intel_dig_port->dp.output_reg = INVALID_MMIO_REG;
intel_dig_port->max_lanes = intel_ddi_max_lanes(intel_dig_port);
switch (port) { switch (port) {
case PORT_A: case PORT_A:
...@@ -2954,26 +2967,6 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) ...@@ -2954,26 +2967,6 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
MISSING_CASE(port); MISSING_CASE(port);
} }
/*
* Some BIOS might fail to set this bit on port A if eDP
* wasn't lit up at boot. Force this bit set when needed
* so we use the proper lane count for our calculations.
*/
if (intel_ddi_a_force_4_lanes(intel_dig_port)) {
DRM_DEBUG_KMS("Forcing DDI_A_4_LANES for port A\n");
intel_dig_port->saved_port_bits |= DDI_A_4_LANES;
max_lanes = 4;
}
intel_dig_port->dp.output_reg = INVALID_MMIO_REG;
intel_dig_port->max_lanes = max_lanes;
intel_encoder->type = INTEL_OUTPUT_DDI;
intel_encoder->power_domain = intel_port_to_power_domain(port);
intel_encoder->port = port;
intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
intel_encoder->cloneable = 0;
intel_infoframe_init(intel_dig_port); intel_infoframe_init(intel_dig_port);
if (init_dp) { if (init_dp) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment