| Tim Wawrzynczak | 5473d29 | 2023-02-06 16:46:33 -0700 | [diff] [blame^] | 1 | -- |
| 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 | |
| 15 | with HW.GFX.DP_Training; |
| 16 | with HW.GFX.GMA.Config; |
| 17 | with HW.GFX.GMA.DP_Aux_Ch; |
| 18 | with HW.GFX.GMA.Registers; |
| 19 | |
| 20 | with HW.Debug; |
| 21 | with GNAT.Source_Info; |
| 22 | |
| 23 | package 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 | |
| 569 | end HW.GFX.GMA.Connectors.Combo_Phy; |