| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 1 | -- |
| Nico Huber | 6b4678d | 2019-09-22 21:31:52 +0200 | [diff] [blame] | 2 | -- Copyright (C) 2014-2016, 2019 secunet Security Networks AG |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 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 GNAT.Source_Info; |
| 16 | |
| 17 | with HW.Time; |
| 18 | with HW.Debug; |
| 19 | with HW.GFX.GMA.Config; |
| 20 | with HW.GFX.GMA.Registers; |
| Nico Huber | 312433c | 2019-09-28 03:15:48 +0200 | [diff] [blame] | 21 | with HW.GFX.GMA.PCode; |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 22 | with HW.GFX.GMA.Power_And_Clocks_Haswell; |
| 23 | |
| 24 | use type HW.Word64; |
| 25 | |
| 26 | package body HW.GFX.GMA.Power_And_Clocks_Skylake is |
| 27 | |
| 28 | type Power_Domain is (MISC_IO, PW1, PW2, DDI_AE, DDI_B, DDI_C, DDI_D); |
| 29 | subtype Power_Well is Power_Domain range PW1 .. PW2; |
| 30 | subtype Dynamic_Domain is Power_Domain range PW2 .. DDI_D; |
| 31 | |
| 32 | NDE_RSTWRN_OPT_RST_PCH_Handshake_En : constant := 1 * 2 ** 4; |
| 33 | |
| 34 | FUSE_STATUS_DOWNLOAD_STATUS : constant := 1 * 2 ** 31; |
| 35 | FUSE_STATUS_PG0_DIST_STATUS : constant := 1 * 2 ** 27; |
| 36 | |
| Nico Huber | 6b4678d | 2019-09-22 21:31:52 +0200 | [diff] [blame] | 37 | DFSM_DISPLAY_CDCLK_LIMIT_675MHZ : constant := 0 * 2 ** 23; |
| 38 | DFSM_DISPLAY_CDCLK_LIMIT_540MHZ : constant := 1 * 2 ** 23; |
| 39 | DFSM_DISPLAY_CDCLK_LIMIT_450MHZ : constant := 2 * 2 ** 23; |
| 40 | DFSM_DISPLAY_CDCLK_LIMIT_337_5MHZ : constant := 3 * 2 ** 23; |
| 41 | DFSM_DISPLAY_CDCLK_LIMIT_MASK : constant := 3 * 2 ** 23; |
| 42 | |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 43 | type Power_Domain_Values is array (Power_Domain) of Word32; |
| 44 | PWR_WELL_CTL_POWER_REQUEST : constant Power_Domain_Values := |
| 45 | (MISC_IO => 1 * 2 ** 1, |
| 46 | DDI_AE => 1 * 2 ** 3, |
| 47 | DDI_B => 1 * 2 ** 5, |
| 48 | DDI_C => 1 * 2 ** 7, |
| 49 | DDI_D => 1 * 2 ** 9, |
| 50 | PW1 => 1 * 2 ** 29, |
| 51 | PW2 => 1 * 2 ** 31); |
| 52 | PWR_WELL_CTL_POWER_STATE : constant Power_Domain_Values := |
| 53 | (MISC_IO => 1 * 2 ** 0, |
| 54 | DDI_AE => 1 * 2 ** 2, |
| 55 | DDI_B => 1 * 2 ** 4, |
| 56 | DDI_C => 1 * 2 ** 6, |
| 57 | DDI_D => 1 * 2 ** 8, |
| 58 | PW1 => 1 * 2 ** 28, |
| 59 | PW2 => 1 * 2 ** 30); |
| 60 | |
| 61 | type Power_Well_Values is array (Power_Well) of Word32; |
| 62 | FUSE_STATUS_PGx_DIST_STATUS : constant Power_Well_Values := |
| 63 | (PW1 => 1 * 2 ** 26, |
| 64 | PW2 => 1 * 2 ** 25); |
| 65 | |
| 66 | DBUF_CTL_DBUF_POWER_REQUEST : constant := 1 * 2 ** 31; |
| 67 | DBUF_CTL_DBUF_POWER_STATE : constant := 1 * 2 ** 30; |
| 68 | |
| 69 | ---------------------------------------------------------------------------- |
| 70 | |
| 71 | DPLL_CTRL1_DPLL0_LINK_RATE_MASK : constant := 7 * 2 ** 1; |
| 72 | DPLL_CTRL1_DPLL0_LINK_RATE_2700MHZ : constant := 0 * 2 ** 1; |
| 73 | DPLL_CTRL1_DPLL0_LINK_RATE_1350MHZ : constant := 1 * 2 ** 1; |
| 74 | DPLL_CTRL1_DPLL0_LINK_RATE_810MHZ : constant := 2 * 2 ** 1; |
| 75 | DPLL_CTRL1_DPLL0_LINK_RATE_1620MHZ : constant := 3 * 2 ** 1; |
| 76 | DPLL_CTRL1_DPLL0_LINK_RATE_1080MHZ : constant := 4 * 2 ** 1; |
| 77 | DPLL_CTRL1_DPLL0_LINK_RATE_2160MHZ : constant := 5 * 2 ** 1; |
| 78 | DPLL_CTRL1_DPLL0_OVERRIDE : constant := 1 * 2 ** 0; |
| 79 | |
| 80 | LCPLL1_CTL_PLL_ENABLE : constant := 1 * 2 ** 31; |
| 81 | LCPLL1_CTL_PLL_LOCK : constant := 1 * 2 ** 30; |
| 82 | |
| 83 | ---------------------------------------------------------------------------- |
| 84 | |
| 85 | CDCLK_CTL_CD_FREQ_SELECT_MASK : constant := 3 * 2 ** 26; |
| 86 | CDCLK_CTL_CD_FREQ_SELECT_450MHZ : constant := 0 * 2 ** 26; |
| 87 | CDCLK_CTL_CD_FREQ_SELECT_540MHZ : constant := 1 * 2 ** 26; |
| 88 | CDCLK_CTL_CD_FREQ_SELECT_337_5MHZ : constant := 2 * 2 ** 26; |
| 89 | CDCLK_CTL_CD_FREQ_SELECT_675MHZ : constant := 3 * 2 ** 26; |
| 90 | CDCLK_CTL_CD_FREQ_DECIMAL_MASK : constant := 16#7ff#; |
| 91 | |
| 92 | SKL_PCODE_CDCLK_CONTROL : constant := 7; |
| 93 | SKL_CDCLK_PREPARE_FOR_CHANGE : constant := 3; |
| 94 | SKL_CDCLK_READY_FOR_CHANGE : constant := 1; |
| 95 | |
| Nico Huber | 6b4678d | 2019-09-22 21:31:52 +0200 | [diff] [blame] | 96 | function CDCLK_CTL_CD_FREQ_DECIMAL (CDClk : Frequency_Type) return Word32 is |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 97 | begin |
| Nico Huber | 6b4678d | 2019-09-22 21:31:52 +0200 | [diff] [blame] | 98 | -- Weirdest representation: CDClk - 1MHz in 10.1 (10 + 1 fractional bit) |
| 99 | return Word32 ((CDClk - 1_000_000) / 500_000); |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 100 | end CDCLK_CTL_CD_FREQ_DECIMAL; |
| 101 | |
| 102 | ---------------------------------------------------------------------------- |
| 103 | |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 104 | procedure PD_Off (PD : Power_Domain) |
| 105 | is |
| 106 | Ctl1, Ctl2, Ctl3, Ctl4 : Word32; |
| 107 | begin |
| 108 | pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); |
| 109 | |
| 110 | Registers.Read (Registers.PWR_WELL_CTL_BIOS, Ctl1); |
| 111 | Registers.Read (Registers.PWR_WELL_CTL_DRIVER, Ctl2); |
| 112 | Registers.Read (Registers.PWR_WELL_CTL_KVMR, Ctl3); |
| 113 | Registers.Read (Registers.PWR_WELL_CTL_DEBUG, Ctl4); |
| 114 | pragma Debug (Registers.Posting_Read (Registers.PWR_WELL_CTL5)); -- Result for debugging only |
| 115 | pragma Debug (Registers.Posting_Read (Registers.PWR_WELL_CTL6)); -- Result for debugging only |
| 116 | |
| 117 | if ((Ctl1 or Ctl2 or Ctl3 or Ctl4) and |
| 118 | PWR_WELL_CTL_POWER_REQUEST (PD)) /= 0 |
| 119 | then |
| 120 | Registers.Wait_Set_Mask |
| 121 | (Register => Registers.PWR_WELL_CTL_DRIVER, |
| 122 | Mask => PWR_WELL_CTL_POWER_STATE (PD)); |
| 123 | end if; |
| 124 | |
| 125 | if (Ctl1 and PWR_WELL_CTL_POWER_REQUEST (PD)) /= 0 then |
| 126 | Registers.Unset_Mask |
| 127 | (Register => Registers.PWR_WELL_CTL_BIOS, |
| 128 | Mask => PWR_WELL_CTL_POWER_REQUEST (PD)); |
| 129 | end if; |
| 130 | |
| 131 | if (Ctl2 and PWR_WELL_CTL_POWER_REQUEST (PD)) /= 0 then |
| 132 | Registers.Unset_Mask |
| 133 | (Register => Registers.PWR_WELL_CTL_DRIVER, |
| 134 | Mask => PWR_WELL_CTL_POWER_REQUEST (PD)); |
| 135 | end if; |
| 136 | end PD_Off; |
| 137 | |
| 138 | procedure PD_On (PD : Power_Domain) |
| 139 | with |
| 140 | Pre => True |
| 141 | is |
| 142 | Ctl1, Ctl2, Ctl3, Ctl4 : Word32; |
| 143 | begin |
| 144 | pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); |
| 145 | |
| 146 | Registers.Read (Registers.PWR_WELL_CTL_BIOS, Ctl1); |
| 147 | Registers.Read (Registers.PWR_WELL_CTL_DRIVER, Ctl2); |
| 148 | Registers.Read (Registers.PWR_WELL_CTL_KVMR, Ctl3); |
| 149 | Registers.Read (Registers.PWR_WELL_CTL_DEBUG, Ctl4); |
| 150 | pragma Debug (Registers.Posting_Read (Registers.PWR_WELL_CTL5)); -- Result for debugging only |
| 151 | pragma Debug (Registers.Posting_Read (Registers.PWR_WELL_CTL6)); -- Result for debugging only |
| 152 | |
| 153 | if ((Ctl1 or Ctl2 or Ctl3 or Ctl4) and |
| 154 | PWR_WELL_CTL_POWER_REQUEST (PD)) = 0 |
| 155 | then |
| 156 | Registers.Wait_Unset_Mask |
| 157 | (Register => Registers.PWR_WELL_CTL_DRIVER, |
| 158 | Mask => PWR_WELL_CTL_POWER_STATE (PD)); |
| 159 | end if; |
| 160 | |
| 161 | if (Ctl2 and PWR_WELL_CTL_POWER_REQUEST (PD)) = 0 then |
| 162 | Registers.Set_Mask |
| 163 | (Register => Registers.PWR_WELL_CTL_DRIVER, |
| 164 | Mask => PWR_WELL_CTL_POWER_REQUEST (PD)); |
| 165 | Registers.Wait_Set_Mask |
| 166 | (Register => Registers.PWR_WELL_CTL_DRIVER, |
| 167 | Mask => PWR_WELL_CTL_POWER_STATE (PD)); |
| 168 | |
| 169 | if PD in Power_Well then |
| 170 | Registers.Wait_Set_Mask |
| 171 | (Register => Registers.FUSE_STATUS, |
| 172 | Mask => FUSE_STATUS_PGx_DIST_STATUS (PD)); |
| 173 | end if; |
| 174 | end if; |
| 175 | end PD_On; |
| 176 | |
| Nico Huber | 99f10f3 | 2016-11-20 00:34:05 +0100 | [diff] [blame] | 177 | function Need_PD (PD : Dynamic_Domain; Configs : Pipe_Configs) return Boolean |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 178 | is |
| 179 | begin |
| 180 | return (case PD is |
| Nico Huber | 8beafd7 | 2020-01-07 14:59:44 +0100 | [diff] [blame] | 181 | when DDI_AE => Configs (Primary).Port = eDP or |
| 182 | Configs (Secondary).Port = eDP or |
| 183 | Configs (Tertiary).Port = eDP, |
| Nico Huber | 0d454cd | 2016-11-21 13:33:43 +0100 | [diff] [blame] | 184 | when DDI_B => Configs (Primary).Port = HDMI1 or |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 185 | Configs (Primary).Port = DP1 or |
| Nico Huber | 0d454cd | 2016-11-21 13:33:43 +0100 | [diff] [blame] | 186 | Configs (Secondary).Port = HDMI1 or |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 187 | Configs (Secondary).Port = DP1 or |
| Nico Huber | 0d454cd | 2016-11-21 13:33:43 +0100 | [diff] [blame] | 188 | Configs (Tertiary).Port = HDMI1 or |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 189 | Configs (Tertiary).Port = DP1, |
| Nico Huber | 0d454cd | 2016-11-21 13:33:43 +0100 | [diff] [blame] | 190 | when DDI_C => Configs (Primary).Port = HDMI2 or |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 191 | Configs (Primary).Port = DP2 or |
| Nico Huber | 0d454cd | 2016-11-21 13:33:43 +0100 | [diff] [blame] | 192 | Configs (Secondary).Port = HDMI2 or |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 193 | Configs (Secondary).Port = DP2 or |
| Nico Huber | 0d454cd | 2016-11-21 13:33:43 +0100 | [diff] [blame] | 194 | Configs (Tertiary).Port = HDMI2 or |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 195 | Configs (Tertiary).Port = DP2, |
| Nico Huber | 0d454cd | 2016-11-21 13:33:43 +0100 | [diff] [blame] | 196 | when DDI_D => Configs (Primary).Port = HDMI3 or |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 197 | Configs (Primary).Port = DP3 or |
| Nico Huber | 0d454cd | 2016-11-21 13:33:43 +0100 | [diff] [blame] | 198 | Configs (Secondary).Port = HDMI3 or |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 199 | Configs (Secondary).Port = DP3 or |
| Nico Huber | 0d454cd | 2016-11-21 13:33:43 +0100 | [diff] [blame] | 200 | Configs (Tertiary).Port = HDMI3 or |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 201 | Configs (Tertiary).Port = DP3, |
| 202 | when PW2 => (Configs (Primary).Port /= Disabled and |
| Nico Huber | 8beafd7 | 2020-01-07 14:59:44 +0100 | [diff] [blame] | 203 | Configs (Primary).Port /= eDP) or |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 204 | Configs (Secondary).Port /= Disabled or |
| 205 | Configs (Tertiary).Port /= Disabled); |
| 206 | end Need_PD; |
| 207 | |
| 208 | ---------------------------------------------------------------------------- |
| 209 | |
| 210 | procedure Pre_All_Off is |
| 211 | begin |
| 212 | Power_And_Clocks_Haswell.PSR_Off; |
| 213 | end Pre_All_Off; |
| 214 | |
| 215 | procedure Post_All_Off is |
| 216 | begin |
| 217 | for PD in reverse Dynamic_Domain loop |
| 218 | PD_Off (PD); |
| 219 | end loop; |
| 220 | |
| 221 | Registers.Unset_Mask |
| 222 | (Register => Registers.DBUF_CTL, |
| 223 | Mask => DBUF_CTL_DBUF_POWER_REQUEST); |
| 224 | Registers.Wait_Unset_Mask |
| 225 | (Register => Registers.DBUF_CTL, |
| 226 | Mask => DBUF_CTL_DBUF_POWER_STATE); |
| 227 | |
| 228 | Registers.Unset_Mask |
| 229 | (Register => Registers.LCPLL1_CTL, |
| 230 | Mask => LCPLL1_CTL_PLL_ENABLE); |
| 231 | Registers.Wait_Unset_Mask |
| 232 | (Register => Registers.LCPLL1_CTL, |
| 233 | Mask => LCPLL1_CTL_PLL_LOCK); |
| 234 | |
| 235 | PD_Off (MISC_IO); |
| 236 | PD_Off (PW1); |
| 237 | end Post_All_Off; |
| 238 | |
| Nico Huber | 6b4678d | 2019-09-22 21:31:52 +0200 | [diff] [blame] | 239 | function Normalize_CDClk (CDClk : in Int64) return Config.CDClk_Range is |
| 240 | ( if CDClk <= 337_500_000 then 337_500_000 |
| 241 | elsif CDClk <= 450_000_000 then 450_000_000 |
| 242 | elsif CDClk <= 540_000_000 then 540_000_000 |
| 243 | else 675_000_000); |
| 244 | |
| 245 | procedure Get_Cur_CDClk (CDClk : out Config.CDClk_Range) |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 246 | is |
| Nico Huber | 6b4678d | 2019-09-22 21:31:52 +0200 | [diff] [blame] | 247 | CDCLK_CTL : Word32; |
| 248 | begin |
| 249 | Registers.Read (Registers.CDCLK_CTL, CDCLK_CTL); |
| 250 | CDCLK_CTL := CDCLK_CTL and CDCLK_CTL_CD_FREQ_DECIMAL_MASK; |
| 251 | CDClk := Normalize_CDClk (Int64 (CDCLK_CTL) * 500_000 + 1_000_000); |
| 252 | end Get_Cur_CDClk; |
| 253 | |
| 254 | procedure Get_Max_CDClk (CDClk : out Config.CDClk_Range) |
| 255 | is |
| 256 | DFSM : Word32; |
| 257 | begin |
| 258 | Registers.Read (Registers.DFSM, DFSM); |
| 259 | CDClk := |
| 260 | (case DFSM and DFSM_DISPLAY_CDCLK_LIMIT_MASK is |
| 261 | when DFSM_DISPLAY_CDCLK_LIMIT_675MHZ => 675_000_000, |
| 262 | when DFSM_DISPLAY_CDCLK_LIMIT_540MHZ => 540_000_000, |
| 263 | when DFSM_DISPLAY_CDCLK_LIMIT_450MHZ => 450_000_000, |
| 264 | when others => 337_500_000); |
| 265 | end Get_Max_CDClk; |
| 266 | |
| 267 | procedure Set_CDClk (CDClk_In : Frequency_Type) |
| 268 | is |
| 269 | CDClk : constant Config.CDClk_Range := |
| 270 | Normalize_CDClk (Frequency_Type'Min (CDClk_In, Config.Max_CDClk)); |
| Nico Huber | 312433c | 2019-09-28 03:15:48 +0200 | [diff] [blame] | 271 | Success : Boolean; |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 272 | begin |
| Nico Huber | 6b4678d | 2019-09-22 21:31:52 +0200 | [diff] [blame] | 273 | PCode.Mailbox_Request |
| 274 | (MBox => SKL_PCODE_CDCLK_CONTROL, |
| 275 | Command => SKL_CDCLK_PREPARE_FOR_CHANGE, |
| 276 | Reply_Mask => SKL_CDCLK_READY_FOR_CHANGE, |
| 277 | Wait_Ready => True, |
| 278 | Success => Success); |
| 279 | |
| 280 | if not Success then |
| 281 | pragma Debug (Debug.Put_Line |
| 282 | ("ERROR: PCODE not ready for frequency change.")); |
| 283 | return; |
| 284 | end if; |
| 285 | |
| 286 | Registers.Write |
| 287 | (Register => Registers.CDCLK_CTL, |
| 288 | Value => (case CDClk is |
| 289 | when 675_000_000 => CDCLK_CTL_CD_FREQ_SELECT_675MHZ, |
| 290 | when 540_000_000 => CDCLK_CTL_CD_FREQ_SELECT_540MHZ, |
| 291 | when 450_000_000 => CDCLK_CTL_CD_FREQ_SELECT_450MHZ, |
| 292 | when others => CDCLK_CTL_CD_FREQ_SELECT_337_5MHZ) |
| 293 | or CDCLK_CTL_CD_FREQ_DECIMAL (CDClk)); |
| 294 | |
| 295 | PCode.Mailbox_Write |
| 296 | (MBox => SKL_PCODE_CDCLK_CONTROL, |
| 297 | Command => (case CDClk is |
| 298 | when 675_000_000 => 3, |
| 299 | when 540_000_000 => 2, |
| 300 | when 450_000_000 => 1, |
| 301 | when others => 0)); |
| 302 | Registers.Set_Mask |
| 303 | (Register => Registers.DBUF_CTL, |
| 304 | Mask => DBUF_CTL_DBUF_POWER_REQUEST); |
| 305 | Registers.Wait_Set_Mask |
| 306 | (Register => Registers.DBUF_CTL, |
| 307 | Mask => DBUF_CTL_DBUF_POWER_STATE); |
| 308 | |
| 309 | Config.CDClk := CDClk; |
| 310 | end Set_CDClk; |
| 311 | |
| 312 | procedure Initialize is |
| 313 | begin |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 314 | Registers.Set_Mask |
| 315 | (Register => Registers.NDE_RSTWRN_OPT, |
| 316 | Mask => NDE_RSTWRN_OPT_RST_PCH_Handshake_En); |
| 317 | |
| 318 | Registers.Wait_Set_Mask |
| 319 | (Register => Registers.FUSE_STATUS, |
| 320 | Mask => FUSE_STATUS_PG0_DIST_STATUS); |
| 321 | PD_On (PW1); |
| 322 | PD_On (MISC_IO); |
| 323 | |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 324 | -- TODO: Set to preferred eDP rate: |
| 325 | -- Registers.Unset_And_Set_Mask |
| 326 | -- (Register => Registers.DPLL_CTRL1, |
| 327 | -- Unset_Mask => DPLL_CTRL1_DPLL0_LINK_RATE_MASK, |
| 328 | -- Set_Mask => DPLL_CTRL1_DPLL0_LINK_RATE_...); |
| 329 | Registers.Set_Mask |
| 330 | (Register => Registers.LCPLL1_CTL, |
| 331 | Mask => LCPLL1_CTL_PLL_ENABLE); |
| 332 | Registers.Wait_Set_Mask |
| 333 | (Register => Registers.LCPLL1_CTL, |
| 334 | Mask => LCPLL1_CTL_PLL_LOCK); |
| 335 | |
| Nico Huber | 6b4678d | 2019-09-22 21:31:52 +0200 | [diff] [blame] | 336 | Get_Cur_CDClk (Config.CDClk); |
| 337 | Get_Max_CDClk (Config.Max_CDClk); |
| 338 | Set_CDClk (Config.Default_CDClk_Freq); |
| Arthur Heymans | d1988d1 | 2018-03-28 16:27:57 +0200 | [diff] [blame] | 339 | |
| 340 | Config.Raw_Clock := Config.Default_RawClk_Freq; |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 341 | end Initialize; |
| 342 | |
| Nico Huber | 6b4678d | 2019-09-22 21:31:52 +0200 | [diff] [blame] | 343 | procedure Limit_Dotclocks |
| 344 | (Configs : in out Pipe_Configs; |
| 345 | CDClk_Switch : out Boolean) |
| 346 | is |
| 347 | begin |
| 348 | Config_Helpers.Limit_Dotclocks (Configs, Config.Max_CDClk); |
| 349 | CDClk_Switch := |
| 350 | Config.CDClk /= Normalize_CDClk |
| 351 | (Config_Helpers.Highest_Dotclock (Configs)); |
| 352 | end Limit_Dotclocks; |
| 353 | |
| 354 | procedure Update_CDClk (Configs : in out Pipe_Configs) |
| 355 | is |
| 356 | New_CDClk : constant Frequency_Type := |
| 357 | Config_Helpers.Highest_Dotclock (Configs); |
| 358 | begin |
| 359 | Set_CDClk (New_CDClk); |
| 360 | Config_Helpers.Limit_Dotclocks (Configs, Config.CDClk); |
| 361 | end Update_CDClk; |
| 362 | |
| Nico Huber | 99f10f3 | 2016-11-20 00:34:05 +0100 | [diff] [blame] | 363 | procedure Power_Set_To (Configs : Pipe_Configs) is |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 364 | begin |
| 365 | for PD in reverse Dynamic_Domain loop |
| 366 | if not Need_PD (PD, Configs) then |
| 367 | PD_Off (PD); |
| 368 | end if; |
| 369 | end loop; |
| 370 | for PD in Dynamic_Domain loop |
| 371 | if Need_PD (PD, Configs) then |
| 372 | PD_On (PD); |
| 373 | end if; |
| 374 | end loop; |
| 375 | end Power_Set_To; |
| 376 | |
| Nico Huber | 99f10f3 | 2016-11-20 00:34:05 +0100 | [diff] [blame] | 377 | procedure Power_Up (Old_Configs, New_Configs : Pipe_Configs) is |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 378 | begin |
| 379 | for PD in Dynamic_Domain loop |
| 380 | if not Need_PD (PD, Old_Configs) and Need_PD (PD, New_Configs) then |
| 381 | PD_On (PD); |
| 382 | end if; |
| 383 | end loop; |
| 384 | end Power_Up; |
| 385 | |
| Nico Huber | 99f10f3 | 2016-11-20 00:34:05 +0100 | [diff] [blame] | 386 | procedure Power_Down (Old_Configs, Tmp_Configs, New_Configs : Pipe_Configs) |
| Nico Huber | 83693c8 | 2016-10-08 22:17:55 +0200 | [diff] [blame] | 387 | is |
| 388 | begin |
| 389 | for PD in reverse Dynamic_Domain loop |
| 390 | if (Need_PD (PD, Old_Configs) or Need_PD (PD, Tmp_Configs)) and |
| 391 | not Need_PD (PD, New_Configs) |
| 392 | then |
| 393 | PD_Off (PD); |
| 394 | end if; |
| 395 | end loop; |
| 396 | end Power_Down; |
| 397 | |
| 398 | end HW.GFX.GMA.Power_And_Clocks_Skylake; |