Example #1
0
static int intel_dp_mst_atomic_check(struct drm_connector *connector,
		struct drm_connector_state *new_conn_state)
{
	struct drm_atomic_state *state = new_conn_state->state;
	struct drm_connector_state *old_conn_state;
	struct drm_crtc *old_crtc;
	struct drm_crtc_state *crtc_state;
	int slots, ret = 0;

	old_conn_state = drm_atomic_get_old_connector_state(state, connector);
	old_crtc = old_conn_state->crtc;
	if (!old_crtc)
		return ret;

	crtc_state = drm_atomic_get_new_crtc_state(state, old_crtc);
	slots = to_intel_crtc_state(crtc_state)->dp_m_n.tu;
	if (drm_atomic_crtc_needs_modeset(crtc_state) && slots > 0) {
		struct drm_dp_mst_topology_mgr *mgr;
		struct drm_encoder *old_encoder;

		old_encoder = old_conn_state->best_encoder;
		mgr = &enc_to_mst(old_encoder)->primary->dp.mst_mgr;

		ret = drm_dp_atomic_release_vcpi_slots(state, mgr, slots);
		if (ret)
			DRM_DEBUG_KMS("failed releasing %d vcpi slots:%d\n", slots, ret);
		else
			to_intel_crtc_state(crtc_state)->dp_m_n.tu = 0;
	}
	return ret;
}
Example #2
0
static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
				      const struct intel_crtc_state *old_crtc_state,
				      const struct drm_connector_state *old_conn_state)
{
	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
	struct intel_digital_port *intel_dig_port = intel_mst->primary;
	struct intel_dp *intel_dp = &intel_dig_port->dp;
	struct intel_connector *connector =
		to_intel_connector(old_conn_state->connector);

	/* this can fail */
	drm_dp_check_act_status(&intel_dp->mst_mgr);
	/* and this can also fail */
	drm_dp_update_payload_part2(&intel_dp->mst_mgr);

	drm_dp_mst_deallocate_vcpi(&intel_dp->mst_mgr, connector->port);

	/*
	 * Power down mst path before disabling the port, otherwise we end
	 * up getting interrupts from the sink upon detecting link loss.
	 */
	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,
				     false);

	intel_dp->active_mst_links--;

	intel_mst->connector = NULL;
	if (intel_dp->active_mst_links == 0) {
		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
		intel_dig_port->base.post_disable(&intel_dig_port->base,
						  old_crtc_state, NULL);
	}

	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
}
Example #3
0
static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
				      struct intel_crtc_state *old_crtc_state,
				      struct drm_connector_state *old_conn_state)
{
	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
	struct intel_digital_port *intel_dig_port = intel_mst->primary;
	struct intel_dp *intel_dp = &intel_dig_port->dp;
	struct intel_connector *connector =
		to_intel_connector(old_conn_state->connector);

	DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links);

	/* this can fail */
	drm_dp_check_act_status(&intel_dp->mst_mgr);
	/* and this can also fail */
	drm_dp_update_payload_part2(&intel_dp->mst_mgr);

	drm_dp_mst_deallocate_vcpi(&intel_dp->mst_mgr, connector->port);

	intel_dp->active_mst_links--;

	intel_mst->connector = NULL;
	if (intel_dp->active_mst_links == 0) {
		intel_dig_port->base.post_disable(&intel_dig_port->base,
						  NULL, NULL);

		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
	}
}
Example #4
0
static void intel_dp_mst_encoder_destroy(struct drm_encoder *encoder)
{
	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);

	drm_encoder_cleanup(encoder);
	kfree(intel_mst);
}
Example #5
0
static void intel_mst_enable_dp(struct intel_encoder *encoder,
				const struct intel_crtc_state *pipe_config,
				const struct drm_connector_state *conn_state)
{
	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
	struct intel_digital_port *intel_dig_port = intel_mst->primary;
	struct intel_dp *intel_dp = &intel_dig_port->dp;
	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
	enum port port = intel_dig_port->base.port;

	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);

	if (intel_wait_for_register(&dev_priv->uncore,
				    DP_TP_STATUS(port),
				    DP_TP_STATUS_ACT_SENT,
				    DP_TP_STATUS_ACT_SENT,
				    1))
		DRM_ERROR("Timed out waiting for ACT sent\n");

	drm_dp_check_act_status(&intel_dp->mst_mgr);

	drm_dp_update_payload_part2(&intel_dp->mst_mgr);
	if (pipe_config->has_audio)
		intel_audio_codec_enable(encoder, pipe_config, conn_state);
}
Example #6
0
static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder,
					struct intel_crtc_state *pipe_config)
{
	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
	struct intel_digital_port *intel_dig_port = intel_mst->primary;

