| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 1 | -- |
| 2 | -- Copyright (C) 2016 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 |
| Nico Huber | 125a29e | 2016-10-18 00:23:54 +0200 | [diff] [blame] | 6 | -- the Free Software Foundation; either version 2 of the License, or |
| 7 | -- (at your option) any later version. |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 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.Time; |
| 16 | with HW.GFX.GMA.Config; |
| 17 | with HW.GFX.GMA.PCH.FDI; |
| 18 | with HW.GFX.GMA.Registers; |
| 19 | |
| 20 | with HW.Debug; |
| 21 | with GNAT.Source_Info; |
| 22 | |
| 23 | package body HW.GFX.GMA.Connectors.FDI |
| 24 | is |
| 25 | |
| Nico Huber | 63dc919 | 2018-06-09 17:42:19 +0200 | [diff] [blame] | 26 | use all type PCH.FDI.Training_Pattern; |
| 27 | |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 28 | PCH_FDI_CHICKEN_B_AND_C : constant := 1 * 2 ** 12; |
| 29 | |
| 30 | type TX_CTL_Regs is array (GPU_FDI_Port) of Registers.Registers_Index; |
| 31 | TX_CTL : constant TX_CTL_Regs := |
| 32 | (DIGI_B => Registers.FDI_TX_CTL_A, |
| 33 | DIGI_C => Registers.FDI_TX_CTL_B, |
| 34 | DIGI_D => Registers.FDI_TX_CTL_C); |
| 35 | |
| 36 | FDI_TX_CTL_FDI_TX_ENABLE : constant := 1 * 2 ** 31; |
| 37 | FDI_TX_CTL_VP_MASK : constant := 16#3f# * 2 ** 22; |
| 38 | FDI_TX_CTL_PORT_WIDTH_SEL_SHIFT : constant := 19; |
| 39 | FDI_TX_CTL_ENHANCED_FRAMING_ENABLE : constant := 1 * 2 ** 18; |
| 40 | FDI_TX_CTL_FDI_PLL_ENABLE : constant := 1 * 2 ** 14; |
| 41 | FDI_TX_CTL_COMPOSITE_SYNC_SELECT : constant := 1 * 2 ** 11; |
| 42 | FDI_TX_CTL_AUTO_TRAIN_ENABLE : constant := 1 * 2 ** 10; |
| 43 | FDI_TX_CTL_AUTO_TRAIN_DONE : constant := 1 * 2 ** 1; |
| 44 | |
| Nico Huber | 63dc919 | 2018-06-09 17:42:19 +0200 | [diff] [blame] | 45 | function TP_SHIFT return Natural is |
| 46 | (if Config.Has_New_FDI_Source then 8 else 28); |
| 47 | |
| 48 | function FDI_TX_CTL_TRAINING_PATTERN_MASK |
| 49 | return Word32 is (Shift_Left (3, TP_SHIFT)); |
| 50 | |
| 51 | function FDI_TX_CTL_TRAINING_PATTERN (TP : PCH.FDI.Training_Pattern) |
| 52 | return Word32 is |
| 53 | (case TP is |
| 54 | when TP_1 => Shift_Left (0, TP_SHIFT), |
| 55 | when TP_2 => Shift_Left (1, TP_SHIFT), |
| 56 | when TP_Idle => Shift_Left (2, TP_SHIFT), |
| 57 | when TP_None => Shift_Left (3, TP_SHIFT)); |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 58 | |
| 59 | subtype FDI_TX_CTL_VP_T is Natural range 0 .. 3; |
| 60 | type Vswing_Preemph_Values is array (FDI_TX_CTL_VP_T) of Word32; |
| 61 | FDI_TX_CTL_VSWING_PREEMPH : constant Vswing_Preemph_Values := |
| 62 | (0 => 16#00# * 2 ** 22, |
| 63 | 1 => 16#3a# * 2 ** 22, |
| 64 | 2 => 16#39# * 2 ** 22, |
| 65 | 3 => 16#38# * 2 ** 22); |
| 66 | |
| 67 | function FDI_TX_CTL_PORT_WIDTH_SEL (Lane_Count : DP_Lane_Count) return Word32 |
| 68 | is |
| 69 | begin |
| 70 | return Shift_Left |
| 71 | (Word32 (Lane_Count_As_Integer (Lane_Count)) - 1, |
| 72 | FDI_TX_CTL_PORT_WIDTH_SEL_SHIFT); |
| 73 | end FDI_TX_CTL_PORT_WIDTH_SEL; |
| 74 | |
| 75 | ---------------------------------------------------------------------------- |
| 76 | |
| 77 | -- |
| 78 | -- This is usually used with Ivy Bridge. |
| 79 | -- |
| 80 | procedure Auto_Training |
| 81 | (Port_Cfg : in Port_Config; |
| 82 | Success : out Boolean) |
| 83 | with |
| 84 | Pre => Port_Cfg.Port in GPU_FDI_Port |
| 85 | is |
| 86 | PCH_FDI_Port : constant PCH.FDI_Port_Type := PCH_FDIs (Port_Cfg.Port); |
| 87 | begin |
| 88 | pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); |
| 89 | |
| 90 | -- try each preemph/voltage pair twice |
| 91 | for VP2 in Natural range 0 .. FDI_TX_CTL_VP_T'Last * 2 + 1 |
| 92 | loop |
| 93 | Registers.Unset_And_Set_Mask |
| 94 | (Register => TX_CTL (Port_Cfg.Port), |
| 95 | Mask_Unset => FDI_TX_CTL_VP_MASK or |
| 96 | FDI_TX_CTL_TRAINING_PATTERN_MASK, |
| 97 | Mask_Set => FDI_TX_CTL_FDI_TX_ENABLE or |
| 98 | FDI_TX_CTL_VSWING_PREEMPH (VP2 / 2) or |
| 99 | FDI_TX_CTL_AUTO_TRAIN_ENABLE or |
| Nico Huber | 63dc919 | 2018-06-09 17:42:19 +0200 | [diff] [blame] | 100 | FDI_TX_CTL_TRAINING_PATTERN (TP_1)); |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 101 | Registers.Posting_Read (TX_CTL (Port_Cfg.Port)); |
| 102 | |
| 103 | PCH.FDI.Auto_Train (PCH_FDI_Port); |
| 104 | |
| 105 | -- read at least twice |
| 106 | for I in 0 .. 3 loop |
| 107 | Registers.Is_Set_Mask |
| 108 | (Register => TX_CTL (Port_Cfg.Port), |
| 109 | Mask => FDI_TX_CTL_AUTO_TRAIN_DONE, |
| 110 | Result => Success); |
| 111 | exit when Success or I = 3; |
| 112 | Time.U_Delay (1); |
| 113 | end loop; |
| 114 | exit when Success; |
| 115 | |
| 116 | Registers.Unset_And_Set_Mask |
| 117 | (Register => TX_CTL (Port_Cfg.Port), |
| 118 | Mask_Unset => FDI_TX_CTL_FDI_TX_ENABLE or |
| 119 | FDI_TX_CTL_AUTO_TRAIN_ENABLE or |
| 120 | FDI_TX_CTL_TRAINING_PATTERN_MASK, |
| Nico Huber | 63dc919 | 2018-06-09 17:42:19 +0200 | [diff] [blame] | 121 | Mask_Set => FDI_TX_CTL_TRAINING_PATTERN (TP_1)); |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 122 | |
| 123 | PCH.FDI.Off (PCH_FDI_Port, PCH.FDI.Rx_Off); |
| 124 | end loop; |
| 125 | |
| 126 | if Success then |
| 127 | PCH.FDI.Enable_EC (PCH_FDI_Port); |
| 128 | else |
| 129 | Registers.Unset_Mask |
| 130 | (Register => TX_CTL (Port_Cfg.Port), |
| 131 | Mask => FDI_TX_CTL_FDI_PLL_ENABLE); |
| 132 | |
| 133 | PCH.FDI.Off (PCH_FDI_Port, PCH.FDI.Clock_Off); |
| 134 | end if; |
| 135 | end Auto_Training; |
| 136 | |
| 137 | ---------------------------------------------------------------------------- |
| 138 | |
| 139 | -- |
| 140 | -- Used with Sandy Bridge (should work with Ivy Bridge too) |
| 141 | -- |
| 142 | procedure Full_Training |
| 143 | (Port_Cfg : in Port_Config; |
| 144 | Success : out Boolean) |
| 145 | with |
| 146 | Pre => Port_Cfg.Port in GPU_FDI_Port |
| 147 | is |
| 148 | PCH_FDI_Port : constant PCH.FDI_Port_Type := PCH_FDIs (Port_Cfg.Port); |
| 149 | begin |
| 150 | pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); |
| 151 | |
| 152 | -- try each preemph/voltage pair twice |
| 153 | for VP2 in Natural range 0 .. FDI_TX_CTL_VP_T'Last * 2 + 1 |
| 154 | loop |
| 155 | Registers.Unset_And_Set_Mask |
| 156 | (Register => TX_CTL (Port_Cfg.Port), |
| 157 | Mask_Unset => FDI_TX_CTL_VP_MASK or |
| 158 | FDI_TX_CTL_TRAINING_PATTERN_MASK, |
| 159 | Mask_Set => FDI_TX_CTL_FDI_TX_ENABLE or |
| 160 | FDI_TX_CTL_VSWING_PREEMPH (VP2 / 2) or |
| Nico Huber | 63dc919 | 2018-06-09 17:42:19 +0200 | [diff] [blame] | 161 | FDI_TX_CTL_TRAINING_PATTERN (TP_1)); |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 162 | Registers.Posting_Read (TX_CTL (Port_Cfg.Port)); |
| 163 | |
| Nico Huber | 63dc919 | 2018-06-09 17:42:19 +0200 | [diff] [blame] | 164 | PCH.FDI.Train (PCH_FDI_Port, TP_1, Success); |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 165 | |
| 166 | if Success then |
| 167 | Registers.Unset_And_Set_Mask |
| 168 | (Register => TX_CTL (Port_Cfg.Port), |
| 169 | Mask_Unset => FDI_TX_CTL_TRAINING_PATTERN_MASK, |
| Nico Huber | 63dc919 | 2018-06-09 17:42:19 +0200 | [diff] [blame] | 170 | Mask_Set => FDI_TX_CTL_TRAINING_PATTERN (TP_2)); |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 171 | Registers.Posting_Read (TX_CTL (Port_Cfg.Port)); |
| 172 | |
| Nico Huber | 63dc919 | 2018-06-09 17:42:19 +0200 | [diff] [blame] | 173 | PCH.FDI.Train (PCH_FDI_Port, TP_2, Success); |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 174 | end if; |
| 175 | exit when Success; |
| 176 | |
| 177 | Registers.Unset_And_Set_Mask |
| 178 | (Register => TX_CTL (Port_Cfg.Port), |
| 179 | Mask_Unset => FDI_TX_CTL_FDI_TX_ENABLE or |
| 180 | FDI_TX_CTL_TRAINING_PATTERN_MASK, |
| Nico Huber | 63dc919 | 2018-06-09 17:42:19 +0200 | [diff] [blame] | 181 | Mask_Set => FDI_TX_CTL_TRAINING_PATTERN (TP_1)); |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 182 | |
| 183 | PCH.FDI.Off (PCH_FDI_Port, PCH.FDI.Rx_Off); |
| 184 | end loop; |
| 185 | |
| 186 | if Success then |
| 187 | Registers.Unset_And_Set_Mask |
| 188 | (Register => TX_CTL (Port_Cfg.Port), |
| 189 | Mask_Unset => FDI_TX_CTL_TRAINING_PATTERN_MASK, |
| Nico Huber | 63dc919 | 2018-06-09 17:42:19 +0200 | [diff] [blame] | 190 | Mask_Set => FDI_TX_CTL_TRAINING_PATTERN (TP_None)); |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 191 | Registers.Posting_Read (TX_CTL (Port_Cfg.Port)); |
| 192 | |
| Nico Huber | 63dc919 | 2018-06-09 17:42:19 +0200 | [diff] [blame] | 193 | PCH.FDI.Train (PCH_FDI_Port, TP_None, Success); |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 194 | else |
| 195 | Registers.Unset_Mask |
| 196 | (Register => TX_CTL (Port_Cfg.Port), |
| 197 | Mask => FDI_TX_CTL_FDI_PLL_ENABLE); |
| 198 | |
| 199 | PCH.FDI.Off (PCH_FDI_Port, PCH.FDI.Clock_Off); |
| 200 | end if; |
| 201 | end Full_Training; |
| 202 | |
| 203 | ---------------------------------------------------------------------------- |
| 204 | |
| 205 | -- |
| 206 | -- Used with original Ironlake (Nehalem CPU) |
| 207 | -- |
| 208 | -- This is close to what Linux' i915 does. A comment in i915_reg.h |
| 209 | -- states that it uses only the lowest voltage / pre-emphasis levels |
| 210 | -- which is why we leave them at zero here and don't try different |
| 211 | -- values. |
| 212 | -- |
| 213 | -- It's actually not clear from i915's code if the values really are |
| 214 | -- at zero or if it's just reusing what the Video BIOS set. Some code |
| 215 | -- in coreboot sets them to zero explicitly. |
| 216 | -- |
| 217 | procedure Simple_Training |
| 218 | (Port_Cfg : in Port_Config; |
| 219 | Success : out Boolean) |
| 220 | with |
| 221 | Pre => Port_Cfg.Port in GPU_FDI_Port |
| 222 | is |
| 223 | PCH_FDI_Port : constant PCH.FDI_Port_Type := PCH_FDIs (Port_Cfg.Port); |
| 224 | begin |
| 225 | pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); |
| 226 | |
| 227 | Registers.Unset_And_Set_Mask |
| 228 | (Register => TX_CTL (Port_Cfg.Port), |
| 229 | Mask_Unset => FDI_TX_CTL_TRAINING_PATTERN_MASK, |
| 230 | Mask_Set => FDI_TX_CTL_FDI_TX_ENABLE or |
| Nico Huber | 63dc919 | 2018-06-09 17:42:19 +0200 | [diff] [blame] | 231 | FDI_TX_CTL_TRAINING_PATTERN (TP_1)); |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 232 | Registers.Posting_Read (TX_CTL (Port_Cfg.Port)); |
| 233 | |
| Nico Huber | 63dc919 | 2018-06-09 17:42:19 +0200 | [diff] [blame] | 234 | PCH.FDI.Train (PCH_FDI_Port, TP_1, Success); |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 235 | |
| 236 | if Success then |
| 237 | Registers.Unset_And_Set_Mask |
| 238 | (Register => TX_CTL (Port_Cfg.Port), |
| 239 | Mask_Unset => FDI_TX_CTL_TRAINING_PATTERN_MASK, |
| Nico Huber | 63dc919 | 2018-06-09 17:42:19 +0200 | [diff] [blame] | 240 | Mask_Set => FDI_TX_CTL_TRAINING_PATTERN (TP_2)); |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 241 | Registers.Posting_Read (TX_CTL (Port_Cfg.Port)); |
| 242 | |
| Nico Huber | 63dc919 | 2018-06-09 17:42:19 +0200 | [diff] [blame] | 243 | PCH.FDI.Train (PCH_FDI_Port, TP_2, Success); |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 244 | end if; |
| 245 | |
| 246 | if Success then |
| 247 | Registers.Unset_And_Set_Mask |
| 248 | (Register => TX_CTL (Port_Cfg.Port), |
| 249 | Mask_Unset => FDI_TX_CTL_TRAINING_PATTERN_MASK, |
| Nico Huber | 63dc919 | 2018-06-09 17:42:19 +0200 | [diff] [blame] | 250 | Mask_Set => FDI_TX_CTL_TRAINING_PATTERN (TP_None)); |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 251 | Registers.Posting_Read (TX_CTL (Port_Cfg.Port)); |
| 252 | |
| Nico Huber | 63dc919 | 2018-06-09 17:42:19 +0200 | [diff] [blame] | 253 | PCH.FDI.Train (PCH_FDI_Port, TP_None, Success); |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 254 | else |
| 255 | Registers.Unset_And_Set_Mask |
| 256 | (Register => TX_CTL (Port_Cfg.Port), |
| 257 | Mask_Unset => FDI_TX_CTL_FDI_TX_ENABLE or |
| 258 | FDI_TX_CTL_TRAINING_PATTERN_MASK, |
| Nico Huber | 63dc919 | 2018-06-09 17:42:19 +0200 | [diff] [blame] | 259 | Mask_Set => FDI_TX_CTL_TRAINING_PATTERN (TP_1)); |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 260 | PCH.FDI.Off (PCH_FDI_Port, PCH.FDI.Rx_Off); |
| 261 | |
| 262 | Registers.Unset_Mask |
| 263 | (Register => TX_CTL (Port_Cfg.Port), |
| 264 | Mask => FDI_TX_CTL_FDI_PLL_ENABLE); |
| 265 | PCH.FDI.Off (PCH_FDI_Port, PCH.FDI.Clock_Off); |
| 266 | end if; |
| 267 | end Simple_Training; |
| 268 | |
| 269 | ---------------------------------------------------------------------------- |
| 270 | |
| 271 | procedure Pre_On (Port_Cfg : Port_Config) |
| 272 | is |
| Nico Huber | 63ec836 | 2018-06-09 17:42:19 +0200 | [diff] [blame^] | 273 | Composite_Sel : constant Word32 := |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 274 | (if Config.Has_FDI_Composite_Sel then |
| 275 | FDI_TX_CTL_COMPOSITE_SYNC_SELECT else 0); |
| 276 | begin |
| 277 | pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); |
| 278 | |
| 279 | -- The PCH_FDI_CHICKEN_B_AND_C bit may not be changed when any of |
| 280 | -- both ports is active. Bandwidth calculations before calling us |
| 281 | -- should ensure this. |
| 282 | if Config.Has_FDI_C then |
| 283 | if Port_Cfg.Port = DIGI_D or |
| 284 | (Port_Cfg.Port = DIGI_C and |
| 285 | Port_Cfg.FDI.Lane_Count <= DP_Lane_Count_2) |
| 286 | then |
| 287 | Registers.Set_Mask |
| 288 | (Register => Registers.PCH_FDI_CHICKEN_B_C, |
| 289 | Mask => PCH_FDI_CHICKEN_B_AND_C); |
| 290 | elsif Port_Cfg.Port = DIGI_C then |
| 291 | Registers.Unset_Mask |
| 292 | (Register => Registers.PCH_FDI_CHICKEN_B_C, |
| 293 | Mask => PCH_FDI_CHICKEN_B_AND_C); |
| 294 | end if; |
| 295 | end if; |
| 296 | |
| 297 | PCH.FDI.Pre_Train (PCH_FDIs (Port_Cfg.Port), Port_Cfg); |
| 298 | |
| 299 | Registers.Write |
| 300 | (Register => TX_CTL (Port_Cfg.Port), |
| 301 | Value => FDI_TX_CTL_PORT_WIDTH_SEL (Port_Cfg.FDI.Lane_Count) or |
| 302 | FDI_TX_CTL_ENHANCED_FRAMING_ENABLE or |
| 303 | FDI_TX_CTL_FDI_PLL_ENABLE or |
| 304 | Composite_Sel or |
| Nico Huber | 63dc919 | 2018-06-09 17:42:19 +0200 | [diff] [blame] | 305 | FDI_TX_CTL_TRAINING_PATTERN (TP_1)); |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 306 | Registers.Posting_Read (TX_CTL (Port_Cfg.Port)); |
| 307 | Time.U_Delay (100); |
| 308 | end Pre_On; |
| 309 | |
| 310 | ---------------------------------------------------------------------------- |
| 311 | |
| 312 | procedure Post_On |
| 313 | (Port_Cfg : in Port_Config; |
| 314 | Success : out Boolean) |
| 315 | is |
| 316 | begin |
| 317 | pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); |
| 318 | |
| 319 | case Config.FDI_Training is |
| 320 | when GMA.Simple_Training => Simple_Training (Port_Cfg, Success); |
| 321 | when GMA.Full_Training => Full_Training (Port_Cfg, Success); |
| 322 | when GMA.Auto_Training => Auto_Training (Port_Cfg, Success); |
| 323 | end case; |
| 324 | end Post_On; |
| 325 | |
| 326 | ---------------------------------------------------------------------------- |
| 327 | |
| 328 | procedure Off (Port : GPU_FDI_Port; OT : Off_Type) |
| 329 | is |
| 330 | PCH_FDI_Port : constant PCH.FDI_Port_Type := PCH_FDIs (Port); |
| 331 | begin |
| 332 | pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); |
| 333 | |
| 334 | Registers.Unset_And_Set_Mask |
| 335 | (Register => TX_CTL (Port), |
| 336 | Mask_Unset => FDI_TX_CTL_FDI_TX_ENABLE or |
| 337 | FDI_TX_CTL_AUTO_TRAIN_ENABLE or |
| 338 | FDI_TX_CTL_TRAINING_PATTERN_MASK, |
| Nico Huber | 63dc919 | 2018-06-09 17:42:19 +0200 | [diff] [blame] | 339 | Mask_Set => FDI_TX_CTL_TRAINING_PATTERN (TP_1)); |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 340 | |
| 341 | PCH.FDI.Off (PCH_FDI_Port, PCH.FDI.Rx_Off); |
| 342 | |
| 343 | if OT >= Clock_Off then |
| 344 | Registers.Unset_Mask |
| 345 | (Register => TX_CTL (Port), |
| 346 | Mask => FDI_TX_CTL_FDI_PLL_ENABLE); |
| 347 | |
| 348 | PCH.FDI.Off (PCH_FDI_Port, PCH.FDI.Clock_Off); |
| 349 | end if; |
| 350 | end Off; |
| 351 | |
| 352 | end HW.GFX.GMA.Connectors.FDI; |