Commit 7b9f35a6 authored by Wang Xingchao's avatar Wang Xingchao Committed by Daniel Vetter
Browse files

drm/i915: HDMI/DP - ELD info refresh support for Haswell



ELD info should be updated dynamically according to hot plug event.
For haswell chip, clear/set the eld valid bit and output enable bit
from callback intel_disable/eanble_ddi().

Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarRodrigo Vivi <rodrigo.vivi@gmail.com>
Signed-off-by: default avatarWang Xingchao <xingchao.wang@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 99433931
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -677,6 +677,7 @@ static void intel_ddi_mode_set(struct drm_encoder *encoder,
	DRM_DEBUG_KMS("Preparing DDI mode for Haswell on port %c, pipe %c\n",
		      port_name(port), pipe_name(pipe));

	intel_crtc->eld_vld = false;
	if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);

@@ -1287,10 +1288,14 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
static void intel_enable_ddi(struct intel_encoder *intel_encoder)
{
	struct drm_encoder *encoder = &intel_encoder->base;
	struct drm_crtc *crtc = encoder->crtc;
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
	int pipe = intel_crtc->pipe;
	struct drm_device *dev = encoder->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	enum port port = intel_ddi_get_encoder_port(intel_encoder);
	int type = intel_encoder->type;
	uint32_t tmp;

	if (type == INTEL_OUTPUT_HDMI) {
		/* In HDMI/DVI mode, the port width, and swing/emphasis values
@@ -1303,18 +1308,34 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)

		ironlake_edp_backlight_on(intel_dp);
	}

	if (intel_crtc->eld_vld) {
		tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
		tmp |= ((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4));
		I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp);
	}
}

static void intel_disable_ddi(struct intel_encoder *intel_encoder)
{
	struct drm_encoder *encoder = &intel_encoder->base;
	struct drm_crtc *crtc = encoder->crtc;
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
	int pipe = intel_crtc->pipe;
	int type = intel_encoder->type;
	struct drm_device *dev = encoder->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	uint32_t tmp;

	if (type == INTEL_OUTPUT_EDP) {
		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);

		ironlake_edp_backlight_off(intel_dp);
	}

	tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
	tmp &= ~((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4));
	I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp);
}

int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
+4 −0
Original line number Diff line number Diff line
@@ -3721,10 +3721,12 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
	struct drm_device *dev = crtc->dev;
	struct drm_connector *connector;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);

	/* crtc should still be enabled when we disable it. */
	WARN_ON(!crtc->enabled);

	intel_crtc->eld_vld = false;
	dev_priv->display.crtc_disable(crtc);
	intel_crtc_update_sarea(crtc, false);
	dev_priv->display.off(crtc);
@@ -5792,6 +5794,7 @@ static void haswell_write_eld(struct drm_connector *connector,
	struct drm_i915_private *dev_priv = connector->dev->dev_private;
	uint8_t *eld = connector->eld;
	struct drm_device *dev = crtc->dev;
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
	uint32_t eldv;
	uint32_t i;
	int len;
@@ -5833,6 +5836,7 @@ static void haswell_write_eld(struct drm_connector *connector,
	DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(pipe));

	eldv = AUDIO_ELD_VALID_A << (pipe * 4);
	intel_crtc->eld_vld = true;

	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
		DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n");
+1 −0
Original line number Diff line number Diff line
@@ -211,6 +211,7 @@ struct intel_crtc {
	 * some outputs connected to this crtc.
	 */
	bool active;
	bool eld_vld;
	bool primary_disabled; /* is the crtc obscured by a plane? */
	bool lowfreq_avail;
	struct intel_overlay *overlay;