	intel_ddi_get_config(&intel_dig_port->base, pipe_config);
}
Example #7
0
static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
				      enum pipe *pipe)
{
	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
	*pipe = intel_mst->pipe;
	if (intel_mst->connector)
		return true;
	return false;
}
Example #8
0
static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
					struct intel_crtc_state *pipe_config,
					struct drm_connector_state *conn_state)
{
	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
	struct intel_digital_port *intel_dig_port = intel_mst->primary;
	struct intel_dp *intel_dp = &intel_dig_port->dp;
	struct intel_connector *connector =
		to_intel_connector(conn_state->connector);
	struct drm_atomic_state *state;
	int bpp;
	int lane_count, slots;
	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
	int mst_pbn;
	bool reduce_m_n = drm_dp_has_quirk(&intel_dp->desc,
					   DP_DPCD_QUIRK_LIMITED_M_N);

	pipe_config->has_pch_encoder = false;
	bpp = 24;
	if (intel_dp->compliance.test_data.bpc) {
		bpp = intel_dp->compliance.test_data.bpc * 3;
		DRM_DEBUG_KMS("Setting pipe bpp to %d\n",
			      bpp);
	}
	/*
	 * for MST we always configure max link bw - the spec doesn't
	 * seem to suggest we should do otherwise.
	 */
	lane_count = drm_dp_max_lane_count(intel_dp->dpcd);

	pipe_config->lane_count = lane_count;

	pipe_config->pipe_bpp = bpp;
	pipe_config->port_clock = intel_dp_max_link_rate(intel_dp);

	state = pipe_config->base.state;

	if (drm_dp_mst_port_has_audio(&intel_dp->mst_mgr, connector->port))
		pipe_config->has_audio = true;
	mst_pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, bpp);

	pipe_config->pbn = mst_pbn;
	slots = drm_dp_find_vcpi_slots(&intel_dp->mst_mgr, mst_pbn);

	intel_link_compute_m_n(bpp, lane_count,
			       adjusted_mode->crtc_clock,
			       pipe_config->port_clock,
			       &pipe_config->dp_m_n,
			       reduce_m_n);

	pipe_config->dp_m_n.tu = slots;

	return true;

}
Example #9
0
static void intel_mst_pre_pll_enable_dp(struct intel_encoder *encoder,
					const struct intel_crtc_state *pipe_config,
					const struct drm_connector_state *conn_state)
{
	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
	struct intel_digital_port *intel_dig_port = intel_mst->primary;
	struct intel_dp *intel_dp = &intel_dig_port->dp;

	if (intel_dp->active_mst_links == 0)
		intel_dig_port->base.pre_pll_enable(&intel_dig_port->base,
						    pipe_config, NULL);
}
Example #10
0
static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
				    struct intel_crtc_state *pipe_config,
				    struct drm_connector_state *conn_state)
{
	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
	struct intel_digital_port *intel_dig_port = intel_mst->primary;
	struct intel_dp *intel_dp = &intel_dig_port->dp;
	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
	enum port port = intel_dig_port->port;
	struct intel_connector *connector =
		to_intel_connector(conn_state->connector);
	int ret;
	uint32_t temp;
	int slots;

	/* MST encoders are bound to a crtc, not to a connector,
	 * force the mapping here for get_hw_state.
	 */
	connector->encoder = encoder;
	intel_mst->connector = connector;

	DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links);

	if (intel_dp->active_mst_links == 0) {
		intel_ddi_clk_select(&intel_dig_port->base, pipe_config);

		intel_prepare_dp_ddi_buffers(&intel_dig_port->base);

		intel_dp_set_link_params(intel_dp, pipe_config);

		intel_ddi_init_dp_buf_reg(&intel_dig_port->base);

		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);

		intel_dp_start_link_train(intel_dp);
		intel_dp_stop_link_train(intel_dp);
	}

	ret = drm_dp_mst_allocate_vcpi(&intel_dp->mst_mgr,
				       connector->port,
				       pipe_config->pbn, &slots);
	if (ret == false) {
		DRM_ERROR("failed to allocate vcpi\n");
		return;
	}


	intel_dp->active_mst_links++;
	temp = I915_READ(DP_TP_STATUS(port));
	I915_WRITE(DP_TP_STATUS(port), temp);

	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
}
Example #11
0
static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
					struct intel_crtc_state *pipe_config)
{
	struct drm_device *dev = encoder->base.dev;
	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
	struct intel_digital_port *intel_dig_port = intel_mst->primary;
	struct intel_dp *intel_dp = &intel_dig_port->dp;
	struct drm_atomic_state *state;
	int bpp, i;
	int lane_count, slots, rate;
	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
	struct drm_connector *drm_connector;
	struct intel_connector *connector, *found = NULL;
	struct drm_connector_state *connector_state;
	int mst_pbn;

