blob: d24d8d1df9536e7f36c4bc8369b2286fa3b26f83 [file] [log] [blame]
Tim Wawrzynczak605660b2022-06-08 12:48:19 -06001--
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 Wawrzynczak605660b2022-06-08 12:48:19 -060015with GNAT.Source_Info;
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -060016with HW.Debug;
17with HW.GFX.GMA.Combo_Phy;
Tim Wawrzynczak605660b2022-06-08 12:48:19 -060018with HW.GFX.GMA.Config;
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -060019with HW.GFX.GMA.PCode;
20with HW.GFX.GMA.Registers;
21with HW.GFX.GMA.Transcoder;
22
23use type HW.Word64;
Tim Wawrzynczak605660b2022-06-08 12:48:19 -060024
25package body HW.GFX.GMA.Power_And_Clocks is
26
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -060027 subtype CDClk_Range is Config.CDClk_Range;
Tim Wawrzynczak605660b2022-06-08 12:48:19 -060028
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -060029 ----------------------------------------------------------------------------
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;
Nico Huber7edb1a72026-05-27 21:10:10 +020039 DBUF_CTL_MIN_TRACKER_STATE_SERVICE_SHIFT : constant := 16;
40 DBUF_CTL_MIN_TRACKER_STATE_SERVICE_MASK : constant := 16#7_0000#;
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -060041 DBUF_CTL_DBUF_POWER_STATE : constant := 1 * 2 ** 30;
42
Nico Huber7edb1a72026-05-27 21:10:10 +020043 type DBUF_Slices is (S1, S2, S3, S4);
44 subtype Enable_DBUF_Slices is DBUF_Slices -- TODO: Maybe decide at runtime?
45 range S1 .. (if Config.Gen_Tigerlake then S1 else S4);
46 subtype Disable_DBUF_Slices is DBUF_Slices
47 range S1 .. (if Config.Gen_Tigerlake then S2 else S4);
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -060048 DBUF_CTL : constant array (DBUF_Slices) of Registers.Registers_Index :=
49 (Registers.DBUF_CTL_S0,
Nico Huber7edb1a72026-05-27 21:10:10 +020050 Registers.DBUF_CTL_S1,
51 Registers.DBUF_CTL_S2,
52 Registers.DBUF_CTL_S3);
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -060053
54 ----------------------------------------------------------------------------
55
56 MBUS_ABOX_CTL_BW_CREDITS_MASK : constant := 16#3# * 2 ** 20;
57 MBUS_ABOX_CTL_B_CREDITS_MASK : constant := 16#f# * 2 ** 16;
58 MBUS_ABOX_CTL_BT_CREDITS_POOL1_MASK : constant := 16#1f# * 2 ** 0;
59 MBUS_ABOX_CTL_BT_CREDITS_POOL2_MASK : constant := 16#1f# * 2 ** 8;
60 MBUS_ABOX_CTL_BW_CREDITS_SHIFT : constant := 20;
61 MBUS_ABOX_CTL_B_CREDITS_SHIFT : constant := 16;
62 MBUS_ABOX_CTL_BT_CREDITS_POOL1_SHIFT : constant := 0;
63 MBUS_ABOX_CTL_BT_CREDITS_POOL2_SHIFT : constant := 8;
64
65 MBUS_ABOX_MASK : constant Word32 :=
66 (MBUS_ABOX_CTL_BW_CREDITS_MASK or
67 MBUS_ABOX_CTL_B_CREDITS_MASK or
68 MBUS_ABOX_CTL_BT_CREDITS_POOL1_MASK or
69 MBUS_ABOX_CTL_BT_CREDITS_POOL2_MASK);
70 MBUS_ABOX_CREDITS : constant Word32 :=
71 ( 1 * 2 ** MBUS_ABOX_CTL_BW_CREDITS_SHIFT or
72 1 * 2 ** MBUS_ABOX_CTL_B_CREDITS_SHIFT or
73 16 * 2 ** MBUS_ABOX_CTL_BT_CREDITS_POOL1_SHIFT or
74 16 * 2 ** MBUS_ABOX_CTL_BT_CREDITS_POOL2_SHIFT);
75
76 MBUS_ABOX_CTL : constant array (0 .. 2) of Registers.Registers_Index :=
77 (Registers.MBUS_ABOX_CTL,
78 Registers.MBUS_ABOX1_CTL,
79 Registers.MBUS_ABOX2_CTL);
80
81 ----------------------------------------------------------------------------
82
Nico Huber7edb1a72026-05-27 21:10:10 +020083 MBUS_JOIN : constant := 1 * 2 ** 31;
84 MBUS_HASHING_MODE_MASK : constant := 1 * 2 ** 30;
85 MBUS_HASHING_MODE_2x2 : constant := 0 * 2 ** 30;
86 MBUS_HASHING_MODE_1x4 : constant := 1 * 2 ** 30;
87 MBUS_JOIN_PIPE_SELECT_MASK : constant := 16#1c00_0000#;
88 MBUS_JOIN_PIPE_SELECT_NONE : constant := 16#1c00_0000#;
89
90 ----------------------------------------------------------------------------
91
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -060092 DCPR_MASK_MAXLATENCY_MEMUP_CLR : constant := 1 * 2 ** 27;
93 DCPR_MASK_LPMODE : constant := 1 * 2 ** 26;
94 DCPR_SEND_RESP_IMM : constant := 1 * 2 ** 25;
95 DCPR_CLEAR_MEMSTAT_DIS : constant := 1 * 2 ** 24;
96
97 ----------------------------------------------------------------------------
98
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -060099 TGL_PCODE_MEM_SUBSYSTEM_INFO : constant := 16#d#;
100 TGL_PCODE_MEM_SS_READ_GLOBAL_INFO : constant := 0 * 2 ** 8;
101 TGL_PCODE_CDCLK_CONTROL : constant := 7;
102 TGL_CDCLK_PREPARE_FOR_CHANGE : constant := 3;
103 TGL_CDCLK_READY_FOR_CHANGE : constant := 1;
104
105 ----------------------------------------------------------------------------
106
107 CDCLK_PLL_ENABLE_PLL_RATIO_MASK : constant := 16#ff#;
108 CDCLK_PLL_ENABLE_PLL_ENABLE : constant := 1 * 2 ** 31;
109 CDCLK_PLL_ENABLE_PLL_LOCK : constant := 1 * 2 ** 30;
110 CDCLK_CD2X_DIV_SEL_MASK : constant := 3 * 2 ** 22;
111 CDCLK_CD2X_DIV_SEL_1 : constant := 0 * 2 ** 22;
Nico Huber7edb1a72026-05-27 21:10:10 +0200112 CDCLK_CD2X_DIV_SEL_1_5 : constant := 1 * 2 ** 22;
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600113 CDCLK_CD2X_DIV_SEL_2 : constant := 2 * 2 ** 22;
Nico Huber7edb1a72026-05-27 21:10:10 +0200114 CDCLK_CD2X_DIV_SEL_4 : constant := 3 * 2 ** 22;
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600115 CDCLK_CD2X_PIPE_NONE : constant := 7 * 2 ** 19;
116 CDCLK_CTL_CD_FREQ_DECIMAL_MASK : constant := 16#7ff#;
117
118 ----------------------------------------------------------------------------
119
Nico Huberac2a1412026-07-02 10:41:59 +0200120 procedure Get_RefClk (RefClk : out RefClk_Range)
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600121 is
122 DSSM : Word32;
123 DSSM_REFERENCE_FREQUENCY_MASK : constant := 16#e000_0000#;
124 DSSM_REFERENCE_FREQUENCY_24MHZ : constant := 16#0000_0000#;
125 DSSM_REFERENCE_FREQUENCY_19_2MHZ : constant := 16#2000_0000#;
126 DSSM_REFERENCE_FREQUENCY_38_4MHZ : constant := 16#4000_0000#;
127 begin
128 Registers.Read (Registers.DSSM, DSSM);
Nico Huberac2a1412026-07-02 10:41:59 +0200129 RefClk :=
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600130 (case DSSM and DSSM_REFERENCE_FREQUENCY_MASK is
131 when DSSM_REFERENCE_FREQUENCY_24MHZ => 24_000_000,
132 when DSSM_REFERENCE_FREQUENCY_19_2MHZ => 19_200_000,
133 when DSSM_REFERENCE_FREQUENCY_38_4MHZ => 38_400_000,
134 when others => 24_000_000);
Nico Huberac2a1412026-07-02 10:41:59 +0200135 end Get_RefClk;
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600136
137 procedure Get_RawClk (Rawclk : out Frequency_Type)
138 is
139 Raw_Frequency_24_MHz : Boolean;
140 SFUSE_STRAP_RAW_FREQUENCY : constant := 1 * 2 ** 8;
141 begin
142 Rawclk := Config.Default_RawClk_Freq;
143 Registers.Is_Set_Mask
144 (Register => Registers.SFUSE_STRAP,
145 Mask => SFUSE_STRAP_RAW_FREQUENCY,
146 Result => Raw_Frequency_24_MHz);
147
148 if not Raw_Frequency_24_MHz then
149 Rawclk := 19_200_000;
150 end if;
151 end Get_RawClk;
152
153 procedure Get_Max_CDClk (CDClk : out CDClk_Range)
154 is
Nico Huberac2a1412026-07-02 10:41:59 +0200155 RefClk_Freq : RefClk_Range;
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600156 begin
Nico Huberac2a1412026-07-02 10:41:59 +0200157 Get_RefClk (RefClk_Freq);
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600158 CDClk :=
Nico Huberac2a1412026-07-02 10:41:59 +0200159 (case RefClk_Freq is
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600160 when 24_000_000 => 648_000_000,
161 when others => 652_800_000);
162 end Get_Max_CDClk;
163
164 procedure Normalize_CDClk
165 (CDClk : in Int64;
166 Normalized : out CDClk_Range)
167 with
168 Post => Normalized >= 172_800_000
169 is
Nico Huberac2a1412026-07-02 10:41:59 +0200170 RefClk_Freq : RefClk_Range;
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600171 begin
Nico Huberac2a1412026-07-02 10:41:59 +0200172 Get_RefClk (RefClk_Freq);
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600173 Normalized :=
Nico Huber7edb1a72026-05-27 21:10:10 +0200174 (if Config.Gen_Tigerlake then
175 (case RefClk_Freq is
176 when 19_200_000 | 38_400_000 =>
177 (if CDClk <= 172_800_000 then 172_800_000
178 elsif CDClk <= 192_000_000 then 192_000_000
179 elsif CDClk <= 307_200_000 then 307_200_000
180 elsif CDClk <= 326_400_000 then 326_400_000
181 elsif CDClk <= 556_800_000 then 556_800_000
182 else 652_800_000),
183 when others => -- 24_000_000
184 (if CDClk <= 180_000_000 then 180_000_000
185 elsif CDClk <= 192_000_000 then 192_000_000
186 elsif CDClk <= 312_000_000 then 312_000_000
187 elsif CDClk <= 324_000_000 then 324_000_000
188 elsif CDClk <= 552_000_000 then 552_000_000
189 else 648_000_000))
190 else
191 (case RefClk_Freq is
192 when 19_200_000 =>
193 (if CDClk <= 172_800_000 then 172_800_000
194 elsif CDClk <= 192_000_000 then 192_000_000
195 elsif CDClk <= 307_200_000 then 307_200_000
196 elsif CDClk <= 556_800_000 then 556_800_000
197 else 652_800_000),
198 when 24_000_000 =>
199 (if CDClk <= 176_000_000 then 176_000_000
200 elsif CDClk <= 192_000_000 then 192_000_000
201 elsif CDClk <= 312_000_000 then 312_000_000
202 elsif CDClk <= 552_000_000 then 552_000_000
203 else 648_000_000),
204 when others => -- 38_400_000
205 (if CDClk <= 179_200_000 then 179_200_000
206 elsif CDClk <= 192_000_000 then 192_000_000
207 elsif CDClk <= 307_200_000 then 307_200_000
208 elsif CDClk <= 556_800_000 then 556_800_000
209 else 652_800_000)));
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600210 end Normalize_CDClk;
211
212 procedure Get_Cur_CDClk (CDClk : out CDClk_Range)
213 with
214 Post => CDClk >= 172_800_000
215 is
216 CDCLK_CTL : Word32;
217 begin
218 Registers.Read (Registers.CDCLK_CTL, CDCLK_CTL);
219 CDCLK_CTL := CDCLK_CTL and CDCLK_CTL_CD_FREQ_DECIMAL_MASK;
220 Normalize_CDClk (Int64 (CDCLK_CTL) * 500_000 + 1_000_000, CDClk);
221 end Get_Cur_CDClk;
222
223 procedure Set_CDClk (CDClk_In : CDClk_Range)
224 is
225 subtype PLL_Ratio_Range is Word32 range 0 .. 68;
Nico Huber7edb1a72026-05-27 21:10:10 +0200226 function Ratio_For_19_2_MHz (CDClk : CDClk_Range) return PLL_Ratio_Range
227 is
228 (case CDClk is
229 when 172_800_000 =>
230 (if Config.Gen_Tigerlake
231 then 18
232 else 27),-- ADL_P: only used with 19.2MHz
233 when 179_200_000 => 28, -- ADL_P: only used with 38.4MHz
234 when 192_000_000 => 20,
235 when 307_200_000 => 32,
236 when 326_400_000 | 652_800_000 => 68,
237 when 556_800_000 => 58,
238 when others => 0);
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600239
Nico Huber7edb1a72026-05-27 21:10:10 +0200240 function Ratio_For_24_MHz (CDClk : CDClk_Range) return PLL_Ratio_Range
241 is
242 (case CDClk is
243 when 176_000_000 => 22, -- only ADL_P
244 when 180_000_000 => 15, -- only TGL
245 when 192_000_000 => 16,
246 when 312_000_000 => 26,
247 when 324_000_000 | 648_000_000 => 54,
248 when 552_000_000 => 46,
249 when others => 0);
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600250
251 function CDCLK_CTL_CD_FREQ_DECIMAL (Freq : CDClk_Range) return Word32
252 with
253 Pre => Freq > 1_000_000
254 is
255 begin
256 -- Weirdest representation: CDClk - 1MHz in 10.1 (10 + 1 fractional bit)
257 return Word32 (Div_Round_Closest (Pos64 (Freq) - 1_000_000, 500_000));
258 end CDCLK_CTL_CD_FREQ_DECIMAL;
259
260 Success : Boolean;
261 CD2X : Word32;
262 PLL_Ratio : PLL_Ratio_Range;
263 CDClk : CDClk_Range;
Nico Huberac2a1412026-07-02 10:41:59 +0200264 RefClk_Freq : RefClk_Range;
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600265 VCO : Pos64;
266 begin
267 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
268
269 Normalize_CDClk (CDClk_Range'Min (CDClk_In, Config.Max_CDClk), CDClk);
Nico Huberac2a1412026-07-02 10:41:59 +0200270 Get_RefClk (RefClk_Freq);
271 PLL_Ratio := (case RefClk_Freq is
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600272 when 19_200_000 => Ratio_For_19_2_MHz (CDClk),
273 when 38_400_000 => Ratio_For_19_2_MHz (CDClk) / 2,
274 when 24_000_000 => Ratio_For_24_MHz (CDClk),
275 when others => 0);
276
277 if PLL_Ratio = 0 then
278 pragma Debug (Debug.Put_Line
Nico Huberac2a1412026-07-02 10:41:59 +0200279 ("ERROR: Invalid RefClk frequency, bad hardware?"));
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600280 return;
281 end if;
282
283 PCode.Mailbox_Request
Nico Huberac2a1412026-07-02 10:41:59 +0200284 (MBox => TGL_PCODE_CDCLK_CONTROL,
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600285 Command => TGL_CDCLK_PREPARE_FOR_CHANGE,
286 Reply_Mask => TGL_CDCLK_READY_FOR_CHANGE,
287 Wait_Ready => True,
288 Success => Success);
289
290 if not Success then
291 pragma Debug (Debug.Put_Line
292 ("ERROR: PCODE not ready for frequency change."));
293 return;
294 end if;
295
296 Registers.Unset_Mask
297 (Register => Registers.CDCLK_PLL_ENABLE,
298 Mask => CDCLK_PLL_ENABLE_PLL_ENABLE);
299 Registers.Wait_Unset_Mask
300 (Register => Registers.CDCLK_PLL_ENABLE,
301 Mask => CDCLK_PLL_ENABLE_PLL_LOCK);
302
303 Registers.Write
304 (Register => Registers.CDCLK_PLL_ENABLE,
305 Value => PLL_Ratio);
306 Registers.Write
307 (Register => Registers.CDCLK_PLL_ENABLE,
308 Value => PLL_Ratio or CDCLK_PLL_ENABLE_PLL_ENABLE);
309 Registers.Wait_Set_Mask
310 (Register => Registers.CDCLK_PLL_ENABLE,
311 Mask => CDCLK_PLL_ENABLE_PLL_LOCK,
312 Success => Success);
313
314 if not Success then
315 Debug.Put_Line ("CDClk PLL failed to lock!");
316 return;
317 end if;
318
Nico Huberac2a1412026-07-02 10:41:59 +0200319 VCO := (RefClk_Freq / 1_000) * Pos64 (PLL_Ratio);
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600320 CD2X :=
321 (case (Div_Round_Closest (VCO, CDClk / 1_000)) is
322 when 2 => CDCLK_CD2X_DIV_SEL_1,
Nico Huber7edb1a72026-05-27 21:10:10 +0200323 when 3 => CDCLK_CD2X_DIV_SEL_1_5,
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600324 when 4 => CDCLK_CD2X_DIV_SEL_2,
Nico Huber7edb1a72026-05-27 21:10:10 +0200325 when 8 => CDCLK_CD2X_DIV_SEL_4,
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600326 when others => CDCLK_CD2X_DIV_SEL_1);
327
328 Registers.Write
329 (Register => Registers.CDCLK_CTL,
330 Value => CDCLK_CTL_CD_FREQ_DECIMAL (CDClk) or
331 CDCLK_CD2X_PIPE_NONE or CD2X);
332
333 PCode.Mailbox_Write
334 (MBox => TGL_PCODE_CDCLK_CONTROL,
335 Command => (if CDClk <= 312_000_000 then 0
336 elsif CDClk <= 326_400_000 then 1
337 elsif CDClk <= 556_800_000 then 2
338 else 3));
339 Config.CDClk := CDClk;
340
341 pragma Debug (Debug.Put ("Set CDClk to "));
342 pragma Debug (Debug.Put_Int64 (CDClk / 1_000_000));
343 pragma Debug (Debug.Put ("."));
344 pragma Debug (Debug.Put_Int64 ((CDClk mod 1_000_000) / 100_000));
345 pragma Debug (Debug.Put_Line ("MHz."));
346 end Set_CDClk;
347
348 procedure Configure_Bandwidth_Buddy
349 is
350 BW_BUDDY_DISABLE : constant := 1 * 2 ** 31;
351 BW_BUDDY_TLB_REQ_TIMER_MASK : constant := 16#3f_0000#;
352
353 type DRAM_Module_Type is (DDR4, DDR5, LPDDR4, LPDDR5);
354 type Bw_Buddy_Info is record
355 DRAM_Channels : Natural;
356 DRAM_Type : DRAM_Module_Type;
357 BW_BUDDY_MASK : Word32;
358 end record;
359 type Bw_Buddy_Info_Array is array (1 .. 8) of Bw_Buddy_Info;
360
361 Buddy_Info : constant Bw_Buddy_Info_Array :=
362 ((1, DDR4, 16#0f#),
363 (1, DDR5, 16#0f#),
364 (2, LPDDR4, 16#1c#),
365 (2, LPDDR5, 16#1c#),
366 (2, DDR4, 16#1f#),
367 (2, DDR5, 16#1e#),
368 (4, LPDDR4, 16#38#),
369 (4, LPDDR5, 16#38#));
370
371 -- TODO: use for ADL-S, RKL A0/B0
372 Buddy_Info_Wa_1409767108 : constant Bw_Buddy_Info_Array :=
373 ((1, DDR4, 1),
374 (1, DDR5, 1),
375 (1, LPDDR4, 1),
376 (1, LPDDR5, 1),
377 (2, DDR4, 3),
378 (2, DDR5, 3),
379 (2, LPDDR4, 3),
380 (2, LPDDR5, 3));
381
382 Result : Word64;
383 Module_Type: DRAM_Module_Type;
384 Channels : Natural;
385 Success : Boolean;
386 begin
387 PCode.Mailbox_Read(MBox => TGL_PCODE_MEM_SUBSYSTEM_INFO or
388 TGL_PCODE_MEM_SS_READ_GLOBAL_INFO,
389 Wait_Ready => True,
390 Reply => Result,
391 Success => Success);
392 if not Success then
393 pragma Debug (Debug.Put_Line
394 ("ERROR: PCODE didn't return memory info."));
395 return;
396 end if;
397
Nico Huberac2a1412026-07-02 10:41:59 +0200398 case Result and 16#f# is
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600399 when 0 => Module_Type := DDR4;
400 when 1 => Module_Type := DDR5;
401 when 2 => Module_Type := LPDDR5;
402 when 3 => Module_Type := LPDDR4;
403 when others =>
404 pragma Debug (Debug.Put_Line ("ERROR: Invalid DRAM Module Type."));
405 return;
406 end case;
407
408 Channels := Natural (Shift_Right (Result and 16#f0#, 4));
409 for I in Buddy_Info'Range loop
410 if Buddy_Info (I).DRAM_Type = Module_Type and
411 Buddy_Info (I).DRAM_Channels = Channels
412 then
413 Registers.Set_Mask
414 (Register => Registers.BW_BUDDY1_PAGE_MASK,
415 Mask => Buddy_Info (I).BW_BUDDY_MASK);
416 Registers.Set_Mask
417 (Register => Registers.BW_BUDDY2_PAGE_MASK,
418 Mask => Buddy_Info (I).BW_BUDDY_MASK);
419
Nico Huber7edb1a72026-05-27 21:10:10 +0200420 if Config.Gen_Tigerlake then
421 -- Wa_22010178259:tgl,rkl
422 Registers.Unset_And_Set_Mask
423 (Register => Registers.BW_BUDDY1_CTL,
424 Mask_Unset => BW_BUDDY_TLB_REQ_TIMER_MASK,
425 Mask_Set => 8 * 2 ** 16);
426 Registers.Unset_And_Set_Mask
427 (Register => Registers.BW_BUDDY2_CTL,
428 Mask_Unset => BW_BUDDY_TLB_REQ_TIMER_MASK,
429 Mask_Set => 8 * 2 ** 16);
430 end if;
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600431
432 return;
433 end if;
434 end loop;
435
436 Registers.Write (Registers.BW_BUDDY1_CTL, BW_BUDDY_DISABLE);
437 Registers.Write (Registers.BW_BUDDY2_CTL, BW_BUDDY_DISABLE);
438 end Configure_Bandwidth_Buddy;
439
440 ----------------------------------------------------------------------------
441
442 procedure Initialize
443 is
444 RawClk : Frequency_Type;
445 begin
446 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
447
448 -- Wa_14011294188:ehl,jsl,tgl,rkl,adl-s,adl-p
449 Registers.Set_Mask
450 (Register => Registers.PCH_DSPCLK_GATE_D,
451 Mask => PCH_DPMGUNIT_CLOCK_GATE_DISABLE);
452
453 Registers.Set_Mask
454 (Register => Registers.NDE_RSTWRN_OPT,
455 Mask => NDE_RSTWRN_OPT_RST_PCH_Handshake_En);
456
Nico Huber27d26272026-05-27 19:01:09 +0200457 Power_Domains_Common.PD_On (Power_Domains.PW1);
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600458
459 Get_Cur_CDClk (Config.CDClk);
460 Get_Max_CDClk (Config.Max_CDClk);
461 if Config.CDClk < Config.Default_CDClk_Freq then
462 Set_CDClk (Config.Default_CDClk_Freq);
463 end if;
464
465 Get_RawClk (RawClk);
466 Config.Raw_Clock := RawClk;
467
Nico Huber7edb1a72026-05-27 21:10:10 +0200468 -- Settings for joined MBUS. MBUS joining is usually used when buffers
469 -- from both DBUF slice pairs 1/2 and 3/4 are used for a single pipe.
470 -- TODO: Investigate if this is needed for our PLANE_BUF_CFG allocation.
471 if Config.Has_Mbus_Joining then
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600472 Registers.Unset_And_Set_Mask
Nico Huber7edb1a72026-05-27 21:10:10 +0200473 (Register => Registers.MBUS_CTL,
474 Mask_Unset => MBUS_HASHING_MODE_MASK or
475 MBUS_JOIN or
476 MBUS_JOIN_PIPE_SELECT_MASK,
477 Mask_Set => MBUS_HASHING_MODE_1x4 or
478 MBUS_JOIN or
479 MBUS_JOIN_PIPE_SELECT_NONE);
480 end if;
481
482 -- TGL: Set DBUF Tracker State Service to 8
483 if Config.Gen_Tigerlake then
484 Registers.Unset_And_Set_Mask
485 (Register => DBUF_CTL (S1),
486 Mask_Unset => DBUF_CTL_TRACKER_STATE_SERVICE_MASK,
487 Mask_Set => 8 * 2 ** DBUF_CTL_TRACKER_STATE_SERVICE_SHIFT);
488 end if;
489
490 if Config.Gen_AlderlakeP then
491 Registers.Unset_And_Set_Mask
492 (Register => DBUF_CTL (S1),
493 Mask_Unset => DBUF_CTL_MIN_TRACKER_STATE_SERVICE_MASK,
494 Mask_Set => 3 * 2 ** DBUF_CTL_MIN_TRACKER_STATE_SERVICE_SHIFT);
495 end if;
496
497 -- Enable required DBUF slices
498 for S in Enable_DBUF_Slices loop
499 Registers.Set_Mask (DBUF_CTL (S), DBUF_CTL_DBUF_POWER_REQUEST);
500 Registers.Wait_Set_Mask (DBUF_CTL (S), DBUF_CTL_DBUF_POWER_STATE);
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600501 end loop;
502
Nico Huber7edb1a72026-05-27 21:10:10 +0200503 if Config.Has_Mbus_Abox_Credits then
504 for I in MBUS_ABOX_CTL'Range loop
505 Registers.Unset_And_Set_Mask
506 (Register => MBUS_ABOX_CTL (I),
507 Mask_Unset => MBUS_ABOX_MASK,
508 Mask_Set => MBUS_ABOX_CREDITS);
509 end loop;
510 end if;
511
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600512 Configure_Bandwidth_Buddy;
513
514 -- Display WA #14011508470 tgl,dg1,rkl,adl-s,adl-p,dg2
515 Registers.Set_Mask
516 (Register => Registers.GEN11_CHICKEN_DCPR_2,
517 Mask => DCPR_MASK_MAXLATENCY_MEMUP_CLR or DCPR_MASK_LPMODE or
518 DCPR_SEND_RESP_IMM or DCPR_CLEAR_MEMSTAT_DIS);
Nico Huber7edb1a72026-05-27 21:10:10 +0200519
520 if Config.Gen_AlderlakeP then
521 declare
522 DPCE_GATING_DIS : constant := 1 * 2 ** 17;
523 DDI_CLOCK_REG_ACCESS : constant := 1 * 2 ** 7;
524 begin
525 -- Display WA #14011503030 xelpd
526 Registers.Write
527 (Register => Registers.DISPLAY_ERR_FATAL_MASK,
528 Value => 16#ffff_ffff#);
529
530 -- Wa_22011091694:adlp
531 Registers.Set_Mask
532 (Register => Registers.GEN9_CLKGATE_DIS_5,
533 Mask => DPCE_GATING_DIS);
534
535 -- Bspec/49189 Initialize Sequence
536 Registers.Unset_Mask
537 (Register => Registers.GEN8_CHICKEN_DCPR_1,
538 Mask => DDI_CLOCK_REG_ACCESS);
539 end;
540 end if;
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600541 end Initialize;
542
543 procedure Limit_Dotclocks
544 (Configs : in out Pipe_Configs;
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600545 CDClk_Switch : out Boolean)
546 is
547 CDClk : CDClk_Range;
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600548 begin
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600549 Config_Helpers.Limit_Dotclocks (Configs, Config.Max_CDClk);
550 Normalize_CDClk (Config_Helpers.Highest_Dotclock (Configs), CDClk);
551 CDClk_Switch := Config.CDClk /= CDClk;
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600552 end Limit_Dotclocks;
553
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600554 procedure Update_CDClk (Configs : in out Pipe_Configs)
555 is
556 New_CDClk : constant Frequency_Type :=
557 Config_Helpers.Highest_Dotclock (Configs);
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600558 begin
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600559 Set_CDClk (New_CDClk);
560 Config_Helpers.Limit_Dotclocks (Configs, Config.CDClk);
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600561 end Update_CDClk;
562
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600563 procedure Enable_CDClk is
564 begin
565 if Config.CDClk < Config.Default_CDClk_Freq then
566 Set_CDClk (Config.Default_CDClk_Freq);
567 end if;
568 end Enable_CDClk;
569
570 ----------------------------------------------------------------------------
571
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600572 procedure Pre_All_Off is
573 begin
574 Transcoder.PSR_Off;
575 end Pre_All_Off;
576
577 procedure Post_All_Off is
578 begin
579 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
580
Nico Huber7edb1a72026-05-27 21:10:10 +0200581 for S in reverse Disable_DBUF_Slices loop
582 Registers.Unset_Mask (DBUF_CTL (S), DBUF_CTL_DBUF_POWER_REQUEST);
583 Registers.Wait_Unset_Mask (DBUF_CTL (S), DBUF_CTL_DBUF_POWER_STATE);
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600584 end loop;
585
586 -- Disable CDClk PLL. FIXME: Not implemented yet.
587 Set_CDClk (CDClk_Range'First);
588
Nico Huber27d26272026-05-27 19:01:09 +0200589 Power_Domains_Common.All_Off;
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600590
591 Combo_Phy.All_Off;
592 end Post_All_Off;
593
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600594end HW.GFX.GMA.Power_And_Clocks;