blob: 48cdf60514a5b72c23bbe6ec937eb22ba3d4e7a5 [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;
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 Wawrzynczak6db27c42022-09-09 10:49:55 -060082 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 Huberac2a1412026-07-02 10:41:59 +0200101 procedure Get_RefClk (RefClk : out RefClk_Range)
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600102 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 Huberac2a1412026-07-02 10:41:59 +0200110 RefClk :=
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600111 (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 Huberac2a1412026-07-02 10:41:59 +0200116 end Get_RefClk;
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600117
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 Huberac2a1412026-07-02 10:41:59 +0200136 RefClk_Freq : RefClk_Range;
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600137 begin
Nico Huberac2a1412026-07-02 10:41:59 +0200138 Get_RefClk (RefClk_Freq);
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600139 CDClk :=
Nico Huberac2a1412026-07-02 10:41:59 +0200140 (case RefClk_Freq is
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600141 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 Huberac2a1412026-07-02 10:41:59 +0200151 RefClk_Freq : RefClk_Range;
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600152 begin
Nico Huberac2a1412026-07-02 10:41:59 +0200153 Get_RefClk (RefClk_Freq);
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600154 Normalized :=
Nico Huberac2a1412026-07-02 10:41:59 +0200155 (case RefClk_Freq is
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600156 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 Huberac2a1412026-07-02 10:41:59 +0200198 function Ratio_For_24_MHz (CDClk : CDClk_Range) return PLL_Ratio_Range is
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600199 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 Huberac2a1412026-07-02 10:41:59 +0200223 RefClk_Freq : RefClk_Range;
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600224 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 Huberac2a1412026-07-02 10:41:59 +0200229 Get_RefClk (RefClk_Freq);
230 PLL_Ratio := (case RefClk_Freq is
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600231 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 Huberac2a1412026-07-02 10:41:59 +0200238 ("ERROR: Invalid RefClk frequency, bad hardware?"));
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600239 return;
240 end if;
241
242 PCode.Mailbox_Request
Nico Huberac2a1412026-07-02 10:41:59 +0200243 (MBox => TGL_PCODE_CDCLK_CONTROL,
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600244 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 Huberac2a1412026-07-02 10:41:59 +0200278 VCO := (RefClk_Freq / 1_000) * Pos64 (PLL_Ratio);
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600279 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 Huberac2a1412026-07-02 10:41:59 +0200355 case Result and 16#f# is
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600356 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 Huber27d26272026-05-27 19:01:09 +0200412 Power_Domains_Common.PD_On (Power_Domains.PW1);
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600413
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 Wawrzynczak605660b2022-06-08 12:48:19 -0600447 end Initialize;
448
449 procedure Limit_Dotclocks
450 (Configs : in out Pipe_Configs;
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600451 CDClk_Switch : out Boolean)
452 is
453 CDClk : CDClk_Range;
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600454 begin
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600455 Config_Helpers.Limit_Dotclocks (Configs, Config.Max_CDClk);
456 Normalize_CDClk (Config_Helpers.Highest_Dotclock (Configs), CDClk);
457 CDClk_Switch := Config.CDClk /= CDClk;
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600458 end Limit_Dotclocks;
459
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600460 procedure Update_CDClk (Configs : in out Pipe_Configs)
461 is
462 New_CDClk : constant Frequency_Type :=
463 Config_Helpers.Highest_Dotclock (Configs);
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600464 begin
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600465 Set_CDClk (New_CDClk);
466 Config_Helpers.Limit_Dotclocks (Configs, Config.CDClk);
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600467 end Update_CDClk;
468
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600469 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 Wawrzynczak6db27c42022-09-09 10:49:55 -0600478 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 Huber27d26272026-05-27 19:01:09 +0200497 Power_Domains_Common.All_Off;
Tim Wawrzynczak6db27c42022-09-09 10:49:55 -0600498
499 Combo_Phy.All_Off;
500 end Post_All_Off;
501
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600502end HW.GFX.GMA.Power_And_Clocks;