	pipe_config->dp_encoder_is_mst = true;
	pipe_config->has_pch_encoder = false;
	pipe_config->has_dp_encoder = true;
	bpp = 24;
	/*
	 * for MST we always configure max link bw - the spec doesn't
	 * seem to suggest we should do otherwise.
	 */
	lane_count = drm_dp_max_lane_count(intel_dp->dpcd);

	rate = intel_dp_max_link_rate(intel_dp);

	if (intel_dp->num_sink_rates) {
		intel_dp->link_bw = 0;
		intel_dp->rate_select = intel_dp_rate_select(intel_dp, rate);
	} else {
		intel_dp->link_bw = drm_dp_link_rate_to_bw_code(rate);
		intel_dp->rate_select = 0;
	}

	intel_dp->lane_count = lane_count;

	pipe_config->pipe_bpp = 24;
	pipe_config->port_clock = rate;

	state = pipe_config->base.state;

	for_each_connector_in_state(state, drm_connector, connector_state, i) {
		connector = to_intel_connector(drm_connector);

		if (connector_state->best_encoder == &encoder->base) {
			found = connector;
			break;
		}
	}
Example #12
0
static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
					    struct intel_crtc_state *crtc_state,
					    struct drm_connector_state *conn_state,
					    struct link_config_limits *limits)
{
	struct drm_atomic_state *state = crtc_state->base.state;
	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
	struct intel_dp *intel_dp = &intel_mst->primary->dp;
	struct intel_connector *connector =
		to_intel_connector(conn_state->connector);
	const struct drm_display_mode *adjusted_mode =
		&crtc_state->base.adjusted_mode;
	void *port = connector->port;
	bool constant_n = drm_dp_has_quirk(&intel_dp->desc,
					   DP_DPCD_QUIRK_CONSTANT_N);
	int bpp, slots = -EINVAL;

	crtc_state->lane_count = limits->max_lane_count;
	crtc_state->port_clock = limits->max_clock;

	for (bpp = limits->max_bpp; bpp >= limits->min_bpp; bpp -= 2 * 3) {
		crtc_state->pipe_bpp = bpp;

		crtc_state->pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock,
						       crtc_state->pipe_bpp);

		slots = drm_dp_atomic_find_vcpi_slots(state, &intel_dp->mst_mgr,
						      port, crtc_state->pbn);
		if (slots == -EDEADLK)
			return slots;
		if (slots >= 0)
			break;
	}

	if (slots < 0) {
		DRM_DEBUG_KMS("failed finding vcpi slots:%d\n", slots);
		return slots;
	}

	intel_link_compute_m_n(crtc_state->pipe_bpp,
			       crtc_state->lane_count,
			       adjusted_mode->crtc_clock,
			       crtc_state->port_clock,
			       &crtc_state->dp_m_n,
			       constant_n);
	crtc_state->dp_m_n.tu = slots;

	return 0;
}
Example #13
0
static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder,
					struct intel_crtc_state *pipe_config)
{
	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
	struct intel_digital_port *intel_dig_port = intel_mst->primary;
	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
	u32 temp, flags = 0;

	pipe_config->has_audio =
		intel_ddi_is_audio_enabled(dev_priv, crtc);

	temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
	if (temp & TRANS_DDI_PHSYNC)
		flags |= DRM_MODE_FLAG_PHSYNC;
	else
		flags |= DRM_MODE_FLAG_NHSYNC;
	if (temp & TRANS_DDI_PVSYNC)
		flags |= DRM_MODE_FLAG_PVSYNC;
	else
		flags |= DRM_MODE_FLAG_NVSYNC;

	switch (temp & TRANS_DDI_BPC_MASK) {
	case TRANS_DDI_BPC_6:
		pipe_config->pipe_bpp = 18;
		break;
	case TRANS_DDI_BPC_8:
		pipe_config->pipe_bpp = 24;
		break;
	case TRANS_DDI_BPC_10:
		pipe_config->pipe_bpp = 30;
		break;
	case TRANS_DDI_BPC_12:
		pipe_config->pipe_bpp = 36;
		break;
	default:
		break;
	}
	pipe_config->base.adjusted_mode.flags |= flags;

