1 | /* |
2 | * Copyright 2018 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 | #include "mod_info_packet.h" |
27 | #include "core_types.h" |
28 | #include "dc_types.h" |
29 | #include "mod_shared.h" |
30 | #include "mod_freesync.h" |
31 | #include "dc.h" |
32 | |
33 | enum vsc_packet_revision { |
34 | vsc_packet_undefined = 0, |
35 | //01h = VSC SDP supports only 3D stereo. |
36 | vsc_packet_rev1 = 1, |
37 | //02h = 3D stereo + PSR. |
38 | vsc_packet_rev2 = 2, |
39 | //03h = 3D stereo + PSR2. |
40 | vsc_packet_rev3 = 3, |
41 | //04h = 3D stereo + PSR/PSR2 + Y-coordinate. |
42 | vsc_packet_rev4 = 4, |
43 | //05h = 3D stereo + PSR/PSR2 + Y-coordinate + Pixel Encoding/Colorimetry Format |
44 | vsc_packet_rev5 = 5, |
45 | }; |
46 | |
47 | #define HDMI_INFOFRAME_TYPE_VENDOR 0x81 |
48 | #define HF_VSIF_VERSION 1 |
49 | |
50 | // VTEM Byte Offset |
51 | #define VTEM_PB0 0 |
52 | #define VTEM_PB1 1 |
53 | #define VTEM_PB2 2 |
54 | #define VTEM_PB3 3 |
55 | #define VTEM_PB4 4 |
56 | #define VTEM_PB5 5 |
57 | #define VTEM_PB6 6 |
58 | |
59 | #define VTEM_MD0 7 |
60 | #define VTEM_MD1 8 |
61 | #define VTEM_MD2 9 |
62 | #define VTEM_MD3 10 |
63 | |
64 | |
65 | // VTEM Byte Masks |
66 | //PB0 |
67 | #define MASK_VTEM_PB0__RESERVED0 0x01 |
68 | #define MASK_VTEM_PB0__SYNC 0x02 |
69 | #define MASK_VTEM_PB0__VFR 0x04 |
70 | #define MASK_VTEM_PB0__AFR 0x08 |
71 | #define MASK_VTEM_PB0__DS_TYPE 0x30 |
72 | //0: Periodic pseudo-static EM Data Set |
73 | //1: Periodic dynamic EM Data Set |
74 | //2: Unique EM Data Set |
75 | //3: Reserved |
76 | #define MASK_VTEM_PB0__END 0x40 |
77 | #define MASK_VTEM_PB0__NEW 0x80 |
78 | |
79 | //PB1 |
80 | #define MASK_VTEM_PB1__RESERVED1 0xFF |
81 | |
82 | //PB2 |
83 | #define MASK_VTEM_PB2__ORGANIZATION_ID 0xFF |
84 | //0: This is a Vendor Specific EM Data Set |
85 | //1: This EM Data Set is defined by This Specification (HDMI 2.1 r102.clean) |
86 | //2: This EM Data Set is defined by CTA-861-G |
87 | //3: This EM Data Set is defined by VESA |
88 | //PB3 |
89 | #define MASK_VTEM_PB3__DATA_SET_TAG_MSB 0xFF |
90 | //PB4 |
91 | #define MASK_VTEM_PB4__DATA_SET_TAG_LSB 0xFF |
92 | //PB5 |
93 | #define MASK_VTEM_PB5__DATA_SET_LENGTH_MSB 0xFF |
94 | //PB6 |
95 | #define MASK_VTEM_PB6__DATA_SET_LENGTH_LSB 0xFF |
96 | |
97 | |
98 | |
99 | //PB7-27 (20 bytes): |
100 | //PB7 = MD0 |
101 | #define MASK_VTEM_MD0__VRR_EN 0x01 |
102 | #define MASK_VTEM_MD0__M_CONST 0x02 |
103 | #define MASK_VTEM_MD0__QMS_EN 0x04 |
104 | #define MASK_VTEM_MD0__RESERVED2 0x08 |
105 | #define MASK_VTEM_MD0__FVA_FACTOR_M1 0xF0 |
106 | |
107 | //MD1 |
108 | #define MASK_VTEM_MD1__BASE_VFRONT 0xFF |
109 | |
110 | //MD2 |
111 | #define MASK_VTEM_MD2__BASE_REFRESH_RATE_98 0x03 |
112 | #define MASK_VTEM_MD2__RB 0x04 |
113 | #define MASK_VTEM_MD2__NEXT_TFR 0xF8 |
114 | |
115 | //MD3 |
116 | #define MASK_VTEM_MD3__BASE_REFRESH_RATE_07 0xFF |
117 | |
118 | enum ColorimetryRGBDP { |
119 | ColorimetryRGB_DP_sRGB = 0, |
120 | ColorimetryRGB_DP_AdobeRGB = 3, |
121 | ColorimetryRGB_DP_P3 = 4, |
122 | ColorimetryRGB_DP_CustomColorProfile = 5, |
123 | ColorimetryRGB_DP_ITU_R_BT2020RGB = 6, |
124 | }; |
125 | enum ColorimetryYCCDP { |
126 | ColorimetryYCC_DP_ITU601 = 0, |
127 | ColorimetryYCC_DP_ITU709 = 1, |
128 | ColorimetryYCC_DP_AdobeYCC = 5, |
129 | ColorimetryYCC_DP_ITU2020YCC = 6, |
130 | ColorimetryYCC_DP_ITU2020YCbCr = 7, |
131 | }; |
132 | |
133 | void mod_build_vsc_infopacket(const struct dc_stream_state *stream, |
134 | struct dc_info_packet *info_packet, |
135 | enum dc_color_space cs, |
136 | enum color_transfer_func tf) |
137 | { |
138 | unsigned int vsc_packet_revision = vsc_packet_undefined; |
139 | unsigned int i; |
140 | unsigned int pixelEncoding = 0; |
141 | unsigned int colorimetryFormat = 0; |
142 | bool stereo3dSupport = false; |
143 | |
144 | if (stream->timing.timing_3d_format != TIMING_3D_FORMAT_NONE && stream->view_format != VIEW_3D_FORMAT_NONE) { |
145 | vsc_packet_revision = vsc_packet_rev1; |
146 | stereo3dSupport = true; |
147 | } |
148 | |
149 | /* VSC packet set to 4 for PSR-SU, or 2 for PSR1 */ |
150 | if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) |
151 | vsc_packet_revision = vsc_packet_rev4; |
152 | else if (stream->link->replay_settings.config.replay_supported) |
153 | vsc_packet_revision = vsc_packet_rev4; |
154 | else if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_1) |
155 | vsc_packet_revision = vsc_packet_rev2; |
156 | |
157 | /* Update to revision 5 for extended colorimetry support */ |
158 | if (stream->use_vsc_sdp_for_colorimetry) |
159 | vsc_packet_revision = vsc_packet_rev5; |
160 | |
161 | /* VSC packet not needed based on the features |
162 | * supported by this DP display |
163 | */ |
164 | if (vsc_packet_revision == vsc_packet_undefined) |
165 | return; |
166 | |
167 | if (vsc_packet_revision == vsc_packet_rev4) { |
168 | /* Secondary-data Packet ID = 0*/ |
169 | info_packet->hb0 = 0x00; |
170 | /* 07h - Packet Type Value indicating Video |
171 | * Stream Configuration packet |
172 | */ |
173 | info_packet->hb1 = 0x07; |
174 | /* 04h = VSC SDP supporting 3D stereo + PSR/PSR2 + Y-coordinate |
175 | * (applies to eDP v1.4 or higher). |
176 | */ |
177 | info_packet->hb2 = 0x04; |
178 | /* 0Eh = VSC SDP supporting 3D stereo + PSR2 |
179 | * (HB2 = 04h), with Y-coordinate of first scan |
180 | * line of the SU region |
181 | */ |
182 | info_packet->hb3 = 0x0E; |
183 | |
184 | for (i = 0; i < 28; i++) |
185 | info_packet->sb[i] = 0; |
186 | |
187 | info_packet->valid = true; |
188 | } |
189 | |
190 | if (vsc_packet_revision == vsc_packet_rev2) { |
191 | /* Secondary-data Packet ID = 0*/ |
192 | info_packet->hb0 = 0x00; |
193 | /* 07h - Packet Type Value indicating Video |
194 | * Stream Configuration packet |
195 | */ |
196 | info_packet->hb1 = 0x07; |
197 | /* 02h = VSC SDP supporting 3D stereo and PSR |
198 | * (applies to eDP v1.3 or higher). |
199 | */ |
200 | info_packet->hb2 = 0x02; |
201 | /* 08h = VSC packet supporting 3D stereo + PSR |
202 | * (HB2 = 02h). |
203 | */ |
204 | info_packet->hb3 = 0x08; |
205 | |
206 | for (i = 0; i < 28; i++) |
207 | info_packet->sb[i] = 0; |
208 | |
209 | info_packet->valid = true; |
210 | } |
211 | |
212 | if (vsc_packet_revision == vsc_packet_rev1) { |
213 | |
214 | info_packet->hb0 = 0x00; // Secondary-data Packet ID = 0 |
215 | info_packet->hb1 = 0x07; // 07h = Packet Type Value indicating Video Stream Configuration packet |
216 | info_packet->hb2 = 0x01; // 01h = Revision number. VSC SDP supporting 3D stereo only |
217 | info_packet->hb3 = 0x01; // 01h = VSC SDP supporting 3D stereo only (HB2 = 01h). |
218 | |
219 | info_packet->valid = true; |
220 | } |
221 | |
222 | if (stereo3dSupport) { |
223 | /* ==============================================================================================================| |
224 | * A. STEREO 3D |
225 | * ==============================================================================================================| |
226 | * VSC Payload (1 byte) From DP1.2 spec |
227 | * |
228 | * Bits 3:0 (Stereo Interface Method Code) | Bits 7:4 (Stereo Interface Method Specific Parameter) |
229 | * ----------------------------------------------------------------------------------------------------- |
230 | * 0 = Non Stereo Video | Must be set to 0x0 |
231 | * ----------------------------------------------------------------------------------------------------- |
232 | * 1 = Frame/Field Sequential | 0x0: L + R view indication based on MISC1 bit 2:1 |
233 | * | 0x1: Right when Stereo Signal = 1 |
234 | * | 0x2: Left when Stereo Signal = 1 |
235 | * | (others reserved) |
236 | * ----------------------------------------------------------------------------------------------------- |
237 | * 2 = Stacked Frame | 0x0: Left view is on top and right view on bottom |
238 | * | (others reserved) |
239 | * ----------------------------------------------------------------------------------------------------- |
240 | * 3 = Pixel Interleaved | 0x0: horiz interleaved, right view pixels on even lines |
241 | * | 0x1: horiz interleaved, right view pixels on odd lines |
242 | * | 0x2: checker board, start with left view pixel |
243 | * | 0x3: vertical interleaved, start with left view pixels |
244 | * | 0x4: vertical interleaved, start with right view pixels |
245 | * | (others reserved) |
246 | * ----------------------------------------------------------------------------------------------------- |
247 | * 4 = Side-by-side | 0x0: left half represents left eye view |
248 | * | 0x1: left half represents right eye view |
249 | */ |
250 | switch (stream->timing.timing_3d_format) { |
251 | case TIMING_3D_FORMAT_HW_FRAME_PACKING: |
252 | case TIMING_3D_FORMAT_SW_FRAME_PACKING: |
253 | case TIMING_3D_FORMAT_TOP_AND_BOTTOM: |
254 | case TIMING_3D_FORMAT_TB_SW_PACKED: |
255 | info_packet->sb[0] = 0x02; // Stacked Frame, Left view is on top and right view on bottom. |
256 | break; |
257 | case TIMING_3D_FORMAT_DP_HDMI_INBAND_FA: |
258 | case TIMING_3D_FORMAT_INBAND_FA: |
259 | info_packet->sb[0] = 0x01; // Frame/Field Sequential, L + R view indication based on MISC1 bit 2:1 |
260 | break; |
261 | case TIMING_3D_FORMAT_SIDE_BY_SIDE: |
262 | case TIMING_3D_FORMAT_SBS_SW_PACKED: |
263 | info_packet->sb[0] = 0x04; // Side-by-side |
264 | break; |
265 | default: |
266 | info_packet->sb[0] = 0x00; // No Stereo Video, Shall be cleared to 0x0. |
267 | break; |
268 | } |
269 | |
270 | } |
271 | |
272 | /* 05h = VSC SDP supporting 3D stereo, PSR2, and Pixel Encoding/Colorimetry Format indication. |
273 | * Added in DP1.3, a DP Source device is allowed to indicate the pixel encoding/colorimetry |
274 | * format to the DP Sink device with VSC SDP only when the DP Sink device supports it |
275 | * (i.e., VSC_SDP_EXTENSION_FOR_COLORIMETRY_SUPPORTED bit in the DPRX_FEATURE_ENUMERATION_LIST |
276 | * register (DPCD Address 02210h, bit 3) is set to 1). |
277 | * (Requires VSC_SDP_EXTENSION_FOR_COLORIMETRY_SUPPORTED bit set to 1 in DPCD 02210h. This |
278 | * DPCD register is exposed in the new Extended Receiver Capability field for DPCD Rev. 1.4 |
279 | * (and higher). When MISC1. bit 6. is Set to 1, a Source device uses a VSC SDP to indicate |
280 | * the Pixel Encoding/Colorimetry Format and that a Sink device must ignore MISC1, bit 7, and |
281 | * MISC0, bits 7:1 (MISC1, bit 7. and MISC0, bits 7:1 become "don't care").) |
282 | */ |
283 | if (vsc_packet_revision == vsc_packet_rev5) { |
284 | /* Secondary-data Packet ID = 0 */ |
285 | info_packet->hb0 = 0x00; |
286 | /* 07h - Packet Type Value indicating Video Stream Configuration packet */ |
287 | info_packet->hb1 = 0x07; |
288 | /* 05h = VSC SDP supporting 3D stereo, PSR2, and Pixel Encoding/Colorimetry Format indication. */ |
289 | info_packet->hb2 = 0x05; |
290 | /* 13h = VSC SDP supporting 3D stereo, + PSR2, + Pixel Encoding/Colorimetry Format indication (HB2 = 05h). */ |
291 | info_packet->hb3 = 0x13; |
292 | |
293 | info_packet->valid = true; |
294 | |
295 | /* Set VSC SDP fields for pixel encoding and colorimetry format from DP 1.3 specs |
296 | * Data Bytes DB 18~16 |
297 | * Bits 3:0 (Colorimetry Format) | Bits 7:4 (Pixel Encoding) |
298 | * ---------------------------------------------------------------------------------------------------- |
299 | * 0x0 = sRGB | 0 = RGB |
300 | * 0x1 = RGB Wide Gamut Fixed Point |
301 | * 0x2 = RGB Wide Gamut Floating Point |
302 | * 0x3 = AdobeRGB |
303 | * 0x4 = DCI-P3 |
304 | * 0x5 = CustomColorProfile |
305 | * (others reserved) |
306 | * ---------------------------------------------------------------------------------------------------- |
307 | * 0x0 = ITU-R BT.601 | 1 = YCbCr444 |
308 | * 0x1 = ITU-R BT.709 |
309 | * 0x2 = xvYCC601 |
310 | * 0x3 = xvYCC709 |
311 | * 0x4 = sYCC601 |
312 | * 0x5 = AdobeYCC601 |
313 | * 0x6 = ITU-R BT.2020 Y'cC'bcC'rc |
314 | * 0x7 = ITU-R BT.2020 Y'C'bC'r |
315 | * (others reserved) |
316 | * ---------------------------------------------------------------------------------------------------- |
317 | * 0x0 = ITU-R BT.601 | 2 = YCbCr422 |
318 | * 0x1 = ITU-R BT.709 |
319 | * 0x2 = xvYCC601 |
320 | * 0x3 = xvYCC709 |
321 | * 0x4 = sYCC601 |
322 | * 0x5 = AdobeYCC601 |
323 | * 0x6 = ITU-R BT.2020 Y'cC'bcC'rc |
324 | * 0x7 = ITU-R BT.2020 Y'C'bC'r |
325 | * (others reserved) |
326 | * ---------------------------------------------------------------------------------------------------- |
327 | * 0x0 = ITU-R BT.601 | 3 = YCbCr420 |
328 | * 0x1 = ITU-R BT.709 |
329 | * 0x2 = xvYCC601 |
330 | * 0x3 = xvYCC709 |
331 | * 0x4 = sYCC601 |
332 | * 0x5 = AdobeYCC601 |
333 | * 0x6 = ITU-R BT.2020 Y'cC'bcC'rc |
334 | * 0x7 = ITU-R BT.2020 Y'C'bC'r |
335 | * (others reserved) |
336 | * ---------------------------------------------------------------------------------------------------- |
337 | * 0x0 =DICOM Part14 Grayscale | 4 = Yonly |
338 | * Display Function |
339 | * (others reserved) |
340 | */ |
341 | |
342 | /* Set Pixel Encoding */ |
343 | switch (stream->timing.pixel_encoding) { |
344 | case PIXEL_ENCODING_RGB: |
345 | pixelEncoding = 0x0; /* RGB = 0h */ |
346 | break; |
347 | case PIXEL_ENCODING_YCBCR444: |
348 | pixelEncoding = 0x1; /* YCbCr444 = 1h */ |
349 | break; |
350 | case PIXEL_ENCODING_YCBCR422: |
351 | pixelEncoding = 0x2; /* YCbCr422 = 2h */ |
352 | break; |
353 | case PIXEL_ENCODING_YCBCR420: |
354 | pixelEncoding = 0x3; /* YCbCr420 = 3h */ |
355 | break; |
356 | default: |
357 | pixelEncoding = 0x0; /* default RGB = 0h */ |
358 | break; |
359 | } |
360 | |
361 | /* Set Colorimetry format based on pixel encoding */ |
362 | switch (stream->timing.pixel_encoding) { |
363 | case PIXEL_ENCODING_RGB: |
364 | if ((cs == COLOR_SPACE_SRGB) || |
365 | (cs == COLOR_SPACE_SRGB_LIMITED)) |
366 | colorimetryFormat = ColorimetryRGB_DP_sRGB; |
367 | else if (cs == COLOR_SPACE_ADOBERGB) |
368 | colorimetryFormat = ColorimetryRGB_DP_AdobeRGB; |
369 | else if ((cs == COLOR_SPACE_2020_RGB_FULLRANGE) || |
370 | (cs == COLOR_SPACE_2020_RGB_LIMITEDRANGE)) |
371 | colorimetryFormat = ColorimetryRGB_DP_ITU_R_BT2020RGB; |
372 | break; |
373 | |
374 | case PIXEL_ENCODING_YCBCR444: |
375 | case PIXEL_ENCODING_YCBCR422: |
376 | case PIXEL_ENCODING_YCBCR420: |
377 | /* Note: xvYCC probably not supported correctly here on DP since colorspace translation |
378 | * loses distinction between BT601 vs xvYCC601 in translation |
379 | */ |
380 | if (cs == COLOR_SPACE_YCBCR601) |
381 | colorimetryFormat = ColorimetryYCC_DP_ITU601; |
382 | else if (cs == COLOR_SPACE_YCBCR709) |
383 | colorimetryFormat = ColorimetryYCC_DP_ITU709; |
384 | else if (cs == COLOR_SPACE_ADOBERGB) |
385 | colorimetryFormat = ColorimetryYCC_DP_AdobeYCC; |
386 | else if (cs == COLOR_SPACE_2020_YCBCR) |
387 | colorimetryFormat = ColorimetryYCC_DP_ITU2020YCbCr; |
388 | |
389 | if (cs == COLOR_SPACE_2020_YCBCR && tf == TRANSFER_FUNC_GAMMA_22) |
390 | colorimetryFormat = ColorimetryYCC_DP_ITU709; |
391 | break; |
392 | |
393 | default: |
394 | colorimetryFormat = ColorimetryRGB_DP_sRGB; |
395 | break; |
396 | } |
397 | |
398 | info_packet->sb[16] = (pixelEncoding << 4) | colorimetryFormat; |
399 | |
400 | /* Set color depth */ |
401 | switch (stream->timing.display_color_depth) { |
402 | case COLOR_DEPTH_666: |
403 | /* NOTE: This is actually not valid for YCbCr pixel encoding to have 6 bpc |
404 | * as of DP1.4 spec, but value of 0 probably reserved here for potential future use. |
405 | */ |
406 | info_packet->sb[17] = 0; |
407 | break; |
408 | case COLOR_DEPTH_888: |
409 | info_packet->sb[17] = 1; |
410 | break; |
411 | case COLOR_DEPTH_101010: |
412 | info_packet->sb[17] = 2; |
413 | break; |
414 | case COLOR_DEPTH_121212: |
415 | info_packet->sb[17] = 3; |
416 | break; |
417 | /*case COLOR_DEPTH_141414: -- NO SUCH FORMAT IN DP SPEC */ |
418 | case COLOR_DEPTH_161616: |
419 | info_packet->sb[17] = 4; |
420 | break; |
421 | default: |
422 | info_packet->sb[17] = 0; |
423 | break; |
424 | } |
425 | |
426 | /* all YCbCr are always limited range */ |
427 | if ((cs == COLOR_SPACE_SRGB_LIMITED) || |
428 | (cs == COLOR_SPACE_2020_RGB_LIMITEDRANGE) || |
429 | (pixelEncoding != 0x0)) { |
430 | info_packet->sb[17] |= 0x80; /* DB17 bit 7 set to 1 for CEA timing. */ |
431 | } |
432 | |
433 | /* Content Type (Bits 2:0) |
434 | * 0 = Not defined. |
435 | * 1 = Graphics. |
436 | * 2 = Photo. |
437 | * 3 = Video. |
438 | * 4 = Game. |
439 | */ |
440 | info_packet->sb[18] = 0; |
441 | } |
442 | } |
443 | |
444 | /** |
445 | * mod_build_hf_vsif_infopacket - Prepare HDMI Vendor Specific info frame. |
446 | * Follows HDMI Spec to build up Vendor Specific info frame |
447 | * |
448 | * @stream: contains data we may need to construct VSIF (i.e. timing_3d_format, etc.) |
449 | * @info_packet: output structure where to store VSIF |
450 | */ |
451 | void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream, |
452 | struct dc_info_packet *info_packet) |
453 | { |
454 | unsigned int length = 5; |
455 | bool hdmi_vic_mode = false; |
456 | uint8_t checksum = 0; |
457 | uint32_t i = 0; |
458 | enum dc_timing_3d_format format; |
459 | |
460 | info_packet->valid = false; |
461 | format = stream->timing.timing_3d_format; |
462 | if (stream->view_format == VIEW_3D_FORMAT_NONE) |
463 | format = TIMING_3D_FORMAT_NONE; |
464 | |
465 | if (stream->timing.hdmi_vic != 0 |
466 | && stream->timing.h_total >= 3840 |
467 | && stream->timing.v_total >= 2160 |
468 | && format == TIMING_3D_FORMAT_NONE) |
469 | hdmi_vic_mode = true; |
470 | |
471 | if ((format == TIMING_3D_FORMAT_NONE) && !hdmi_vic_mode) |
472 | return; |
473 | |
474 | info_packet->sb[1] = 0x03; |
475 | info_packet->sb[2] = 0x0C; |
476 | info_packet->sb[3] = 0x00; |
477 | |
478 | if (format != TIMING_3D_FORMAT_NONE) |
479 | info_packet->sb[4] = (2 << 5); |
480 | |
481 | else if (hdmi_vic_mode) |
482 | info_packet->sb[4] = (1 << 5); |
483 | |
484 | switch (format) { |
485 | case TIMING_3D_FORMAT_HW_FRAME_PACKING: |
486 | case TIMING_3D_FORMAT_SW_FRAME_PACKING: |
487 | info_packet->sb[5] = (0x0 << 4); |
488 | break; |
489 | |
490 | case TIMING_3D_FORMAT_SIDE_BY_SIDE: |
491 | case TIMING_3D_FORMAT_SBS_SW_PACKED: |
492 | info_packet->sb[5] = (0x8 << 4); |
493 | length = 6; |
494 | break; |
495 | |
496 | case TIMING_3D_FORMAT_TOP_AND_BOTTOM: |
497 | case TIMING_3D_FORMAT_TB_SW_PACKED: |
498 | info_packet->sb[5] = (0x6 << 4); |
499 | break; |
500 | |
501 | default: |
502 | break; |
503 | } |
504 | |
505 | if (hdmi_vic_mode) |
506 | info_packet->sb[5] = stream->timing.hdmi_vic; |
507 | |
508 | info_packet->hb0 = HDMI_INFOFRAME_TYPE_VENDOR; |
509 | info_packet->hb1 = 0x01; |
510 | info_packet->hb2 = (uint8_t) (length); |
511 | |
512 | checksum += info_packet->hb0; |
513 | checksum += info_packet->hb1; |
514 | checksum += info_packet->hb2; |
515 | |
516 | for (i = 1; i <= length; i++) |
517 | checksum += info_packet->sb[i]; |
518 | |
519 | info_packet->sb[0] = (uint8_t) (0x100 - checksum); |
520 | |
521 | info_packet->valid = true; |
522 | } |
523 | |
524 | void mod_build_adaptive_sync_infopacket(const struct dc_stream_state *stream, |
525 | enum adaptive_sync_type asType, |
526 | const struct AS_Df_params *param, |
527 | struct dc_info_packet *info_packet) |
528 | { |
529 | info_packet->valid = false; |
530 | |
531 | memset(info_packet, 0, sizeof(struct dc_info_packet)); |
532 | |
533 | switch (asType) { |
534 | case ADAPTIVE_SYNC_TYPE_DP: |
535 | if (stream != NULL) |
536 | mod_build_adaptive_sync_infopacket_v2(stream, param, info_packet); |
537 | break; |
538 | case FREESYNC_TYPE_PCON_IN_WHITELIST: |
539 | mod_build_adaptive_sync_infopacket_v1(info_packet); |
540 | break; |
541 | case ADAPTIVE_SYNC_TYPE_EDP: |
542 | mod_build_adaptive_sync_infopacket_v1(info_packet); |
543 | break; |
544 | case ADAPTIVE_SYNC_TYPE_NONE: |
545 | case FREESYNC_TYPE_PCON_NOT_IN_WHITELIST: |
546 | default: |
547 | break; |
548 | } |
549 | } |
550 | |
551 | void mod_build_adaptive_sync_infopacket_v1(struct dc_info_packet *info_packet) |
552 | { |
553 | info_packet->valid = true; |
554 | // HEADER {HB0, HB1, HB2, HB3} = {00, Type, Version, Length} |
555 | info_packet->hb0 = 0x00; |
556 | info_packet->hb1 = 0x22; |
557 | info_packet->hb2 = AS_SDP_VER_1; |
558 | info_packet->hb3 = 0x00; |
559 | } |
560 | |
561 | void mod_build_adaptive_sync_infopacket_v2(const struct dc_stream_state *stream, |
562 | const struct AS_Df_params *param, |
563 | struct dc_info_packet *info_packet) |
564 | { |
565 | info_packet->valid = true; |
566 | // HEADER {HB0, HB1, HB2, HB3} = {00, Type, Version, Length} |
567 | info_packet->hb0 = 0x00; |
568 | info_packet->hb1 = 0x22; |
569 | info_packet->hb2 = AS_SDP_VER_2; |
570 | info_packet->hb3 = AS_DP_SDP_LENGTH; |
571 | |
572 | //Payload |
573 | info_packet->sb[0] = param->supportMode; //1: AVT; 0: FAVT |
574 | info_packet->sb[1] = (stream->timing.v_total & 0x00FF); |
575 | info_packet->sb[2] = (stream->timing.v_total & 0xFF00) >> 8; |
576 | //info_packet->sb[3] = 0x00; Target RR, not use fot AVT |
577 | info_packet->sb[4] = (param->increase.support << 6 | param->decrease.support << 7); |
578 | info_packet->sb[5] = param->increase.frame_duration_hex; |
579 | info_packet->sb[6] = param->decrease.frame_duration_hex; |
580 | } |
581 | |
582 | |