Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+39 −46
Original line number Diff line number Diff line
@@ -2842,39 +2842,45 @@ static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dport)
	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)
{
	struct intel_digital_port *intel_dig_port;
	struct intel_encoder *intel_encoder;
	struct drm_encoder *encoder;
	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 ||
		     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)
	intel_encoder->get_config = intel_ddi_get_config;
	intel_encoder->suspend = intel_dp_encoder_suspend;
	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)) &
					  (DDI_BUF_PORT_REVERSAL |
					   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) {
	case PORT_A:
@@ -2954,26 +2967,6 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port 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);

	if (init_dp) {