	pipe_config->lane_count =
		((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;

	intel_dp_get_m_n(crtc, pipe_config);

	intel_ddi_clock_get(&intel_dig_port->base, pipe_config);
}
Example #14
0
static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
				    const struct intel_crtc_state *pipe_config,
				    const struct drm_connector_state *conn_state)
{
	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
	struct intel_digital_port *intel_dig_port = intel_mst->primary;
	struct intel_dp *intel_dp = &intel_dig_port->dp;
	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
	enum port port = intel_dig_port->base.port;
	struct intel_connector *connector =
		to_intel_connector(conn_state->connector);
	int ret;
	uint32_t temp;

	/* MST encoders are bound to a crtc, not to a connector,
	 * force the mapping here for get_hw_state.
	 */
	connector->encoder = encoder;
	intel_mst->connector = connector;

	DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);

	if (intel_dp->active_mst_links == 0)
		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);

	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, true);

	if (intel_dp->active_mst_links == 0)
		intel_dig_port->base.pre_enable(&intel_dig_port->base,
						pipe_config, NULL);

	ret = drm_dp_mst_allocate_vcpi(&intel_dp->mst_mgr,
				       connector->port,
				       pipe_config->pbn,
				       pipe_config->dp_m_n.tu);
	if (ret == false) {
		DRM_ERROR("failed to allocate vcpi\n");
		return;
	}


	intel_dp->active_mst_links++;
	temp = I915_READ(DP_TP_STATUS(port));
	I915_WRITE(DP_TP_STATUS(port), temp);

	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
}
Example #15
0
static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
					struct intel_crtc_state *pipe_config,
					struct drm_connector_state *conn_state)
{
	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
	struct intel_digital_port *intel_dig_port = intel_mst->primary;
	struct intel_dp *intel_dp = &intel_dig_port->dp;
	struct drm_atomic_state *state;
	int bpp;
	int lane_count, slots;
	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
	int mst_pbn;

	pipe_config->dp_encoder_is_mst = true;
	pipe_config->has_pch_encoder = false;
	bpp = 24;
	/*
	 * for MST we always configure max link bw - the spec doesn't
	 * seem to suggest we should do otherwise.
	 */
	lane_count = drm_dp_max_lane_count(intel_dp->dpcd);

	pipe_config->lane_count = lane_count;

	pipe_config->pipe_bpp = 24;
	pipe_config->port_clock = intel_dp_max_link_rate(intel_dp);

	state = pipe_config->base.state;

	mst_pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, bpp);

	pipe_config->pbn = mst_pbn;
	slots = drm_dp_find_vcpi_slots(&intel_dp->mst_mgr, mst_pbn);

	intel_link_compute_m_n(bpp, lane_count,
			       adjusted_mode->crtc_clock,
			       pipe_config->port_clock,
			       &pipe_config->dp_m_n);

	pipe_config->dp_m_n.tu = slots;

	return true;

}
Example #16
0
static void intel_mst_disable_dp(struct intel_encoder *encoder,
				 struct intel_crtc_state *old_crtc_state,
				 struct drm_connector_state *old_conn_state)
{
	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
	struct intel_digital_port *intel_dig_port = intel_mst->primary;
	struct intel_dp *intel_dp = &intel_dig_port->dp;
	struct intel_connector *connector =
		to_intel_connector(old_conn_state->connector);
	int ret;

	DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links);

	drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);

	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
	if (ret) {
		DRM_ERROR("failed to update payload %d\n", ret);
	}
}
Example #17
0
static int
intel_dp_mst_atomic_check(struct drm_connector *connector,
			  struct drm_connector_state *new_conn_state)
{
	struct drm_atomic_state *state = new_conn_state->state;
	struct drm_connector_state *old_conn_state =
		drm_atomic_get_old_connector_state(state, connector);
	struct intel_connector *intel_connector =
		to_intel_connector(connector);
	struct drm_crtc *new_crtc = new_conn_state->crtc;
	struct drm_crtc_state *crtc_state;
	struct drm_dp_mst_topology_mgr *mgr;
	int ret;

	ret = intel_digital_connector_atomic_check(connector, new_conn_state);
	if (ret)
		return ret;

	if (!old_conn_state->crtc)
		return 0;

	/* We only want to free VCPI if this state disables the CRTC on this
	 * connector
	 */
	if (new_crtc) {
		crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc);

