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

Commit 3708d5e0 authored by Libin Yang's avatar Libin Yang Committed by Rodrigo Vivi
Browse files

drm/i915: start adding dp mst audio



(This patch is developed by Dave Airlie <airlied@redhat.com> originally)

This patch adds support for DP MST audio in i915.

Enable audio codec when DP MST is enabled if has_audio flag is set.
Disable audio codec when DP MST is disabled if has_audio flag is set.

Another separated patches to support DP MST audio will be implemented
in audio driver.

v2:
Rebased.

Signed-off-by: default avatarLibin Yang <libin.yang@linux.intel.com>
Signed-off-by: default avatarDhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Reviewed-by: default avatarLyude <cpaul@redhat.com>
Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1474334681-22690-6-git-send-email-dhinakaran.pandiyan@intel.com
parent f1a3acea
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -2888,6 +2888,20 @@ static void intel_dp_info(struct seq_file *m,
				&intel_dp->aux);
}

static void intel_dp_mst_info(struct seq_file *m,
			  struct intel_connector *intel_connector)
{
	struct intel_encoder *intel_encoder = intel_connector->encoder;
	struct intel_dp_mst_encoder *intel_mst =
		enc_to_mst(&intel_encoder->base);
	struct intel_digital_port *intel_dig_port = intel_mst->primary;
	struct intel_dp *intel_dp = &intel_dig_port->dp;
	bool has_audio = drm_dp_mst_port_has_audio(&intel_dp->mst_mgr,
					intel_connector->port);

	seq_printf(m, "\taudio support: %s\n", yesno(has_audio));
}

static void intel_hdmi_info(struct seq_file *m,
			    struct intel_connector *intel_connector)
{
@@ -2930,6 +2944,9 @@ static void intel_connector_info(struct seq_file *m,
	switch (connector->connector_type) {
	case DRM_MODE_CONNECTOR_DisplayPort:
	case DRM_MODE_CONNECTOR_eDP:
		if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
			intel_dp_mst_info(m, intel_connector);
		else
			intel_dp_info(m, intel_connector);
		break;
	case DRM_MODE_CONNECTOR_LVDS:
+15 −5
Original line number Diff line number Diff line
@@ -2227,6 +2227,19 @@ void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
	udelay(600);
}

bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
				 struct intel_crtc *intel_crtc)
{
	u32 temp;

	if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
		temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
		if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
			return true;
	}
	return false;
}

void intel_ddi_get_config(struct intel_encoder *encoder,
			  struct intel_crtc_state *pipe_config)
{
@@ -2292,11 +2305,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
		break;
	}

	if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
		temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
		if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
			pipe_config->has_audio = true;
	}
	pipe_config->has_audio =
		intel_ddi_is_audio_enabled(dev_priv, intel_crtc);

	if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.bpp &&
	    pipe_config->pipe_bpp > dev_priv->vbt.edp.bpp) {
+18 −0
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
	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;
@@ -59,6 +61,8 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,

	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;
@@ -84,6 +88,7 @@ static void intel_mst_disable_dp(struct intel_encoder *encoder,
	struct intel_dp *intel_dp = &intel_dig_port->dp;
	struct intel_connector *connector =
		to_intel_connector(old_conn_state->connector);
	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
	int ret;

	DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links);
@@ -94,6 +99,10 @@ static void intel_mst_disable_dp(struct intel_encoder *encoder,
	if (ret) {
		DRM_ERROR("failed to update payload %d\n", ret);
	}
	if (old_crtc_state->has_audio) {
		intel_audio_codec_disable(encoder);
		intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
	}
}

static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
@@ -206,6 +215,12 @@ static void intel_mst_enable_dp(struct intel_encoder *encoder,
	ret = drm_dp_check_act_status(&intel_dp->mst_mgr);

	ret = drm_dp_update_payload_part2(&intel_dp->mst_mgr);
	if (pipe_config->has_audio) {
		DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n",
				 pipe_name(intel_mst->pipe));
		intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
		intel_audio_codec_enable(encoder);
	}
}

static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
@@ -228,6 +243,9 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder,
	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;
+2 −0
Original line number Diff line number Diff line
@@ -1156,6 +1156,8 @@ bool intel_ddi_pll_select(struct intel_crtc *crtc,
void intel_ddi_set_pipe_settings(struct drm_crtc *crtc);
void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp);
bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
				 struct intel_crtc *intel_crtc);
void intel_ddi_get_config(struct intel_encoder *encoder,
			  struct intel_crtc_state *pipe_config);
struct intel_encoder *