[PATCH v2] drm/amd/display: Add DP-HDMI FRL PCON Support in DC

Harry Wentland harry.wentland at amd.com
Fri Nov 26 15:15:13 UTC 2021


On 2021-11-26 09:32, Fangzhi Zuo wrote:
> Change since v1: add brief description
> 1. Add hdmi frl pcon support to existing asic family.
> 2. Determine pcon frl capability based on pcon dpcd.
> 3. pcon frl is taken into consideration into mode validation.
> 
> Signed-off-by: Fangzhi Zuo <Jerry.Zuo at amd.com>

Acked-by: Harry Wentland <harry.wentland at amd.com>

Harry

> ---
>  drivers/gpu/drm/amd/display/dc/core/dc_link.c | 15 ++++
>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 71 +++++++++++++++++++
>  drivers/gpu/drm/amd/display/dc/dc.h           |  6 ++
>  drivers/gpu/drm/amd/display/dc/dc_dp_types.h  | 31 ++++++++
>  drivers/gpu/drm/amd/display/dc/dc_hw_types.h  |  3 +
>  drivers/gpu/drm/amd/display/dc/dc_link.h      |  1 +
>  drivers/gpu/drm/amd/display/dc/dc_types.h     |  1 +
>  .../drm/amd/display/dc/dcn20/dcn20_resource.c |  2 +
>  .../drm/amd/display/dc/dcn21/dcn21_resource.c |  2 +
>  .../drm/amd/display/dc/dcn30/dcn30_resource.c |  2 +
>  .../drm/amd/display/dc/dcn31/dcn31_resource.c |  1 +
>  11 files changed, 135 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> index 3d08f8eba402..dad7a4fdc427 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
> @@ -2750,8 +2750,23 @@ static bool dp_active_dongle_validate_timing(
>  		return false;
>  	}
>  
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +	if (dongle_caps->dp_hdmi_frl_max_link_bw_in_kbps > 0) { // DP to HDMI FRL converter
> +		struct dc_crtc_timing outputTiming = *timing;
> +
> +		if (timing->flags.DSC && !timing->dsc_cfg.is_frl)
> +			/* DP input has DSC, HDMI FRL output doesn't have DSC, remove DSC from output timing */
> +			outputTiming.flags.DSC = 0;
> +		if (dc_bandwidth_in_kbps_from_timing(&outputTiming) > dongle_caps->dp_hdmi_frl_max_link_bw_in_kbps)
> +			return false;
> +	} else { // DP to HDMI TMDS converter
> +		if (get_timing_pixel_clock_100hz(timing) > (dongle_caps->dp_hdmi_max_pixel_clk_in_khz * 10))
> +			return false;
> +	}
> +#else
>  	if (get_timing_pixel_clock_100hz(timing) > (dongle_caps->dp_hdmi_max_pixel_clk_in_khz * 10))
>  		return false;
> +#endif
>  
>  #if defined(CONFIG_DRM_AMD_DC_DCN)
>  	}
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> index 84f3545c3032..da1532356c07 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> @@ -4313,6 +4313,56 @@ static int translate_dpcd_max_bpc(enum dpcd_downstream_port_max_bpc bpc)
>  	return -1;
>  }
>  
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw)
> +{
> +	switch (bw) {
> +	case 0b001:
> +		return 9000000;
> +	case 0b010:
> +		return 18000000;
> +	case 0b011:
> +		return 24000000;
> +	case 0b100:
> +		return 32000000;
> +	case 0b101:
> +		return 40000000;
> +	case 0b110:
> +		return 48000000;
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * Return PCON's post FRL link training supported BW if its non-zero, otherwise return max_supported_frl_bw.
> + */
> +static uint32_t intersect_frl_link_bw_support(
> +	const uint32_t max_supported_frl_bw_in_kbps,
> +	const union hdmi_encoded_link_bw hdmi_encoded_link_bw)
> +{
> +	uint32_t supported_bw_in_kbps = max_supported_frl_bw_in_kbps;
> +
> +	// HDMI_ENCODED_LINK_BW bits are only valid if HDMI Link Configuration bit is 1 (FRL mode)
> +	if (hdmi_encoded_link_bw.bits.FRL_MODE) {
> +		if (hdmi_encoded_link_bw.bits.BW_48Gbps)
> +			supported_bw_in_kbps = 48000000;
> +		else if (hdmi_encoded_link_bw.bits.BW_40Gbps)
> +			supported_bw_in_kbps = 40000000;
> +		else if (hdmi_encoded_link_bw.bits.BW_32Gbps)
> +			supported_bw_in_kbps = 32000000;
> +		else if (hdmi_encoded_link_bw.bits.BW_24Gbps)
> +			supported_bw_in_kbps = 24000000;
> +		else if (hdmi_encoded_link_bw.bits.BW_18Gbps)
> +			supported_bw_in_kbps = 18000000;
> +		else if (hdmi_encoded_link_bw.bits.BW_9Gbps)
> +			supported_bw_in_kbps = 9000000;
> +	}
> +
> +	return supported_bw_in_kbps;
> +}
> +#endif
> +
>  static void read_dp_device_vendor_id(struct dc_link *link)
>  {
>  	struct dp_device_vendor_id dp_id;
> @@ -4424,6 +4474,27 @@ static void get_active_converter_info(
>  						translate_dpcd_max_bpc(
>  							hdmi_color_caps.bits.MAX_BITS_PER_COLOR_COMPONENT);
>  
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +					if (link->dc->caps.hdmi_frl_pcon_support) {
> +						link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps =
> +								dc_link_bw_kbps_from_raw_frl_link_rate_data(
> +										hdmi_color_caps.bits.MAX_ENCODED_LINK_BW_SUPPORT);
> +
> +						union hdmi_encoded_link_bw hdmi_encoded_link_bw;
> +
> +						// Intersect reported max link bw support with the supported link rate post FRL link training
> +						if (core_link_read_dpcd(link, DP_PCON_HDMI_POST_FRL_STATUS,
> +								&hdmi_encoded_link_bw.raw, sizeof(hdmi_encoded_link_bw)) == DC_OK) {
> +							link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps = intersect_frl_link_bw_support(
> +									link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps,
> +									hdmi_encoded_link_bw);
> +						}
> +
> +						if (link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps > 0)
> +							link->dpcd_caps.dongle_caps.extendedCapValid = true;
> +					}
> +#endif
> +
>  					if (link->dpcd_caps.dongle_caps.dp_hdmi_max_pixel_clk_in_khz != 0)
>  						link->dpcd_caps.dongle_caps.extendedCapValid = true;
>  				}
> diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
> index c14e7db3f69d..2d001de42117 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc.h
> @@ -187,6 +187,7 @@ struct dc_caps {
>  	struct dc_color_caps color;
>  #if defined(CONFIG_DRM_AMD_DC_DCN)
>  	bool dp_hpo;
> +	bool hdmi_frl_pcon_support;
>  #endif
>  	bool edp_dsc_support;
>  	bool vbios_lttpr_aware;
> @@ -1294,6 +1295,11 @@ struct dc_sink_dsc_caps {
>  	// 'true' if these are virtual DPCD's DSC caps (immediately upstream of sink in MST topology),
>  	// 'false' if they are sink's DSC caps
>  	bool is_virtual_dpcd_dsc;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +	// 'true' if MST topology supports DSC passthrough for sink
> +	// 'false' if MST topology does not support DSC passthrough
> +	bool is_dsc_passthrough_supported;
> +#endif
>  	struct dsc_dec_dpcd_caps dsc_dec_caps;
>  };
>  
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
> index e68e9a86a4d9..99d26fb31566 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
> @@ -378,7 +378,14 @@ enum dpcd_downstream_port_detailed_type {
>  union dwnstream_port_caps_byte2 {
>  	struct {
>  		uint8_t MAX_BITS_PER_COLOR_COMPONENT:2;
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +		uint8_t MAX_ENCODED_LINK_BW_SUPPORT:3;
> +		uint8_t SOURCE_CONTROL_MODE_SUPPORT:1;
> +		uint8_t CONCURRENT_LINK_BRING_UP_SEQ_SUPPORT:1;
> +		uint8_t RESERVED:1;
> +#else
>  		uint8_t RESERVED:6;
> +#endif
>  	} bits;
>  	uint8_t raw;
>  };
> @@ -416,6 +423,30 @@ union dwnstream_port_caps_byte3_hdmi {
>  	uint8_t raw;
>  };
>  
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +union hdmi_sink_encoded_link_bw_support {
> +	struct {
> +		uint8_t HDMI_SINK_ENCODED_LINK_BW_SUPPORT:3;
> +		uint8_t RESERVED:5;
> +	} bits;
> +	uint8_t raw;
> +};
> +
> +union hdmi_encoded_link_bw {
> +	struct {
> +		uint8_t FRL_MODE:1; // Bit 0
> +		uint8_t BW_9Gbps:1;
> +		uint8_t BW_18Gbps:1;
> +		uint8_t BW_24Gbps:1;
> +		uint8_t BW_32Gbps:1;
> +		uint8_t BW_40Gbps:1;
> +		uint8_t BW_48Gbps:1;
> +		uint8_t RESERVED:1; // Bit 7
> +	} bits;
> +	uint8_t raw;
> +};
> +#endif
> +
>  /*4-byte structure for detailed capabilities of a down-stream port
>  (DP-to-TMDS converter).*/
>  union dwnstream_portxcaps {
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
> index 52355fe6994c..eac34f591a3f 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
> @@ -741,6 +741,9 @@ struct dc_dsc_config {
>  	uint32_t version_minor; /* DSC minor version. Full version is formed as 1.version_minor. */
>  	bool ycbcr422_simple; /* Tell DSC engine to convert YCbCr 4:2:2 to 'YCbCr 4:2:2 simple'. */
>  	int32_t rc_buffer_size; /* DSC RC buffer block size in bytes */
> +#if defined(CONFIG_DRM_AMD_DC_DCN)
> +	bool is_frl; /* indicate if DSC is applied based on HDMI FRL sink's capability */
> +#endif
>  	bool is_dp; /* indicate if DSC is applied based on DP's capability */
>  };
>  struct dc_crtc_timing {
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
> index d449e72a4e2a..d5887d976ef6 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_link.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
> @@ -443,6 +443,7 @@ bool dc_link_is_fec_supported(const struct dc_link *link);
>  bool dc_link_should_enable_fec(const struct dc_link *link);
>  
>  #if defined(CONFIG_DRM_AMD_DC_DCN)
> +uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw);
>  enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link);
>  #endif
>  #endif /* DC_LINK_H_ */
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
> index 388457ffc0a8..cb26ff8a54c5 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_types.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
> @@ -430,6 +430,7 @@ struct dc_dongle_caps {
>  	uint32_t dp_hdmi_max_bpc;
>  	uint32_t dp_hdmi_max_pixel_clk_in_khz;
>  #if defined(CONFIG_DRM_AMD_DC_DCN)
> +	uint32_t dp_hdmi_frl_max_link_bw_in_kbps;
>  	struct dc_dongle_dfp_cap_ext dfp_cap_ext;
>  #endif
>  };
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
> index 3883f918b3bb..40b122a708ef 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
> @@ -3796,6 +3796,8 @@ static bool dcn20_resource_construct(
>  	dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
>  	dc->caps.color.mpc.ocsc = 1;
>  
> +	dc->caps.hdmi_frl_pcon_support = true;
> +
>  	if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) {
>  		dc->debug = debug_defaults_drv;
>  	} else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
> index d452a0d1777e..da6031cef244 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
> @@ -2028,6 +2028,8 @@ static bool dcn21_resource_construct(
>  	dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
>  	dc->caps.color.mpc.ocsc = 1;
>  
> +	dc->caps.hdmi_frl_pcon_support = true;
> +
>  	if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
>  		dc->debug = debug_defaults_drv;
>  	else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
> index 79a66e0c4303..77331a45a749 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
> @@ -2639,6 +2639,8 @@ static bool dcn30_resource_construct(
>  	dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
>  	dc->caps.color.mpc.ocsc = 1;
>  
> +	dc->caps.hdmi_frl_pcon_support = true;
> +
>  	/* read VBIOS LTTPR caps */
>  	{
>  		if (ctx->dc_bios->funcs->get_lttpr_caps) {
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
> index 6460fab496f6..673e080e1982 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
> @@ -2193,6 +2193,7 @@ static bool dcn31_resource_construct(
>  	dc->caps.post_blend_color_processing = true;
>  	dc->caps.force_dp_tps4_for_cp2520 = true;
>  	dc->caps.dp_hpo = true;
> +	dc->caps.hdmi_frl_pcon_support = true;
>  	dc->caps.edp_dsc_support = true;
>  	dc->caps.extended_aux_timeout_support = true;
>  	dc->caps.dmcub_support = true;
> 



More information about the amd-gfx mailing list