		if (!crtc_state ||
		    !drm_atomic_crtc_needs_modeset(crtc_state) ||
		    crtc_state->enable)
			return 0;
	}

	mgr = &enc_to_mst(old_conn_state->best_encoder)->primary->dp.mst_mgr;
	ret = drm_dp_atomic_release_vcpi_slots(state, mgr,
					       intel_connector->port);

	return ret;
}
Example #18
0
static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
				       struct intel_crtc_state *pipe_config,
				       struct drm_connector_state *conn_state)
{
	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
	struct intel_dp *intel_dp = &intel_mst->primary->dp;
	struct intel_connector *connector =
		to_intel_connector(conn_state->connector);
	struct intel_digital_connector_state *intel_conn_state =
		to_intel_digital_connector_state(conn_state);
	const struct drm_display_mode *adjusted_mode =
		&pipe_config->base.adjusted_mode;
	void *port = connector->port;
	struct link_config_limits limits;
	int ret;

	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
		return -EINVAL;

	pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
	pipe_config->has_pch_encoder = false;

	if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO)
		pipe_config->has_audio =
			drm_dp_mst_port_has_audio(&intel_dp->mst_mgr, port);
	else
		pipe_config->has_audio =
			intel_conn_state->force_audio == HDMI_AUDIO_ON;

	/*
	 * for MST we always configure max link bw - the spec doesn't
	 * seem to suggest we should do otherwise.
	 */
	limits.min_clock =
	limits.max_clock = intel_dp_max_link_rate(intel_dp);

	limits.min_lane_count =
	limits.max_lane_count = intel_dp_max_lane_count(intel_dp);

	limits.min_bpp = intel_dp_min_bpp(pipe_config);
	limits.max_bpp = pipe_config->pipe_bpp;

	intel_dp_adjust_compliance_config(intel_dp, pipe_config, &limits);

	ret = intel_dp_mst_compute_link_config(encoder, pipe_config,
					       conn_state, &limits);
	if (ret)
		return ret;

	pipe_config->limited_color_range =
		intel_dp_limited_color_range(pipe_config, conn_state);

	if (IS_GEN9_LP(dev_priv))
		pipe_config->lane_lat_optim_mask =
			bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count);

	intel_ddi_compute_min_voltage_level(dev_priv, pipe_config);

	return 0;
}
Example #19
0
static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
					struct intel_crtc_state *pipe_config,
					struct drm_connector_state *conn_state)
{
	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
	struct intel_digital_port *intel_dig_port = intel_mst->primary;
	struct intel_dp *intel_dp = &intel_dig_port->dp;
	struct intel_connector *connector =
		to_intel_connector(conn_state->connector);
	struct drm_atomic_state *state = pipe_config->base.state;
	int bpp;
	int lane_count, slots;
	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
	int mst_pbn;
	bool reduce_m_n = drm_dp_has_quirk(&intel_dp->desc,
					   DP_DPCD_QUIRK_LIMITED_M_N);

	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
		return false;

	pipe_config->has_pch_encoder = false;
	bpp = 24;
	if (intel_dp->compliance.test_data.bpc) {
		bpp = intel_dp->compliance.test_data.bpc * 3;
		DRM_DEBUG_KMS("Setting pipe bpp to %d\n",
			      bpp);
	}
	/*
	 * for MST we always configure max link bw - the spec doesn't
	 * seem to suggest we should do otherwise.
	 */
	lane_count = intel_dp_max_lane_count(intel_dp);

	pipe_config->lane_count = lane_count;

	pipe_config->pipe_bpp = bpp;

	pipe_config->port_clock = intel_dp_max_link_rate(intel_dp);

	if (drm_dp_mst_port_has_audio(&intel_dp->mst_mgr, connector->port))
		pipe_config->has_audio = true;

	mst_pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, bpp);
	pipe_config->pbn = mst_pbn;

	slots = drm_dp_atomic_find_vcpi_slots(state, &intel_dp->mst_mgr,
					      connector->port, mst_pbn);
	if (slots < 0) {
		DRM_DEBUG_KMS("failed finding vcpi slots:%d\n", slots);
		return false;
	}

	intel_link_compute_m_n(bpp, lane_count,
			       adjusted_mode->crtc_clock,
			       pipe_config->port_clock,
			       &pipe_config->dp_m_n,
			       reduce_m_n);

	pipe_config->dp_m_n.tu = slots;

	if (IS_GEN9_LP(dev_priv))
		pipe_config->lane_lat_optim_mask =
			bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count);

	intel_ddi_compute_min_voltage_level(dev_priv, pipe_config);

	return true;
}