blob: 057f221f511d24a49c4c97afba79a8738d4cc827 [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
15with HW.GFX.DP_Training;
16with HW.GFX.GMA.Config;
17with HW.GFX.GMA.DP_Aux_Ch;
18with HW.GFX.GMA.Registers;
19
20with HW.Debug;
21with GNAT.Source_Info;
22
23package body HW.GFX.GMA.Connectors.Combo_Phy is
24
25 DDI_BUF_CTL_BUFFER_ENABLE : constant := 1 * 2 ** 31;
26 DDI_BUF_CTL_TRANS_SELECT_MASK : constant := 16#f# * 2 ** 24;
27 DDI_BUF_CTL_PORT_REVERSAL : constant := 1 * 2 ** 16;
28 DDI_BUF_CTL_PORT_WIDTH_MASK : constant := 7 * 2 ** 1;
29 DDI_BUF_CTL_PORT_WIDTH_1_LANE : constant := 0 * 2 ** 1;
30 DDI_BUF_CTL_PORT_WIDTH_2_LANES : constant := 1 * 2 ** 1;
31 DDI_BUF_CTL_PORT_WIDTH_4_LANES : constant := 3 * 2 ** 1;
32 DDI_BUF_CTL_IDLE_STATUS : constant := 1 * 2 ** 7;
33
34 DDI_BUF_CTL : constant array (Combo_Port) of Registers.Registers_Index :=
35 (DIGI_A => Registers.DDI_BUF_CTL_A,
36 DIGI_B => Registers.DDI_BUF_CTL_B,
37 DIGI_C => Registers.DDI_BUF_CTL_C);
38
39 DDI_BUF_CTL_PORT_WIDTH : constant array (DP_Lane_Count) of Word32 :=
40 (HW.GFX.DP_Lane_Count_1 => DDI_BUF_CTL_PORT_WIDTH_1_LANE,
41 HW.GFX.DP_Lane_Count_2 => DDI_BUF_CTL_PORT_WIDTH_2_LANES,
42 HW.GFX.DP_Lane_Count_4 => DDI_BUF_CTL_PORT_WIDTH_4_LANES);
43
44 type Port_Regs_Record is record
45 PORT_TX_DW5_LN0 : Registers.Registers_Index;
46 PORT_TX_DW5_GRP : Registers.Registers_Index;
47 PORT_TX_DW7_LN0 : Registers.Registers_Index;
48 PORT_TX_DW7_GRP : Registers.Registers_Index;
49 PORT_TX_DW2_LN0 : Registers.Registers_Index;
50 PORT_TX_DW2_GRP : Registers.Registers_Index;
51 PORT_TX_DW4_LN0 : Registers.Registers_Index;
52 PORT_TX_DW4_LN1 : Registers.Registers_Index;
53 PORT_TX_DW4_LN2 : Registers.Registers_Index;
54 PORT_TX_DW4_LN3 : Registers.Registers_Index;
55 PORT_TX_DW4_GRP : Registers.Registers_Index;
56 PORT_PCS_DW1_LN0 : Registers.Registers_Index;
57 PORT_PCS_DW1_GRP : Registers.Registers_Index;
58 PORT_CL_DW5 : Registers.Registers_Index;
59 PORT_CL_DW10 : Registers.Registers_Index;
60 DDI_BUF_CTL : Registers.Registers_Index;
61 end record;
62
63 Port_Regs : constant array (Combo_Port) of Port_Regs_Record :=
64 (DIGI_A =>
65 (Registers.PORT_TX_DW5_LN0_A, Registers.PORT_TX_DW5_GRP_A,
66 Registers.PORT_TX_DW7_LN0_A, Registers.PORT_TX_DW7_GRP_A,
67 Registers.PORT_TX_DW2_LN0_A, Registers.PORT_TX_DW2_GRP_A,
68 Registers.PORT_TX_DW4_LN0_A, Registers.PORT_TX_DW4_LN1_A,
69 Registers.PORT_TX_DW4_LN2_A, Registers.PORT_TX_DW4_LN3_A,
70 Registers.PORT_TX_DW4_GRP_A,
71 Registers.PORT_PCS_DW1_LN0_A, Registers.PORT_PCS_DW1_GRP_A,
72 Registers.PORT_CL_DW5_A,
73 Registers.PORT_CL_DW10_A,
74 Registers.DDI_BUF_CTL_A),
75 DIGI_B =>
76 (Registers.PORT_TX_DW5_LN0_B, Registers.PORT_TX_DW5_GRP_B,
77 Registers.PORT_TX_DW7_LN0_B, Registers.PORT_TX_DW7_GRP_B,
78 Registers.PORT_TX_DW2_LN0_B, Registers.PORT_TX_DW2_GRP_B,
79 Registers.PORT_TX_DW4_LN0_B, Registers.PORT_TX_DW4_LN1_B,
80 Registers.PORT_TX_DW4_LN2_B, Registers.PORT_TX_DW4_LN3_B,
81 Registers.PORT_TX_DW4_GRP_B,
82 Registers.PORT_PCS_DW1_LN0_B, Registers.PORT_PCS_DW1_GRP_B,
83 Registers.PORT_CL_DW5_B,
84 Registers.PORT_CL_DW10_B,
85 Registers.DDI_BUF_CTL_B),
86 DIGI_C =>
87 (Registers.PORT_TX_DW5_LN0_C, Registers.PORT_TX_DW5_GRP_C,
88 Registers.PORT_TX_DW7_LN0_C, Registers.PORT_TX_DW7_GRP_C,
89 Registers.PORT_TX_DW2_LN0_C, Registers.PORT_TX_DW2_GRP_C,
90 Registers.PORT_TX_DW4_LN0_C, Registers.PORT_TX_DW4_LN1_C,
91 Registers.PORT_TX_DW4_LN2_C, Registers.PORT_TX_DW4_LN3_C,
92 Registers.PORT_TX_DW4_GRP_C,
93 Registers.PORT_PCS_DW1_LN0_C, Registers.PORT_PCS_DW1_GRP_C,
94 Registers.PORT_CL_DW5_C,
95 Registers.PORT_CL_DW10_C,
96 Registers.DDI_BUF_CTL_C));
97
98 type Lanes is (LN0, LN1, LN2, LN3);
99 function PORT_TX_DW4 (Lane : Lanes; Port : Combo_Port)
100 return Registers.Registers_Index
101 is (case Lane is
102 when LN0 => Port_Regs (Port).PORT_TX_DW4_LN0,
103 when LN1 => Port_Regs (Port).PORT_TX_DW4_LN1,
104 when LN2 => Port_Regs (Port).PORT_TX_DW4_LN2,
105 when LN3 => Port_Regs (Port).PORT_TX_DW4_LN3);
106
107 PORT_PCS_DW1_LN0_COMMON_KEEPER : constant := 1 * 2 ** 26;
108
109 type Post_Cursor is new Natural range 0 .. 63;
110 function PORT_TX_DW4_POST_CURSOR1 (P : Post_Cursor) return Word32 is
111 (Shift_Left (Word32 (P), 12));
112
113 type Cursor_Coeff is new Natural range 0 .. 63;
114 function PORT_TX_DW4_CURSOR_COEFF (C : Cursor_Coeff) return Word32 is
115 (Word32 (C));
116
117 type N_Scalar is new Natural range 0 .. 127;
118 function PORT_TX_DW7_N_SCALAR (N : N_Scalar) return Word32 is
119 (Shift_Left (Word32 (N), 24));
120
121 type Swing_Select is new Natural range 0 .. 15;
122 function PORT_TX_SWING_SEL_UPPER (S : Swing_Select) return Word32 is
123 (Shift_Left (Shift_Right (Word32(S), 3), 15));
124 function PORT_TX_SWING_SEL_LOWER (S : Swing_Select) return Word32 is
125 (Shift_Left (Word32(S), 11));
126
127 type Buffer_Trans is record
128 DW2_SWING_SEL : Swing_Select;
129 DW7_N_SCALAR : N_Scalar;
130 DW4_CURSOR_COEFF : Cursor_Coeff;
131 DW4_POST_CURSOR1 : Post_Cursor;
132 end record;
133
134 type Buffer_Trans_HDMI_Range is new Natural range 0 .. 6;
135 Buffer_Trans_HDMI : constant array (Buffer_Trans_HDMI_Range) of Buffer_Trans :=
136 ((16#A#, 16#60#, 16#3F#, 16#00#),
137 (16#B#, 16#73#, 16#36#, 16#09#),
138 (16#6#, 16#7F#, 16#31#, 16#0E#),
139 (16#B#, 16#73#, 16#3F#, 16#00#),
140 (16#6#, 16#7F#, 16#37#, 16#08#),
141 (16#6#, 16#7F#, 16#3F#, 16#00#),
142 (16#6#, 16#7F#, 16#35#, 16#0A#));
143
144 type Buffer_Trans_DP_Range is new Natural range 0 .. 9;
145 type Buffer_Trans_DP_Array is array (Buffer_Trans_DP_Range) of Buffer_Trans;
146
147 TGL_Buffer_Trans_DP_HBR : constant Buffer_Trans_DP_Array :=
148 ((16#a#, 16#32#, 16#3f#, 16#00#),
149 (16#a#, 16#4f#, 16#37#, 16#08#),
150 (16#c#, 16#71#, 16#2f#, 16#10#),
151 (16#6#, 16#7d#, 16#2b#, 16#14#),
152 (16#a#, 16#4c#, 16#3f#, 16#00#),
153 (16#c#, 16#73#, 16#34#, 16#0b#),
154 (16#6#, 16#7f#, 16#2f#, 16#10#),
155 (16#c#, 16#6c#, 16#3c#, 16#03#),
156 (16#6#, 16#7f#, 16#35#, 16#0a#),
157 (16#6#, 16#7f#, 16#3f#, 16#00#));
158
159 TGL_Buffer_Trans_DP_HBR2 : constant Buffer_Trans_DP_Array :=
160 ((16#a#, 16#35#, 16#3f#, 16#00#),
161 (16#a#, 16#4f#, 16#37#, 16#08#),
162 (16#c#, 16#63#, 16#2f#, 16#10#),
163 (16#6#, 16#7f#, 16#2b#, 16#14#),
164 (16#a#, 16#47#, 16#3f#, 16#00#),
165 (16#c#, 16#63#, 16#34#, 16#0b#),
166 (16#6#, 16#7f#, 16#2f#, 16#10#),
167 (16#c#, 16#61#, 16#3c#, 16#03#),
168 (16#6#, 16#7b#, 16#35#, 16#0a#),
169 (16#6#, 16#7f#, 16#3f#, 16#00#));
170
171 TGL_Buffer_Trans_DP_HBR2_U_Y : constant Buffer_Trans_DP_Array :=
172 ((16#a#, 16#35#, 16#3f#, 16#00#),
173 (16#a#, 16#4f#, 16#36#, 16#09#),
174 (16#c#, 16#60#, 16#32#, 16#0d#),
175 (16#c#, 16#7f#, 16#2d#, 16#12#),
176 (16#c#, 16#47#, 16#3f#, 16#00#),
177 (16#c#, 16#6f#, 16#36#, 16#09#),
178 (16#6#, 16#7d#, 16#32#, 16#0d#),
179 (16#6#, 16#60#, 16#3c#, 16#03#),
180 (16#6#, 16#7f#, 16#34#, 16#0b#),
181 (16#6#, 16#7f#, 16#3f#, 16#00#));
182
183 TGL_Buffer_Trans_DP_HBR2_EDP_HBR3 : constant Buffer_Trans_DP_Array :=
184 ((16#a#, 16#35#, 16#3f#, 16#00#),
185 (16#a#, 16#4f#, 16#37#, 16#08#),
186 (16#c#, 16#71#, 16#2f#, 16#10#),
187 (16#6#, 16#7f#, 16#2b#, 16#14#),
188 (16#a#, 16#4c#, 16#3f#, 16#00#),
189 (16#c#, 16#73#, 16#34#, 16#0b#),
190 (16#6#, 16#7f#, 16#2f#, 16#10#),
191 (16#c#, 16#6c#, 16#3c#, 16#03#),
192 (16#6#, 16#7f#, 16#35#, 16#0a#),
193 (16#6#, 16#7f#, 16#3f#, 16#00#));
194
195 TGL_Buffer_Trans_EDP_HBR2 : constant Buffer_Trans_DP_Array :=
196 ((16#0#, 16#7F#, 16#3F#, 16#00#),
197 (16#8#, 16#7F#, 16#38#, 16#07#),
198 (16#1#, 16#7F#, 16#33#, 16#0C#),
199 (16#9#, 16#7F#, 16#31#, 16#0E#),
200 (16#8#, 16#7F#, 16#3F#, 16#00#),
201 (16#1#, 16#7F#, 16#38#, 16#07#),
202 (16#9#, 16#7F#, 16#35#, 16#0A#),
203 (16#1#, 16#7F#, 16#3F#, 16#00#),
204 (16#9#, 16#7F#, 16#38#, 16#07#),
205 (16#9#, 16#7F#, 16#3F#, 16#00#));
206
207 ADL_Buffer_Trans_EDP_HBR3 : constant Buffer_Trans_DP_Array :=
208 ((16#a#, 16#35#, 16#3f#, 16#00#),
209 (16#a#, 16#4f#, 16#37#, 16#08#),
210 (16#c#, 16#71#, 16#30#, 16#0f#),
211 (16#6#, 16#7f#, 16#2b#, 16#14#),
212 (16#a#, 16#4c#, 16#3f#, 16#00#),
213 (16#c#, 16#73#, 16#34#, 16#0b#),
214 (16#6#, 16#7f#, 16#30#, 16#0f#),
215 (16#c#, 16#63#, 16#3f#, 16#00#),
216 (16#6#, 16#7f#, 16#38#, 16#07#),
217 (16#6#, 16#7f#, 16#3f#, 16#00#));
218
219 ADL_Buffer_Trans_EDP_HBR2 : constant Buffer_Trans_DP_Array :=
220 ((16#4#, 16#50#, 16#38#, 16#07#),
221 (16#4#, 16#58#, 16#35#, 16#0a#),
222 (16#4#, 16#60#, 16#34#, 16#0b#),
223 (16#4#, 16#6a#, 16#32#, 16#0d#),
224 (16#4#, 16#5e#, 16#38#, 16#07#),
225 (16#4#, 16#61#, 16#36#, 16#09#),
226 (16#4#, 16#6b#, 16#34#, 16#0b#),
227 (16#4#, 16#69#, 16#39#, 16#06#),
228 (16#4#, 16#73#, 16#37#, 16#08#),
229 (16#4#, 16#7a#, 16#38#, 16#07#));
230
231 ADL_Buffer_Trans_DP_HBR3 : constant Buffer_Trans_DP_Array :=
232 ((16#a#, 16#35#, 16#3f#, 16#00#),
233 (16#a#, 16#4f#, 16#37#, 16#08#),
234 (16#c#, 16#71#, 16#30#, 16#0f#),
235 (16#6#, 16#7f#, 16#2b#, 16#14#),
236 (16#a#, 16#4c#, 16#3f#, 16#00#),
237 (16#c#, 16#73#, 16#34#, 16#0b#),
238 (16#6#, 16#7f#, 16#30#, 16#0f#),
239 (16#c#, 16#63#, 16#3f#, 16#00#),
240 (16#6#, 16#7f#, 16#38#, 16#07#),
241 (16#6#, 16#7f#, 16#3f#, 16#00#));
242
243 ADL_Buffer_Trans_DP_HBR : constant Buffer_Trans_DP_Array :=
244 ((16#a#, 16#35#, 16#3f#, 16#00#),
245 (16#a#, 16#4f#, 16#37#, 16#08#),
246 (16#c#, 16#71#, 16#31#, 16#0e#),
247 (16#6#, 16#7f#, 16#2c#, 16#13#),
248 (16#a#, 16#4c#, 16#3f#, 16#00#),
249 (16#c#, 16#73#, 16#34#, 16#0b#),
250 (16#6#, 16#7f#, 16#2f#, 16#10#),
251 (16#c#, 16#7c#, 16#3c#, 16#03#),
252 (16#6#, 16#7f#, 16#35#, 16#0a#),
253 (16#6#, 16#7f#, 16#3f#, 16#00#));
254
255 PORT_CL_DW10_PWR_DOWN_LN_MASK : constant := 16#f# * 2 ** 4;
256 PORT_CL_DW10_PWR_UP_ALL : constant := 0 * 2 ** 4;
257 PORT_CL_DW10_PWR_DOWN_LN_3_2 : constant := 16#c# * 2 ** 4;
258 PORT_CL_DW10_PWR_DOWN_LN_3_2_1 : constant := 16#e# * 2 ** 4;
259 PORT_CL_DW10_PWR_DOWN_LN_1_0 : constant := 16#3# * 2 ** 4;
260 PORT_CL_DW10_PWR_DOWN_LN_2_1_0 : constant := 16#7# * 2 ** 4;
261
262 EDP4K2K_MODE_OVRD_EN : constant := 1 * 2 ** 2;
263 EDP4K2K_MODE_OVRD_OPTIMIZED : constant := 1 * 2 ** 3;
264
265 ---------------------------------------------------------------------
266
267 procedure Set_Vswing_And_Deemphasis
268 (Port : Combo_Port;
269 Buf_Trans : Buffer_Trans;
270 Display : Display_Type;
271 Lane_Count : DP_Lane_Count)
272 is
273 type Training_Values is (Training_Enable, Training_Disable);
274
275 PORT_TX_DW5_TX_TRAINING_EN : constant := 1 * 2 ** 31;
276 PORT_TX_DW5_SCALING_MODE_SEL_MASK : constant := 7 * 2 ** 18;
277 PORT_TX_DW5_RTERM_SELECT_MASK : constant := 7 * 2 ** 3;
278 PORT_TX_DW5_TAP2_DISABLE : constant := 1 * 2 ** 30;
279 PORT_TX_DW5_TAP3_DISABLE : constant := 1 * 2 ** 29;
280 PORT_TX_DW5_CURSOR_PROGRAM : constant := 1 * 2 ** 26;
281 PORT_TX_DW5_COEFF_POLARITY : constant := 1 * 2 ** 25;
282
283 PORT_TX_DW2_RCOMP_SCALAR_MASK : constant := 16#ff# * 2 ** 0;
284 PORT_TX_DW2_SWING_SEL_LOWER_MASK : constant := 7 * 2 ** 11;
285 PORT_TX_DW2_SWING_SEL_UPPER : constant := 1 * 2 ** 15;
286
287 PORT_TX_DW4_LOADGEN_SELECT : constant := 1 * 2 ** 31;
288 PORT_TX_DW4_POST_CURSOR2_MASK : constant := 16#3f# * 2 ** 6;
289 PORT_TX_DW4_POST_CURSOR1_MASK : constant := 16#3f# * 2 ** 12;
290 PORT_TX_DW4_CURSOR_COEFF_MASK : constant := 16#3f# * 2 ** 0;
291
292 PORT_TX_DW7_N_SCALAR_MASK : constant := 16#7f# * 2 ** 24;
293
294 type Scaling_Mode is new Natural range 0 .. 7;
295 function PORT_TX_DW5_SCALING_MODE_SEL (S : Scaling_Mode) return Word32 is
296 (Shift_Left (Word32 (S), 18));
297
298 type Rterm_Select is new Natural range 0 .. 7;
299 function PORT_TX_DW5_RTERM_SELECT (R : Rterm_Select) return Word32 is
300 (Shift_Left (Word32 (R), 3));
301
302 type Rcomp_Scalar is new Natural range 0 .. 255;
303 function PORT_TX_DW2_RCOMP_SCALAR (R : Rcomp_Scalar) return Word32 is
304 (Word32 (R));
305
306 procedure Set_Tx_Training (Port : Combo_Port; Training : Training_Values) is
307 DW5 : Word32;
308 begin
309 Registers.Read (Port_Regs (Port).PORT_TX_DW5_LN0, DW5);
310 Registers.Write
311 (Register => Port_Regs (Port).PORT_TX_DW5_GRP,
312 Value => (if Training = Training_Enable
313 then DW5 or PORT_TX_DW5_TX_TRAINING_EN
314 else DW5 and not PORT_TX_DW5_TX_TRAINING_EN));
315 end Set_Tx_Training;
316
317 Tmp : Word32;
318 PORT_CL_DW5_SUS_CLOCK_CONFIG : constant := 3 * 2 ** 0;
319 begin
320 -- Enable common keeper for DP/eDP only
321 Registers.Read (Port_Regs (Port).PORT_PCS_DW1_LN0, Tmp);
322 Registers.Write
323 (Port_Regs (Port).PORT_PCS_DW1_GRP,
324 (if Display = DP
325 then Tmp or PORT_PCS_DW1_LN0_COMMON_KEEPER
326 else Tmp and not PORT_PCS_DW1_LN0_COMMON_KEEPER));
327
328 -- Program loadgen select (group access is not allowed since each lane may
329 -- have a unique value.
330 -- <= 6GHz, 4 lanes (0, 1, 1, 1)
331 -- <= 6GHz, 1,2 lanes (0, 1, 1, 0)
332 -- > 6GHz, any lanes (0, 0, 0, 0)
333 for Lane in Lanes loop
334 if (Lane_Count = DP_Lane_Count_4 and Lane /= LN0) or
335 (Lane_Count /= DP_Lane_Count_4 and (Lane = LN1 or Lane = LN2))
336 then
337 Registers.Set_Mask (PORT_TX_DW4 (Lane, Port),
338 PORT_TX_DW4_LOADGEN_SELECT);
339 else
340 Registers.Unset_Mask (PORT_TX_DW4 (Lane, Port),
341 PORT_TX_DW4_LOADGEN_SELECT);
342 end if;
343 end loop;
344
345 Registers.Set_Mask
346 (Register => Port_Regs (Port).PORT_CL_DW5,
347 Mask => PORT_CL_DW5_SUS_CLOCK_CONFIG);
348
349 -- In order to change swing values, training must be disabled
350 Set_Tx_Training (Port, Training_Disable);
351
352 if Display = DP then
353 Registers.Unset_Mask
354 (Register => Port_Regs (Port).PORT_CL_DW10,
355 Mask => EDP4K2K_MODE_OVRD_EN or EDP4K2K_MODE_OVRD_OPTIMIZED);
356 end if;
357
358 Registers.Read (Port_Regs (Port).PORT_TX_DW5_LN0, Tmp);
359 Tmp := Tmp and not
360 (PORT_TX_DW5_SCALING_MODE_SEL_MASK or
361 PORT_TX_DW5_RTERM_SELECT_MASK or
362 PORT_TX_DW5_TAP2_DISABLE or
363 PORT_TX_DW5_TAP3_DISABLE or
364 PORT_TX_DW5_CURSOR_PROGRAM or
365 PORT_TX_DW5_COEFF_POLARITY);
366 Tmp := Tmp or
367 PORT_TX_DW5_SCALING_MODE_SEL (2) or
368 PORT_TX_DW5_RTERM_SELECT (6) or
369 PORT_TX_DW5_TAP3_DISABLE;
370 Registers.Write (Port_Regs (Port).PORT_TX_DW5_GRP, Tmp);
371
372 Registers.Read (Port_Regs (Port).PORT_TX_DW2_LN0, Tmp);
373 Tmp := Tmp and not
374 (PORT_TX_DW2_RCOMP_SCALAR_MASK or
375 PORT_TX_DW2_SWING_SEL_LOWER_MASK or
376 PORT_TX_DW2_SWING_SEL_UPPER);
377 Tmp := Tmp or PORT_TX_SWING_SEL_UPPER (Buf_Trans.DW2_SWING_SEL);
378 Tmp := Tmp or PORT_TX_SWING_SEL_LOWER (Buf_Trans.DW2_SWING_SEL);
379 Tmp := Tmp or PORT_TX_DW2_RCOMP_SCALAR (16#98#);
380 Registers.Write (Port_Regs (Port).PORT_TX_DW2_GRP, Tmp);
381
382 -- Cannot write to GRP, because it would overwrite individual loadgen bits
383 for Lane in Lanes loop
384 Registers.Read (PORT_TX_DW4 (Lane, Port), Tmp);
385 Tmp := Tmp and not
386 (PORT_TX_DW4_POST_CURSOR2_MASK or
387 PORT_TX_DW4_POST_CURSOR1_MASK or
388 PORT_TX_DW4_CURSOR_COEFF_MASK);
389 Tmp := Tmp or PORT_TX_DW4_POST_CURSOR1 (Buf_Trans.DW4_POST_CURSOR1);
390 Tmp := Tmp or PORT_TX_DW4_CURSOR_COEFF (Buf_Trans.DW4_CURSOR_COEFF);
391 Registers.Write (PORT_TX_DW4 (Lane, Port), Tmp);
392 end loop;
393
394 Registers.Read (Port_Regs (Port).PORT_TX_DW7_LN0, Tmp);
395 Tmp := Tmp and not PORT_TX_DW7_N_SCALAR_MASK;
396 Tmp := Tmp or PORT_TX_DW7_N_SCALAR (Buf_Trans.DW7_N_SCALAR);
397 Registers.Write (Port_Regs (Port).PORT_TX_DW7_GRP, Tmp);
398
399 -- To trigger an update of swing values, set training enable
400 Set_Tx_Training (Port, Training_Enable);
401 end Set_Vswing_And_Deemphasis;
402
403 ---------------------------------------------------------------------
404
405 procedure Power_Up_Lanes
406 (Port : Combo_Port;
407 Lane_Count : DP_Lane_Count)
408 is
409 Lane_Mask : constant Word32 :=
410 (case Lane_Count is
411 -- if Lane_Reversal then PWR_DOWN_LN_2_1_0
412 -- else PORT_CL_DW10_PWR_DOWN_LN_3_2_1
413 when DP_Lane_Count_1 => PORT_CL_DW10_PWR_DOWN_LN_3_2_1,
414 -- if Lane_Reversal then PWR_DOWN_1_0
415 -- else PORT_CL_DW10_PWR_DOWN_LN_3_2
416 when DP_Lane_Count_2 => PORT_CL_DW10_PWR_DOWN_LN_3_2,
417 when others => PORT_CL_DW10_PWR_UP_ALL);
418 begin
419 Registers.Unset_And_Set_Mask
420 (Register => Port_Regs (Port).PORT_CL_DW10,
421 Mask_Unset => PORT_CL_DW10_PWR_DOWN_LN_MASK,
422 Mask_Set => Lane_Mask);
423 end Power_Up_Lanes;
424
425 ---------------------------------------------------------------------
426
427 procedure Set_Signal_Levels
428 (Port : Combo_Port;
429 eDP : Boolean;
430 Link : DP_Link;
431 Train_Set : DP_Info.Train_Set)
432 is
433 function Get_Buf_Trans_Table
434 (eDP : Boolean) return Buffer_Trans_DP_Array is
435 begin
436 if Config.Has_TGL_Buffer_Translations then
437 if eDP then
438 if Link.Bandwidth > DP_Bandwidth_5_4 then
439 return TGL_Buffer_Trans_DP_HBR2_EDP_HBR3;
440 else
441 return TGL_Buffer_Trans_DP_HBR;
442 end if;
443 else
444 if Link.Bandwidth > DP_Bandwidth_2_7 then
445 if Config.Is_LP then
446 return TGL_Buffer_Trans_DP_HBR2_U_Y;
447 else
448 return TGL_Buffer_Trans_DP_HBR2;
449 end if;
450 else
451 return TGL_Buffer_Trans_DP_HBR;
452 end if;
453 end if;
454 else
455 if eDP then
456 if Link.Bandwidth > DP_Bandwidth_5_4 then
457 return ADL_Buffer_Trans_EDP_HBR3;
458 else
459 return ADL_Buffer_Trans_DP_HBR; -- EDP_HBR2 ?
460 end if;
461 else
462 if Link.Bandwidth > DP_Bandwidth_2_7 then
463 return ADL_Buffer_Trans_DP_HBR3;
464 else
465 return ADL_Buffer_Trans_DP_HBR;
466 end if;
467 end if;
468 end if;
469 end Get_Buf_Trans_Table;
470
471 function To_Buf_Trans_Index
472 (Set : DP_Info.Train_Set) return Buffer_Trans_DP_Range
473 is
474 begin
475 case Set.Voltage_Swing is
476 when DP_Info.VS_Level_0 =>
477 case Set.Pre_Emph is
478 when DP_Info.Emph_Level_0 => return 0;
479 when DP_Info.Emph_Level_1 => return 1;
480 when DP_Info.Emph_Level_2 => return 2;
481 when DP_Info.Emph_Level_3 => return 3;
482 end case;
483 when DP_Info.VS_Level_1 =>
484 case Set.Pre_Emph is
485 when DP_Info.Emph_Level_0 => return 4;
486 when DP_Info.Emph_Level_1 => return 5;
487 when DP_Info.Emph_Level_2 => return 6;
488 when others => return 0;
489 end case;
490 when DP_Info.VS_Level_2 =>
491 case Set.Pre_Emph is
492 when DP_Info.Emph_Level_0 => return 7;
493 when DP_Info.Emph_Level_1 => return 8;
494 when others => return 0;
495 end case;
496 when DP_Info.VS_Level_3 =>
497 case Set.Pre_Emph is
498 when DP_Info.Emph_Level_0 => return 9;
499 when others => return 0;
500 end case;
501 end case;
502 end To_Buf_Trans_Index;
503
504 Was_Enabled : Boolean;
505 Buf_Trans : Buffer_Trans;
506 Entry_Index : constant Buffer_Trans_DP_Range :=
507 To_Buf_Trans_Index (Train_Set);
508 begin
509 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
510
511 Registers.Is_Set_Mask
512 (Register => Port_Regs (Port).DDI_BUF_CTL,
513 Mask => DDI_BUF_CTL_BUFFER_ENABLE,
514 Result => Was_Enabled);
515
516 Buf_Trans := Get_Buf_Trans_Table (eDP) (Entry_Index);
517
518 Set_Vswing_And_Deemphasis
519 (Port => Port,
520 Buf_Trans => Buf_Trans,
521 Display => DP,
522 Lane_Count => Link.Lane_Count);
523
524 if not Was_Enabled then
525 Power_Up_Lanes (Port, Link.Lane_Count);
526 end if;
527
528 Registers.Unset_And_Set_Mask
529 (Register => Port_Regs (Port).DDI_BUF_CTL,
530 Mask_Unset => DDI_BUF_CTL_TRANS_SELECT_MASK or
531 DDI_BUF_CTL_PORT_REVERSAL or
532 DDI_BUF_CTL_PORT_WIDTH_MASK,
533 Mask_Set => DDI_BUF_CTL_BUFFER_ENABLE or
534 DDI_BUF_CTL_PORT_WIDTH (Link.Lane_Count));
535 Registers.Posting_Read (Port_Regs (Port).DDI_BUF_CTL);
536
537 if not Was_Enabled then
538 Registers.Wait_Unset_Mask (Port_Regs (Port).DDI_BUF_CTL, DDI_BUF_CTL_IDLE_STATUS);
539 end if;
540 end Set_Signal_Levels;
541
542 ---------------------------------------------------------------------
543
544 procedure Enable_HDMI (Port : Combo_Port)
545 is
546 HDMI_Lane_Count : constant DP_Lane_Count := DP_Lane_Count_4;
547 begin
548 Set_Vswing_And_Deemphasis
549 (Port => Port,
550 Buf_Trans => Buffer_Trans_HDMI (Buffer_Trans_HDMI'First),
551 Display => HDMI,
552 Lane_Count => HDMI_Lane_Count);
553
554 Power_Up_Lanes (Port, HDMI_Lane_Count);
555
556 Registers.Unset_And_Set_Mask
557 (Register => DDI_BUF_CTL (Port),
558 Mask_Unset => DDI_BUF_CTL_TRANS_SELECT_MASK or
559 DDI_BUF_CTL_PORT_REVERSAL or
560 DDI_BUF_CTL_PORT_WIDTH_MASK,
561 Mask_Set => DDI_BUF_CTL_BUFFER_ENABLE);
562
563 Registers.Wait_Unset_Mask
564 (Register => DDI_BUF_CTL (Port),
565 Mask => DDI_BUF_CTL_IDLE_STATUS,
566 TOut_MS => 1);
567 end Enable_HDMI;
568
569end HW.GFX.GMA.Connectors.Combo_Phy;