| Tim Wawrzynczak | 605660b | 2022-06-08 12:48:19 -0600 | [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 | |
| Tim Wawrzynczak | 605660b | 2022-06-08 12:48:19 -0600 | [diff] [blame] | 15 | with GNAT.Source_Info; |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 16 | with HW.Debug; |
| 17 | with HW.GFX.GMA.Combo_Phy; |
| Tim Wawrzynczak | 605660b | 2022-06-08 12:48:19 -0600 | [diff] [blame] | 18 | with HW.GFX.GMA.Config; |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 19 | with HW.GFX.GMA.PCode; |
| 20 | with HW.GFX.GMA.Registers; |
| 21 | with HW.GFX.GMA.Transcoder; |
| 22 | |
| 23 | use type HW.Word64; |
| Tim Wawrzynczak | 605660b | 2022-06-08 12:48:19 -0600 | [diff] [blame] | 24 | |
| 25 | package body HW.GFX.GMA.Power_And_Clocks is |
| 26 | |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 27 | subtype CDClk_Range is Config.CDClk_Range; |
| Tim Wawrzynczak | 605660b | 2022-06-08 12:48:19 -0600 | [diff] [blame] | 28 | |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 29 | ---------------------------------------------------------------------------- |
| 30 | |
| 31 | PCH_DPMGUNIT_CLOCK_GATE_DISABLE : constant := 1 * 2 ** 15; |
| 32 | NDE_RSTWRN_OPT_RST_PCH_Handshake_En : constant := 1 * 2 ** 4; |
| 33 | |
| 34 | ---------------------------------------------------------------------------- |
| 35 | |
| 36 | DBUF_CTL_DBUF_POWER_REQUEST : constant := 1 * 2 ** 31; |
| 37 | DBUF_CTL_TRACKER_STATE_SERVICE_MASK : constant := 16#f8_0000#; |
| 38 | DBUF_CTL_TRACKER_STATE_SERVICE_SHIFT : constant := 19; |
| 39 | DBUF_CTL_DBUF_POWER_STATE : constant := 1 * 2 ** 30; |
| 40 | |
| 41 | type DBUF_Slices is (S1, S2); |
| 42 | DBUF_CTL : constant array (DBUF_Slices) of Registers.Registers_Index := |
| 43 | (Registers.DBUF_CTL_S0, |
| 44 | Registers.DBUF_CTL_S1); |
| 45 | |
| 46 | ---------------------------------------------------------------------------- |
| 47 | |
| 48 | MBUS_ABOX_CTL_BW_CREDITS_MASK : constant := 16#3# * 2 ** 20; |
| 49 | MBUS_ABOX_CTL_B_CREDITS_MASK : constant := 16#f# * 2 ** 16; |
| 50 | MBUS_ABOX_CTL_BT_CREDITS_POOL1_MASK : constant := 16#1f# * 2 ** 0; |
| 51 | MBUS_ABOX_CTL_BT_CREDITS_POOL2_MASK : constant := 16#1f# * 2 ** 8; |
| 52 | MBUS_ABOX_CTL_BW_CREDITS_SHIFT : constant := 20; |
| 53 | MBUS_ABOX_CTL_B_CREDITS_SHIFT : constant := 16; |
| 54 | MBUS_ABOX_CTL_BT_CREDITS_POOL1_SHIFT : constant := 0; |
| 55 | MBUS_ABOX_CTL_BT_CREDITS_POOL2_SHIFT : constant := 8; |
| 56 | |
| 57 | MBUS_ABOX_MASK : constant Word32 := |
| 58 | (MBUS_ABOX_CTL_BW_CREDITS_MASK or |
| 59 | MBUS_ABOX_CTL_B_CREDITS_MASK or |
| 60 | MBUS_ABOX_CTL_BT_CREDITS_POOL1_MASK or |
| 61 | MBUS_ABOX_CTL_BT_CREDITS_POOL2_MASK); |
| 62 | MBUS_ABOX_CREDITS : constant Word32 := |
| 63 | ( 1 * 2 ** MBUS_ABOX_CTL_BW_CREDITS_SHIFT or |
| 64 | 1 * 2 ** MBUS_ABOX_CTL_B_CREDITS_SHIFT or |
| 65 | 16 * 2 ** MBUS_ABOX_CTL_BT_CREDITS_POOL1_SHIFT or |
| 66 | 16 * 2 ** MBUS_ABOX_CTL_BT_CREDITS_POOL2_SHIFT); |
| 67 | |
| 68 | MBUS_ABOX_CTL : constant array (0 .. 2) of Registers.Registers_Index := |
| 69 | (Registers.MBUS_ABOX_CTL, |
| 70 | Registers.MBUS_ABOX1_CTL, |
| 71 | Registers.MBUS_ABOX2_CTL); |
| 72 | |
| 73 | ---------------------------------------------------------------------------- |
| 74 | |
| 75 | DCPR_MASK_MAXLATENCY_MEMUP_CLR : constant := 1 * 2 ** 27; |
| 76 | DCPR_MASK_LPMODE : constant := 1 * 2 ** 26; |
| 77 | DCPR_SEND_RESP_IMM : constant := 1 * 2 ** 25; |
| 78 | DCPR_CLEAR_MEMSTAT_DIS : constant := 1 * 2 ** 24; |
| 79 | |
| 80 | ---------------------------------------------------------------------------- |
| 81 | |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 82 | TGL_PCODE_MEM_SUBSYSTEM_INFO : constant := 16#d#; |
| 83 | TGL_PCODE_MEM_SS_READ_GLOBAL_INFO : constant := 0 * 2 ** 8; |
| 84 | TGL_PCODE_CDCLK_CONTROL : constant := 7; |
| 85 | TGL_CDCLK_PREPARE_FOR_CHANGE : constant := 3; |
| 86 | TGL_CDCLK_READY_FOR_CHANGE : constant := 1; |
| 87 | |
| 88 | ---------------------------------------------------------------------------- |
| 89 | |
| 90 | CDCLK_PLL_ENABLE_PLL_RATIO_MASK : constant := 16#ff#; |
| 91 | CDCLK_PLL_ENABLE_PLL_ENABLE : constant := 1 * 2 ** 31; |
| 92 | CDCLK_PLL_ENABLE_PLL_LOCK : constant := 1 * 2 ** 30; |
| 93 | CDCLK_CD2X_DIV_SEL_MASK : constant := 3 * 2 ** 22; |
| 94 | CDCLK_CD2X_DIV_SEL_1 : constant := 0 * 2 ** 22; |
| 95 | CDCLK_CD2X_DIV_SEL_2 : constant := 2 * 2 ** 22; |
| 96 | CDCLK_CD2X_PIPE_NONE : constant := 7 * 2 ** 19; |
| 97 | CDCLK_CTL_CD_FREQ_DECIMAL_MASK : constant := 16#7ff#; |
| 98 | |
| 99 | ---------------------------------------------------------------------------- |
| 100 | |
| Nico Huber | ac2a141 | 2026-07-02 10:41:59 +0200 | [diff] [blame] | 101 | procedure Get_RefClk (RefClk : out RefClk_Range) |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 102 | is |
| 103 | DSSM : Word32; |
| 104 | DSSM_REFERENCE_FREQUENCY_MASK : constant := 16#e000_0000#; |
| 105 | DSSM_REFERENCE_FREQUENCY_24MHZ : constant := 16#0000_0000#; |
| 106 | DSSM_REFERENCE_FREQUENCY_19_2MHZ : constant := 16#2000_0000#; |
| 107 | DSSM_REFERENCE_FREQUENCY_38_4MHZ : constant := 16#4000_0000#; |
| 108 | begin |
| 109 | Registers.Read (Registers.DSSM, DSSM); |
| Nico Huber | ac2a141 | 2026-07-02 10:41:59 +0200 | [diff] [blame] | 110 | RefClk := |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 111 | (case DSSM and DSSM_REFERENCE_FREQUENCY_MASK is |
| 112 | when DSSM_REFERENCE_FREQUENCY_24MHZ => 24_000_000, |
| 113 | when DSSM_REFERENCE_FREQUENCY_19_2MHZ => 19_200_000, |
| 114 | when DSSM_REFERENCE_FREQUENCY_38_4MHZ => 38_400_000, |
| 115 | when others => 24_000_000); |
| Nico Huber | ac2a141 | 2026-07-02 10:41:59 +0200 | [diff] [blame] | 116 | end Get_RefClk; |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 117 | |
| 118 | procedure Get_RawClk (Rawclk : out Frequency_Type) |
| 119 | is |
| 120 | Raw_Frequency_24_MHz : Boolean; |
| 121 | SFUSE_STRAP_RAW_FREQUENCY : constant := 1 * 2 ** 8; |
| 122 | begin |
| 123 | Rawclk := Config.Default_RawClk_Freq; |
| 124 | Registers.Is_Set_Mask |
| 125 | (Register => Registers.SFUSE_STRAP, |
| 126 | Mask => SFUSE_STRAP_RAW_FREQUENCY, |
| 127 | Result => Raw_Frequency_24_MHz); |
| 128 | |
| 129 | if not Raw_Frequency_24_MHz then |
| 130 | Rawclk := 19_200_000; |
| 131 | end if; |
| 132 | end Get_RawClk; |
| 133 | |
| 134 | procedure Get_Max_CDClk (CDClk : out CDClk_Range) |
| 135 | is |
| Nico Huber | ac2a141 | 2026-07-02 10:41:59 +0200 | [diff] [blame] | 136 | RefClk_Freq : RefClk_Range; |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 137 | begin |
| Nico Huber | ac2a141 | 2026-07-02 10:41:59 +0200 | [diff] [blame] | 138 | Get_RefClk (RefClk_Freq); |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 139 | CDClk := |
| Nico Huber | ac2a141 | 2026-07-02 10:41:59 +0200 | [diff] [blame] | 140 | (case RefClk_Freq is |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 141 | when 24_000_000 => 648_000_000, |
| 142 | when others => 652_800_000); |
| 143 | end Get_Max_CDClk; |
| 144 | |
| 145 | procedure Normalize_CDClk |
| 146 | (CDClk : in Int64; |
| 147 | Normalized : out CDClk_Range) |
| 148 | with |
| 149 | Post => Normalized >= 172_800_000 |
| 150 | is |
| Nico Huber | ac2a141 | 2026-07-02 10:41:59 +0200 | [diff] [blame] | 151 | RefClk_Freq : RefClk_Range; |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 152 | begin |
| Nico Huber | ac2a141 | 2026-07-02 10:41:59 +0200 | [diff] [blame] | 153 | Get_RefClk (RefClk_Freq); |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 154 | Normalized := |
| Nico Huber | ac2a141 | 2026-07-02 10:41:59 +0200 | [diff] [blame] | 155 | (case RefClk_Freq is |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 156 | when 19_200_000 | 38_400_000 => |
| 157 | (if CDClk <= 172_800_000 then 172_800_000 |
| 158 | elsif CDClk <= 192_000_000 then 192_000_000 |
| 159 | elsif CDClk <= 307_200_000 then 307_200_000 |
| 160 | elsif CDClk <= 326_400_000 then 326_400_000 |
| 161 | elsif CDClk <= 556_800_000 then 556_800_000 |
| 162 | else 652_800_000), |
| 163 | when others => |
| 164 | (if CDClk <= 180_000_000 then 180_000_000 |
| 165 | elsif CDClk <= 192_000_000 then 192_000_000 |
| 166 | elsif CDClk <= 312_000_000 then 312_000_000 |
| 167 | elsif CDClk <= 324_000_000 then 324_000_000 |
| 168 | elsif CDClk <= 552_000_000 then 552_000_000 |
| 169 | else 648_000_000)); |
| 170 | end Normalize_CDClk; |
| 171 | |
| 172 | procedure Get_Cur_CDClk (CDClk : out CDClk_Range) |
| 173 | with |
| 174 | Post => CDClk >= 172_800_000 |
| 175 | is |
| 176 | CDCLK_CTL : Word32; |
| 177 | begin |
| 178 | Registers.Read (Registers.CDCLK_CTL, CDCLK_CTL); |
| 179 | CDCLK_CTL := CDCLK_CTL and CDCLK_CTL_CD_FREQ_DECIMAL_MASK; |
| 180 | Normalize_CDClk (Int64 (CDCLK_CTL) * 500_000 + 1_000_000, CDClk); |
| 181 | end Get_Cur_CDClk; |
| 182 | |
| 183 | procedure Set_CDClk (CDClk_In : CDClk_Range) |
| 184 | is |
| 185 | subtype PLL_Ratio_Range is Word32 range 0 .. 68; |
| 186 | function Ratio_For_19_2_MHz (CDClk : CDClk_Range) return PLL_Ratio_Range is |
| 187 | begin |
| 188 | case CDClk is |
| 189 | when 172_800_000 => return 18; |
| 190 | when 192_000_000 => return 20; |
| 191 | when 307_200_000 => return 32; |
| 192 | when 326_400_000 | 652_800_000 => return 68; |
| 193 | when 556_800_000 => return 58; |
| 194 | when others => return 0; |
| 195 | end case; |
| 196 | end Ratio_For_19_2_MHz; |
| 197 | |
| Nico Huber | ac2a141 | 2026-07-02 10:41:59 +0200 | [diff] [blame] | 198 | function Ratio_For_24_MHz (CDClk : CDClk_Range) return PLL_Ratio_Range is |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 199 | begin |
| 200 | case CDClk is |
| 201 | when 180_800_000 => return 15; |
| 202 | when 192_000_000 => return 16; |
| 203 | when 312_000_000 => return 26; |
| 204 | when 324_000_000 | 648_000_000 => return 54; |
| 205 | when 552_000_000 => return 46; |
| 206 | when others => return 0; |
| 207 | end case; |
| 208 | end Ratio_For_24_MHz; |
| 209 | |
| 210 | function CDCLK_CTL_CD_FREQ_DECIMAL (Freq : CDClk_Range) return Word32 |
| 211 | with |
| 212 | Pre => Freq > 1_000_000 |
| 213 | is |
| 214 | begin |
| 215 | -- Weirdest representation: CDClk - 1MHz in 10.1 (10 + 1 fractional bit) |
| 216 | return Word32 (Div_Round_Closest (Pos64 (Freq) - 1_000_000, 500_000)); |
| 217 | end CDCLK_CTL_CD_FREQ_DECIMAL; |
| 218 | |
| 219 | Success : Boolean; |
| 220 | CD2X : Word32; |
| 221 | PLL_Ratio : PLL_Ratio_Range; |
| 222 | CDClk : CDClk_Range; |
| Nico Huber | ac2a141 | 2026-07-02 10:41:59 +0200 | [diff] [blame] | 223 | RefClk_Freq : RefClk_Range; |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 224 | VCO : Pos64; |
| 225 | begin |
| 226 | pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); |
| 227 | |
| 228 | Normalize_CDClk (CDClk_Range'Min (CDClk_In, Config.Max_CDClk), CDClk); |
| Nico Huber | ac2a141 | 2026-07-02 10:41:59 +0200 | [diff] [blame] | 229 | Get_RefClk (RefClk_Freq); |
| 230 | PLL_Ratio := (case RefClk_Freq is |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 231 | when 19_200_000 => Ratio_For_19_2_MHz (CDClk), |
| 232 | when 38_400_000 => Ratio_For_19_2_MHz (CDClk) / 2, |
| 233 | when 24_000_000 => Ratio_For_24_MHz (CDClk), |
| 234 | when others => 0); |
| 235 | |
| 236 | if PLL_Ratio = 0 then |
| 237 | pragma Debug (Debug.Put_Line |
| Nico Huber | ac2a141 | 2026-07-02 10:41:59 +0200 | [diff] [blame] | 238 | ("ERROR: Invalid RefClk frequency, bad hardware?")); |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 239 | return; |
| 240 | end if; |
| 241 | |
| 242 | PCode.Mailbox_Request |
| Nico Huber | ac2a141 | 2026-07-02 10:41:59 +0200 | [diff] [blame] | 243 | (MBox => TGL_PCODE_CDCLK_CONTROL, |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 244 | Command => TGL_CDCLK_PREPARE_FOR_CHANGE, |
| 245 | Reply_Mask => TGL_CDCLK_READY_FOR_CHANGE, |
| 246 | Wait_Ready => True, |
| 247 | Success => Success); |
| 248 | |
| 249 | if not Success then |
| 250 | pragma Debug (Debug.Put_Line |
| 251 | ("ERROR: PCODE not ready for frequency change.")); |
| 252 | return; |
| 253 | end if; |
| 254 | |
| 255 | Registers.Unset_Mask |
| 256 | (Register => Registers.CDCLK_PLL_ENABLE, |
| 257 | Mask => CDCLK_PLL_ENABLE_PLL_ENABLE); |
| 258 | Registers.Wait_Unset_Mask |
| 259 | (Register => Registers.CDCLK_PLL_ENABLE, |
| 260 | Mask => CDCLK_PLL_ENABLE_PLL_LOCK); |
| 261 | |
| 262 | Registers.Write |
| 263 | (Register => Registers.CDCLK_PLL_ENABLE, |
| 264 | Value => PLL_Ratio); |
| 265 | Registers.Write |
| 266 | (Register => Registers.CDCLK_PLL_ENABLE, |
| 267 | Value => PLL_Ratio or CDCLK_PLL_ENABLE_PLL_ENABLE); |
| 268 | Registers.Wait_Set_Mask |
| 269 | (Register => Registers.CDCLK_PLL_ENABLE, |
| 270 | Mask => CDCLK_PLL_ENABLE_PLL_LOCK, |
| 271 | Success => Success); |
| 272 | |
| 273 | if not Success then |
| 274 | Debug.Put_Line ("CDClk PLL failed to lock!"); |
| 275 | return; |
| 276 | end if; |
| 277 | |
| Nico Huber | ac2a141 | 2026-07-02 10:41:59 +0200 | [diff] [blame] | 278 | VCO := (RefClk_Freq / 1_000) * Pos64 (PLL_Ratio); |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 279 | CD2X := |
| 280 | (case (Div_Round_Closest (VCO, CDClk / 1_000)) is |
| 281 | when 2 => CDCLK_CD2X_DIV_SEL_1, |
| 282 | when 4 => CDCLK_CD2X_DIV_SEL_2, |
| 283 | when others => CDCLK_CD2X_DIV_SEL_1); |
| 284 | |
| 285 | Registers.Write |
| 286 | (Register => Registers.CDCLK_CTL, |
| 287 | Value => CDCLK_CTL_CD_FREQ_DECIMAL (CDClk) or |
| 288 | CDCLK_CD2X_PIPE_NONE or CD2X); |
| 289 | |
| 290 | PCode.Mailbox_Write |
| 291 | (MBox => TGL_PCODE_CDCLK_CONTROL, |
| 292 | Command => (if CDClk <= 312_000_000 then 0 |
| 293 | elsif CDClk <= 326_400_000 then 1 |
| 294 | elsif CDClk <= 556_800_000 then 2 |
| 295 | else 3)); |
| 296 | Config.CDClk := CDClk; |
| 297 | |
| 298 | pragma Debug (Debug.Put ("Set CDClk to ")); |
| 299 | pragma Debug (Debug.Put_Int64 (CDClk / 1_000_000)); |
| 300 | pragma Debug (Debug.Put (".")); |
| 301 | pragma Debug (Debug.Put_Int64 ((CDClk mod 1_000_000) / 100_000)); |
| 302 | pragma Debug (Debug.Put_Line ("MHz.")); |
| 303 | end Set_CDClk; |
| 304 | |
| 305 | procedure Configure_Bandwidth_Buddy |
| 306 | is |
| 307 | BW_BUDDY_DISABLE : constant := 1 * 2 ** 31; |
| 308 | BW_BUDDY_TLB_REQ_TIMER_MASK : constant := 16#3f_0000#; |
| 309 | |
| 310 | type DRAM_Module_Type is (DDR4, DDR5, LPDDR4, LPDDR5); |
| 311 | type Bw_Buddy_Info is record |
| 312 | DRAM_Channels : Natural; |
| 313 | DRAM_Type : DRAM_Module_Type; |
| 314 | BW_BUDDY_MASK : Word32; |
| 315 | end record; |
| 316 | type Bw_Buddy_Info_Array is array (1 .. 8) of Bw_Buddy_Info; |
| 317 | |
| 318 | Buddy_Info : constant Bw_Buddy_Info_Array := |
| 319 | ((1, DDR4, 16#0f#), |
| 320 | (1, DDR5, 16#0f#), |
| 321 | (2, LPDDR4, 16#1c#), |
| 322 | (2, LPDDR5, 16#1c#), |
| 323 | (2, DDR4, 16#1f#), |
| 324 | (2, DDR5, 16#1e#), |
| 325 | (4, LPDDR4, 16#38#), |
| 326 | (4, LPDDR5, 16#38#)); |
| 327 | |
| 328 | -- TODO: use for ADL-S, RKL A0/B0 |
| 329 | Buddy_Info_Wa_1409767108 : constant Bw_Buddy_Info_Array := |
| 330 | ((1, DDR4, 1), |
| 331 | (1, DDR5, 1), |
| 332 | (1, LPDDR4, 1), |
| 333 | (1, LPDDR5, 1), |
| 334 | (2, DDR4, 3), |
| 335 | (2, DDR5, 3), |
| 336 | (2, LPDDR4, 3), |
| 337 | (2, LPDDR5, 3)); |
| 338 | |
| 339 | Result : Word64; |
| 340 | Module_Type: DRAM_Module_Type; |
| 341 | Channels : Natural; |
| 342 | Success : Boolean; |
| 343 | begin |
| 344 | PCode.Mailbox_Read(MBox => TGL_PCODE_MEM_SUBSYSTEM_INFO or |
| 345 | TGL_PCODE_MEM_SS_READ_GLOBAL_INFO, |
| 346 | Wait_Ready => True, |
| 347 | Reply => Result, |
| 348 | Success => Success); |
| 349 | if not Success then |
| 350 | pragma Debug (Debug.Put_Line |
| 351 | ("ERROR: PCODE didn't return memory info.")); |
| 352 | return; |
| 353 | end if; |
| 354 | |
| Nico Huber | ac2a141 | 2026-07-02 10:41:59 +0200 | [diff] [blame] | 355 | case Result and 16#f# is |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 356 | when 0 => Module_Type := DDR4; |
| 357 | when 1 => Module_Type := DDR5; |
| 358 | when 2 => Module_Type := LPDDR5; |
| 359 | when 3 => Module_Type := LPDDR4; |
| 360 | when others => |
| 361 | pragma Debug (Debug.Put_Line ("ERROR: Invalid DRAM Module Type.")); |
| 362 | return; |
| 363 | end case; |
| 364 | |
| 365 | Channels := Natural (Shift_Right (Result and 16#f0#, 4)); |
| 366 | for I in Buddy_Info'Range loop |
| 367 | if Buddy_Info (I).DRAM_Type = Module_Type and |
| 368 | Buddy_Info (I).DRAM_Channels = Channels |
| 369 | then |
| 370 | Registers.Set_Mask |
| 371 | (Register => Registers.BW_BUDDY1_PAGE_MASK, |
| 372 | Mask => Buddy_Info (I).BW_BUDDY_MASK); |
| 373 | Registers.Set_Mask |
| 374 | (Register => Registers.BW_BUDDY2_PAGE_MASK, |
| 375 | Mask => Buddy_Info (I).BW_BUDDY_MASK); |
| 376 | |
| 377 | -- Wa_22010178259:tgl,rkl |
| 378 | Registers.Unset_And_Set_Mask |
| 379 | (Register => Registers.BW_BUDDY1_CTL, |
| 380 | Mask_Unset => BW_BUDDY_TLB_REQ_TIMER_MASK, |
| 381 | Mask_Set => 8 * 2 ** 16); |
| 382 | Registers.Unset_And_Set_Mask |
| 383 | (Register => Registers.BW_BUDDY2_CTL, |
| 384 | Mask_Unset => BW_BUDDY_TLB_REQ_TIMER_MASK, |
| 385 | Mask_Set => 8 * 2 ** 16); |
| 386 | |
| 387 | return; |
| 388 | end if; |
| 389 | end loop; |
| 390 | |
| 391 | Registers.Write (Registers.BW_BUDDY1_CTL, BW_BUDDY_DISABLE); |
| 392 | Registers.Write (Registers.BW_BUDDY2_CTL, BW_BUDDY_DISABLE); |
| 393 | end Configure_Bandwidth_Buddy; |
| 394 | |
| 395 | ---------------------------------------------------------------------------- |
| 396 | |
| 397 | procedure Initialize |
| 398 | is |
| 399 | RawClk : Frequency_Type; |
| 400 | begin |
| 401 | pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); |
| 402 | |
| 403 | -- Wa_14011294188:ehl,jsl,tgl,rkl,adl-s,adl-p |
| 404 | Registers.Set_Mask |
| 405 | (Register => Registers.PCH_DSPCLK_GATE_D, |
| 406 | Mask => PCH_DPMGUNIT_CLOCK_GATE_DISABLE); |
| 407 | |
| 408 | Registers.Set_Mask |
| 409 | (Register => Registers.NDE_RSTWRN_OPT, |
| 410 | Mask => NDE_RSTWRN_OPT_RST_PCH_Handshake_En); |
| 411 | |
| Nico Huber | 27d2627 | 2026-05-27 19:01:09 +0200 | [diff] [blame^] | 412 | Power_Domains_Common.PD_On (Power_Domains.PW1); |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 413 | |
| 414 | Get_Cur_CDClk (Config.CDClk); |
| 415 | Get_Max_CDClk (Config.Max_CDClk); |
| 416 | if Config.CDClk < Config.Default_CDClk_Freq then |
| 417 | Set_CDClk (Config.Default_CDClk_Freq); |
| 418 | end if; |
| 419 | |
| 420 | Get_RawClk (RawClk); |
| 421 | Config.Raw_Clock := RawClk; |
| 422 | |
| 423 | -- TGL: Set DBUF Tracker State Service to 8 |
| 424 | Registers.Unset_And_Set_Mask |
| 425 | (Register => DBUF_CTL (S1), |
| 426 | Mask_Unset => DBUF_CTL_TRACKER_STATE_SERVICE_MASK, |
| 427 | Mask_Set => 8 * 2 ** DBUF_CTL_TRACKER_STATE_SERVICE_SHIFT); |
| 428 | |
| 429 | -- Enable first DBUF slice (TODO: Is this ok to use for all pipes?) |
| 430 | Registers.Set_Mask (DBUF_CTL (S1), DBUF_CTL_DBUF_POWER_REQUEST); |
| 431 | Registers.Wait_Set_Mask (DBUF_CTL (S1), DBUF_CTL_DBUF_POWER_STATE); |
| 432 | |
| 433 | for I in MBUS_ABOX_CTL'Range loop |
| 434 | Registers.Unset_And_Set_Mask |
| 435 | (Register => MBUS_ABOX_CTL (I), |
| 436 | Mask_Unset => MBUS_ABOX_MASK, |
| 437 | Mask_Set => MBUS_ABOX_CREDITS); |
| 438 | end loop; |
| 439 | |
| 440 | Configure_Bandwidth_Buddy; |
| 441 | |
| 442 | -- Display WA #14011508470 tgl,dg1,rkl,adl-s,adl-p,dg2 |
| 443 | Registers.Set_Mask |
| 444 | (Register => Registers.GEN11_CHICKEN_DCPR_2, |
| 445 | Mask => DCPR_MASK_MAXLATENCY_MEMUP_CLR or DCPR_MASK_LPMODE or |
| 446 | DCPR_SEND_RESP_IMM or DCPR_CLEAR_MEMSTAT_DIS); |
| Tim Wawrzynczak | 605660b | 2022-06-08 12:48:19 -0600 | [diff] [blame] | 447 | end Initialize; |
| 448 | |
| 449 | procedure Limit_Dotclocks |
| 450 | (Configs : in out Pipe_Configs; |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 451 | CDClk_Switch : out Boolean) |
| 452 | is |
| 453 | CDClk : CDClk_Range; |
| Tim Wawrzynczak | 605660b | 2022-06-08 12:48:19 -0600 | [diff] [blame] | 454 | begin |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 455 | Config_Helpers.Limit_Dotclocks (Configs, Config.Max_CDClk); |
| 456 | Normalize_CDClk (Config_Helpers.Highest_Dotclock (Configs), CDClk); |
| 457 | CDClk_Switch := Config.CDClk /= CDClk; |
| Tim Wawrzynczak | 605660b | 2022-06-08 12:48:19 -0600 | [diff] [blame] | 458 | end Limit_Dotclocks; |
| 459 | |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 460 | procedure Update_CDClk (Configs : in out Pipe_Configs) |
| 461 | is |
| 462 | New_CDClk : constant Frequency_Type := |
| 463 | Config_Helpers.Highest_Dotclock (Configs); |
| Tim Wawrzynczak | 605660b | 2022-06-08 12:48:19 -0600 | [diff] [blame] | 464 | begin |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 465 | Set_CDClk (New_CDClk); |
| 466 | Config_Helpers.Limit_Dotclocks (Configs, Config.CDClk); |
| Tim Wawrzynczak | 605660b | 2022-06-08 12:48:19 -0600 | [diff] [blame] | 467 | end Update_CDClk; |
| 468 | |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 469 | procedure Enable_CDClk is |
| 470 | begin |
| 471 | if Config.CDClk < Config.Default_CDClk_Freq then |
| 472 | Set_CDClk (Config.Default_CDClk_Freq); |
| 473 | end if; |
| 474 | end Enable_CDClk; |
| 475 | |
| 476 | ---------------------------------------------------------------------------- |
| 477 | |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 478 | procedure Pre_All_Off is |
| 479 | begin |
| 480 | Transcoder.PSR_Off; |
| 481 | end Pre_All_Off; |
| 482 | |
| 483 | procedure Post_All_Off is |
| 484 | begin |
| 485 | pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); |
| 486 | |
| 487 | for S in reverse DBUF_CTL'Range loop |
| 488 | Registers.Unset_Mask |
| 489 | (DBUF_CTL (S), DBUF_CTL_DBUF_POWER_REQUEST); |
| 490 | Registers.Wait_Unset_Mask |
| 491 | (DBUF_CTL (S), DBUF_CTL_DBUF_POWER_STATE); |
| 492 | end loop; |
| 493 | |
| 494 | -- Disable CDClk PLL. FIXME: Not implemented yet. |
| 495 | Set_CDClk (CDClk_Range'First); |
| 496 | |
| Nico Huber | 27d2627 | 2026-05-27 19:01:09 +0200 | [diff] [blame^] | 497 | Power_Domains_Common.All_Off; |
| Tim Wawrzynczak | 6db27c4 | 2022-09-09 10:49:55 -0600 | [diff] [blame] | 498 | |
| 499 | Combo_Phy.All_Off; |
| 500 | end Post_All_Off; |
| 501 | |
| Tim Wawrzynczak | 605660b | 2022-06-08 12:48:19 -0600 | [diff] [blame] | 502 | end HW.GFX.GMA.Power_And_Clocks; |