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 (timing->flags.DSC && !timing->dsc_cfg.is_frl)
127 				/* DP input has DSC, HDMI FRL output doesn't have DSC, remove DSC from output timing */
128 				outputTiming.flags.DSC = 0;
129 			if (dc_bandwidth_in_kbps_from_timing(&outputTiming) > dongle_caps->dp_hdmi_frl_max_link_bw_in_kbps)
130 				return false;
131 		} else { // DP to HDMI TMDS converter
132 			if (get_tmds_output_pixel_clock_100hz(timing) > (dongle_caps->dp_hdmi_max_pixel_clk_in_khz * 10))
133 				return false;
134 		}
135 	}
136 
137 	if (dpcd_caps->channel_coding_cap.bits.DP_128b_132b_SUPPORTED == 0 &&
138 			dpcd_caps->dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT == 0 &&
139 			dongle_caps->dfp_cap_ext.supported) {
140 
141 		if (dongle_caps->dfp_cap_ext.max_pixel_rate_in_mps < (timing->pix_clk_100hz / 10000))
142 			return false;
143 
144 		if (dongle_caps->dfp_cap_ext.max_video_h_active_width < timing->h_addressable)
145 			return false;
146 
147 		if (dongle_caps->dfp_cap_ext.max_video_v_active_height < timing->v_addressable)
148 			return false;
149 
150 		if (timing->pixel_encoding == PIXEL_ENCODING_RGB) {
151 			if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb)
152 				return false;
153 			if (timing->display_color_depth == COLOR_DEPTH_666 &&
154 					!dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_6bpc)
155 				return false;
156 			else if (timing->display_color_depth == COLOR_DEPTH_888 &&
157 					!dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_8bpc)
158 				return false;
159 			else if (timing->display_color_depth == COLOR_DEPTH_101010 &&
160 					!dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_10bpc)
161 				return false;
162 			else if (timing->display_color_depth == COLOR_DEPTH_121212 &&
163 					!dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_12bpc)
164 				return false;
165 			else if (timing->display_color_depth == COLOR_DEPTH_161616 &&
166 					!dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_16bpc)
167 				return false;
168 		} else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR444) {
169 			if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb)
170 				return false;
171 			if (timing->display_color_depth == COLOR_DEPTH_888 &&
172 					!dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_8bpc)
173 				return false;
174 			else if (timing->display_color_depth == COLOR_DEPTH_101010 &&
175 					!dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_10bpc)
176 				return false;
177 			else if (timing->display_color_depth == COLOR_DEPTH_121212 &&
178 					!dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_12bpc)
179 				return false;
180 			else if (timing->display_color_depth == COLOR_DEPTH_161616 &&
181 					!dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_16bpc)
182 				return false;
183 		} else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
184 			if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb)
185 				return false;
186 			if (timing->display_color_depth == COLOR_DEPTH_888 &&
187 					!dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_8bpc)
188 				return false;
189 			else if (timing->display_color_depth == COLOR_DEPTH_101010 &&
190 					!dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_10bpc)
191 				return false;
192 			else if (timing->display_color_depth == COLOR_DEPTH_121212 &&
193 					!dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_12bpc)
194 				return false;
195 			else if (timing->display_color_depth == COLOR_DEPTH_161616 &&
196 					!dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_16bpc)
197 				return false;
198 		} else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) {
199 			if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb)
200 				return false;
201 			if (timing->display_color_depth == COLOR_DEPTH_888 &&
202 					!dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_8bpc)
203 				return false;
204 			else if (timing->display_color_depth == COLOR_DEPTH_101010 &&
205 					!dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_10bpc)
206 				return false;
207 			else if (timing->display_color_depth == COLOR_DEPTH_121212 &&
208 					!dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_12bpc)
209 				return false;
210 			else if (timing->display_color_depth == COLOR_DEPTH_161616 &&
211 					!dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_16bpc)
212 				return false;
213 		}
214 	}
215 
216 	return true;
217 }
218 
219 uint32_t dc_link_bandwidth_kbps(
220 	const struct dc_link *link,
221 	const struct dc_link_settings *link_setting)
222 {
223 	uint32_t total_data_bw_efficiency_x10000 = 0;
224 	uint32_t link_rate_per_lane_kbps = 0;
225 
226 	switch (link_dp_get_encoding_format(link_setting)) {
227 	case DP_8b_10b_ENCODING:
228 		/* For 8b/10b encoding:
229 		 * link rate is defined in the unit of LINK_RATE_REF_FREQ_IN_KHZ per DP byte per lane.
230 		 * data bandwidth efficiency is 80% with additional 3% overhead if FEC is supported.
231 		 */
232 		link_rate_per_lane_kbps = link_setting->link_rate * LINK_RATE_REF_FREQ_IN_KHZ * BITS_PER_DP_BYTE;
233 		total_data_bw_efficiency_x10000 = DATA_EFFICIENCY_8b_10b_x10000;
234 		if (dc_link_should_enable_fec(link)) {
235 			total_data_bw_efficiency_x10000 /= 100;
236 			total_data_bw_efficiency_x10000 *= DATA_EFFICIENCY_8b_10b_FEC_EFFICIENCY_x100;
237 		}
238 		break;
239 	case DP_128b_132b_ENCODING:
240 		/* For 128b/132b encoding:
241 		 * link rate is defined in the unit of 10mbps per lane.
242 		 * total data bandwidth efficiency is always 96.71%.
243 		 */
244 		link_rate_per_lane_kbps = link_setting->link_rate * 10000;
245 		total_data_bw_efficiency_x10000 = DATA_EFFICIENCY_128b_132b_x10000;
246 		break;
247 	default:
248 		break;
249 	}
250 
251 	/* overall effective link bandwidth = link rate per lane * lane count * total data bandwidth efficiency */
252 	return link_rate_per_lane_kbps * link_setting->lane_count / 10000 * total_data_bw_efficiency_x10000;
253 }
254 
255 uint32_t dc_bandwidth_in_kbps_from_timing(
256 	const struct dc_crtc_timing *timing)
257 {
258 	uint32_t bits_per_channel = 0;
259 	uint32_t kbps;
260 
261 #if defined(CONFIG_DRM_AMD_DC_DCN)
262 	if (timing->flags.DSC)
263 		return dc_dsc_stream_bandwidth_in_kbps(timing,
264 				timing->dsc_cfg.bits_per_pixel,
265 				timing->dsc_cfg.num_slices_h,
266 				timing->dsc_cfg.is_dp);
267 #endif /* CONFIG_DRM_AMD_DC_DCN */
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 = dc_link_get_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 = dc_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