Commit 436009b5 authored by Rodrigo Vivi's avatar Rodrigo Vivi

drm/i915/cnl: Force DDI_A_4_LANES when needed.

As we faced in BXT, on CNL DDI_A_4_LANES is not
set as expected when system is boot with multiple
monitors connected. This result in wrong lane
setup impacting the max data rate available and
consequently blocking modeset on eDP, resulting
in a blank screen.

Most of CNL SKUs don't support DDI-E.
The only SKU that supports DDI-E is the same
that supports the full A/E split called DDI-F.

Also when DDI-F is used DDI-E cannot be used because
they share Interrupts. So DDI-E is almost useless.
Anyways let's consider this is possible and rely on
VBT for that.

This patch was initialy start by Clint, but required
many changes including full commit message. So
Credits entirely to Clint for finding this.

v2: Extract all messy conditions into a helper function
    as suggested by Ville.
    Along with simplification I removed the debug
    message on the working case since now all conditions
    are grouped.
v3: Split the conditions even more as suggested by Ville.
    Get's cleaner and easier to add new cases in the
    future.
Suggested-by: default avatarClint Taylor <clinton.a.taylor@intel.com>
Cc: Clint Taylor <clinton.a.taylor@intel.com>
Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20171023173920.22890-1-rodrigo.vivi@intel.com
parent 191f8960
...@@ -2711,6 +2711,34 @@ intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port) ...@@ -2711,6 +2711,34 @@ intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
return connector; return connector;
} }
static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dport)
{
struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev);
if (dport->port != PORT_A)
return false;
if (dport->saved_port_bits & DDI_A_4_LANES)
return false;
/* Broxton/Geminilake: Bspec says that DDI_A_4_LANES is the only
* supported configuration
*/
if (IS_GEN9_LP(dev_priv))
return true;
/* Cannonlake: Most of SKUs don't support DDI_E, and the only
* one who does also have a full A/E split called
* DDI_F what makes DDI_E useless. However for this
* case let's trust VBT info.
*/
if (IS_CANNONLAKE(dev_priv) &&
!intel_bios_is_port_present(dev_priv, PORT_E))
return true;
return false;
}
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;
...@@ -2820,19 +2848,15 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) ...@@ -2820,19 +2848,15 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
} }
/* /*
* Bspec says that DDI_A_4_LANES is the only supported configuration * Some BIOS might fail to set this bit on port A if eDP
* for Broxton. Yet some BIOS fail to set this bit on port A if eDP * wasn't lit up at boot. Force this bit set when needed
* wasn't lit up at boot. Force this bit on in our internal * so we use the proper lane count for our calculations.
* configuration so that we use the proper lane count for our
* calculations.
*/ */
if (IS_GEN9_LP(dev_priv) && port == PORT_A) { if (intel_ddi_a_force_4_lanes(intel_dig_port)) {
if (!(intel_dig_port->saved_port_bits & DDI_A_4_LANES)) { DRM_DEBUG_KMS("Forcing DDI_A_4_LANES for port A\n");
DRM_DEBUG_KMS("BXT BIOS forgot to set DDI_A_4_LANES for port A; fixing\n");
intel_dig_port->saved_port_bits |= DDI_A_4_LANES; intel_dig_port->saved_port_bits |= DDI_A_4_LANES;
max_lanes = 4; max_lanes = 4;
} }
}
intel_dig_port->max_lanes = max_lanes; intel_dig_port->max_lanes = max_lanes;
......
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