| -- |
| -- Copyright (C) 2022 Google, LLC |
| -- |
| -- This program is free software; you can redistribute it and/or modify |
| -- it under the terms of the GNU General Public License as published by |
| -- the Free Software Foundation; either version 2 of the License, or |
| -- (at your option) any later version. |
| -- |
| -- This program is distributed in the hope that it will be useful, |
| -- but WITHOUT ANY WARRANTY; without even the implied warranty of |
| -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| -- GNU General Public License for more details. |
| -- |
| |
| with HW.GFX.DP_Training; |
| with HW.GFX.GMA.Config; |
| with HW.GFX.GMA.DP_Aux_Ch; |
| with HW.GFX.GMA.Registers; |
| |
| with HW.Debug; |
| with GNAT.Source_Info; |
| |
| package body HW.GFX.GMA.Connectors.Combo_Phy is |
| |
| DDI_BUF_CTL_BUFFER_ENABLE : constant := 1 * 2 ** 31; |
| DDI_BUF_CTL_TRANS_SELECT_MASK : constant := 16#f# * 2 ** 24; |
| DDI_BUF_CTL_PORT_REVERSAL : constant := 1 * 2 ** 16; |
| DDI_BUF_CTL_PORT_WIDTH_MASK : constant := 7 * 2 ** 1; |
| DDI_BUF_CTL_PORT_WIDTH_1_LANE : constant := 0 * 2 ** 1; |
| DDI_BUF_CTL_PORT_WIDTH_2_LANES : constant := 1 * 2 ** 1; |
| DDI_BUF_CTL_PORT_WIDTH_4_LANES : constant := 3 * 2 ** 1; |
| DDI_BUF_CTL_IDLE_STATUS : constant := 1 * 2 ** 7; |
| |
| DDI_BUF_CTL : constant array (Combo_Port) of Registers.Registers_Index := |
| (DIGI_A => Registers.DDI_BUF_CTL_A, |
| DIGI_B => Registers.DDI_BUF_CTL_B, |
| DIGI_C => Registers.DDI_BUF_CTL_C); |
| |
| DDI_BUF_CTL_PORT_WIDTH : constant array (DP_Lane_Count) of Word32 := |
| (HW.GFX.DP_Lane_Count_1 => DDI_BUF_CTL_PORT_WIDTH_1_LANE, |
| HW.GFX.DP_Lane_Count_2 => DDI_BUF_CTL_PORT_WIDTH_2_LANES, |
| HW.GFX.DP_Lane_Count_4 => DDI_BUF_CTL_PORT_WIDTH_4_LANES); |
| |
| type Port_Regs_Record is record |
| PORT_TX_DW5_LN0 : Registers.Registers_Index; |
| PORT_TX_DW5_GRP : Registers.Registers_Index; |
| PORT_TX_DW7_LN0 : Registers.Registers_Index; |
| PORT_TX_DW7_GRP : Registers.Registers_Index; |
| PORT_TX_DW2_LN0 : Registers.Registers_Index; |
| PORT_TX_DW2_GRP : Registers.Registers_Index; |
| PORT_TX_DW4_LN0 : Registers.Registers_Index; |
| PORT_TX_DW4_LN1 : Registers.Registers_Index; |
| PORT_TX_DW4_LN2 : Registers.Registers_Index; |
| PORT_TX_DW4_LN3 : Registers.Registers_Index; |
| PORT_TX_DW4_GRP : Registers.Registers_Index; |
| PORT_PCS_DW1_LN0 : Registers.Registers_Index; |
| PORT_PCS_DW1_GRP : Registers.Registers_Index; |
| PORT_CL_DW5 : Registers.Registers_Index; |
| PORT_CL_DW10 : Registers.Registers_Index; |
| DDI_BUF_CTL : Registers.Registers_Index; |
| end record; |
| |
| Port_Regs : constant array (Combo_Port) of Port_Regs_Record := |
| (DIGI_A => |
| (Registers.PORT_TX_DW5_LN0_A, Registers.PORT_TX_DW5_GRP_A, |
| Registers.PORT_TX_DW7_LN0_A, Registers.PORT_TX_DW7_GRP_A, |
| Registers.PORT_TX_DW2_LN0_A, Registers.PORT_TX_DW2_GRP_A, |
| Registers.PORT_TX_DW4_LN0_A, Registers.PORT_TX_DW4_LN1_A, |
| Registers.PORT_TX_DW4_LN2_A, Registers.PORT_TX_DW4_LN3_A, |
| Registers.PORT_TX_DW4_GRP_A, |
| Registers.PORT_PCS_DW1_LN0_A, Registers.PORT_PCS_DW1_GRP_A, |
| Registers.PORT_CL_DW5_A, |
| Registers.PORT_CL_DW10_A, |
| Registers.DDI_BUF_CTL_A), |
| DIGI_B => |
| (Registers.PORT_TX_DW5_LN0_B, Registers.PORT_TX_DW5_GRP_B, |
| Registers.PORT_TX_DW7_LN0_B, Registers.PORT_TX_DW7_GRP_B, |
| Registers.PORT_TX_DW2_LN0_B, Registers.PORT_TX_DW2_GRP_B, |
| Registers.PORT_TX_DW4_LN0_B, Registers.PORT_TX_DW4_LN1_B, |
| Registers.PORT_TX_DW4_LN2_B, Registers.PORT_TX_DW4_LN3_B, |
| Registers.PORT_TX_DW4_GRP_B, |
| Registers.PORT_PCS_DW1_LN0_B, Registers.PORT_PCS_DW1_GRP_B, |
| Registers.PORT_CL_DW5_B, |
| Registers.PORT_CL_DW10_B, |
| Registers.DDI_BUF_CTL_B), |
| DIGI_C => |
| (Registers.PORT_TX_DW5_LN0_C, Registers.PORT_TX_DW5_GRP_C, |
| Registers.PORT_TX_DW7_LN0_C, Registers.PORT_TX_DW7_GRP_C, |
| Registers.PORT_TX_DW2_LN0_C, Registers.PORT_TX_DW2_GRP_C, |
| Registers.PORT_TX_DW4_LN0_C, Registers.PORT_TX_DW4_LN1_C, |
| Registers.PORT_TX_DW4_LN2_C, Registers.PORT_TX_DW4_LN3_C, |
| Registers.PORT_TX_DW4_GRP_C, |
| Registers.PORT_PCS_DW1_LN0_C, Registers.PORT_PCS_DW1_GRP_C, |
| Registers.PORT_CL_DW5_C, |
| Registers.PORT_CL_DW10_C, |
| Registers.DDI_BUF_CTL_C)); |
| |
| type Lanes is (LN0, LN1, LN2, LN3); |
| function PORT_TX_DW4 (Lane : Lanes; Port : Combo_Port) |
| return Registers.Registers_Index |
| is (case Lane is |
| when LN0 => Port_Regs (Port).PORT_TX_DW4_LN0, |
| when LN1 => Port_Regs (Port).PORT_TX_DW4_LN1, |
| when LN2 => Port_Regs (Port).PORT_TX_DW4_LN2, |
| when LN3 => Port_Regs (Port).PORT_TX_DW4_LN3); |
| |
| PORT_PCS_DW1_LN0_COMMON_KEEPER : constant := 1 * 2 ** 26; |
| |
| type Post_Cursor is new Natural range 0 .. 63; |
| function PORT_TX_DW4_POST_CURSOR1 (P : Post_Cursor) return Word32 is |
| (Shift_Left (Word32 (P), 12)); |
| |
| type Cursor_Coeff is new Natural range 0 .. 63; |
| function PORT_TX_DW4_CURSOR_COEFF (C : Cursor_Coeff) return Word32 is |
| (Word32 (C)); |
| |
| type N_Scalar is new Natural range 0 .. 127; |
| function PORT_TX_DW7_N_SCALAR (N : N_Scalar) return Word32 is |
| (Shift_Left (Word32 (N), 24)); |
| |
| type Swing_Select is new Natural range 0 .. 15; |
| function PORT_TX_SWING_SEL_UPPER (S : Swing_Select) return Word32 is |
| (Shift_Left (Shift_Right (Word32(S), 3), 15)); |
| function PORT_TX_SWING_SEL_LOWER (S : Swing_Select) return Word32 is |
| (Shift_Left (Word32(S), 11)); |
| |
| type Buffer_Trans is record |
| DW2_SWING_SEL : Swing_Select; |
| DW7_N_SCALAR : N_Scalar; |
| DW4_CURSOR_COEFF : Cursor_Coeff; |
| DW4_POST_CURSOR1 : Post_Cursor; |
| end record; |
| |
| type Buffer_Trans_HDMI_Range is new Natural range 0 .. 6; |
| Buffer_Trans_HDMI : constant array (Buffer_Trans_HDMI_Range) of Buffer_Trans := |
| ((16#A#, 16#60#, 16#3F#, 16#00#), |
| (16#B#, 16#73#, 16#36#, 16#09#), |
| (16#6#, 16#7F#, 16#31#, 16#0E#), |
| (16#B#, 16#73#, 16#3F#, 16#00#), |
| (16#6#, 16#7F#, 16#37#, 16#08#), |
| (16#6#, 16#7F#, 16#3F#, 16#00#), |
| (16#6#, 16#7F#, 16#35#, 16#0A#)); |
| |
| type Buffer_Trans_DP_Range is new Natural range 0 .. 9; |
| type Buffer_Trans_DP_Array is array (Buffer_Trans_DP_Range) of Buffer_Trans; |
| |
| TGL_Buffer_Trans_DP_HBR : constant Buffer_Trans_DP_Array := |
| ((16#a#, 16#32#, 16#3f#, 16#00#), |
| (16#a#, 16#4f#, 16#37#, 16#08#), |
| (16#c#, 16#71#, 16#2f#, 16#10#), |
| (16#6#, 16#7d#, 16#2b#, 16#14#), |
| (16#a#, 16#4c#, 16#3f#, 16#00#), |
| (16#c#, 16#73#, 16#34#, 16#0b#), |
| (16#6#, 16#7f#, 16#2f#, 16#10#), |
| (16#c#, 16#6c#, 16#3c#, 16#03#), |
| (16#6#, 16#7f#, 16#35#, 16#0a#), |
| (16#6#, 16#7f#, 16#3f#, 16#00#)); |
| |
| TGL_Buffer_Trans_DP_HBR2 : constant Buffer_Trans_DP_Array := |
| ((16#a#, 16#35#, 16#3f#, 16#00#), |
| (16#a#, 16#4f#, 16#37#, 16#08#), |
| (16#c#, 16#63#, 16#2f#, 16#10#), |
| (16#6#, 16#7f#, 16#2b#, 16#14#), |
| (16#a#, 16#47#, 16#3f#, 16#00#), |
| (16#c#, 16#63#, 16#34#, 16#0b#), |
| (16#6#, 16#7f#, 16#2f#, 16#10#), |
| (16#c#, 16#61#, 16#3c#, 16#03#), |
| (16#6#, 16#7b#, 16#35#, 16#0a#), |
| (16#6#, 16#7f#, 16#3f#, 16#00#)); |
| |
| TGL_Buffer_Trans_DP_HBR2_U_Y : constant Buffer_Trans_DP_Array := |
| ((16#a#, 16#35#, 16#3f#, 16#00#), |
| (16#a#, 16#4f#, 16#36#, 16#09#), |
| (16#c#, 16#60#, 16#32#, 16#0d#), |
| (16#c#, 16#7f#, 16#2d#, 16#12#), |
| (16#c#, 16#47#, 16#3f#, 16#00#), |
| (16#c#, 16#6f#, 16#36#, 16#09#), |
| (16#6#, 16#7d#, 16#32#, 16#0d#), |
| (16#6#, 16#60#, 16#3c#, 16#03#), |
| (16#6#, 16#7f#, 16#34#, 16#0b#), |
| (16#6#, 16#7f#, 16#3f#, 16#00#)); |
| |
| TGL_Buffer_Trans_DP_HBR2_EDP_HBR3 : constant Buffer_Trans_DP_Array := |
| ((16#a#, 16#35#, 16#3f#, 16#00#), |
| (16#a#, 16#4f#, 16#37#, 16#08#), |
| (16#c#, 16#71#, 16#2f#, 16#10#), |
| (16#6#, 16#7f#, 16#2b#, 16#14#), |
| (16#a#, 16#4c#, 16#3f#, 16#00#), |
| (16#c#, 16#73#, 16#34#, 16#0b#), |
| (16#6#, 16#7f#, 16#2f#, 16#10#), |
| (16#c#, 16#6c#, 16#3c#, 16#03#), |
| (16#6#, 16#7f#, 16#35#, 16#0a#), |
| (16#6#, 16#7f#, 16#3f#, 16#00#)); |
| |
| TGL_Buffer_Trans_EDP_HBR2 : constant Buffer_Trans_DP_Array := |
| ((16#0#, 16#7F#, 16#3F#, 16#00#), |
| (16#8#, 16#7F#, 16#38#, 16#07#), |
| (16#1#, 16#7F#, 16#33#, 16#0C#), |
| (16#9#, 16#7F#, 16#31#, 16#0E#), |
| (16#8#, 16#7F#, 16#3F#, 16#00#), |
| (16#1#, 16#7F#, 16#38#, 16#07#), |
| (16#9#, 16#7F#, 16#35#, 16#0A#), |
| (16#1#, 16#7F#, 16#3F#, 16#00#), |
| (16#9#, 16#7F#, 16#38#, 16#07#), |
| (16#9#, 16#7F#, 16#3F#, 16#00#)); |
| |
| ADL_Buffer_Trans_EDP_HBR3 : constant Buffer_Trans_DP_Array := |
| ((16#a#, 16#35#, 16#3f#, 16#00#), |
| (16#a#, 16#4f#, 16#37#, 16#08#), |
| (16#c#, 16#71#, 16#30#, 16#0f#), |
| (16#6#, 16#7f#, 16#2b#, 16#14#), |
| (16#a#, 16#4c#, 16#3f#, 16#00#), |
| (16#c#, 16#73#, 16#34#, 16#0b#), |
| (16#6#, 16#7f#, 16#30#, 16#0f#), |
| (16#c#, 16#63#, 16#3f#, 16#00#), |
| (16#6#, 16#7f#, 16#38#, 16#07#), |
| (16#6#, 16#7f#, 16#3f#, 16#00#)); |
| |
| ADL_Buffer_Trans_EDP_HBR2 : constant Buffer_Trans_DP_Array := |
| ((16#4#, 16#50#, 16#38#, 16#07#), |
| (16#4#, 16#58#, 16#35#, 16#0a#), |
| (16#4#, 16#60#, 16#34#, 16#0b#), |
| (16#4#, 16#6a#, 16#32#, 16#0d#), |
| (16#4#, 16#5e#, 16#38#, 16#07#), |
| (16#4#, 16#61#, 16#36#, 16#09#), |
| (16#4#, 16#6b#, 16#34#, 16#0b#), |
| (16#4#, 16#69#, 16#39#, 16#06#), |
| (16#4#, 16#73#, 16#37#, 16#08#), |
| (16#4#, 16#7a#, 16#38#, 16#07#)); |
| |
| ADL_Buffer_Trans_DP_HBR3 : constant Buffer_Trans_DP_Array := |
| ((16#a#, 16#35#, 16#3f#, 16#00#), |
| (16#a#, 16#4f#, 16#37#, 16#08#), |
| (16#c#, 16#71#, 16#30#, 16#0f#), |
| (16#6#, 16#7f#, 16#2b#, 16#14#), |
| (16#a#, 16#4c#, 16#3f#, 16#00#), |
| (16#c#, 16#73#, 16#34#, 16#0b#), |
| (16#6#, 16#7f#, 16#30#, 16#0f#), |
| (16#c#, 16#63#, 16#3f#, 16#00#), |
| (16#6#, 16#7f#, 16#38#, 16#07#), |
| (16#6#, 16#7f#, 16#3f#, 16#00#)); |
| |
| ADL_Buffer_Trans_DP_HBR : constant Buffer_Trans_DP_Array := |
| ((16#a#, 16#35#, 16#3f#, 16#00#), |
| (16#a#, 16#4f#, 16#37#, 16#08#), |
| (16#c#, 16#71#, 16#31#, 16#0e#), |
| (16#6#, 16#7f#, 16#2c#, 16#13#), |
| (16#a#, 16#4c#, 16#3f#, 16#00#), |
| (16#c#, 16#73#, 16#34#, 16#0b#), |
| (16#6#, 16#7f#, 16#2f#, 16#10#), |
| (16#c#, 16#7c#, 16#3c#, 16#03#), |
| (16#6#, 16#7f#, 16#35#, 16#0a#), |
| (16#6#, 16#7f#, 16#3f#, 16#00#)); |
| |
| PORT_CL_DW10_PWR_DOWN_LN_MASK : constant := 16#f# * 2 ** 4; |
| PORT_CL_DW10_PWR_UP_ALL : constant := 0 * 2 ** 4; |
| PORT_CL_DW10_PWR_DOWN_LN_3_2 : constant := 16#c# * 2 ** 4; |
| PORT_CL_DW10_PWR_DOWN_LN_3_2_1 : constant := 16#e# * 2 ** 4; |
| PORT_CL_DW10_PWR_DOWN_LN_1_0 : constant := 16#3# * 2 ** 4; |
| PORT_CL_DW10_PWR_DOWN_LN_2_1_0 : constant := 16#7# * 2 ** 4; |
| |
| EDP4K2K_MODE_OVRD_EN : constant := 1 * 2 ** 2; |
| EDP4K2K_MODE_OVRD_OPTIMIZED : constant := 1 * 2 ** 3; |
| |
| --------------------------------------------------------------------- |
| |
| procedure Set_Vswing_And_Deemphasis |
| (Port : Combo_Port; |
| Buf_Trans : Buffer_Trans; |
| Display : Display_Type; |
| Lane_Count : DP_Lane_Count) |
| is |
| type Training_Values is (Training_Enable, Training_Disable); |
| |
| PORT_TX_DW5_TX_TRAINING_EN : constant := 1 * 2 ** 31; |
| PORT_TX_DW5_SCALING_MODE_SEL_MASK : constant := 7 * 2 ** 18; |
| PORT_TX_DW5_RTERM_SELECT_MASK : constant := 7 * 2 ** 3; |
| PORT_TX_DW5_TAP2_DISABLE : constant := 1 * 2 ** 30; |
| PORT_TX_DW5_TAP3_DISABLE : constant := 1 * 2 ** 29; |
| PORT_TX_DW5_CURSOR_PROGRAM : constant := 1 * 2 ** 26; |
| PORT_TX_DW5_COEFF_POLARITY : constant := 1 * 2 ** 25; |
| |
| PORT_TX_DW2_RCOMP_SCALAR_MASK : constant := 16#ff# * 2 ** 0; |
| PORT_TX_DW2_SWING_SEL_LOWER_MASK : constant := 7 * 2 ** 11; |
| PORT_TX_DW2_SWING_SEL_UPPER : constant := 1 * 2 ** 15; |
| |
| PORT_TX_DW4_LOADGEN_SELECT : constant := 1 * 2 ** 31; |
| PORT_TX_DW4_POST_CURSOR2_MASK : constant := 16#3f# * 2 ** 6; |
| PORT_TX_DW4_POST_CURSOR1_MASK : constant := 16#3f# * 2 ** 12; |
| PORT_TX_DW4_CURSOR_COEFF_MASK : constant := 16#3f# * 2 ** 0; |
| |
| PORT_TX_DW7_N_SCALAR_MASK : constant := 16#7f# * 2 ** 24; |
| |
| type Scaling_Mode is new Natural range 0 .. 7; |
| function PORT_TX_DW5_SCALING_MODE_SEL (S : Scaling_Mode) return Word32 is |
| (Shift_Left (Word32 (S), 18)); |
| |
| type Rterm_Select is new Natural range 0 .. 7; |
| function PORT_TX_DW5_RTERM_SELECT (R : Rterm_Select) return Word32 is |
| (Shift_Left (Word32 (R), 3)); |
| |
| type Rcomp_Scalar is new Natural range 0 .. 255; |
| function PORT_TX_DW2_RCOMP_SCALAR (R : Rcomp_Scalar) return Word32 is |
| (Word32 (R)); |
| |
| procedure Set_Tx_Training (Port : Combo_Port; Training : Training_Values) is |
| DW5 : Word32; |
| begin |
| Registers.Read (Port_Regs (Port).PORT_TX_DW5_LN0, DW5); |
| Registers.Write |
| (Register => Port_Regs (Port).PORT_TX_DW5_GRP, |
| Value => (if Training = Training_Enable |
| then DW5 or PORT_TX_DW5_TX_TRAINING_EN |
| else DW5 and not PORT_TX_DW5_TX_TRAINING_EN)); |
| end Set_Tx_Training; |
| |
| Tmp : Word32; |
| PORT_CL_DW5_SUS_CLOCK_CONFIG : constant := 3 * 2 ** 0; |
| begin |
| -- Enable common keeper for DP/eDP only |
| Registers.Read (Port_Regs (Port).PORT_PCS_DW1_LN0, Tmp); |
| Registers.Write |
| (Port_Regs (Port).PORT_PCS_DW1_GRP, |
| (if Display = DP |
| then Tmp or PORT_PCS_DW1_LN0_COMMON_KEEPER |
| else Tmp and not PORT_PCS_DW1_LN0_COMMON_KEEPER)); |
| |
| -- Program loadgen select (group access is not allowed since each lane may |
| -- have a unique value. |
| -- <= 6GHz, 4 lanes (0, 1, 1, 1) |
| -- <= 6GHz, 1,2 lanes (0, 1, 1, 0) |
| -- > 6GHz, any lanes (0, 0, 0, 0) |
| for Lane in Lanes loop |
| if (Lane_Count = DP_Lane_Count_4 and Lane /= LN0) or |
| (Lane_Count /= DP_Lane_Count_4 and (Lane = LN1 or Lane = LN2)) |
| then |
| Registers.Set_Mask (PORT_TX_DW4 (Lane, Port), |
| PORT_TX_DW4_LOADGEN_SELECT); |
| else |
| Registers.Unset_Mask (PORT_TX_DW4 (Lane, Port), |
| PORT_TX_DW4_LOADGEN_SELECT); |
| end if; |
| end loop; |
| |
| Registers.Set_Mask |
| (Register => Port_Regs (Port).PORT_CL_DW5, |
| Mask => PORT_CL_DW5_SUS_CLOCK_CONFIG); |
| |
| -- In order to change swing values, training must be disabled |
| Set_Tx_Training (Port, Training_Disable); |
| |
| if Display = DP then |
| Registers.Unset_Mask |
| (Register => Port_Regs (Port).PORT_CL_DW10, |
| Mask => EDP4K2K_MODE_OVRD_EN or EDP4K2K_MODE_OVRD_OPTIMIZED); |
| end if; |
| |
| Registers.Read (Port_Regs (Port).PORT_TX_DW5_LN0, Tmp); |
| Tmp := Tmp and not |
| (PORT_TX_DW5_SCALING_MODE_SEL_MASK or |
| PORT_TX_DW5_RTERM_SELECT_MASK or |
| PORT_TX_DW5_TAP2_DISABLE or |
| PORT_TX_DW5_TAP3_DISABLE or |
| PORT_TX_DW5_CURSOR_PROGRAM or |
| PORT_TX_DW5_COEFF_POLARITY); |
| Tmp := Tmp or |
| PORT_TX_DW5_SCALING_MODE_SEL (2) or |
| PORT_TX_DW5_RTERM_SELECT (6) or |
| PORT_TX_DW5_TAP3_DISABLE; |
| Registers.Write (Port_Regs (Port).PORT_TX_DW5_GRP, Tmp); |
| |
| Registers.Read (Port_Regs (Port).PORT_TX_DW2_LN0, Tmp); |
| Tmp := Tmp and not |
| (PORT_TX_DW2_RCOMP_SCALAR_MASK or |
| PORT_TX_DW2_SWING_SEL_LOWER_MASK or |
| PORT_TX_DW2_SWING_SEL_UPPER); |
| Tmp := Tmp or PORT_TX_SWING_SEL_UPPER (Buf_Trans.DW2_SWING_SEL); |
| Tmp := Tmp or PORT_TX_SWING_SEL_LOWER (Buf_Trans.DW2_SWING_SEL); |
| Tmp := Tmp or PORT_TX_DW2_RCOMP_SCALAR (16#98#); |
| Registers.Write (Port_Regs (Port).PORT_TX_DW2_GRP, Tmp); |
| |
| -- Cannot write to GRP, because it would overwrite individual loadgen bits |
| for Lane in Lanes loop |
| Registers.Read (PORT_TX_DW4 (Lane, Port), Tmp); |
| Tmp := Tmp and not |
| (PORT_TX_DW4_POST_CURSOR2_MASK or |
| PORT_TX_DW4_POST_CURSOR1_MASK or |
| PORT_TX_DW4_CURSOR_COEFF_MASK); |
| Tmp := Tmp or PORT_TX_DW4_POST_CURSOR1 (Buf_Trans.DW4_POST_CURSOR1); |
| Tmp := Tmp or PORT_TX_DW4_CURSOR_COEFF (Buf_Trans.DW4_CURSOR_COEFF); |
| Registers.Write (PORT_TX_DW4 (Lane, Port), Tmp); |
| end loop; |
| |
| Registers.Read (Port_Regs (Port).PORT_TX_DW7_LN0, Tmp); |
| Tmp := Tmp and not PORT_TX_DW7_N_SCALAR_MASK; |
| Tmp := Tmp or PORT_TX_DW7_N_SCALAR (Buf_Trans.DW7_N_SCALAR); |
| Registers.Write (Port_Regs (Port).PORT_TX_DW7_GRP, Tmp); |
| |
| -- To trigger an update of swing values, set training enable |
| Set_Tx_Training (Port, Training_Enable); |
| end Set_Vswing_And_Deemphasis; |
| |
| --------------------------------------------------------------------- |
| |
| procedure Power_Up_Lanes |
| (Port : Combo_Port; |
| Lane_Count : DP_Lane_Count) |
| is |
| Lane_Mask : constant Word32 := |
| (case Lane_Count is |
| -- if Lane_Reversal then PWR_DOWN_LN_2_1_0 |
| -- else PORT_CL_DW10_PWR_DOWN_LN_3_2_1 |
| when DP_Lane_Count_1 => PORT_CL_DW10_PWR_DOWN_LN_3_2_1, |
| -- if Lane_Reversal then PWR_DOWN_1_0 |
| -- else PORT_CL_DW10_PWR_DOWN_LN_3_2 |
| when DP_Lane_Count_2 => PORT_CL_DW10_PWR_DOWN_LN_3_2, |
| when others => PORT_CL_DW10_PWR_UP_ALL); |
| begin |
| Registers.Unset_And_Set_Mask |
| (Register => Port_Regs (Port).PORT_CL_DW10, |
| Mask_Unset => PORT_CL_DW10_PWR_DOWN_LN_MASK, |
| Mask_Set => Lane_Mask); |
| end Power_Up_Lanes; |
| |
| --------------------------------------------------------------------- |
| |
| procedure Set_Signal_Levels |
| (Port : Combo_Port; |
| eDP : Boolean; |
| Link : DP_Link; |
| Train_Set : DP_Info.Train_Set) |
| is |
| function Get_Buf_Trans_Table |
| (eDP : Boolean) return Buffer_Trans_DP_Array is |
| begin |
| if Config.Has_TGL_Buffer_Translations then |
| if eDP then |
| if Link.Bandwidth > DP_Bandwidth_5_4 then |
| return TGL_Buffer_Trans_DP_HBR2_EDP_HBR3; |
| else |
| return TGL_Buffer_Trans_DP_HBR; |
| end if; |
| else |
| if Link.Bandwidth > DP_Bandwidth_2_7 then |
| if Config.Is_LP then |
| return TGL_Buffer_Trans_DP_HBR2_U_Y; |
| else |
| return TGL_Buffer_Trans_DP_HBR2; |
| end if; |
| else |
| return TGL_Buffer_Trans_DP_HBR; |
| end if; |
| end if; |
| else |
| if eDP then |
| if Link.Bandwidth > DP_Bandwidth_5_4 then |
| return ADL_Buffer_Trans_EDP_HBR3; |
| else |
| return ADL_Buffer_Trans_DP_HBR; -- EDP_HBR2 ? |
| end if; |
| else |
| if Link.Bandwidth > DP_Bandwidth_2_7 then |
| return ADL_Buffer_Trans_DP_HBR3; |
| else |
| return ADL_Buffer_Trans_DP_HBR; |
| end if; |
| end if; |
| end if; |
| end Get_Buf_Trans_Table; |
| |
| function To_Buf_Trans_Index |
| (Set : DP_Info.Train_Set) return Buffer_Trans_DP_Range |
| is |
| begin |
| case Set.Voltage_Swing is |
| when DP_Info.VS_Level_0 => |
| case Set.Pre_Emph is |
| when DP_Info.Emph_Level_0 => return 0; |
| when DP_Info.Emph_Level_1 => return 1; |
| when DP_Info.Emph_Level_2 => return 2; |
| when DP_Info.Emph_Level_3 => return 3; |
| end case; |
| when DP_Info.VS_Level_1 => |
| case Set.Pre_Emph is |
| when DP_Info.Emph_Level_0 => return 4; |
| when DP_Info.Emph_Level_1 => return 5; |
| when DP_Info.Emph_Level_2 => return 6; |
| when others => return 0; |
| end case; |
| when DP_Info.VS_Level_2 => |
| case Set.Pre_Emph is |
| when DP_Info.Emph_Level_0 => return 7; |
| when DP_Info.Emph_Level_1 => return 8; |
| when others => return 0; |
| end case; |
| when DP_Info.VS_Level_3 => |
| case Set.Pre_Emph is |
| when DP_Info.Emph_Level_0 => return 9; |
| when others => return 0; |
| end case; |
| end case; |
| end To_Buf_Trans_Index; |
| |
| Was_Enabled : Boolean; |
| Buf_Trans : Buffer_Trans; |
| Entry_Index : constant Buffer_Trans_DP_Range := |
| To_Buf_Trans_Index (Train_Set); |
| begin |
| pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); |
| |
| Registers.Is_Set_Mask |
| (Register => Port_Regs (Port).DDI_BUF_CTL, |
| Mask => DDI_BUF_CTL_BUFFER_ENABLE, |
| Result => Was_Enabled); |
| |
| Buf_Trans := Get_Buf_Trans_Table (eDP) (Entry_Index); |
| |
| Set_Vswing_And_Deemphasis |
| (Port => Port, |
| Buf_Trans => Buf_Trans, |
| Display => DP, |
| Lane_Count => Link.Lane_Count); |
| |
| if not Was_Enabled then |
| Power_Up_Lanes (Port, Link.Lane_Count); |
| end if; |
| |
| Registers.Unset_And_Set_Mask |
| (Register => Port_Regs (Port).DDI_BUF_CTL, |
| Mask_Unset => DDI_BUF_CTL_TRANS_SELECT_MASK or |
| DDI_BUF_CTL_PORT_REVERSAL or |
| DDI_BUF_CTL_PORT_WIDTH_MASK, |
| Mask_Set => DDI_BUF_CTL_BUFFER_ENABLE or |
| DDI_BUF_CTL_PORT_WIDTH (Link.Lane_Count)); |
| Registers.Posting_Read (Port_Regs (Port).DDI_BUF_CTL); |
| |
| if not Was_Enabled then |
| Registers.Wait_Unset_Mask (Port_Regs (Port).DDI_BUF_CTL, DDI_BUF_CTL_IDLE_STATUS); |
| end if; |
| end Set_Signal_Levels; |
| |
| --------------------------------------------------------------------- |
| |
| procedure Enable_HDMI (Port : Combo_Port) |
| is |
| HDMI_Lane_Count : constant DP_Lane_Count := DP_Lane_Count_4; |
| begin |
| Set_Vswing_And_Deemphasis |
| (Port => Port, |
| Buf_Trans => Buffer_Trans_HDMI (Buffer_Trans_HDMI'First), |
| Display => HDMI, |
| Lane_Count => HDMI_Lane_Count); |
| |
| Power_Up_Lanes (Port, HDMI_Lane_Count); |
| |
| Registers.Unset_And_Set_Mask |
| (Register => DDI_BUF_CTL (Port), |
| Mask_Unset => DDI_BUF_CTL_TRANS_SELECT_MASK or |
| DDI_BUF_CTL_PORT_REVERSAL or |
| DDI_BUF_CTL_PORT_WIDTH_MASK, |
| Mask_Set => DDI_BUF_CTL_BUFFER_ENABLE); |
| |
| Registers.Wait_Unset_Mask |
| (Register => DDI_BUF_CTL (Port), |
| Mask => DDI_BUF_CTL_IDLE_STATUS, |
| TOut_MS => 1); |
| end Enable_HDMI; |
| |
| end HW.GFX.GMA.Connectors.Combo_Phy; |