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

Commit ed92f0b2 authored by Paulo Zanoni's avatar Paulo Zanoni Committed by Daniel Vetter
Browse files

drm/i915: extract intel_edp_init_connector



Because intel_dp_init_connector is too big for my poor little brain.
No functional changes.

Signed-off-by: default avatarPaulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: default avatarZoltan Nyul <zoltan.nyul@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent acd8db10
Loading
Loading
Loading
Loading
+82 −69
Original line number Diff line number Diff line
@@ -2955,6 +2955,86 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
		      I915_READ(pp_div_reg));
}

static bool intel_edp_init_connector(struct intel_dp *intel_dp,
				     struct intel_connector *intel_connector)
{
	struct drm_connector *connector = &intel_connector->base;
	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
	struct drm_device *dev = intel_dig_port->base.base.dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_display_mode *fixed_mode = NULL;
	struct edp_power_seq power_seq = { 0 };
	bool has_dpcd;
	struct drm_display_mode *scan;
	struct edid *edid;

	if (!is_edp(intel_dp))
		return true;

	intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq);

	/* Cache DPCD and EDID for edp. */
	ironlake_edp_panel_vdd_on(intel_dp);
	has_dpcd = intel_dp_get_dpcd(intel_dp);
	ironlake_edp_panel_vdd_off(intel_dp, false);

	if (has_dpcd) {
		if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11)
			dev_priv->no_aux_handshake =
				intel_dp->dpcd[DP_MAX_DOWNSPREAD] &
				DP_NO_AUX_HANDSHAKE_LINK_TRAINING;
	} else {
		/* if this fails, presume the device is a ghost */
		DRM_INFO("failed to retrieve link info, disabling eDP\n");
		intel_dp_encoder_destroy(&intel_dig_port->base.base);
		intel_dp_destroy(connector);
		return false;
	}

	/* We now know it's not a ghost, init power sequence regs. */
	intel_dp_init_panel_power_sequencer_registers(dev, intel_dp,
						      &power_seq);

	ironlake_edp_panel_vdd_on(intel_dp);
	edid = drm_get_edid(connector, &intel_dp->adapter);
	if (edid) {
		if (drm_add_edid_modes(connector, edid)) {
			drm_mode_connector_update_edid_property(connector,
								edid);
			drm_edid_to_eld(connector, edid);
		} else {
			kfree(edid);
			edid = ERR_PTR(-EINVAL);
		}
	} else {
		edid = ERR_PTR(-ENOENT);
	}
	intel_connector->edid = edid;

	/* prefer fixed mode from EDID if available */
	list_for_each_entry(scan, &connector->probed_modes, head) {
		if ((scan->type & DRM_MODE_TYPE_PREFERRED)) {
			fixed_mode = drm_mode_duplicate(dev, scan);
			break;
		}
	}

	/* fallback to VBT if available for eDP */
	if (!fixed_mode && dev_priv->vbt.lfp_lvds_vbt_mode) {
		fixed_mode = drm_mode_duplicate(dev,
					dev_priv->vbt.lfp_lvds_vbt_mode);
		if (fixed_mode)
			fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
	}

	ironlake_edp_panel_vdd_off(intel_dp, false);

	intel_panel_init(&intel_connector->panel, fixed_mode);
	intel_panel_setup_backlight(connector);

	return true;
}

void
intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
			struct intel_connector *intel_connector)
@@ -2964,8 +3044,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
	struct intel_encoder *intel_encoder = &intel_dig_port->base;
	struct drm_device *dev = intel_encoder->base.dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_display_mode *fixed_mode = NULL;
	struct edp_power_seq power_seq = { 0 };
	enum port port = intel_dig_port->port;
	const char *name = NULL;
	int type;
@@ -3066,75 +3144,10 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
		BUG();
	}

	if (is_edp(intel_dp))
		intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq);

	intel_dp_i2c_init(intel_dp, intel_connector, name);

	/* Cache DPCD and EDID for edp. */
	if (is_edp(intel_dp)) {
		bool ret;
		struct drm_display_mode *scan;
		struct edid *edid;

		ironlake_edp_panel_vdd_on(intel_dp);
		ret = intel_dp_get_dpcd(intel_dp);
		ironlake_edp_panel_vdd_off(intel_dp, false);

		if (ret) {
			if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11)
				dev_priv->no_aux_handshake =
					intel_dp->dpcd[DP_MAX_DOWNSPREAD] &
					DP_NO_AUX_HANDSHAKE_LINK_TRAINING;
		} else {
			/* if this fails, presume the device is a ghost */
			DRM_INFO("failed to retrieve link info, disabling eDP\n");
			intel_dp_encoder_destroy(&intel_encoder->base);
			intel_dp_destroy(connector);
	if (!intel_edp_init_connector(intel_dp, intel_connector))
		return;
		}

		/* We now know it's not a ghost, init power sequence regs. */
		intel_dp_init_panel_power_sequencer_registers(dev, intel_dp,
							      &power_seq);

		ironlake_edp_panel_vdd_on(intel_dp);
		edid = drm_get_edid(connector, &intel_dp->adapter);
		if (edid) {
			if (drm_add_edid_modes(connector, edid)) {
				drm_mode_connector_update_edid_property(connector, edid);
				drm_edid_to_eld(connector, edid);
			} else {
				kfree(edid);
				edid = ERR_PTR(-EINVAL);
			}
		} else {
			edid = ERR_PTR(-ENOENT);
		}
		intel_connector->edid = edid;

		/* prefer fixed mode from EDID if available */
		list_for_each_entry(scan, &connector->probed_modes, head) {
			if ((scan->type & DRM_MODE_TYPE_PREFERRED)) {
				fixed_mode = drm_mode_duplicate(dev, scan);
				break;
			}
		}

		/* fallback to VBT if available for eDP */
		if (!fixed_mode && dev_priv->vbt.lfp_lvds_vbt_mode) {
			fixed_mode = drm_mode_duplicate(dev, dev_priv->vbt.lfp_lvds_vbt_mode);
			if (fixed_mode)
				fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
		}

		ironlake_edp_panel_vdd_off(intel_dp, false);
	}

	if (is_edp(intel_dp)) {
		intel_panel_init(&intel_connector->panel, fixed_mode);
		intel_panel_setup_backlight(connector);
	}

	intel_dp_add_properties(intel_dp, connector);