blob: fdd8ea5f77ec9a938b1ff8d60643b0a1c39a100f [file] [log] [blame]
Nico Huberf6266002017-02-03 12:17:28 +01001--
2-- Copyright (C) 2017 secunet Security Networks AG
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 GNAT.Source_Info;
16with HW.Debug;
17
Nico Huberfdd93652017-02-08 13:41:38 +010018with HW.GFX.GMA.Config;
Nico Huberf6266002017-02-03 12:17:28 +010019with HW.GFX.GMA.Registers;
20
21use HW.GFX.GMA.Registers;
22
23package body HW.GFX.GMA.DDI_Phy is
24
25 subtype Dual_Channel is T range BC .. BC;
26
27 type DDI_Range is record
28 First : DDI_Phy_Port;
29 Last : DDI_Phy_Port;
30 end record;
31 type DDI_Range_Array is array (T) of DDI_Range;
32 DDIs : constant DDI_Range_Array :=
33 (A => (DIGI_A, DIGI_A),
34 BC => (DIGI_B, DIGI_C));
35
36 ----------------------------------------------------------------------------
37
38 type CL1CM is record
39 DW0 : Registers_Index;
40 DW9 : Registers_Index;
41 DW10 : Registers_Index;
42 DW28 : Registers_Index;
43 DW30 : Registers_Index;
44 end record;
45 type CL1CM_Array is array (T) of CL1CM;
46 PORT_CL1CM : constant CL1CM_Array :=
47 (A =>
48 (DW0 => BXT_PORT_CL1CM_DW0_A,
49 DW9 => BXT_PORT_CL1CM_DW9_A,
50 DW10 => BXT_PORT_CL1CM_DW10_A,
51 DW28 => BXT_PORT_CL1CM_DW28_A,
52 DW30 => BXT_PORT_CL1CM_DW30_A),
53 BC =>
54 (DW0 => BXT_PORT_CL1CM_DW0_BC,
55 DW9 => BXT_PORT_CL1CM_DW9_BC,
56 DW10 => BXT_PORT_CL1CM_DW10_BC,
57 DW28 => BXT_PORT_CL1CM_DW28_BC,
58 DW30 => BXT_PORT_CL1CM_DW30_BC));
59
60 type CL2CM is record
61 DW6 : Registers_Index;
62 end record;
63 type CL2CM_Array is array (Dual_Channel) of CL2CM;
64 PORT_CL2CM : constant CL2CM_Array :=
65 (BC => (DW6 => BXT_PORT_CL2CM_DW6_BC));
66
67 type Port_Ref_Regs is record
68 DW3 : Registers_Index;
69 DW6 : Registers_Index;
70 DW8 : Registers_Index;
71 end record;
72 type Port_Ref_Array is array (T) of Port_Ref_Regs;
73 PORT_REF : constant Port_Ref_Array :=
74 (A =>
75 (DW3 => BXT_PORT_REF_DW3_A,
76 DW6 => BXT_PORT_REF_DW6_A,
77 DW8 => BXT_PORT_REF_DW8_A),
78 BC =>
79 (DW3 => BXT_PORT_REF_DW3_BC,
80 DW6 => BXT_PORT_REF_DW6_BC,
81 DW8 => BXT_PORT_REF_DW8_BC));
82
83 type Regs is array (T) of Registers_Index;
84 PHY_CTL_FAMILY : constant Regs :=
85 (A => BXT_PHY_CTL_FAM_EDP, BC => BXT_PHY_CTL_FAM_DDI);
86
87 type DDI_Regs is array (DDI_Phy_Port) of Registers_Index;
88 PHY_CTL : constant DDI_Regs :=
89 (DIGI_A => BXT_PHY_CTL_A,
90 DIGI_B => BXT_PHY_CTL_B,
91 DIGI_C => BXT_PHY_CTL_C);
92
93 ----------------------------------------------------------------------------
94
95 type Values is array (T) of Word32;
96 GT_DISPLAY_POWER_ON : constant Values :=
97 (A => 1 * 2 ** 1,
98 BC => 1 * 2 ** 0);
99
100 PORT_CL1CM_PHY_POWER_GOOD : constant := 1 * 2 ** 16;
101 PORT_CL1CM_PHY_RESERVED : constant := 1 * 2 ** 7;
102
103 PORT_CL1CM_IREFxRC_OFFSET_SHIFT : constant := 8;
104 PORT_CL1CM_IREFxRC_OFFSET_MASK : constant := 16#ff# * 2 ** 8;
105
106 PORT_CL1CM_OCL1_POWER_DOWN_EN : constant := 1 * 2 ** 23;
107 PORT_CL1CM_OLDO_DYN_POWER_DOWN_EN : constant := 1 * 2 ** 22;
108 PORT_CL1CM_SUS_CLK_CONFIG : constant := 3 * 2 ** 0;
109
110 PORT_CL2CM_OLDO_DYN_POWER_DOWN_EN : constant := 1 * 2 ** 28;
111
112 PORT_REF_GRC_DONE : constant := 1 * 2 ** 22;
113
114 PORT_REF_GRC_CODE_SHIFT : constant := 24;
115 PORT_REF_GRC_FAST_SHIFT : constant := 16;
116 PORT_REF_GRC_SLOW_SHIFT : constant := 8;
117
118 PORT_REF_GRC_DISABLE : constant := 1 * 2 ** 15;
119 PORT_REF_GRC_READY_OVERRIDE : constant := 1 * 2 ** 1;
120
121 PHY_CTL_FAM_CMN_RESET_DIS : constant := 1 * 2 ** 31;
122
123 PHY_CTL_CMNLANE_POWERDOWN_ACK : constant := 1 * 2 ** 10;
124
125 ----------------------------------------------------------------------------
126
127 procedure Is_Enabled (Phy : in T; Enabled : out Boolean)
128 is
129 Phy_Pwr : Word32;
130 begin
131 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
132
133 Is_Set_Mask (BXT_P_CR_GT_DISP_PWRON, GT_DISPLAY_POWER_ON (Phy), Enabled);
134
135 if Enabled then
136 Read (PORT_CL1CM (Phy).DW0, Phy_Pwr);
137 Enabled :=
138 (Phy_Pwr and (PORT_CL1CM_PHY_POWER_GOOD or PORT_CL1CM_PHY_RESERVED))
139 = PORT_CL1CM_PHY_POWER_GOOD;
140 pragma Debug (not Enabled, Debug.Put_Line ("DDI PHY power unsettled"));
141 end if;
142
143 if Enabled then
144 Is_Set_Mask (PHY_CTL_FAMILY (Phy), PHY_CTL_FAM_CMN_RESET_DIS, Enabled);
145 pragma Debug (not Enabled, Debug.Put_Line ("DDI PHY still in reset"));
146 end if;
147
148 for DDI in DDIs (Phy).First .. DDIs (Phy).Last loop
149 if Enabled then
150 declare
151 Common_Lane_Powerdown : Boolean;
152 begin
153 Is_Set_Mask
154 (Register => PHY_CTL (DDI),
155 Mask => PHY_CTL_CMNLANE_POWERDOWN_ACK,
156 Result => Common_Lane_Powerdown);
157 Enabled := not Common_Lane_Powerdown;
158 pragma Debug
159 (not Enabled, Debug.Put_Line ("Common lane powered down"));
160 end;
161 end if;
162 end loop;
163 end Is_Enabled;
164
165 procedure Power_On_Phy (Phy : T)
166 with
167 Pre => True
168 is
169 begin
170 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
171
172 Set_Mask (BXT_P_CR_GT_DISP_PWRON, GT_DISPLAY_POWER_ON (Phy));
173
174 Wait
175 (Register => PORT_CL1CM (Phy).DW0,
176 Mask => PORT_CL1CM_PHY_POWER_GOOD or
177 PORT_CL1CM_PHY_RESERVED,
178 Value => PORT_CL1CM_PHY_POWER_GOOD,
179 TOut_MS => 1); -- 50~100us
180
181 Unset_And_Set_Mask
182 (Register => PORT_CL1CM (Phy).DW9,
183 Mask_Unset => PORT_CL1CM_IREFxRC_OFFSET_MASK,
184 Mask_Set => Shift_Left
185 (16#e4#, PORT_CL1CM_IREFxRC_OFFSET_SHIFT));
186 Unset_And_Set_Mask
187 (Register => PORT_CL1CM (Phy).DW10,
188 Mask_Unset => PORT_CL1CM_IREFxRC_OFFSET_MASK,
189 Mask_Set => Shift_Left
190 (16#e4#, PORT_CL1CM_IREFxRC_OFFSET_SHIFT));
191
192 Set_Mask
193 (Register => PORT_CL1CM (Phy).DW28,
194 Mask => PORT_CL1CM_OCL1_POWER_DOWN_EN or
195 PORT_CL1CM_OLDO_DYN_POWER_DOWN_EN or
196 PORT_CL1CM_SUS_CLK_CONFIG);
197
198 if Phy in Dual_Channel then
199 Set_Mask (PORT_CL2CM (Phy).DW6, PORT_CL2CM_OLDO_DYN_POWER_DOWN_EN);
200 end if;
201
202 if Phy = BC then
203 declare
204 GRC_Val : Word32;
205 begin
206 -- take RCOMP calibration result from A
207
208 Wait_Set_Mask (PORT_REF (A).DW3, PORT_REF_GRC_DONE, TOut_MS => 10);
209 Read (PORT_REF (A).DW6, GRC_Val);
210 GRC_Val := Shift_Right (GRC_Val, PORT_REF_GRC_CODE_SHIFT);
211
212 -- use it for BC too
213 GRC_Val := Shift_Left (GRC_Val, PORT_REF_GRC_FAST_SHIFT) or
214 Shift_Left (GRC_Val, PORT_REF_GRC_SLOW_SHIFT) or
215 GRC_Val;
216 Write (PORT_REF (Phy).DW6, GRC_Val);
217
218 Set_Mask
219 (Register => PORT_REF (Phy).DW8,
220 Mask => PORT_REF_GRC_DISABLE or
221 PORT_REF_GRC_READY_OVERRIDE);
222 end;
223 end if;
224
225 Set_Mask (PHY_CTL_FAMILY (Phy), PHY_CTL_FAM_CMN_RESET_DIS);
226 end Power_On_Phy;
227
228 procedure Power_On (Phy : T)
229 is
230 Phy_A_Enabled : Boolean := False;
231 Enabled : Boolean;
232 begin
233 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
234
235 Is_Enabled (Phy, Enabled);
236 pragma Debug (Enabled, Debug.Put_Line ("DDI PHY already enabled"));
237
238 if not Enabled then
239 if Phy = BC then
240 -- PHY BC needs RCOMP calibration results from PHY A
241 Is_Enabled (A, Phy_A_Enabled);
242 if not Phy_A_Enabled then
243 Power_On_Phy (A);
244 end if;
245 end if;
246
247 Power_On_Phy (Phy);
248
249 if Phy = BC and then not Phy_A_Enabled then
250 Power_Off (A);
251 end if;
252 end if;
253 end Power_On;
254
255 procedure Power_Off (Phy : T) is
256 begin
257 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
258
259 Unset_Mask (PHY_CTL_FAMILY (Phy), PHY_CTL_FAM_CMN_RESET_DIS);
260 Unset_Mask (BXT_P_CR_GT_DISP_PWRON, GT_DISPLAY_POWER_ON (Phy));
261 end Power_Off;
262
Nico Huberafadcac2017-02-08 13:41:38 +0100263 ----------------------------------------------------------------------------
264
265 type Lanes is range 0 .. 3;
266 type Lane_Reg_Array is array (Lanes) of Registers_Index;
267
268 type Port_TX_Regs is record
Nico Huberfdd93652017-02-08 13:41:38 +0100269 DW2_LN0 : Registers_Index;
270 DW2_GRP : Registers_Index;
271 DW3_LN0 : Registers_Index;
272 DW3_GRP : Registers_Index;
273 DW4_LN0 : Registers_Index;
274 DW4_GRP : Registers_Index;
Nico Huberafadcac2017-02-08 13:41:38 +0100275 DW14_LN : Lane_Reg_Array;
276 end record;
277 type Port_TX_Array is array (DDI_Phy_Port) of Port_TX_Regs;
278
279 PORT_TX : constant Port_TX_Array :=
280 (DIGI_A =>
Nico Huberfdd93652017-02-08 13:41:38 +0100281 (DW2_LN0 => BXT_PORT_TX_DW2_LN0_A,
282 DW2_GRP => BXT_PORT_TX_DW2_GRP_A,
283 DW3_LN0 => BXT_PORT_TX_DW3_LN0_A,
284 DW3_GRP => BXT_PORT_TX_DW3_GRP_A,
285 DW4_LN0 => BXT_PORT_TX_DW4_LN0_A,
286 DW4_GRP => BXT_PORT_TX_DW4_GRP_A,
287 DW14_LN =>
Nico Huberafadcac2017-02-08 13:41:38 +0100288 (BXT_PORT_TX_DW14_LN0_A,
289 BXT_PORT_TX_DW14_LN1_A,
290 BXT_PORT_TX_DW14_LN2_A,
291 BXT_PORT_TX_DW14_LN3_A)),
292 DIGI_B =>
Nico Huberfdd93652017-02-08 13:41:38 +0100293 (DW2_LN0 => BXT_PORT_TX_DW2_LN0_B,
294 DW2_GRP => BXT_PORT_TX_DW2_GRP_B,
295 DW3_LN0 => BXT_PORT_TX_DW3_LN0_B,
296 DW3_GRP => BXT_PORT_TX_DW3_GRP_B,
297 DW4_LN0 => BXT_PORT_TX_DW4_LN0_B,
298 DW4_GRP => BXT_PORT_TX_DW4_GRP_B,
299 DW14_LN =>
Nico Huberafadcac2017-02-08 13:41:38 +0100300 (BXT_PORT_TX_DW14_LN0_B,
301 BXT_PORT_TX_DW14_LN1_B,
302 BXT_PORT_TX_DW14_LN2_B,
303 BXT_PORT_TX_DW14_LN3_B)),
304 DIGI_C =>
Nico Huberfdd93652017-02-08 13:41:38 +0100305 (DW2_LN0 => BXT_PORT_TX_DW2_LN0_C,
306 DW2_GRP => BXT_PORT_TX_DW2_GRP_C,
307 DW3_LN0 => BXT_PORT_TX_DW3_LN0_C,
308 DW3_GRP => BXT_PORT_TX_DW3_GRP_C,
309 DW4_LN0 => BXT_PORT_TX_DW4_LN0_C,
310 DW4_GRP => BXT_PORT_TX_DW4_GRP_C,
311 DW14_LN =>
Nico Huberafadcac2017-02-08 13:41:38 +0100312 (BXT_PORT_TX_DW14_LN0_C,
313 BXT_PORT_TX_DW14_LN1_C,
314 BXT_PORT_TX_DW14_LN2_C,
315 BXT_PORT_TX_DW14_LN3_C)));
316
Nico Huberfdd93652017-02-08 13:41:38 +0100317 PORT_TX_DW2_MARGIN_000_SHIFT : constant := 16;
318 PORT_TX_DW2_MARGIN_000_MASK : constant := 16#ff# * 2 ** 16;
319 PORT_TX_DW2_UNIQ_TRANS_SCALE_SHIFT : constant := 8;
320 PORT_TX_DW2_UNIQ_TRANS_SCALE_MASK : constant := 16#ff# * 2 ** 8;
321 function PORT_TX_DW2_MARGIN_000 (Margin : Word8) return Word32 is
322 begin
323 return Shift_Left (Word32 (Margin), PORT_TX_DW2_MARGIN_000_SHIFT);
324 end PORT_TX_DW2_MARGIN_000;
325 function PORT_TX_DW2_UNIQ_TRANS_SCALE (Scale : Word8) return Word32 is
326 begin
327 return Shift_Left (Word32 (Scale), PORT_TX_DW2_UNIQ_TRANS_SCALE_SHIFT);
328 end PORT_TX_DW2_UNIQ_TRANS_SCALE;
329
330 PORT_TX_DW3_UNIQUE_TRANGE_EN_METHOD : constant := 1 * 2 ** 27;
331 PORT_TX_DW3_SCALE_DCOMP_METHOD : constant := 1 * 2 ** 26;
332
333 PORT_TX_DW4_DE_EMPHASIS_SHIFT : constant := 24;
334 PORT_TX_DW4_DE_EMPHASIS_MASK : constant := 16#ff# * 2 ** 24;
335 function PORT_TX_DW4_DE_EMPHASIS (De_Emph : Word8) return Word32 is
336 begin
337 return Shift_Left (Word32 (De_Emph), PORT_TX_DW4_DE_EMPHASIS_SHIFT);
338 end PORT_TX_DW4_DE_EMPHASIS;
339
340 PORT_TX_DW14_LN_LATENCY_OPTIM : constant := 1 * 2 ** 30;
341
342 ----------------------------------------------------------------------------
343
344 type Port_PCS_Regs is record
345 DW10_LN01 : Registers_Index;
346 DW10_GRP : Registers_Index;
347 end record;
348 type Port_PCS_Array is array (DDI_Phy_Port) of Port_PCS_Regs;
349
350 PORT_PCS : constant Port_PCS_Array :=
351 (DIGI_A =>
352 (DW10_LN01 => BXT_PORT_PCS_DW10_01_A,
353 DW10_GRP => BXT_PORT_PCS_DW10_GRP_A),
354 DIGI_B =>
355 (DW10_LN01 => BXT_PORT_PCS_DW10_01_B,
356 DW10_GRP => BXT_PORT_PCS_DW10_GRP_B),
357 DIGI_C =>
358 (DW10_LN01 => BXT_PORT_PCS_DW10_01_C,
359 DW10_GRP => BXT_PORT_PCS_DW10_GRP_C));
360
361 PORT_PCS_TX2_SWING_CALC_INIT : constant := 1 * 2 ** 31;
362 PORT_PCS_TX1_SWING_CALC_INIT : constant := 1 * 2 ** 30;
363
364 ----------------------------------------------------------------------------
Nico Huberafadcac2017-02-08 13:41:38 +0100365
366 procedure Pre_PLL (Port_Cfg : Port_Config)
367 is
368 type Lane_Values is array (Lanes) of Word32;
369 Lane_Optim : constant Lane_Values :=
370 (if Port_Cfg.Display = HDMI or
371 Port_Cfg.DP.Lane_Count = DP_Lane_Count_4
372 then
373 (0 => PORT_TX_DW14_LN_LATENCY_OPTIM,
374 1 => 0,
375 2 => PORT_TX_DW14_LN_LATENCY_OPTIM,
376 3 => PORT_TX_DW14_LN_LATENCY_OPTIM)
377 elsif Port_Cfg.DP.Lane_Count = DP_Lane_Count_2 then
378 (0 => PORT_TX_DW14_LN_LATENCY_OPTIM,
379 1 => 0,
380 2 => PORT_TX_DW14_LN_LATENCY_OPTIM,
381 3 => 0)
382 else
383 (Lanes => 0));
384 begin
385 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
386
387 if Port_Cfg.Port in DDI_Phy_Port then
388 for Lane in Lanes loop
389 Unset_And_Set_Mask
390 (Register => PORT_TX (Port_Cfg.Port).DW14_LN (Lane),
391 Mask_Unset => PORT_TX_DW14_LN_LATENCY_OPTIM,
392 Mask_Set => Lane_Optim (Lane));
393 end loop;
394 end if;
395 end Pre_PLL;
396
Nico Huberfdd93652017-02-08 13:41:38 +0100397 ----------------------------------------------------------------------------
398
399 type DDI_Buf_Trans is record
400 Margin : Word8;
401 Scale : Word8;
402 Scale_En : Boolean;
403 De_Emph : Word8;
404 end record;
405 Invalid_Buf_Trans : constant DDI_Buf_Trans := (0, 0, False, 0);
406
407 function DP_Buf_Trans (TS : DP_Info.Train_Set) return DDI_Buf_Trans
408 with
409 Pre => True
410 is
411 begin
412 return
413 (case TS.Voltage_Swing is
414 when DP_Info.VS_Level_0 =>
415 (case TS.Pre_Emph is
416 when DP_Info.Emph_Level_0 => ( 52, 16#9a#, False, 128),
417 when DP_Info.Emph_Level_1 => ( 78, 16#9a#, False, 85),
418 when DP_Info.Emph_Level_2 => (104, 16#9a#, False, 64),
419 when DP_Info.Emph_Level_3 => (154, 16#9a#, False, 43)),
420 when DP_Info.VS_Level_1 =>
421 (case TS.Pre_Emph is
422 when DP_Info.Emph_Level_0 => ( 77, 16#9a#, False, 128),
423 when DP_Info.Emph_Level_1 => (116, 16#9a#, False, 85),
424 when DP_Info.Emph_Level_2 => (154, 16#9a#, False, 64),
425 when others => Invalid_Buf_Trans),
426 when DP_Info.VS_Level_2 =>
427 (case TS.Pre_Emph is
428 when DP_Info.Emph_Level_0 => (102, 16#9a#, False, 128),
429 when DP_Info.Emph_Level_1 => (154, 16#9a#, False, 85),
430 when others => Invalid_Buf_Trans),
431 when DP_Info.VS_Level_3 =>
432 (case TS.Pre_Emph is
433 when DP_Info.Emph_Level_0 => (154, 16#9a#, True, 128),
434 when others => Invalid_Buf_Trans));
435 end DP_Buf_Trans;
436
437 function eDP_Buf_Trans (TS : DP_Info.Train_Set) return DDI_Buf_Trans
438 with
439 Pre => True
440 is
441 begin
442 return
443 (case TS.Voltage_Swing is
444 when DP_Info.VS_Level_0 =>
445 (case TS.Pre_Emph is
446 when DP_Info.Emph_Level_0 => ( 26, 16#00#, False, 128),
447 when DP_Info.Emph_Level_1 => ( 38, 16#00#, False, 112),
448 when DP_Info.Emph_Level_2 => ( 48, 16#00#, False, 96),
449 when DP_Info.Emph_Level_3 => ( 54, 16#00#, False, 69)),
450 when DP_Info.VS_Level_1 =>
451 (case TS.Pre_Emph is
452 when DP_Info.Emph_Level_0 => ( 32, 16#00#, False, 128),
453 when DP_Info.Emph_Level_1 => ( 48, 16#00#, False, 104),
454 when DP_Info.Emph_Level_2 => ( 54, 16#00#, False, 85),
455 when others => Invalid_Buf_Trans),
456 when DP_Info.VS_Level_2 =>
457 (case TS.Pre_Emph is
458 when DP_Info.Emph_Level_0 => ( 43, 16#00#, False, 128),
459 when DP_Info.Emph_Level_1 => ( 54, 16#00#, False, 101),
460 when others => Invalid_Buf_Trans),
461 when DP_Info.VS_Level_3 =>
462 (case TS.Pre_Emph is
463 when DP_Info.Emph_Level_0 => ( 48, 16#00#, False, 128),
464 when others => Invalid_Buf_Trans));
465 end eDP_Buf_Trans;
466
467 type HDMI_Buf_Trans_Array is array (HDMI_Buf_Trans_Range) of DDI_Buf_Trans;
468 HDMI_Buf_Trans : constant HDMI_Buf_Trans_Array :=
469 (0 => ( 52, 16#9a#, False, 128),
470 1 => ( 52, 16#9a#, False, 85),
471 2 => ( 52, 16#9a#, False, 64),
472 3 => ( 42, 16#9a#, False, 43), -- XXX: typo in i915?
473 4 => ( 77, 16#9a#, False, 128),
474 5 => ( 77, 16#9a#, False, 85),
475 6 => ( 77, 16#9a#, False, 64),
476 7 => (102, 16#9a#, False, 128),
477 8 => (102, 16#9a#, False, 85),
478 9 => (154, 16#9a#, True, 128));
479
480 procedure Set_Signal_Levels
481 (Port : DDI_Phy_Port;
482 Trans : DDI_Buf_Trans)
483 with
484 Pre => True
485 is
486 -- We read from / write to different registers
487 -- to program all lanes in a group at once.
488 Val32 : Word32;
489 begin
490 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
491
492 Read (PORT_PCS (Port).DW10_LN01, Val32);
493 Val32 := Val32 and
494 not PORT_PCS_TX2_SWING_CALC_INIT and
495 not PORT_PCS_TX1_SWING_CALC_INIT;
496 Write (PORT_PCS (Port).DW10_GRP, Val32);
497
498 Read (PORT_TX (Port).DW2_LN0, Val32);
499 Val32 := Val32 and
500 not PORT_TX_DW2_MARGIN_000_MASK and
501 not PORT_TX_DW2_UNIQ_TRANS_SCALE_MASK;
502 Val32 := Val32 or
503 PORT_TX_DW2_MARGIN_000 (Trans.Margin) or
504 PORT_TX_DW2_UNIQ_TRANS_SCALE (Trans.Scale);
505 Write (PORT_TX (Port).DW2_GRP, Val32);
506
507 Read (PORT_TX (Port).DW3_LN0, Val32);
508 Val32 := Val32 and not PORT_TX_DW3_SCALE_DCOMP_METHOD;
509 if Trans.Scale_En then
510 Val32 := Val32 or PORT_TX_DW3_SCALE_DCOMP_METHOD;
511 end if;
512 Write (PORT_TX (Port).DW3_GRP, Val32);
513
514 pragma Debug
515 ((Val32 and PORT_TX_DW3_UNIQUE_TRANGE_EN_METHOD) /= 0 and
516 (Val32 and PORT_TX_DW3_SCALE_DCOMP_METHOD) = 0,
517 Debug.Put_Line ("XXX: Unique trange enabled but scaling disabled."));
518
519 Read (PORT_TX (Port).DW4_LN0, Val32);
520 Val32 := Val32 and not PORT_TX_DW4_DE_EMPHASIS_MASK;
521 Val32 := Val32 or PORT_TX_DW4_DE_EMPHASIS (Trans.De_Emph);
522 Write (PORT_TX (Port).DW4_GRP, Val32);
523
524 Read (PORT_PCS (Port).DW10_LN01, Val32);
525 Val32 := Val32 or
526 PORT_PCS_TX2_SWING_CALC_INIT or
527 PORT_PCS_TX1_SWING_CALC_INIT;
528 Write (PORT_PCS (Port).DW10_GRP, Val32);
529 end Set_Signal_Levels;
530
531 procedure Set_DP_Signal_Levels
532 (Port : Digital_Port;
533 Train_Set : DP_Info.Train_Set)
534 is
535 Trans : constant DDI_Buf_Trans :=
536 (if Port = DIGI_A and Config.EDP_Low_Voltage_Swing then
537 eDP_Buf_Trans (Train_Set)
538 else
539 DP_Buf_Trans (Train_Set));
540 begin
541 if Port in DDI_Phy_Port then
542 Set_Signal_Levels (Port, Trans);
543 end if;
544 end Set_DP_Signal_Levels;
545
546 procedure Set_HDMI_Signal_Levels
547 (Port : DDI_Phy_Port;
548 Level : HDMI_Buf_Trans_Range)
549 is
550 begin
551 Set_Signal_Levels (Port, HDMI_Buf_Trans (Level));
552 end Set_HDMI_Signal_Levels;
553
Nico Huberf6266002017-02-03 12:17:28 +0100554end HW.GFX.GMA.DDI_Phy;