diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_dp.c')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_dp.c | 95 | 
1 files changed, 71 insertions, 24 deletions
| diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index ff67899522cf..32292c0be2bd 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -40,6 +40,7 @@  #include <drm/display/drm_hdmi_helper.h>  #include <drm/drm_atomic_helper.h>  #include <drm/drm_crtc.h> +#include <drm/drm_edid.h>  #include <drm/drm_probe_helper.h>  #include "g4x_dp.h" @@ -434,6 +435,26 @@ static int dg1_max_source_rate(struct intel_dp *intel_dp)  	return 810000;  } +static int vbt_max_link_rate(struct intel_dp *intel_dp) +{ +	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; +	int max_rate; + +	max_rate = intel_bios_dp_max_link_rate(encoder); + +	if (intel_dp_is_edp(intel_dp)) { +		struct intel_connector *connector = intel_dp->attached_connector; +		int edp_max_rate = connector->panel.vbt.edp.max_link_rate; + +		if (max_rate && edp_max_rate) +			max_rate = min(max_rate, edp_max_rate); +		else if (edp_max_rate) +			max_rate = edp_max_rate; +	} + +	return max_rate; +} +  static void  intel_dp_set_source_rates(struct intel_dp *intel_dp)  { @@ -455,7 +476,6 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp)  		162000, 270000  	};  	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); -	struct intel_encoder *encoder = &dig_port->base;  	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);  	const int *source_rates;  	int size, max_rate = 0, vbt_max_rate; @@ -491,7 +511,7 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp)  		size = ARRAY_SIZE(g4x_rates);  	} -	vbt_max_rate = intel_bios_dp_max_link_rate(encoder); +	vbt_max_rate = vbt_max_link_rate(intel_dp);  	if (max_rate && vbt_max_rate)  		max_rate = min(max_rate, vbt_max_rate);  	else if (vbt_max_rate) @@ -684,7 +704,6 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,  	 */  	bits_per_pixel = (link_clock * lane_count * 8) /  			 intel_dp_mode_to_fec_clock(mode_clock); -	drm_dbg_kms(&i915->drm, "Max link bpp: %u\n", bits_per_pixel);  	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */  	max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) / @@ -693,9 +712,6 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,  	if (bigjoiner)  		max_bpp_small_joiner_ram *= 2; -	drm_dbg_kms(&i915->drm, "Max small joiner bpp: %u\n", -		    max_bpp_small_joiner_ram); -  	/*  	 * Greatest allowed DSC BPP = MIN (output BPP from available Link BW  	 * check, output bpp from small joiner RAM check) @@ -707,7 +723,6 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,  			i915->max_cdclk_freq * 48 /  			intel_dp_mode_to_fec_clock(mode_clock); -		drm_dbg_kms(&i915->drm, "Max big joiner bpp: %u\n", max_bpp_bigjoiner);  		bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);  	} @@ -1246,11 +1261,12 @@ static int intel_dp_max_bpp(struct intel_dp *intel_dp,  	if (intel_dp_is_edp(intel_dp)) {  		/* Get bpp from vbt only for panels that dont have bpp in edid */  		if (intel_connector->base.display_info.bpc == 0 && -		    dev_priv->vbt.edp.bpp && dev_priv->vbt.edp.bpp < bpp) { +		    intel_connector->panel.vbt.edp.bpp && +		    intel_connector->panel.vbt.edp.bpp < bpp) {  			drm_dbg_kms(&dev_priv->drm,  				    "clamping bpp for eDP panel to BIOS-provided %i\n", -				    dev_priv->vbt.edp.bpp); -			bpp = dev_priv->vbt.edp.bpp; +				    intel_connector->panel.vbt.edp.bpp); +			bpp = intel_connector->panel.vbt.edp.bpp;  		}  	} @@ -1906,7 +1922,7 @@ intel_dp_drrs_compute_config(struct intel_connector *connector,  	}  	if (IS_IRONLAKE(i915) || IS_SANDYBRIDGE(i915) || IS_IVYBRIDGE(i915)) -		pipe_config->msa_timing_delay = i915->vbt.edp.drrs_msa_timing_delay; +		pipe_config->msa_timing_delay = connector->panel.vbt.edp.drrs_msa_timing_delay;  	pipe_config->has_drrs = true; @@ -2736,6 +2752,33 @@ static void intel_edp_mso_mode_fixup(struct intel_connector *connector,  		    DRM_MODE_ARG(mode));  } +void intel_edp_fixup_vbt_bpp(struct intel_encoder *encoder, int pipe_bpp) +{ +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); +	struct intel_dp *intel_dp = enc_to_intel_dp(encoder); +	struct intel_connector *connector = intel_dp->attached_connector; + +	if (connector->panel.vbt.edp.bpp && pipe_bpp > connector->panel.vbt.edp.bpp) { +		/* +		 * This is a big fat ugly hack. +		 * +		 * Some machines in UEFI boot mode provide us a VBT that has 18 +		 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons +		 * unknown we fail to light up. Yet the same BIOS boots up with +		 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as +		 * max, not what it tells us to use. +		 * +		 * Note: This will still be broken if the eDP panel is not lit +		 * up by the BIOS, and thus we can't get the mode at module +		 * load. +		 */ +		drm_dbg_kms(&dev_priv->drm, +			    "pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n", +			    pipe_bpp, connector->panel.vbt.edp.bpp); +		connector->panel.vbt.edp.bpp = pipe_bpp; +	} +} +  static void intel_edp_mso_init(struct intel_dp *intel_dp)  {  	struct drm_i915_private *i915 = dp_to_i915(intel_dp); @@ -2850,9 +2893,6 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp)  		intel_dp_set_sink_rates(intel_dp);  	intel_dp_set_max_sink_lane_count(intel_dp); -	intel_dp_set_common_rates(intel_dp); -	intel_dp_reset_max_link_params(intel_dp); -  	/* Read the eDP DSC DPCD registers */  	if (DISPLAY_VER(dev_priv) >= 10)  		intel_dp_get_dsc_sink_cap(intel_dp); @@ -4550,7 +4590,7 @@ intel_dp_set_edid(struct intel_dp *intel_dp)  	edid = intel_dp_get_edid(intel_dp);  	connector->detect_edid = edid; -	vrr_capable = intel_vrr_is_capable(&connector->base); +	vrr_capable = intel_vrr_is_capable(connector);  	drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] VRR capable: %s\n",  		    connector->base.base.id, connector->base.name, str_yes_no(vrr_capable));  	drm_connector_set_vrr_capable_property(&connector->base, vrr_capable); @@ -5155,6 +5195,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,  	struct drm_device *dev = &dev_priv->drm;  	struct drm_connector *connector = &intel_connector->base;  	struct drm_display_mode *fixed_mode; +	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;  	bool has_dpcd;  	enum pipe pipe = INVALID_PIPE;  	struct edid *edid; @@ -5211,8 +5252,12 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,  	}  	intel_connector->edid = edid; +	intel_bios_init_panel(dev_priv, &intel_connector->panel, +			      encoder->devdata, IS_ERR(edid) ? NULL : edid); +  	intel_panel_add_edid_fixed_modes(intel_connector, -					 dev_priv->vbt.drrs_type != DRRS_TYPE_NONE); +					 intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE, +					 intel_vrr_is_capable(intel_connector));  	/* MSO requires information from the EDID */  	intel_edp_mso_init(intel_dp); @@ -5254,6 +5299,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,  	intel_edp_add_properties(intel_dp); +	intel_pps_init_late(intel_dp); +  	return true;  out_vdd_off: @@ -5334,11 +5381,8 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,  		type = DRM_MODE_CONNECTOR_DisplayPort;  	} -	intel_dp_set_source_rates(intel_dp);  	intel_dp_set_default_sink_rates(intel_dp);  	intel_dp_set_default_max_sink_lane_count(intel_dp); -	intel_dp_set_common_rates(intel_dp); -	intel_dp_reset_max_link_params(intel_dp);  	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))  		intel_dp->pps.active_pipe = vlv_active_pipe(intel_dp); @@ -5366,16 +5410,19 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,  	else  		intel_connector->get_hw_state = intel_connector_get_hw_state; -	/* init MST on ports that can support it */ -	intel_dp_mst_encoder_init(dig_port, -				  intel_connector->base.base.id); -  	if (!intel_edp_init_connector(intel_dp, intel_connector)) {  		intel_dp_aux_fini(intel_dp); -		intel_dp_mst_encoder_cleanup(dig_port);  		goto fail;  	} +	intel_dp_set_source_rates(intel_dp); +	intel_dp_set_common_rates(intel_dp); +	intel_dp_reset_max_link_params(intel_dp); + +	/* init MST on ports that can support it */ +	intel_dp_mst_encoder_init(dig_port, +				  intel_connector->base.base.id); +  	intel_dp_add_properties(intel_dp, connector);  	if (is_hdcp_supported(dev_priv, port) && !intel_dp_is_edp(intel_dp)) { | 
