diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_hdmi.c')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_hdmi.c | 53 | 
1 files changed, 32 insertions, 21 deletions
| diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index bac85d88054f..c0ce6d3dc505 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -44,6 +44,7 @@  #include "i915_drv.h"  #include "i915_reg.h"  #include "intel_atomic.h" +#include "intel_audio.h"  #include "intel_connector.h"  #include "intel_ddi.h"  #include "intel_de.h" @@ -537,8 +538,7 @@ void hsw_write_infoframe(struct intel_encoder *encoder,  			       0);  	/* Wa_14013475917 */ -	if (DISPLAY_VER(dev_priv) == 13 && crtc_state->has_psr && -	    type == DP_SDP_VSC) +	if (IS_DISPLAY_VER(dev_priv, 13, 14) && crtc_state->has_psr && type == DP_SDP_VSC)  		return;  	val |= hsw_infoframe_enable(type); @@ -767,6 +767,7 @@ intel_hdmi_compute_spd_infoframe(struct intel_encoder *encoder,  				 struct intel_crtc_state *crtc_state,  				 struct drm_connector_state *conn_state)  { +	struct drm_i915_private *i915 = to_i915(encoder->base.dev);  	struct hdmi_spd_infoframe *frame = &crtc_state->infoframes.spd.spd;  	int ret; @@ -776,7 +777,11 @@ intel_hdmi_compute_spd_infoframe(struct intel_encoder *encoder,  	crtc_state->infoframes.enable |=  		intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_SPD); -	ret = hdmi_spd_infoframe_init(frame, "Intel", "Integrated gfx"); +	if (IS_DGFX(i915)) +		ret = hdmi_spd_infoframe_init(frame, "Intel", "Discrete gfx"); +	else +		ret = hdmi_spd_infoframe_init(frame, "Intel", "Integrated gfx"); +  	if (drm_WARN_ON(encoder->base.dev, ret))  		return false; @@ -1988,9 +1993,6 @@ intel_hdmi_mode_valid(struct drm_connector *connector,  	bool has_hdmi_sink = intel_has_hdmi_sink(hdmi, connector->state);  	bool ycbcr_420_only; -	if (mode->flags & DRM_MODE_FLAG_DBLSCAN) -		return MODE_NO_DBLESCAN; -  	if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING)  		clock *= 2; @@ -2252,6 +2254,10 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,  	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)  		return -EINVAL; +	if (!connector->interlace_allowed && +	    adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) +		return -EINVAL; +  	pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;  	pipe_config->has_hdmi_sink =  		intel_has_hdmi_sink(intel_hdmi, conn_state) && @@ -2264,7 +2270,8 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,  		pipe_config->pixel_multiplier = 2;  	pipe_config->has_audio = -		intel_hdmi_has_audio(encoder, pipe_config, conn_state); +		intel_hdmi_has_audio(encoder, pipe_config, conn_state) && +		intel_audio_compute_config(encoder, pipe_config, conn_state);  	/*  	 * Try to respect downstream TMDS clock limits first, if @@ -2353,7 +2360,7 @@ intel_hdmi_unset_edid(struct drm_connector *connector)  	intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE;  	intel_hdmi->dp_dual_mode.max_tmds_clock = 0; -	kfree(to_intel_connector(connector)->detect_edid); +	drm_edid_free(to_intel_connector(connector)->detect_edid);  	to_intel_connector(connector)->detect_edid = NULL;  } @@ -2414,7 +2421,8 @@ intel_hdmi_set_edid(struct drm_connector *connector)  	struct drm_i915_private *dev_priv = to_i915(connector->dev);  	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));  	intel_wakeref_t wakeref; -	struct edid *edid; +	const struct drm_edid *drm_edid; +	const struct edid *edid;  	bool connected = false;  	struct i2c_adapter *i2c; @@ -2422,17 +2430,23 @@ intel_hdmi_set_edid(struct drm_connector *connector)  	i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus); -	edid = drm_get_edid(connector, i2c); +	drm_edid = drm_edid_read_ddc(connector, i2c); -	if (!edid && !intel_gmbus_is_forced_bit(i2c)) { +	if (!drm_edid && !intel_gmbus_is_forced_bit(i2c)) {  		drm_dbg_kms(&dev_priv->drm,  			    "HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n");  		intel_gmbus_force_bit(i2c, true); -		edid = drm_get_edid(connector, i2c); +		drm_edid = drm_edid_read_ddc(connector, i2c);  		intel_gmbus_force_bit(i2c, false);  	} -	to_intel_connector(connector)->detect_edid = edid; +	/* Below we depend on display info having been updated */ +	drm_edid_connector_update(connector, drm_edid); + +	to_intel_connector(connector)->detect_edid = drm_edid; + +	/* FIXME: Get rid of drm_edid_raw() */ +	edid = drm_edid_raw(drm_edid);  	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {  		intel_hdmi->has_audio = drm_detect_monitor_audio(edid);  		intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid); @@ -2508,13 +2522,8 @@ intel_hdmi_force(struct drm_connector *connector)  static int intel_hdmi_get_modes(struct drm_connector *connector)  { -	struct edid *edid; - -	edid = to_intel_connector(connector)->detect_edid; -	if (edid == NULL) -		return 0; - -	return intel_connector_update_modes(connector, edid); +	/* drm_edid_connector_update() done in ->detect() or ->force() */ +	return drm_edid_connector_add_modes(connector);  }  static struct i2c_adapter * @@ -2953,7 +2962,9 @@ void intel_hdmi_init_connector(struct intel_digital_port *dig_port,  				    ddc);  	drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs); -	connector->interlace_allowed = true; +	if (DISPLAY_VER(dev_priv) < 12) +		connector->interlace_allowed = true; +  	connector->stereo_allowed = true;  	if (DISPLAY_VER(dev_priv) >= 10) | 
