brintos

brintos / linux-shallow public Read only

0
0
Text · 14.0 KiB · 60f15a9 Raw
412 lines · c
1/*2 * Copyright 2023 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: AMD23 *24 */25 26/* FILE POLICY AND INTENDED USAGE:27 * This file owns timing validation against various link limitations. (ex.28 * link bandwidth, receiver capability or our hardware capability) It also29 * provides helper functions exposing bandwidth formulas used in validation.30 */31#include "link_validation.h"32#include "protocols/link_dp_capability.h"33#include "protocols/link_dp_dpia_bw.h"34#include "resource.h"35 36#define DC_LOGGER_INIT(logger)37 38static uint32_t get_tmds_output_pixel_clock_100hz(const struct dc_crtc_timing *timing)39{40 41	uint32_t pxl_clk = timing->pix_clk_100hz;42 43	if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)44		pxl_clk /= 2;45	else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)46		pxl_clk = pxl_clk * 2 / 3;47 48	if (timing->display_color_depth == COLOR_DEPTH_101010)49		pxl_clk = pxl_clk * 10 / 8;50	else if (timing->display_color_depth == COLOR_DEPTH_121212)51		pxl_clk = pxl_clk * 12 / 8;52 53	return pxl_clk;54}55 56static bool dp_active_dongle_validate_timing(57		const struct dc_crtc_timing *timing,58		const struct dpcd_caps *dpcd_caps)59{60	const struct dc_dongle_caps *dongle_caps = &dpcd_caps->dongle_caps;61 62	switch (dpcd_caps->dongle_type) {63	case DISPLAY_DONGLE_DP_VGA_CONVERTER:64	case DISPLAY_DONGLE_DP_DVI_CONVERTER:65	case DISPLAY_DONGLE_DP_DVI_DONGLE:66		if (timing->pixel_encoding == PIXEL_ENCODING_RGB)67			return true;68		else69			return false;70	default:71		break;72	}73 74	if (dpcd_caps->dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER &&75			dongle_caps->extendedCapValid == true) {76		/* Check Pixel Encoding */77		switch (timing->pixel_encoding) {78		case PIXEL_ENCODING_RGB:79		case PIXEL_ENCODING_YCBCR444:80			break;81		case PIXEL_ENCODING_YCBCR422:82			if (!dongle_caps->is_dp_hdmi_ycbcr422_pass_through)83				return false;84			break;85		case PIXEL_ENCODING_YCBCR420:86			if (!dongle_caps->is_dp_hdmi_ycbcr420_pass_through)87				return false;88			break;89		default:90			/* Invalid Pixel Encoding*/91			return false;92		}93 94		switch (timing->display_color_depth) {95		case COLOR_DEPTH_666:96		case COLOR_DEPTH_888:97			/*888 and 666 should always be supported*/98			break;99		case COLOR_DEPTH_101010:100			if (dongle_caps->dp_hdmi_max_bpc < 10)101				return false;102			break;103		case COLOR_DEPTH_121212:104			if (dongle_caps->dp_hdmi_max_bpc < 12)105				return false;106			break;107		case COLOR_DEPTH_141414:108		case COLOR_DEPTH_161616:109		default:110			/* These color depths are currently not supported */111			return false;112		}113 114		/* Check 3D format */115		switch (timing->timing_3d_format) {116		case TIMING_3D_FORMAT_NONE:117		case TIMING_3D_FORMAT_FRAME_ALTERNATE:118			/*Only frame alternate 3D is supported on active dongle*/119			break;120		default:121			/*other 3D formats are not supported due to bad infoframe translation */122			return false;123		}124 125		if (dongle_caps->dp_hdmi_frl_max_link_bw_in_kbps > 0) { // DP to HDMI FRL converter126			struct dc_crtc_timing outputTiming = *timing;127 128			if (timing->flags.DSC && !timing->dsc_cfg.is_frl)129				/* DP input has DSC, HDMI FRL output doesn't have DSC, remove DSC from output timing */130				outputTiming.flags.DSC = 0;131			if (dc_bandwidth_in_kbps_from_timing(&outputTiming, DC_LINK_ENCODING_HDMI_FRL) >132					dongle_caps->dp_hdmi_frl_max_link_bw_in_kbps)133				return false;134		} else { // DP to HDMI TMDS converter135			if (get_tmds_output_pixel_clock_100hz(timing) > (dongle_caps->dp_hdmi_max_pixel_clk_in_khz * 10))136				return false;137		}138	}139 140	if (dpcd_caps->channel_coding_cap.bits.DP_128b_132b_SUPPORTED == 0 &&141			dpcd_caps->dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT == 0 &&142			dongle_caps->dfp_cap_ext.supported) {143 144		if (dongle_caps->dfp_cap_ext.max_pixel_rate_in_mps < (timing->pix_clk_100hz / 10000))145			return false;146 147		if (dongle_caps->dfp_cap_ext.max_video_h_active_width < timing->h_addressable)148			return false;149 150		if (dongle_caps->dfp_cap_ext.max_video_v_active_height < timing->v_addressable)151			return false;152 153		if (timing->pixel_encoding == PIXEL_ENCODING_RGB) {154			if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb)155				return false;156			if (timing->display_color_depth == COLOR_DEPTH_666 &&157					!dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_6bpc)158				return false;159			else if (timing->display_color_depth == COLOR_DEPTH_888 &&160					!dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_8bpc)161				return false;162			else if (timing->display_color_depth == COLOR_DEPTH_101010 &&163					!dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_10bpc)164				return false;165			else if (timing->display_color_depth == COLOR_DEPTH_121212 &&166					!dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_12bpc)167				return false;168			else if (timing->display_color_depth == COLOR_DEPTH_161616 &&169					!dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_16bpc)170				return false;171		} else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR444) {172			if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb)173				return false;174			if (timing->display_color_depth == COLOR_DEPTH_888 &&175					!dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_8bpc)176				return false;177			else if (timing->display_color_depth == COLOR_DEPTH_101010 &&178					!dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_10bpc)179				return false;180			else if (timing->display_color_depth == COLOR_DEPTH_121212 &&181					!dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_12bpc)182				return false;183			else if (timing->display_color_depth == COLOR_DEPTH_161616 &&184					!dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_16bpc)185				return false;186		} else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) {187			if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb)188				return false;189			if (timing->display_color_depth == COLOR_DEPTH_888 &&190					!dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_8bpc)191				return false;192			else if (timing->display_color_depth == COLOR_DEPTH_101010 &&193					!dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_10bpc)194				return false;195			else if (timing->display_color_depth == COLOR_DEPTH_121212 &&196					!dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_12bpc)197				return false;198			else if (timing->display_color_depth == COLOR_DEPTH_161616 &&199					!dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_16bpc)200				return false;201		} else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) {202			if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb)203				return false;204			if (timing->display_color_depth == COLOR_DEPTH_888 &&205					!dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_8bpc)206				return false;207			else if (timing->display_color_depth == COLOR_DEPTH_101010 &&208					!dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_10bpc)209				return false;210			else if (timing->display_color_depth == COLOR_DEPTH_121212 &&211					!dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_12bpc)212				return false;213			else if (timing->display_color_depth == COLOR_DEPTH_161616 &&214					!dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_16bpc)215				return false;216		}217	}218 219	return true;220}221 222uint32_t dp_link_bandwidth_kbps(223	const struct dc_link *link,224	const struct dc_link_settings *link_settings)225{226	uint32_t total_data_bw_efficiency_x10000 = 0;227	uint32_t link_rate_per_lane_kbps = 0;228 229	switch (link_dp_get_encoding_format(link_settings)) {230	case DP_8b_10b_ENCODING:231		/* For 8b/10b encoding:232		 * link rate is defined in the unit of LINK_RATE_REF_FREQ_IN_KHZ per DP byte per lane.233		 * data bandwidth efficiency is 80% with additional 3% overhead if FEC is supported.234		 */235		link_rate_per_lane_kbps = link_settings->link_rate * LINK_RATE_REF_FREQ_IN_KHZ * BITS_PER_DP_BYTE;236		total_data_bw_efficiency_x10000 = DATA_EFFICIENCY_8b_10b_x10000;237		if (dp_should_enable_fec(link)) {238			total_data_bw_efficiency_x10000 /= 100;239			total_data_bw_efficiency_x10000 *= DATA_EFFICIENCY_8b_10b_FEC_EFFICIENCY_x100;240		}241		break;242	case DP_128b_132b_ENCODING:243		/* For 128b/132b encoding:244		 * link rate is defined in the unit of 10mbps per lane.245		 * total data bandwidth efficiency is always 96.71%.246		 */247		link_rate_per_lane_kbps = link_settings->link_rate * 10000;248		total_data_bw_efficiency_x10000 = DATA_EFFICIENCY_128b_132b_x10000;249		break;250	default:251		break;252	}253 254	/* overall effective link bandwidth = link rate per lane * lane count * total data bandwidth efficiency */255	return link_rate_per_lane_kbps * link_settings->lane_count / 10000 * total_data_bw_efficiency_x10000;256}257 258static bool dp_validate_mode_timing(259	struct dc_link *link,260	const struct dc_crtc_timing *timing)261{262	uint32_t req_bw;263	uint32_t max_bw;264 265	const struct dc_link_settings *link_setting;266 267	/* According to spec, VSC SDP should be used if pixel format is YCbCr420 */268	if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420 &&269			!link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED &&270			dal_graphics_object_id_get_connector_id(link->link_id) != CONNECTOR_ID_VIRTUAL)271		return false;272 273	/*always DP fail safe mode*/274	if ((timing->pix_clk_100hz / 10) == (uint32_t) 25175 &&275		timing->h_addressable == (uint32_t) 640 &&276		timing->v_addressable == (uint32_t) 480)277		return true;278 279	link_setting = dp_get_verified_link_cap(link);280 281	/* TODO: DYNAMIC_VALIDATION needs to be implemented */282	/*if (flags.DYNAMIC_VALIDATION == 1 &&283		link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN)284		link_setting = &link->verified_link_cap;285	*/286 287	req_bw = dc_bandwidth_in_kbps_from_timing(timing, dc_link_get_highest_encoding_format(link));288	max_bw = dp_link_bandwidth_kbps(link, link_setting);289 290	bool is_max_uncompressed_pixel_rate_exceeded = link->dpcd_caps.max_uncompressed_pixel_rate_cap.bits.valid &&291			timing->pix_clk_100hz > link->dpcd_caps.max_uncompressed_pixel_rate_cap.bits.max_uncompressed_pixel_rate_cap * 10000;292 293	if (is_max_uncompressed_pixel_rate_exceeded && !timing->flags.DSC) {294		return false;295	}296 297	if (req_bw <= max_bw) {298		/* remember the biggest mode here, during299		 * initial link training (to get300		 * verified_link_cap), LS sends event about301		 * cannot train at reported cap to upper302		 * layer and upper layer will re-enumerate modes.303		 * this is not necessary if the lower304		 * verified_link_cap is enough to drive305		 * all the modes */306 307		/* TODO: DYNAMIC_VALIDATION needs to be implemented */308		/* if (flags.DYNAMIC_VALIDATION == 1)309			dpsst->max_req_bw_for_verified_linkcap = dal_max(310				dpsst->max_req_bw_for_verified_linkcap, req_bw); */311		return true;312	} else313		return false;314}315 316enum dc_status link_validate_mode_timing(317		const struct dc_stream_state *stream,318		struct dc_link *link,319		const struct dc_crtc_timing *timing)320{321	uint32_t max_pix_clk = stream->link->dongle_max_pix_clk * 10;322	struct dpcd_caps *dpcd_caps = &link->dpcd_caps;323 324	/* A hack to avoid failing any modes for EDID override feature on325	 * topology change such as lower quality cable for DP or different dongle326	 */327	if (link->remote_sinks[0] && link->remote_sinks[0]->sink_signal == SIGNAL_TYPE_VIRTUAL)328		return DC_OK;329 330	/* Passive Dongle */331	if (max_pix_clk != 0 && get_tmds_output_pixel_clock_100hz(timing) > max_pix_clk)332		return DC_EXCEED_DONGLE_CAP;333 334	/* Active Dongle*/335	if (!dp_active_dongle_validate_timing(timing, dpcd_caps))336		return DC_EXCEED_DONGLE_CAP;337 338	switch (stream->signal) {339	case SIGNAL_TYPE_EDP:340	case SIGNAL_TYPE_DISPLAY_PORT:341		if (!dp_validate_mode_timing(342				link,343				timing))344			return DC_NO_DP_LINK_BANDWIDTH;345		break;346 347	default:348		break;349	}350 351	return DC_OK;352}353 354/*355 * This function calculates the bandwidth required for the stream timing356 * and aggregates the stream bandwidth for the respective dpia link357 *358 * @stream: pointer to the dc_stream_state struct instance359 * @num_streams: number of streams to be validated360 *361 * return: true if validation is succeeded362 */363bool link_validate_dpia_bandwidth(const struct dc_stream_state *stream, const unsigned int num_streams)364{365	int bw_needed[MAX_DPIA_NUM] = {0};366	struct dc_link *dpia_link[MAX_DPIA_NUM] = {0};367	int num_dpias = 0;368 369	for (unsigned int i = 0; i < num_streams; ++i) {370		if (stream[i].signal == SIGNAL_TYPE_DISPLAY_PORT) {371			/* new dpia sst stream, check whether it exceeds max dpia */372			if (num_dpias >= MAX_DPIA_NUM)373				return false;374 375			dpia_link[num_dpias] = stream[i].link;376			bw_needed[num_dpias] = dc_bandwidth_in_kbps_from_timing(&stream[i].timing,377					dc_link_get_highest_encoding_format(dpia_link[num_dpias]));378			num_dpias++;379		} else if (stream[i].signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {380			uint8_t j = 0;381			/* check whether its a known dpia link */382			for (; j < num_dpias; ++j) {383				if (dpia_link[j] == stream[i].link)384					break;385			}386 387			if (j == num_dpias) {388				/* new dpia mst stream, check whether it exceeds max dpia */389				if (num_dpias >= MAX_DPIA_NUM)390					return false;391				else {392					dpia_link[j] = stream[i].link;393					num_dpias++;394				}395			}396 397			bw_needed[j] += dc_bandwidth_in_kbps_from_timing(&stream[i].timing,398				dc_link_get_highest_encoding_format(dpia_link[j]));399		}400	}401 402	/* Include dp overheads */403	for (uint8_t i = 0; i < num_dpias; ++i) {404		int dp_overhead = 0;405 406		dp_overhead = link_dp_dpia_get_dp_overhead_in_dp_tunneling(dpia_link[i]);407		bw_needed[i] += dp_overhead;408	}409 410	return dpia_validate_usb4_bw(dpia_link, bw_needed, num_dpias);411}412