blob: ca87fffcfb00ceb9dfeea8020123b3c038b2866f [file] [log] [blame]
Tim Wawrzynczak5473d292023-02-06 16:46:33 -07001--
2-- Copyright (C) 2022 Google, LLC
3--
4-- This program is free software; you can redistribute it and/or modify
5-- it under the terms of the GNU General Public License as published by
6-- the Free Software Foundation; either version 2 of the License, or
7-- (at your option) any later version.
8--
9-- This program is distributed in the hope that it will be useful,
10-- but WITHOUT ANY WARRANTY; without even the implied warranty of
11-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12-- GNU General Public License for more details.
13--
14
Tim Wawrzynczak5473d292023-02-06 16:46:33 -070015with HW.GFX.DP_Info;
16with HW.GFX.GMA.PCode;
17
18with HW.Debug;
19with GNAT.Source_Info;
20
21use type HW.Word64;
22
23package body HW.GFX.GMA.Connectors.TC is
24
25 function HIP_INDEX_REG (P : USBC_Port) return Registers.Registers_Index
26 is
27 (if P <= DDI_TC4
28 then Registers.HIP_INDEX_REG0
29 else Registers.HIP_INDEX_REG1);
30
Nico Huber80b25df2024-08-28 00:03:29 +020031 function HIP_INDEX_VAL (P : USBC_Port; Val : Word32) return Word32
32 is
Tim Wawrzynczak5473d292023-02-06 16:46:33 -070033 (Val * 2 ** (8 * ((GPU_Port'Pos (P) - GPU_Port'Pos (DDI_TC1)) mod 4)));
34
Tim Wawrzynczak5473d292023-02-06 16:46:33 -070035 DKL_DP_MODE : constant Port_Regs_Array :=
36 (DDI_TC1 => Registers.DKL_DP_MODE_1,
37 DDI_TC2 => Registers.DKL_DP_MODE_2,
38 DDI_TC3 => Registers.DKL_DP_MODE_3,
39 DDI_TC4 => Registers.DKL_DP_MODE_4,
40 DDI_TC5 => Registers.DKL_DP_MODE_5,
41 DDI_TC6 => Registers.DKL_DP_MODE_6);
42
Nico Huber80b25df2024-08-28 00:03:29 +020043 DKL_PCS_DW5 : constant Port_Regs_Array :=
44 (DDI_TC1 => Registers.DKL_PCS_DW5_1,
45 DDI_TC2 => Registers.DKL_PCS_DW5_2,
46 DDI_TC3 => Registers.DKL_PCS_DW5_3,
47 DDI_TC4 => Registers.DKL_PCS_DW5_4,
48 others => Registers.Invalid_Register);
49
50 function DP_PIN_ASSIGNMENT_SHIFT (P : USBC_Port) return Natural
51 is
Tim Wawrzynczak5473d292023-02-06 16:46:33 -070052 (case P is
53 when DDI_TC1 => 0,
54 when DDI_TC2 => 4,
55 when DDI_TC3 => 8,
56 when DDI_TC4 => 12,
57 when DDI_TC5 => 16,
58 when DDI_TC6 => 20);
59
60 DP_PIN_ASSIGNMENT_MASK : constant := 16#f#;
61
62 TGL_PCODE_TCCOLD : constant := 16#26#;
63 TCCOLD_BLOCK_REQ : constant := 16#00#;
64 TCCOLD_UNBLOCK_REQ : constant := 16#01#;
65 TCCOLD_BLOCK_RESULT_FAIL : constant := 16#01#;
66
Tim Wawrzynczak5473d292023-02-06 16:46:33 -070067 type Buffer_Trans is record
68 Vswing_Control : Word32;
69 Preshoot_Control : Word32;
70 Deemphasis_Control : Word32;
71 end record;
72
Nico Huberac2a1412026-07-02 10:41:59 +020073 type Buffer_Trans_Range is new Natural range 0 .. 9;
Tim Wawrzynczak5473d292023-02-06 16:46:33 -070074 type Buffer_Trans_Array is array (Buffer_Trans_Range) of Buffer_Trans;
75 TGL_Buffer_Trans_DP_HBR2 : constant Buffer_Trans_Array :=
76 ((16#7#, 16#0#, 16#00#),
77 (16#5#, 16#0#, 16#05#),
78 (16#2#, 16#0#, 16#0B#),
79 (16#0#, 16#0#, 16#19#),
80 (16#5#, 16#0#, 16#00#),
81 (16#2#, 16#0#, 16#08#),
82 (16#0#, 16#0#, 16#14#),
83 (16#2#, 16#0#, 16#00#),
84 (16#0#, 16#0#, 16#0B#),
85 (16#0#, 16#0#, 16#00#));
86 TGL_Buffer_Trans_DP_HBR : constant Buffer_Trans_Array :=
87 ((16#7#, 16#0#, 16#00#),
88 (16#5#, 16#0#, 16#05#),
89 (16#2#, 16#0#, 16#0B#),
90 (16#0#, 16#0#, 16#18#),
91 (16#5#, 16#0#, 16#00#),
92 (16#2#, 16#0#, 16#08#),
93 (16#0#, 16#0#, 16#14#),
94 (16#2#, 16#0#, 16#00#),
95 (16#0#, 16#0#, 16#0B#),
96 (16#0#, 16#0#, 16#00#));
97 Buffer_Trans_HDMI : constant Buffer_Trans_Array :=
98 ((16#7#, 16#0#, 16#0#),
99 (16#6#, 16#0#, 16#0#),
100 (16#4#, 16#0#, 16#0#),
101 (16#2#, 16#0#, 16#0#),
102 (16#0#, 16#0#, 16#0#),
103 (16#0#, 16#0#, 16#5#),
104 (16#0#, 16#0#, 16#6#),
105 (16#0#, 16#0#, 16#7#),
106 (16#0#, 16#0#, 16#8#),
107 (16#0#, 16#0#, 16#A#));
108 ADL_Buffer_Trans_DP_HBR2 : constant Buffer_Trans_Array :=
109 ((16#7#, 16#0#, 16#00#),
110 (16#5#, 16#0#, 16#04#),
111 (16#2#, 16#0#, 16#0a#),
112 (16#0#, 16#0#, 16#18#),
113 (16#5#, 16#0#, 16#00#),
114 (16#2#, 16#0#, 16#06#),
115 (16#0#, 16#0#, 16#14#),
116 (16#2#, 16#0#, 16#00#),
117 (16#0#, 16#0#, 16#09#),
118 (16#0#, 16#0#, 16#00#));
119 ADL_Buffer_Trans_DP_HBR : constant Buffer_Trans_Array :=
120 ((16#7#, 16#0#, 16#01#),
121 (16#5#, 16#0#, 16#06#),
122 (16#2#, 16#0#, 16#0b#),
123 (16#0#, 16#0#, 16#17#),
124 (16#5#, 16#0#, 16#00#),
125 (16#2#, 16#0#, 16#08#),
126 (16#0#, 16#0#, 16#14#),
127 (16#2#, 16#0#, 16#00#),
128 (16#0#, 16#0#, 16#0b#),
129 (16#0#, 16#0#, 16#00#));
130
131 type Vswing_Regs_Record is record
132 DKL_TX_PMD_LANE_SUS : Registers.Registers_Index;
133 DKL_TX_DPCNTL0 : Registers.Registers_Index;
134 DKL_TX_DPCNTL1 : Registers.Registers_Index;
135 DKL_TX_DPCNTL2 : Registers.Registers_Index;
136 end record;
137
138 Vswing_Regs : constant array (USBC_Port) of Vswing_Regs_Record :=
139 (DDI_TC1 =>
140 (Registers.DKL_TX_PMD_LANE_SUS_1,
141 Registers.DKL_TX_DPCNTL0_1,
142 Registers.DKL_TX_DPCNTL1_1,
143 Registers.DKL_TX_DPCNTL2_1),
144 DDI_TC2 =>
145 (Registers.DKL_TX_PMD_LANE_SUS_2,
146 Registers.DKL_TX_DPCNTL0_2,
147 Registers.DKL_TX_DPCNTL1_2,
148 Registers.DKL_TX_DPCNTL2_2),
149 DDI_TC3 =>
150 (Registers.DKL_TX_PMD_LANE_SUS_3,
151 Registers.DKL_TX_DPCNTL0_3,
152 Registers.DKL_TX_DPCNTL1_3,
153 Registers.DKL_TX_DPCNTL2_3),
154 DDI_TC4 =>
155 (Registers.DKL_TX_PMD_LANE_SUS_4,
156 Registers.DKL_TX_DPCNTL0_4,
157 Registers.DKL_TX_DPCNTL1_4,
158 Registers.DKL_TX_DPCNTL2_4),
159 DDI_TC5 =>
160 (Registers.DKL_TX_PMD_LANE_SUS_5,
161 Registers.DKL_TX_DPCNTL0_5,
162 Registers.DKL_TX_DPCNTL1_5,
163 Registers.DKL_TX_DPCNTL2_5),
164 DDI_TC6 =>
165 (Registers.DKL_TX_PMD_LANE_SUS_6,
166 Registers.DKL_TX_DPCNTL0_6,
167 Registers.DKL_TX_DPCNTL1_6,
168 Registers.DKL_TX_DPCNTL2_6));
169
170 procedure Set_HIP_For_Port (P : USBC_Port; N : Natural) is
171 begin
172 Registers.Write (HIP_INDEX_REG (P), HIP_INDEX_VAL (P, Word32 (N)));
173 end Set_HIP_For_Port;
174
Nico Huberac2a1412026-07-02 10:41:59 +0200175 subtype Pin_Assignment_Type is Natural range 0 .. 6;
Tim Wawrzynczak5473d292023-02-06 16:46:33 -0700176 procedure Get_Pin_Assignment
177 (P : in USBC_Port;
178 Assignment : out Pin_Assignment_Type)
179 is
180 Tmp : Word32;
181 A : Word32;
182 begin
183 Registers.Read (Fia_Regs (P).PORT_TX_DFLEXPA1, Tmp);
184 A := Shift_Right (Tmp, DP_PIN_ASSIGNMENT_SHIFT (P));
185 A := A and DP_PIN_ASSIGNMENT_MASK;
186
Nico Huberac2a1412026-07-02 10:41:59 +0200187 if Natural (A) in Pin_Assignment_Type then
Tim Wawrzynczak5473d292023-02-06 16:46:33 -0700188 Assignment := Pin_Assignment_Type (A);
189 else
190 Assignment := Pin_Assignment_Type'First;
191 end if;
192 end Get_Pin_Assignment;
193
194 ---------------------------------------------------------------------
195
196 procedure Program_DP_Mode (P : USBC_Port; Lane_Count : Natural)
197 is
198 MG_DP_MODE_CFG_DP_X1_MODE : constant := 1 * 2 ** 6;
199 MG_DP_MODE_CFG_DP_X2_MODE : constant := 1 * 2 ** 7;
200 DP_X_MODE_MASK : constant Word32 :=
201 MG_DP_MODE_CFG_DP_X1_MODE or MG_DP_MODE_CFG_DP_X2_MODE;
202 Assignment : Pin_Assignment_Type;
203 Ln0, Ln1 : Word32;
204 begin
205 Set_HIP_For_Port (P, 0);
206 Registers.Read (DKL_DP_MODE (P), Ln0);
207 Set_HIP_For_Port (P, 1);
208 Registers.Read (DKL_DP_MODE (P), Ln1);
209
210 Ln0 := Ln0 and not DP_X_MODE_MASK;
211 Ln1 := Ln1 and not DP_X_MODE_MASK;
212
213 Get_Pin_Assignment (P, Assignment);
214 case Assignment is
215 when 0 =>
216 if Lane_Count = 1 then
217 Ln1 := Ln1 or MG_DP_MODE_CFG_DP_X1_MODE;
218 else
219 Ln0 := Ln0 or MG_DP_MODE_CFG_DP_X2_MODE;
220 Ln1 := Ln1 or MG_DP_MODE_CFG_DP_X2_MODE;
221 end if;
222 when 1 =>
223 if Lane_Count = 4 then
224 Ln0 := Ln0 or MG_DP_MODE_CFG_DP_X2_MODE;
225 Ln1 := Ln1 or MG_DP_MODE_CFG_DP_X2_MODE;
226 end if;
227 when 2 =>
228 if Lane_Count = 2 then
229 Ln0 := Ln0 or MG_DP_MODE_CFG_DP_X2_MODE;
230 Ln1 := Ln1 or MG_DP_MODE_CFG_DP_X2_MODE;
231 end if;
232 when 3 | 4 | 5 | 6 =>
233 if Lane_Count = 1 then
234 Ln0 := Ln0 or MG_DP_MODE_CFG_DP_X1_MODE;
235 Ln1 := Ln1 or MG_DP_MODE_CFG_DP_X1_MODE;
236 else
237 Ln0 := Ln0 or MG_DP_MODE_CFG_DP_X2_MODE;
238 Ln1 := Ln1 or MG_DP_MODE_CFG_DP_X2_MODE;
239 end if;
240 end case;
241
242 Set_HIP_For_Port (P, 0);
243 Registers.Unset_And_Set_Mask (DKL_DP_MODE (P), DP_X_MODE_MASK, Ln0);
244 Set_HIP_For_Port (P, 1);
245 Registers.Unset_And_Set_Mask (DKL_DP_MODE (P), DP_X_MODE_MASK, Ln1);
246 end Program_DP_Mode;
247
248 ---------------------------------------------------------------------
249
250 procedure TC_Cold_Request
251 (Request : in TC_Cold_Request_Type;
252 Success : out Boolean)
253 is
254 Result : Word64;
255 begin
256 for Try in 1 .. 3 loop
257 PCode.Mailbox_Read
258 (MBox => TGL_PCODE_TCCOLD,
259 Command => (if Request = Block
260 then TCCOLD_BLOCK_REQ
261 else TCCOLD_UNBLOCK_REQ),
262 Wait_Ready => True,
263 Reply => Result,
264 Success => Success);
265
266 if Success then
267 Success := (Result and TCCOLD_BLOCK_RESULT_FAIL) = 0;
268 end if;
269
270 exit when Success;
271
272 -- Wait 1 millisecond and try again
273 Time.U_Delay (1_000);
274 end loop;
275 end TC_Cold_Request;
276
277 ---------------------------------------------------------------------
278
Nico Huberc74eafd2024-07-23 12:38:02 +0200279 procedure Set_Lane_Count (Port : USBC_Port; Lanes : DP_Lane_Count) is
280 begin
281 Registers.Unset_And_Set_Mask
282 (Register => Fia_Regs (Port).PORT_TX_DFLEXDPMLE1,
283 Mask_Unset => DFLEXDPMLE1_DPMLETC_MASK (Port),
284 Mask_Set =>
285 (case Lanes is
286 -- ML0 is not lane-reversed, ML3 is reverse
287 when DP_Lane_Count_1 => DFLEXDPMLE1_DPMLETC_ML0 (Port),
288 -- ML1_0 is not reversed, ML3_2 is reverse
289 when DP_Lane_Count_2 => DFLEXDPMLE1_DPMLETC_ML1_0 (Port),
290 -- symmetric
291 when DP_Lane_Count_4 => DFLEXDPMLE1_DPMLETC_ML3_0 (Port)));
292 end Set_Lane_Count;
293
294 procedure Get_Lane_Assignment_Count
295 (Port : in USBC_Port;
296 Lanes : out DP_Lane_Count)
Tim Wawrzynczak5473d292023-02-06 16:46:33 -0700297 is
Nico Huberc74eafd2024-07-23 12:38:02 +0200298 Lane_Mask : Word32;
299 Tmp : Word32;
Tim Wawrzynczak5473d292023-02-06 16:46:33 -0700300 begin
Nico Huberc74eafd2024-07-23 12:38:02 +0200301 Registers.Read (Fia_Regs (Port).PORT_TX_DFLEXDPSP, Tmp);
302 Lane_Mask := Shift_Right (Tmp and DP_LANE_ASSIGNMENT_MASK (Port),
303 DP_LANE_ASSIGNMENT_SHIFT (Port));
304 Lanes :=
305 (case Lane_Mask is
306 when 16#1# | 16#2# | 16#4# | 16#8# => DP_Lane_Count_1,
307 when 16#3# | 16#c# => DP_Lane_Count_2,
308 when 16#f# => DP_Lane_Count_4,
309 when others => DP_Lane_Count_1);
310 end Get_Lane_Assignment_Count;
Tim Wawrzynczak5473d292023-02-06 16:46:33 -0700311
312 ---------------------------------------------------------------------
313
314 procedure Set_Vswing_And_Deemphasis
Nico Huber80b25df2024-08-28 00:03:29 +0200315 (Port : USBC_Port;
316 Buf_Trans : Buffer_Trans;
317 HDMI : Boolean := False)
Tim Wawrzynczak5473d292023-02-06 16:46:33 -0700318 is
319 -- Preshoot Coeff, Deemphasis Coeff, VSwing Control,
320 DPcnt_Mask : constant Word32 := 16#3_ff07#;
321 DPcnt_Val : constant Word32 :=
322 Buf_Trans.Vswing_Control or
323 Shift_Left (Buf_Trans.Deemphasis_Control, 8) or
324 Shift_Left (Buf_Trans.Preshoot_Control, 13);
325 DKL_TX_DP20BITMODE : constant := 1 * 2 ** 2;
Nico Huber80b25df2024-08-28 00:03:29 +0200326
327 function DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1 (N : Word32) return Word32
328 is
329 (Shift_Left (N and 16#3#, 3));
330
331 function DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2 (N : Word32) return Word32
332 is
333 (Shift_Left (N and 16#3#, 5));
334
335 DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK : constant := 16#18#;
336 DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK : constant := 16#60#;
Tim Wawrzynczak5473d292023-02-06 16:46:33 -0700337 begin
338 for Lane in 0 .. 1 loop
339 Set_HIP_For_Port (Port, Lane);
340 Registers.Write (Vswing_Regs (Port).DKL_TX_PMD_LANE_SUS, 0);
341 Registers.Unset_And_Set_Mask
342 (Vswing_Regs (Port).DKL_TX_DPCNTL0, DPcnt_Mask, DPcnt_Val);
343 Registers.Unset_And_Set_Mask
344 (Vswing_Regs (Port).DKL_TX_DPCNTL1, DPcnt_Mask, DPcnt_Val);
345 Registers.Unset_Mask
346 (Vswing_Regs (Port).DKL_TX_DPCNTL2, DKL_TX_DP20BITMODE);
Nico Huber80b25df2024-08-28 00:03:29 +0200347
348 if Config.Need_TC_Loadgen_Select then
349 declare
350 Val : Word32;
351 begin
352 if HDMI then
353 if Lane = 0 then
354 Val := DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1 (0) or
355 DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2 (2);
356 else
357 Val := DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1 (3) or
358 DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2 (3);
359 end if;
360 else
361 Val := DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1 (0) or
362 DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2 (0);
363 end if;
364
365 Registers.Unset_And_Set_Mask
366 (Register => Vswing_Regs (Port).DKL_TX_DPCNTL2,
367 Mask_Unset => DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK or
368 DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK,
369 Mask_Set => Val);
370 end;
371 end if;
Tim Wawrzynczak5473d292023-02-06 16:46:33 -0700372 end loop;
373
374 end Set_Vswing_And_Deemphasis;
375
376 ---------------------------------------------------------------------
377
378 procedure Set_Signal_Levels
379 (Port : USBC_Port;
380 Link : DP_Link;
381 Train_Set : DP_Info.Train_Set)
382 is
Nico Huber80b25df2024-08-28 00:03:29 +0200383 DKL_PCS_DW5_CORE_SOFTRESET : constant := 1 * 2 ** 11;
Tim Wawrzynczak5473d292023-02-06 16:46:33 -0700384 function To_Buf_Trans_Index
385 (Set : DP_Info.Train_Set) return Buffer_Trans_Range
386 is
387 begin
388 case Set.Voltage_Swing is
389 when DP_Info.VS_Level_0 =>
390 case Set.Pre_Emph is
391 when DP_Info.Emph_Level_0 => return 0;
392 when DP_Info.Emph_Level_1 => return 1;
393 when DP_Info.Emph_Level_2 => return 2;
394 when DP_Info.Emph_Level_3 => return 3;
395 end case;
396 when DP_Info.VS_Level_1 =>
397 case Set.Pre_Emph is
398 when DP_Info.Emph_Level_0 => return 4;
399 when DP_Info.Emph_Level_1 => return 5;
400 when DP_Info.Emph_Level_2 => return 6;
401 when others => return 0;
402 end case;
403 when DP_Info.VS_Level_2 =>
404 case Set.Pre_Emph is
405 when DP_Info.Emph_Level_0 => return 7;
406 when DP_Info.Emph_Level_1 => return 8;
407 when others => return 0;
408 end case;
409 when DP_Info.VS_Level_3 =>
410 case Set.Pre_Emph is
411 when DP_Info.Emph_Level_0 => return 9;
412 when others => return 0;
413 end case;
414 end case;
415 end To_Buf_Trans_Index;
416
417 Was_Enabled : Boolean;
418 Buf_Trans : Buffer_Trans;
419 Entry_Index : constant Buffer_Trans_Range :=
420 To_Buf_Trans_Index (Train_Set);
421 begin
422 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
423
424 Registers.Is_Set_Mask
425 (Register => DDI_BUF_CTL (Port),
426 Mask => DDI_BUF_CTL_BUFFER_ENABLE,
427 Result => Was_Enabled);
428
429 if Config.Has_TGL_Buffer_Translations then
430 if Link.Bandwidth > DP_Bandwidth_2_7 then
431 Buf_Trans := TGL_Buffer_Trans_DP_HBR2 (Entry_Index);
432 else
433 Buf_Trans := TGL_Buffer_Trans_DP_HBR (Entry_Index);
434 end if;
435 else
436 if Link.Bandwidth > DP_Bandwidth_2_7 then
437 Buf_Trans := ADL_Buffer_Trans_DP_HBR2 (Entry_Index);
438 else
439 Buf_Trans := ADL_Buffer_Trans_DP_HBR (Entry_Index);
440 end if;
441 end if;
442
443 Set_Vswing_And_Deemphasis (Port, Buf_Trans);
444
Nico Huber80b25df2024-08-28 00:03:29 +0200445 -- Wa_1309179469: Taken from i915's adlp_tbt_to_dp_alt_switch_wa()
446 if Config.Need_TBT_DP_Alt_Switch_Wa and then
447 Port in Valid_TC_Port and then
448 not Was_Enabled
449 then
450 for Lane in 0 .. 1 loop
451 Set_HIP_For_Port (Port, Lane);
452 Registers.Unset_Mask
453 (Register => DKL_PCS_DW5 (Port),
454 Mask => DKL_PCS_DW5_CORE_SOFTRESET);
455 end loop;
456 end if;
457
Tim Wawrzynczak5473d292023-02-06 16:46:33 -0700458 Registers.Unset_And_Set_Mask
459 (Register => DDI_BUF_CTL (Port),
460 Mask_Unset => DDI_BUF_CTL_TRANS_SELECT_MASK or
461 DDI_BUF_CTL_PORT_REVERSAL or
462 DDI_BUF_CTL_PORT_WIDTH_MASK,
463 Mask_Set => DDI_BUF_CTL_BUFFER_ENABLE or
Nico Huber80b25df2024-08-28 00:03:29 +0200464 DDI_BUF_CTL_PORT_WIDTH (Link.Lane_Count) or
465 (if Config.Need_TC_PHY_Ownership
466 then DDI_BUF_CTL_TC_PHY_OWNERSHIP else 0));
467
Tim Wawrzynczak5473d292023-02-06 16:46:33 -0700468 Registers.Posting_Read (DDI_BUF_CTL (Port));
469
470 if not Was_Enabled then
471 Registers.Wait_Unset_Mask (DDI_BUF_CTL (Port), DDI_BUF_CTL_IDLE_STATUS);
472 end if;
473 end Set_Signal_Levels;
474
475 procedure Enable_HDMI (Port : USBC_Port)
476 is
477 HDMI_Lane_Count : constant := 4;
478 Buf_Trans : constant Buffer_Trans :=
479 Buffer_Trans_HDMI (Buffer_Trans_HDMI'Last);
480 begin
481 Program_DP_Mode (Port, HDMI_Lane_Count);
Nico Huber80b25df2024-08-28 00:03:29 +0200482 Set_Vswing_And_Deemphasis (Port, Buf_Trans, HDMI => True);
Tim Wawrzynczak5473d292023-02-06 16:46:33 -0700483
484 Registers.Unset_And_Set_Mask
485 (Register => DDI_BUF_CTL (Port),
486 Mask_Unset => DDI_BUF_CTL_TRANS_SELECT_MASK or
487 DDI_BUF_CTL_PORT_REVERSAL or
488 DDI_BUF_CTL_PORT_WIDTH_MASK,
489 Mask_Set => DDI_BUF_CTL_BUFFER_ENABLE);
490
491 Registers.Wait_Unset_Mask
492 (Register => DDI_BUF_CTL (Port),
493 Mask => DDI_BUF_CTL_IDLE_STATUS,
494 TOut_MS => 1);
495 end Enable_HDMI;
496
497end HW.GFX.GMA.Connectors.TC;