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(const struct dc_crtc_timing *timing)
259 {
260 	uint32_t bits_per_channel = 0;
261 	uint32_t kbps;
262 
263 	if (timing->flags.DSC)
264 		return dc_dsc_stream_bandwidth_in_kbps(timing,
265 				timing->dsc_cfg.bits_per_pixel,
266 				timing->dsc_cfg.num_slices_h,
267 				timing->dsc_cfg.is_dp);
268 
269 	switch (timing->display_color_depth) {
270 	case COLOR_DEPTH_666:
271 		bits_per_channel = 6;
272 		break;
273 	case COLOR_DEPTH_888:
274 		bits_per_channel = 8;
275 		break;
276 	case COLOR_DEPTH_101010:
277 		bits_per_channel = 10;
278 		break;
279 	case COLOR_DEPTH_121212:
280 		bits_per_channel = 12;
281 		break;
282 	case COLOR_DEPTH_141414:
283 		bits_per_channel = 14;
284 		break;
285 	case COLOR_DEPTH_161616:
286 		bits_per_channel = 16;
287 		break;
288 	default:
289 		ASSERT(bits_per_channel != 0);
290 		bits_per_channel = 8;
291 		break;
292 	}
293 
294 	kbps = timing->pix_clk_100hz / 10;
295 	kbps *= bits_per_channel;
296 
297 	if (timing->flags.Y_ONLY != 1) {
298 		/*Only YOnly make reduce bandwidth by 1/3 compares to RGB*/
299 		kbps *= 3;
300 		if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
301 			kbps /= 2;
302 		else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
303 			kbps = kbps * 2 / 3;
304 	}
305 
306 	return kbps;
307 }
308 
309 static bool dp_validate_mode_timing(
310 	struct dc_link *link,
311 	const struct dc_crtc_timing *timing)
312 {
313 	uint32_t req_bw;
314 	uint32_t max_bw;
315 
316 	const struct dc_link_settings *link_setting;
317 
318 	/* According to spec, VSC SDP should be used if pixel format is YCbCr420 */
319 	if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420 &&
320 			!link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED &&
321 			dal_graphics_object_id_get_connector_id(link->link_id) != CONNECTOR_ID_VIRTUAL)
322 		return false;
323 
324 	/*always DP fail safe mode*/
325 	if ((timing->pix_clk_100hz / 10) == (uint32_t) 25175 &&
326 		timing->h_addressable == (uint32_t) 640 &&
327 		timing->v_addressable == (uint32_t) 480)
328 		return true;
329 
330 	link_setting = dp_get_verified_link_cap(link);
331 
332 	/* TODO: DYNAMIC_VALIDATION needs to be implemented */
333 	/*if (flags.DYNAMIC_VALIDATION == 1 &&
334 		link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN)
335 		link_setting = &link->verified_link_cap;
336 	*/
337 
338 	req_bw = dc_bandwidth_in_kbps_from_timing(timing);
339 	max_bw = dp_link_bandwidth_kbps(link, link_setting);
340 
341 	if (req_bw <= max_bw) {
342 		/* remember the biggest mode here, during
343 		 * initial link training (to get
344 		 * verified_link_cap), LS sends event about
345 		 * cannot train at reported cap to upper
346 		 * layer and upper layer will re-enumerate modes.
347 		 * this is not necessary if the lower
348 		 * verified_link_cap is enough to drive
349 		 * all the modes */
350 
351 		/* TODO: DYNAMIC_VALIDATION needs to be implemented */
352 		/* if (flags.DYNAMIC_VALIDATION == 1)
353 			dpsst->max_req_bw_for_verified_linkcap = dal_max(
354 				dpsst->max_req_bw_for_verified_linkcap, req_bw); */
355 		return true;
356 	} else
357 		return false;
358 }
359 
360 enum dc_status link_validate_mode_timing(
361 		const struct dc_stream_state *stream,
362 		struct dc_link *link,
363 		const struct dc_crtc_timing *timing)
364 {
365 	uint32_t max_pix_clk = stream->link->dongle_max_pix_clk * 10;
366 	struct dpcd_caps *dpcd_caps = &link->dpcd_caps;
367 
368 	/* A hack to avoid failing any modes for EDID override feature on
369 	 * topology change such as lower quality cable for DP or different dongle
370 	 */
371 	if (link->remote_sinks[0] && link->remote_sinks[0]->sink_signal == SIGNAL_TYPE_VIRTUAL)
372 		return DC_OK;
373 
374 	/* Passive Dongle */
375 	if (max_pix_clk != 0 && get_tmds_output_pixel_clock_100hz(timing) > max_pix_clk)
376 		return DC_EXCEED_DONGLE_CAP;
377 
378 	/* Active Dongle*/
379 	if (!dp_active_dongle_validate_timing(timing, dpcd_caps))
380 		return DC_EXCEED_DONGLE_CAP;
381 
382 	switch (stream->signal) {
383 	case SIGNAL_TYPE_EDP:
384 	case SIGNAL_TYPE_DISPLAY_PORT:
385 		if (!dp_validate_mode_timing(
386 				link,
387 				timing))
388 			return DC_NO_DP_LINK_BANDWIDTH;
389 		break;
390 
391 	default:
392 		break;
393 	}
394 
395 	return DC_OK;
396 }
397