1 /*
2  * Copyright 2023 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * 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 OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
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 also
29  * provides helper functions exposing bandwidth formulas used in validation.
30  */
31 #include "link_validation.h"
32 #include "protocols/link_dp_capability.h"
33 #include "resource.h"
34 
35 #define DC_LOGGER_INIT(logger)
36 
37 static uint32_t get_tmds_output_pixel_clock_100hz(const struct dc_crtc_timing *timing)
38 {
39 
40 	uint32_t pxl_clk = timing->pix_clk_100hz;
41 
42 	if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
43 		pxl_clk /= 2;
44 	else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
45 		pxl_clk = pxl_clk * 2 / 3;
46 
47 	if (timing->display_color_depth == COLOR_DEPTH_101010)
48 		pxl_clk = pxl_clk * 10 / 8;
49 	else if (timing->display_color_depth == COLOR_DEPTH_121212)
50 		pxl_clk = pxl_clk * 12 / 8;
51 
52 	return pxl_clk;
53 }
54 
55 static bool dp_active_dongle_validate_timing(
56 		const struct dc_crtc_timing *timing,
57 		const struct dpcd_caps *dpcd_caps)
58 {
59 	const struct dc_dongle_caps *dongle_caps = &dpcd_caps->dongle_caps;
60 
61 	switch (dpcd_caps->dongle_type) {
62 	case DISPLAY_DONGLE_DP_VGA_CONVERTER:
63 	case DISPLAY_DONGLE_DP_DVI_CONVERTER:
64 	case DISPLAY_DONGLE_DP_DVI_DONGLE:
65 		if (timing->pixel_encoding == PIXEL_ENCODING_RGB)
66 			return true;
67 		else
68 			return false;
69 	default:
70 		break;
71 	}
72 
73 	if (dpcd_caps->dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER &&
74 			dongle_caps->extendedCapValid == true) {
75 		/* Check Pixel Encoding */
76 		switch (timing->pixel_encoding) {
77 		case PIXEL_ENCODING_RGB:
78 		case PIXEL_ENCODING_YCBCR444:
79 			break;
80 		case PIXEL_ENCODING_YCBCR422:
81 			if (!dongle_caps->is_dp_hdmi_ycbcr422_pass_through)
82 				return false;
83 			break;
84 		case PIXEL_ENCODING_YCBCR420:
85 			if (!dongle_caps->is_dp_hdmi_ycbcr420_pass_through)
86 				return false;
87 			break;
88 		default:
89 			/* Invalid Pixel Encoding*/
90 			return false;
91 		}
92 
93 		switch (timing->display_color_depth) {
94 		case COLOR_DEPTH_666:
95 		case COLOR_DEPTH_888:
96 			/*888 and 666 should always be supported*/
97 			break;
98 		case COLOR_DEPTH_101010:
99 			if (dongle_caps->dp_hdmi_max_bpc < 10)
100 				return false;
101 			break;
102 		case COLOR_DEPTH_121212:
103 			if (dongle_caps->dp_hdmi_max_bpc < 12)
104 				return false;
105 			break;
106 		case COLOR_DEPTH_141414:
107 		case COLOR_DEPTH_161616:
108 		default:
109 			/* These color depths are currently not supported */
110 			return false;
111 		}
112 
113 		/* Check 3D format */
114 		switch (timing->timing_3d_format) {
115 		case TIMING_3D_FORMAT_NONE:
116 		case TIMING_3D_FORMAT_FRAME_ALTERNATE:
117 			/*Only frame alternate 3D is supported on active dongle*/
118 			break;
119 		default:
120 			/*other 3D formats are not supported due to bad infoframe translation */
121 			return false;
122 		}
123 
124 		if (dongle_caps->dp_hdmi_frl_max_link_bw_in_kbps > 0) { // DP to HDMI FRL converter
125 			struct dc_crtc_timing outputTiming = *timing;
126 
127 #if defined(CONFIG_DRM_AMD_DC_FP)
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 #endif
132 			if (dc_bandwidth_in_kbps_from_timing(&outputTiming) > dongle_caps->dp_hdmi_frl_max_link_bw_in_kbps)
133 				return false;
134 		} else { // DP to HDMI TMDS converter
135 			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 
222 uint32_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 
258 uint32_t link_timing_bandwidth_kbps(
259 	const struct dc_crtc_timing *timing)
260 {
261 	uint32_t bits_per_channel = 0;
262 	uint32_t kbps;
263 
264 	if (timing->flags.DSC)
265 		return dc_dsc_stream_bandwidth_in_kbps(timing,
266 				timing->dsc_cfg.bits_per_pixel,
267 				timing->dsc_cfg.num_slices_h,
268 				timing->dsc_cfg.is_dp);
269 
270 	switch (timing->display_color_depth) {
271 	case COLOR_DEPTH_666:
272 		bits_per_channel = 6;
273 		break;
274 	case COLOR_DEPTH_888:
275 		bits_per_channel = 8;
276 		break;
277 	case COLOR_DEPTH_101010:
278 		bits_per_channel = 10;
279 		break;
280 	case COLOR_DEPTH_121212:
281 		bits_per_channel = 12;
282 		break;
283 	case COLOR_DEPTH_141414:
284 		bits_per_channel = 14;
285 		break;
286 	case COLOR_DEPTH_161616:
287 		bits_per_channel = 16;
288 		break;
289 	default:
290 		ASSERT(bits_per_channel != 0);
291 		bits_per_channel = 8;
292 		break;
293 	}
294 
295 	kbps = timing->pix_clk_100hz / 10;
296 	kbps *= bits_per_channel;
297 
298 	if (timing->flags.Y_ONLY != 1) {
299 		/*Only YOnly make reduce bandwidth by 1/3 compares to RGB*/
300 		kbps *= 3;
301 		if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
302 			kbps /= 2;
303 		else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
304 			kbps = kbps * 2 / 3;
305 	}
306 
307 	return kbps;
308 }
309 
310 static bool dp_validate_mode_timing(
311 	struct dc_link *link,
312 	const struct dc_crtc_timing *timing)
313 {
314 	uint32_t req_bw;
315 	uint32_t max_bw;
316 
317 	const struct dc_link_settings *link_setting;
318 
319 	/* According to spec, VSC SDP should be used if pixel format is YCbCr420 */
320 	if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420 &&
321 			!link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED &&
322 			dal_graphics_object_id_get_connector_id(link->link_id) != CONNECTOR_ID_VIRTUAL)
323 		return false;
324 
325 	/*always DP fail safe mode*/
326 	if ((timing->pix_clk_100hz / 10) == (uint32_t) 25175 &&
327 		timing->h_addressable == (uint32_t) 640 &&
328 		timing->v_addressable == (uint32_t) 480)
329 		return true;
330 
331 	link_setting = dp_get_verified_link_cap(link);
332 
333 	/* TODO: DYNAMIC_VALIDATION needs to be implemented */
334 	/*if (flags.DYNAMIC_VALIDATION == 1 &&
335 		link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN)
336 		link_setting = &link->verified_link_cap;
337 	*/
338 
339 	req_bw = dc_bandwidth_in_kbps_from_timing(timing);
340 	max_bw = dc_link_bandwidth_kbps(link, link_setting);
341 
342 	if (req_bw <= max_bw) {
343 		/* remember the biggest mode here, during
344 		 * initial link training (to get
345 		 * verified_link_cap), LS sends event about
346 		 * cannot train at reported cap to upper
347 		 * layer and upper layer will re-enumerate modes.
348 		 * this is not necessary if the lower
349 		 * verified_link_cap is enough to drive
350 		 * all the modes */
351 
352 		/* TODO: DYNAMIC_VALIDATION needs to be implemented */
353 		/* if (flags.DYNAMIC_VALIDATION == 1)
354 			dpsst->max_req_bw_for_verified_linkcap = dal_max(
355 				dpsst->max_req_bw_for_verified_linkcap, req_bw); */
356 		return true;
357 	} else
358 		return false;
359 }
360 
361 enum dc_status link_validate_mode_timing(
362 		const struct dc_stream_state *stream,
363 		struct dc_link *link,
364 		const struct dc_crtc_timing *timing)
365 {
366 	uint32_t max_pix_clk = stream->link->dongle_max_pix_clk * 10;
367 	struct dpcd_caps *dpcd_caps = &link->dpcd_caps;
368 
369 	/* A hack to avoid failing any modes for EDID override feature on
370 	 * topology change such as lower quality cable for DP or different dongle
371 	 */
372 	if (link->remote_sinks[0] && link->remote_sinks[0]->sink_signal == SIGNAL_TYPE_VIRTUAL)
373 		return DC_OK;
374 
375 	/* Passive Dongle */
376 	if (max_pix_clk != 0 && get_tmds_output_pixel_clock_100hz(timing) > max_pix_clk)
377 		return DC_EXCEED_DONGLE_CAP;
378 
379 	/* Active Dongle*/
380 	if (!dp_active_dongle_validate_timing(timing, dpcd_caps))
381 		return DC_EXCEED_DONGLE_CAP;
382 
383 	switch (stream->signal) {
384 	case SIGNAL_TYPE_EDP:
385 	case SIGNAL_TYPE_DISPLAY_PORT:
386 		if (!dp_validate_mode_timing(
387 				link,
388 				timing))
389 			return DC_NO_DP_LINK_BANDWIDTH;
390 		break;
391 
392 	default:
393 		break;
394 	}
395 
396 	return DC_OK;
397 }
398