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 "resource.h"
33 
34 #define DC_LOGGER_INIT(logger)
35 
36 static uint32_t get_tmds_output_pixel_clock_100hz(const struct dc_crtc_timing *timing)
37 {
38 
39 	uint32_t pxl_clk = timing->pix_clk_100hz;
40 
41 	if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
42 		pxl_clk /= 2;
43 	else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
44 		pxl_clk = pxl_clk * 2 / 3;
45 
46 	if (timing->display_color_depth == COLOR_DEPTH_101010)
47 		pxl_clk = pxl_clk * 10 / 8;
48 	else if (timing->display_color_depth == COLOR_DEPTH_121212)
49 		pxl_clk = pxl_clk * 12 / 8;
50 
51 	return pxl_clk;
52 }
53 
54 static bool dp_active_dongle_validate_timing(
55 		const struct dc_crtc_timing *timing,
56 		const struct dpcd_caps *dpcd_caps)
57 {
58 	const struct dc_dongle_caps *dongle_caps = &dpcd_caps->dongle_caps;
59 
60 	switch (dpcd_caps->dongle_type) {
61 	case DISPLAY_DONGLE_DP_VGA_CONVERTER:
62 	case DISPLAY_DONGLE_DP_DVI_CONVERTER:
63 	case DISPLAY_DONGLE_DP_DVI_DONGLE:
64 		if (timing->pixel_encoding == PIXEL_ENCODING_RGB)
65 			return true;
66 		else
67 			return false;
68 	default:
69 		break;
70 	}
71 
72 	if (dpcd_caps->dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER &&
73 			dongle_caps->extendedCapValid == true) {
74 		/* Check Pixel Encoding */
75 		switch (timing->pixel_encoding) {
76 		case PIXEL_ENCODING_RGB:
77 		case PIXEL_ENCODING_YCBCR444:
78 			break;
79 		case PIXEL_ENCODING_YCBCR422:
80 			if (!dongle_caps->is_dp_hdmi_ycbcr422_pass_through)
81 				return false;
82 			break;
83 		case PIXEL_ENCODING_YCBCR420:
84 			if (!dongle_caps->is_dp_hdmi_ycbcr420_pass_through)
85 				return false;
86 			break;
87 		default:
88 			/* Invalid Pixel Encoding*/
89 			return false;
90 		}
91 
92 		switch (timing->display_color_depth) {
93 		case COLOR_DEPTH_666:
94 		case COLOR_DEPTH_888:
95 			/*888 and 666 should always be supported*/
96 			break;
97 		case COLOR_DEPTH_101010:
98 			if (dongle_caps->dp_hdmi_max_bpc < 10)
99 				return false;
100 			break;
101 		case COLOR_DEPTH_121212:
102 			if (dongle_caps->dp_hdmi_max_bpc < 12)
103 				return false;
104 			break;
105 		case COLOR_DEPTH_141414:
106 		case COLOR_DEPTH_161616:
107 		default:
108 			/* These color depths are currently not supported */
109 			return false;
110 		}
111 
112 		/* Check 3D format */
113 		switch (timing->timing_3d_format) {
114 		case TIMING_3D_FORMAT_NONE:
115 		case TIMING_3D_FORMAT_FRAME_ALTERNATE:
116 			/*Only frame alternate 3D is supported on active dongle*/
117 			break;
118 		default:
119 			/*other 3D formats are not supported due to bad infoframe translation */
120 			return false;
121 		}
122 
123 		if (dongle_caps->dp_hdmi_frl_max_link_bw_in_kbps > 0) { // DP to HDMI FRL converter
124 			struct dc_crtc_timing outputTiming = *timing;
125 
126 #if defined(CONFIG_DRM_AMD_DC_DCN)
127 			if (timing->flags.DSC && !timing->dsc_cfg.is_frl)
128 				/* DP input has DSC, HDMI FRL output doesn't have DSC, remove DSC from output timing */
129 				outputTiming.flags.DSC = 0;
130 #endif
131 			if (dc_bandwidth_in_kbps_from_timing(&outputTiming) > dongle_caps->dp_hdmi_frl_max_link_bw_in_kbps)
132 				return false;
133 		} else { // DP to HDMI TMDS converter
134 			if (get_tmds_output_pixel_clock_100hz(timing) > (dongle_caps->dp_hdmi_max_pixel_clk_in_khz * 10))
135 				return false;
136 		}
137 	}
138 
139 	if (dpcd_caps->channel_coding_cap.bits.DP_128b_132b_SUPPORTED == 0 &&
140 			dpcd_caps->dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT == 0 &&
141 			dongle_caps->dfp_cap_ext.supported) {
142 
143 		if (dongle_caps->dfp_cap_ext.max_pixel_rate_in_mps < (timing->pix_clk_100hz / 10000))
144 			return false;
145 
146 		if (dongle_caps->dfp_cap_ext.max_video_h_active_width < timing->h_addressable)
147 			return false;
148 
149 		if (dongle_caps->dfp_cap_ext.max_video_v_active_height < timing->v_addressable)
150 			return false;
151 
152 		if (timing->pixel_encoding == PIXEL_ENCODING_RGB) {
153 			if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb)
154 				return false;
155 			if (timing->display_color_depth == COLOR_DEPTH_666 &&
156 					!dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_6bpc)
157 				return false;
158 			else if (timing->display_color_depth == COLOR_DEPTH_888 &&
159 					!dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_8bpc)
160 				return false;
161 			else if (timing->display_color_depth == COLOR_DEPTH_101010 &&
162 					!dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_10bpc)
163 				return false;
164 			else if (timing->display_color_depth == COLOR_DEPTH_121212 &&
165 					!dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_12bpc)
166 				return false;
167 			else if (timing->display_color_depth == COLOR_DEPTH_161616 &&
168 					!dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_16bpc)
169 				return false;
170 		} else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR444) {
171 			if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb)
172 				return false;
173 			if (timing->display_color_depth == COLOR_DEPTH_888 &&
174 					!dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_8bpc)
175 				return false;
176 			else if (timing->display_color_depth == COLOR_DEPTH_101010 &&
177 					!dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_10bpc)
178 				return false;
179 			else if (timing->display_color_depth == COLOR_DEPTH_121212 &&
180 					!dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_12bpc)
181 				return false;
182 			else if (timing->display_color_depth == COLOR_DEPTH_161616 &&
183 					!dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_16bpc)
184 				return false;
185 		} else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
186 			if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb)
187 				return false;
188 			if (timing->display_color_depth == COLOR_DEPTH_888 &&
189 					!dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_8bpc)
190 				return false;
191 			else if (timing->display_color_depth == COLOR_DEPTH_101010 &&
192 					!dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_10bpc)
193 				return false;
194 			else if (timing->display_color_depth == COLOR_DEPTH_121212 &&
195 					!dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_12bpc)
196 				return false;
197 			else if (timing->display_color_depth == COLOR_DEPTH_161616 &&
198 					!dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_16bpc)
199 				return false;
200 		} else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) {
201 			if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb)
202 				return false;
203 			if (timing->display_color_depth == COLOR_DEPTH_888 &&
204 					!dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_8bpc)
205 				return false;
206 			else if (timing->display_color_depth == COLOR_DEPTH_101010 &&
207 					!dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_10bpc)
208 				return false;
209 			else if (timing->display_color_depth == COLOR_DEPTH_121212 &&
210 					!dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_12bpc)
211 				return false;
212 			else if (timing->display_color_depth == COLOR_DEPTH_161616 &&
213 					!dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_16bpc)
214 				return false;
215 		}
216 	}
217 
218 	return true;
219 }
220 
221 uint32_t dc_link_bandwidth_kbps(
222 	const struct dc_link *link,
223 	const struct dc_link_settings *link_setting)
224 {
225 	uint32_t total_data_bw_efficiency_x10000 = 0;
226 	uint32_t link_rate_per_lane_kbps = 0;
227 
228 	switch (link_dp_get_encoding_format(link_setting)) {
229 	case DP_8b_10b_ENCODING:
230 		/* For 8b/10b encoding:
231 		 * link rate is defined in the unit of LINK_RATE_REF_FREQ_IN_KHZ per DP byte per lane.
232 		 * data bandwidth efficiency is 80% with additional 3% overhead if FEC is supported.
233 		 */
234 		link_rate_per_lane_kbps = link_setting->link_rate * LINK_RATE_REF_FREQ_IN_KHZ * BITS_PER_DP_BYTE;
235 		total_data_bw_efficiency_x10000 = DATA_EFFICIENCY_8b_10b_x10000;
236 		if (dc_link_should_enable_fec(link)) {
237 			total_data_bw_efficiency_x10000 /= 100;
238 			total_data_bw_efficiency_x10000 *= DATA_EFFICIENCY_8b_10b_FEC_EFFICIENCY_x100;
239 		}
240 		break;
241 	case DP_128b_132b_ENCODING:
242 		/* For 128b/132b encoding:
243 		 * link rate is defined in the unit of 10mbps per lane.
244 		 * total data bandwidth efficiency is always 96.71%.
245 		 */
246 		link_rate_per_lane_kbps = link_setting->link_rate * 10000;
247 		total_data_bw_efficiency_x10000 = DATA_EFFICIENCY_128b_132b_x10000;
248 		break;
249 	default:
250 		break;
251 	}
252 
253 	/* overall effective link bandwidth = link rate per lane * lane count * total data bandwidth efficiency */
254 	return link_rate_per_lane_kbps * link_setting->lane_count / 10000 * total_data_bw_efficiency_x10000;
255 }
256 
257 uint32_t dc_bandwidth_in_kbps_from_timing(
258 	const struct dc_crtc_timing *timing)
259 {
260 	uint32_t bits_per_channel = 0;
261 	uint32_t kbps;
262 
263 #if defined(CONFIG_DRM_AMD_DC_DCN)
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 #endif /* CONFIG_DRM_AMD_DC_DCN */
270 
271 	switch (timing->display_color_depth) {
272 	case COLOR_DEPTH_666:
273 		bits_per_channel = 6;
274 		break;
275 	case COLOR_DEPTH_888:
276 		bits_per_channel = 8;
277 		break;
278 	case COLOR_DEPTH_101010:
279 		bits_per_channel = 10;
280 		break;
281 	case COLOR_DEPTH_121212:
282 		bits_per_channel = 12;
283 		break;
284 	case COLOR_DEPTH_141414:
285 		bits_per_channel = 14;
286 		break;
287 	case COLOR_DEPTH_161616:
288 		bits_per_channel = 16;
289 		break;
290 	default:
291 		ASSERT(bits_per_channel != 0);
292 		bits_per_channel = 8;
293 		break;
294 	}
295 
296 	kbps = timing->pix_clk_100hz / 10;
297 	kbps *= bits_per_channel;
298 
299 	if (timing->flags.Y_ONLY != 1) {
300 		/*Only YOnly make reduce bandwidth by 1/3 compares to RGB*/
301 		kbps *= 3;
302 		if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
303 			kbps /= 2;
304 		else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
305 			kbps = kbps * 2 / 3;
306 	}
307 
308 	return kbps;
309 }
310 
311 static bool dp_validate_mode_timing(
312 	struct dc_link *link,
313 	const struct dc_crtc_timing *timing)
314 {
315 	uint32_t req_bw;
316 	uint32_t max_bw;
317 
318 	const struct dc_link_settings *link_setting;
319 
320 	/* According to spec, VSC SDP should be used if pixel format is YCbCr420 */
321 	if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420 &&
322 			!link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED &&
323 			dal_graphics_object_id_get_connector_id(link->link_id) != CONNECTOR_ID_VIRTUAL)
324 		return false;
325 
326 	/*always DP fail safe mode*/
327 	if ((timing->pix_clk_100hz / 10) == (uint32_t) 25175 &&
328 		timing->h_addressable == (uint32_t) 640 &&
329 		timing->v_addressable == (uint32_t) 480)
330 		return true;
331 
332 	link_setting = dc_link_get_link_cap(link);
333 
334 	/* TODO: DYNAMIC_VALIDATION needs to be implemented */
335 	/*if (flags.DYNAMIC_VALIDATION == 1 &&
336 		link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN)
337 		link_setting = &link->verified_link_cap;
338 	*/
339 
340 	req_bw = dc_bandwidth_in_kbps_from_timing(timing);
341 	max_bw = dc_link_bandwidth_kbps(link, link_setting);
342 
343 	if (req_bw <= max_bw) {
344 		/* remember the biggest mode here, during
345 		 * initial link training (to get
346 		 * verified_link_cap), LS sends event about
347 		 * cannot train at reported cap to upper
348 		 * layer and upper layer will re-enumerate modes.
349 		 * this is not necessary if the lower
350 		 * verified_link_cap is enough to drive
351 		 * all the modes */
352 
353 		/* TODO: DYNAMIC_VALIDATION needs to be implemented */
354 		/* if (flags.DYNAMIC_VALIDATION == 1)
355 			dpsst->max_req_bw_for_verified_linkcap = dal_max(
356 				dpsst->max_req_bw_for_verified_linkcap, req_bw); */
357 		return true;
358 	} else
359 		return false;
360 }
361 
362 enum dc_status link_validate_mode_timing(
363 		const struct dc_stream_state *stream,
364 		struct dc_link *link,
365 		const struct dc_crtc_timing *timing)
366 {
367 	uint32_t max_pix_clk = stream->link->dongle_max_pix_clk * 10;
368 	struct dpcd_caps *dpcd_caps = &link->dpcd_caps;
369 
370 	/* A hack to avoid failing any modes for EDID override feature on
371 	 * topology change such as lower quality cable for DP or different dongle
372 	 */
373 	if (link->remote_sinks[0] && link->remote_sinks[0]->sink_signal == SIGNAL_TYPE_VIRTUAL)
374 		return DC_OK;
375 
376 	/* Passive Dongle */
377 	if (max_pix_clk != 0 && get_tmds_output_pixel_clock_100hz(timing) > max_pix_clk)
378 		return DC_EXCEED_DONGLE_CAP;
379 
380 	/* Active Dongle*/
381 	if (!dp_active_dongle_validate_timing(timing, dpcd_caps))
382 		return DC_EXCEED_DONGLE_CAP;
383 
384 	switch (stream->signal) {
385 	case SIGNAL_TYPE_EDP:
386 	case SIGNAL_TYPE_DISPLAY_PORT:
387 		if (!dp_validate_mode_timing(
388 				link,
389 				timing))
390 			return DC_NO_DP_LINK_BANDWIDTH;
391 		break;
392 
393 	default:
394 		break;
395 	}
396 
397 	return DC_OK;
398 }
399