diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_dp.c')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_dp.c | 133 | 
1 files changed, 78 insertions, 55 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 642c60f3d9b1..5c9222283044 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -46,13 +46,15 @@  #include "intel_audio.h"  #include "intel_connector.h"  #include "intel_ddi.h" +#include "intel_de.h"  #include "intel_display_types.h"  #include "intel_dp.h"  #include "intel_dp_aux.h" +#include "intel_dp_hdcp.h"  #include "intel_dp_link_training.h"  #include "intel_dp_mst.h" -#include "intel_dpll.h"  #include "intel_dpio_phy.h" +#include "intel_dpll.h"  #include "intel_fifo_underrun.h"  #include "intel_hdcp.h"  #include "intel_hdmi.h" @@ -107,6 +109,7 @@ bool intel_dp_is_edp(struct intel_dp *intel_dp)  }  static void intel_dp_unset_edid(struct intel_dp *intel_dp); +static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc);  /* update sink rates from dpcd */  static void intel_dp_set_sink_rates(struct intel_dp *intel_dp) @@ -215,7 +218,7 @@ bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp)  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);  	return DISPLAY_VER(dev_priv) >= 12 || -		(IS_DISPLAY_VER(dev_priv, 11) && +		(DISPLAY_VER(dev_priv) == 11 &&  		 encoder->port != PORT_A);  } @@ -295,16 +298,16 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp)  	if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) {  		source_rates = cnl_rates;  		size = ARRAY_SIZE(cnl_rates); -		if (IS_DISPLAY_VER(dev_priv, 10)) +		if (DISPLAY_VER(dev_priv) == 10)  			max_rate = cnl_max_source_rate(intel_dp);  		else if (IS_JSL_EHL(dev_priv))  			max_rate = ehl_max_source_rate(intel_dp);  		else  			max_rate = icl_max_source_rate(intel_dp); -	} else if (IS_GEN9_LP(dev_priv)) { +	} else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {  		source_rates = bxt_rates;  		size = ARRAY_SIZE(bxt_rates); -	} else if (IS_GEN9_BC(dev_priv)) { +	} else if (DISPLAY_VER(dev_priv) == 9) {  		source_rates = skl_rates;  		size = ARRAY_SIZE(skl_rates);  	} else if ((IS_HASWELL(dev_priv) && !IS_HSW_ULX(dev_priv)) || @@ -492,7 +495,8 @@ small_joiner_ram_size_bits(struct drm_i915_private *i915)  static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,  				       u32 link_clock, u32 lane_count,  				       u32 mode_clock, u32 mode_hdisplay, -				       bool bigjoiner) +				       bool bigjoiner, +				       u32 pipe_bpp)  {  	u32 bits_per_pixel, max_bpp_small_joiner_ram;  	int i; @@ -539,12 +543,17 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,  		return 0;  	} -	/* Find the nearest match in the array of known BPPs from VESA */ -	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) { -		if (bits_per_pixel < valid_dsc_bpp[i + 1]) -			break; +	/* From XE_LPD onwards we support from bpc upto uncompressed bpp-1 BPPs */ +	if (DISPLAY_VER(i915) >= 13) { +		bits_per_pixel = min(bits_per_pixel, pipe_bpp - 1); +	} else { +		/* Find the nearest match in the array of known BPPs from VESA */ +		for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) { +			if (bits_per_pixel < valid_dsc_bpp[i + 1]) +				break; +		} +		bits_per_pixel = valid_dsc_bpp[i];  	} -	bits_per_pixel = valid_dsc_bpp[i];  	/*  	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11, @@ -778,6 +787,12 @@ intel_dp_mode_valid(struct drm_connector *connector,  	 */  	if (DISPLAY_VER(dev_priv) >= 10 &&  	    drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd)) { +		/* +		 * TBD pass the connector BPC, +		 * for now U8_MAX so that max BPC on that platform would be picked +		 */ +		int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX); +  		if (intel_dp_is_edp(intel_dp)) {  			dsc_max_output_bpp =  				drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4; @@ -791,7 +806,8 @@ intel_dp_mode_valid(struct drm_connector *connector,  							    max_lanes,  							    target_clock,  							    mode->hdisplay, -							    bigjoiner) >> 4; +							    bigjoiner, +							    pipe_bpp) >> 4;  			dsc_slice_count =  				intel_dp_dsc_get_slice_count(intel_dp,  							     target_clock, @@ -802,8 +818,11 @@ intel_dp_mode_valid(struct drm_connector *connector,  		dsc = dsc_max_output_bpp && dsc_slice_count;  	} -	/* big joiner configuration needs DSC */ -	if (bigjoiner && !dsc) +	/* +	 * Big joiner configuration needs DSC for TGL which is not true for +	 * XE_LPD where uncompressed joiner is supported. +	 */ +	if (DISPLAY_VER(dev_priv) < 13 && bigjoiner && !dsc)  		return MODE_CLOCK_HIGH;  	if (mode_rate > max_rate && !dsc) @@ -916,7 +935,7 @@ static bool intel_dp_source_supports_fec(struct intel_dp *intel_dp,  	if (DISPLAY_VER(dev_priv) >= 12)  		return true; -	if (IS_DISPLAY_VER(dev_priv, 11) && pipe_config->cpu_transcoder != TRANSCODER_A) +	if (DISPLAY_VER(dev_priv) == 11 && pipe_config->cpu_transcoder != TRANSCODER_A)  		return true;  	return false; @@ -1095,10 +1114,18 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp,  	return -EINVAL;  } -static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc) +static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 max_req_bpc)  { +	struct drm_i915_private *i915 = dp_to_i915(intel_dp);  	int i, num_bpc;  	u8 dsc_bpc[3] = {0}; +	u8 dsc_max_bpc; + +	/* Max DSC Input BPC for ICL is 10 and for TGL+ is 12 */ +	if (DISPLAY_VER(i915) >= 12) +		dsc_max_bpc = min_t(u8, 12, max_req_bpc); +	else +		dsc_max_bpc = min_t(u8, 10, max_req_bpc);  	num_bpc = drm_dp_dsc_sink_supported_input_bpcs(intel_dp->dsc_dpcd,  						       dsc_bpc); @@ -1129,10 +1156,6 @@ static int intel_dp_dsc_compute_params(struct intel_encoder *encoder,  	 */  	vdsc_cfg->rc_model_size = DSC_RC_MODEL_SIZE_CONST; -	ret = intel_dsc_compute_params(encoder, crtc_state); -	if (ret) -		return ret; -  	/*  	 * Slice Height of 8 works for all currently available panels. So start  	 * with that if pic_height is an integral multiple of 8. Eventually add @@ -1145,6 +1168,10 @@ static int intel_dp_dsc_compute_params(struct intel_encoder *encoder,  	else  		vdsc_cfg->slice_height = 2; +	ret = intel_dsc_compute_params(encoder, crtc_state); +	if (ret) +		return ret; +  	vdsc_cfg->dsc_version_major =  		(intel_dp->dsc_dpcd[DP_DSC_REV - DP_DSC_SUPPORT] &  		 DP_DSC_MAJOR_MASK) >> DP_DSC_MAJOR_SHIFT; @@ -1186,7 +1213,6 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,  	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);  	const struct drm_display_mode *adjusted_mode =  		&pipe_config->hw.adjusted_mode; -	u8 dsc_max_bpc;  	int pipe_bpp;  	int ret; @@ -1196,14 +1222,7 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,  	if (!intel_dp_supports_dsc(intel_dp, pipe_config))  		return -EINVAL; -	/* Max DSC Input BPC for ICL is 10 and for TGL+ is 12 */ -	if (DISPLAY_VER(dev_priv) >= 12) -		dsc_max_bpc = min_t(u8, 12, conn_state->max_requested_bpc); -	else -		dsc_max_bpc = min_t(u8, 10, -				    conn_state->max_requested_bpc); - -	pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, dsc_max_bpc); +	pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, conn_state->max_requested_bpc);  	/* Min Input BPC for ICL+ is 8 */  	if (pipe_bpp < 8 * 3) { @@ -1238,7 +1257,8 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,  						    pipe_config->lane_count,  						    adjusted_mode->crtc_clock,  						    adjusted_mode->crtc_hdisplay, -						    pipe_config->bigjoiner); +						    pipe_config->bigjoiner, +						    pipe_bpp);  		dsc_dp_slice_count =  			intel_dp_dsc_get_slice_count(intel_dp,  						     adjusted_mode->crtc_clock, @@ -1350,9 +1370,13 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,  	 */  	ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, &limits); -	/* enable compression if the mode doesn't fit available BW */ +	/* +	 * Pipe joiner needs compression upto display12 due to BW limitation. DG2 +	 * onwards pipe joiner can be enabled without compression. +	 */  	drm_dbg_kms(&i915->drm, "Force DSC en = %d\n", intel_dp->force_dsc_en); -	if (ret || intel_dp->force_dsc_en || pipe_config->bigjoiner) { +	if (ret || intel_dp->force_dsc_en || (DISPLAY_VER(i915) < 13 && +					      pipe_config->bigjoiner)) {  		ret = intel_dp_dsc_compute_config(intel_dp, pipe_config,  						  conn_state, &limits);  		if (ret < 0) @@ -1812,7 +1836,7 @@ void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp,  	if (ret < 0)  		drm_dbg_kms(&i915->drm,  			    "Failed to %s sink decompression state\n", -			    enable ? "enable" : "disable"); +			    enabledisable(enable));  }  static void @@ -2244,8 +2268,8 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,  	if (drm_dp_dpcd_writeb(&intel_dp->aux,  			       DP_PROTOCOL_CONVERTER_CONTROL_0, tmp) != 1) -		drm_dbg_kms(&i915->drm, "Failed to set protocol converter HDMI mode to %s\n", -			    enableddisabled(intel_dp->has_hdmi_sink)); +		drm_dbg_kms(&i915->drm, "Failed to %s protocol converter HDMI mode\n", +			    enabledisable(intel_dp->has_hdmi_sink));  	tmp = crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444 &&  		intel_dp->dfp.ycbcr_444_to_420 ? DP_CONVERSION_TO_YCBCR420_ENABLE : 0; @@ -2253,8 +2277,8 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,  	if (drm_dp_dpcd_writeb(&intel_dp->aux,  			       DP_PROTOCOL_CONVERTER_CONTROL_1, tmp) != 1)  		drm_dbg_kms(&i915->drm, -			    "Failed to set protocol converter YCbCr 4:2:0 conversion mode to %s\n", -			    enableddisabled(intel_dp->dfp.ycbcr_444_to_420)); +			    "Failed to %s protocol converter YCbCr 4:2:0 conversion mode\n", +			    enabledisable(intel_dp->dfp.ycbcr_444_to_420));  	tmp = 0;  	if (intel_dp->dfp.rgb_to_ycbcr) { @@ -2291,8 +2315,8 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,  	if (drm_dp_pcon_convert_rgb_to_ycbcr(&intel_dp->aux, tmp) < 0)  		drm_dbg_kms(&i915->drm, -			   "Failed to set protocol converter RGB->YCbCr conversion mode to %s\n", -			   enableddisabled(tmp ? true : false)); +			   "Failed to %s protocol converter RGB->YCbCr conversion mode\n", +			   enabledisable(tmp));  } @@ -2812,31 +2836,25 @@ void intel_dp_set_infoframes(struct intel_encoder *encoder,  			     const struct drm_connector_state *conn_state)  {  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); -	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);  	i915_reg_t reg = HSW_TVIDEO_DIP_CTL(crtc_state->cpu_transcoder);  	u32 dip_enable = VIDEO_DIP_ENABLE_AVI_HSW | VIDEO_DIP_ENABLE_GCP_HSW |  			 VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW |  			 VIDEO_DIP_ENABLE_SPD_HSW | VIDEO_DIP_ENABLE_DRM_GLK; -	u32 val = intel_de_read(dev_priv, reg); +	u32 val = intel_de_read(dev_priv, reg) & ~dip_enable;  	/* TODO: Add DSC case (DIP_ENABLE_PPS) */  	/* When PSR is enabled, this routine doesn't disable VSC DIP */ -	if (intel_psr_enabled(intel_dp)) -		val &= ~dip_enable; -	else -		val &= ~(dip_enable | VIDEO_DIP_ENABLE_VSC_HSW); - -	if (!enable) { -		intel_de_write(dev_priv, reg, val); -		intel_de_posting_read(dev_priv, reg); -		return; -	} +	if (!crtc_state->has_psr) +		val &= ~VIDEO_DIP_ENABLE_VSC_HSW;  	intel_de_write(dev_priv, reg, val);  	intel_de_posting_read(dev_priv, reg); +	if (!enable) +		return; +  	/* When PSR is enabled, VSC SDP is handled by PSR routine */ -	if (!intel_psr_enabled(intel_dp)) +	if (!crtc_state->has_psr)  		intel_write_dp_sdp(encoder, crtc_state, DP_SDP_VSC);  	intel_write_dp_sdp(encoder, crtc_state, HDMI_PACKET_TYPE_GAMUT_METADATA); @@ -2963,14 +2981,13 @@ static void intel_read_dp_vsc_sdp(struct intel_encoder *encoder,  				  struct drm_dp_vsc_sdp *vsc)  {  	struct intel_digital_port *dig_port = enc_to_dig_port(encoder); -	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);  	unsigned int type = DP_SDP_VSC;  	struct dp_sdp sdp = {};  	int ret;  	/* When PSR is enabled, VSC SDP is handled by PSR routine */ -	if (intel_psr_enabled(intel_dp)) +	if (crtc_state->has_psr)  		return;  	if ((crtc_state->infoframes.enable & @@ -5359,7 +5376,7 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,  	intel_dp_add_properties(intel_dp, connector);  	if (is_hdcp_supported(dev_priv, port) && !intel_dp_is_edp(intel_dp)) { -		int ret = intel_dp_init_hdcp(dig_port, intel_connector); +		int ret = intel_dp_hdcp_init(dig_port, intel_connector);  		if (ret)  			drm_dbg_kms(&dev_priv->drm,  				    "HDCP init failed, skipping.\n"); @@ -5392,6 +5409,9 @@ void intel_dp_mst_suspend(struct drm_i915_private *dev_priv)  {  	struct intel_encoder *encoder; +	if (!HAS_DISPLAY(dev_priv)) +		return; +  	for_each_intel_encoder(&dev_priv->drm, encoder) {  		struct intel_dp *intel_dp; @@ -5412,6 +5432,9 @@ void intel_dp_mst_resume(struct drm_i915_private *dev_priv)  {  	struct intel_encoder *encoder; +	if (!HAS_DISPLAY(dev_priv)) +		return; +  	for_each_intel_encoder(&dev_priv->drm, encoder) {  		struct intel_dp *intel_dp;  		int ret;  | 
