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

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
...@@ -677,6 +677,7 @@ static void intel_ddi_mode_set(struct drm_encoder *encoder, ...@@ -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", DRM_DEBUG_KMS("Preparing DDI mode for Haswell on port %c, pipe %c\n",
port_name(port), pipe_name(pipe)); port_name(port), pipe_name(pipe));
intel_crtc->eld_vld = false;
if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 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) ...@@ -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) static void intel_enable_ddi(struct intel_encoder *intel_encoder)
{ {
struct drm_encoder *encoder = &intel_encoder->base; 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_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
enum port port = intel_ddi_get_encoder_port(intel_encoder); enum port port = intel_ddi_get_encoder_port(intel_encoder);
int type = intel_encoder->type; int type = intel_encoder->type;
uint32_t tmp;
if (type == INTEL_OUTPUT_HDMI) { if (type == INTEL_OUTPUT_HDMI) {
/* In HDMI/DVI mode, the port width, and swing/emphasis values /* 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) ...@@ -1303,18 +1308,34 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)
ironlake_edp_backlight_on(intel_dp); 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) static void intel_disable_ddi(struct intel_encoder *intel_encoder)
{ {
struct drm_encoder *encoder = &intel_encoder->base; 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; 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) { if (type == INTEL_OUTPUT_EDP) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
ironlake_edp_backlight_off(intel_dp); 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) int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
......
...@@ -3721,10 +3721,12 @@ static void intel_crtc_disable(struct drm_crtc *crtc) ...@@ -3721,10 +3721,12 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_i915_private *dev_priv = dev->dev_private; 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. */ /* crtc should still be enabled when we disable it. */
WARN_ON(!crtc->enabled); WARN_ON(!crtc->enabled);
intel_crtc->eld_vld = false;
dev_priv->display.crtc_disable(crtc); dev_priv->display.crtc_disable(crtc);
intel_crtc_update_sarea(crtc, false); intel_crtc_update_sarea(crtc, false);
dev_priv->display.off(crtc); dev_priv->display.off(crtc);
...@@ -5792,6 +5794,7 @@ static void haswell_write_eld(struct drm_connector *connector, ...@@ -5792,6 +5794,7 @@ static void haswell_write_eld(struct drm_connector *connector,
struct drm_i915_private *dev_priv = connector->dev->dev_private; struct drm_i915_private *dev_priv = connector->dev->dev_private;
uint8_t *eld = connector->eld; uint8_t *eld = connector->eld;
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
uint32_t eldv; uint32_t eldv;
uint32_t i; uint32_t i;
int len; int len;
...@@ -5833,6 +5836,7 @@ static void haswell_write_eld(struct drm_connector *connector, ...@@ -5833,6 +5836,7 @@ static void haswell_write_eld(struct drm_connector *connector,
DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(pipe)); DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(pipe));
eldv = AUDIO_ELD_VALID_A << (pipe * 4); eldv = AUDIO_ELD_VALID_A << (pipe * 4);
intel_crtc->eld_vld = true;
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n"); DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n");
......
...@@ -211,6 +211,7 @@ struct intel_crtc { ...@@ -211,6 +211,7 @@ struct intel_crtc {
* some outputs connected to this crtc. * some outputs connected to this crtc.
*/ */
bool active; bool active;
bool eld_vld;
bool primary_disabled; /* is the crtc obscured by a plane? */ bool primary_disabled; /* is the crtc obscured by a plane? */
bool lowfreq_avail; bool lowfreq_avail;
struct intel_overlay *overlay; struct intel_overlay *overlay;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment