blob: 48be928ff2e4096b2b397d8579abfc889885d906 [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
15with HW.Debug;
16with GNAT.Source_Info;
Tim Wawrzynczak68deeb42022-09-09 10:59:08 -060017with HW.GFX.GMA.PLLs.Combo_Phy;
18with HW.GFX.GMA.PLLs.Dekel_Phy;
19with HW.GFX.GMA.Config;
Tim Wawrzynczak605660b2022-06-08 12:48:19 -060020
21package body HW.GFX.GMA.PLLs
22with
23 Refined_State => (State => PLLs)
24is
25
Tim Wawrzynczak68deeb42022-09-09 10:59:08 -060026 type PLL_Type is (PLL_Unknown, PLL_Combo_Phy, PLL_DKL);
27 function Port_PLL_Type (Port : GPU_Port) return PLL_Type is
28 (case Port is
29 when Combo_Port => PLL_Combo_Phy,
30 when USBC_Port => PLL_DKL,
31 when others => PLL_Unknown);
Tim Wawrzynczak605660b2022-06-08 12:48:19 -060032
Tim Wawrzynczak68deeb42022-09-09 10:59:08 -060033 type Count_Range is new Natural range 0 .. 2;
Tim Wawrzynczak605660b2022-06-08 12:48:19 -060034 type PLL_State is record
35 Use_Count : Count_Range;
Tim Wawrzynczak68deeb42022-09-09 10:59:08 -060036 Used_For_DP : Boolean;
37 Link_Rate : DP_Bandwidth;
38 Mode : Mode_Type;
Tim Wawrzynczak605660b2022-06-08 12:48:19 -060039 end record;
40
41 type PLL_State_Array is array (Configurable_DPLLs) of PLL_State;
Angel Pons17cfc922024-04-11 14:08:16 +020042
43 pragma Warnings (Off, "unused variable ""PLLs""",
44 Reason => "Not yet implemented.");
45 pragma Warnings (Off, "variable ""PLLs"" is assigned but never read",
46 Reason => "Not yet implemented.");
Tim Wawrzynczak605660b2022-06-08 12:48:19 -060047 PLLs : PLL_State_Array;
Angel Pons17cfc922024-04-11 14:08:16 +020048 pragma Warnings (On, "variable ""PLLs"" is assigned but never read");
49 pragma Warnings (On, "unused variable ""PLLs""");
Tim Wawrzynczak605660b2022-06-08 12:48:19 -060050
51 procedure Initialize is
52 begin
53 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
54 PLLs :=
55 (Configurable_DPLLs =>
Tim Wawrzynczak68deeb42022-09-09 10:59:08 -060056 (Use_Count => 0,
57 Used_For_DP => False,
58 Link_Rate => DP_Bandwidth'First,
59 Mode => Invalid_Mode));
Tim Wawrzynczak605660b2022-06-08 12:48:19 -060060 end Initialize;
61
62 procedure Alloc
63 (Port_Cfg : in Port_Config;
64 PLL : out T;
65 Success : out Boolean)
66 is
Tim Wawrzynczak68deeb42022-09-09 10:59:08 -060067 function Port_PLL_Match (Port : GPU_Port; PLL : T) return Boolean is
68 (case Port is
69 when Combo_Port => PLL in Combo_DPLLs,
70 when DDI_TC1 => PLL = TCPLL1,
71 when DDI_TC2 => PLL = TCPLL2,
72 when DDI_TC3 => PLL = TCPLL3,
73 when DDI_TC4 => PLL = TCPLL4,
74 when DDI_TC5 => PLL = TCPLL5,
75 when DDI_TC6 => PLL = TCPLL6,
76 when others => False);
77
78 function Config_Matches (PE : HW.GFX.GMA.PLLs.PLL_State) return Boolean
79 is
80 begin
81 return
82 PE.Used_For_DP = (Port_Cfg.Display = DP) and
83 ((PE.Used_For_DP and PE.Link_Rate = Port_Cfg.DP.Bandwidth) or
84 (not PE.Used_For_DP and PE.Mode = Port_Cfg.Mode));
85 end Config_Matches;
Tim Wawrzynczak605660b2022-06-08 12:48:19 -060086 begin
87 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
Tim Wawrzynczak68deeb42022-09-09 10:59:08 -060088
89 for P in Configurable_DPLLs loop
90 Success := PLLs (P).Use_Count /= 0 and
91 PLLs (P).Use_Count /= Count_Range'Last and
92 Port_PLL_Match (Port_Cfg.Port, P) and
93 Config_Matches (PLLs (P));
94 if Success then
95 PLL := P;
96 PLLs (PLL).Use_Count := PLLs (PLL).Use_Count + 1;
97 return;
98 end if;
99 end loop;
100
101 for P in Configurable_DPLLs loop
102 if PLLs (P).Use_Count = 0 and Port_PLL_Match (Port_Cfg.Port, P) then
103 PLL := P;
104 case P is
105 when Combo_DPLLs => Combo_Phy.On (PLL, Port_Cfg, Success);
106 when DKL_DPLLs => Dekel_Phy.On (PLL, Port_Cfg, Success);
107 end case;
108 if Success then
109 PLLs (PLL) :=
110 (Use_Count => 1,
111 Used_For_DP => Port_Cfg.Display = DP,
112 Link_Rate => Port_Cfg.DP.Bandwidth,
113 Mode => Port_Cfg.Mode);
114 end if;
115 return;
116 end if;
117 end loop;
118
119 PLL := Invalid;
120 Success := False;
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600121 end Alloc;
122
123 procedure Free (PLL : T) is
124 begin
125 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
Tim Wawrzynczak68deeb42022-09-09 10:59:08 -0600126
127 if PLL /= Invalid_PLL then
128 PLLs (PLL).Use_Count := 0;
129 end if;
130
131 case PLL is
132 when Combo_DPLLs => Combo_Phy.Free (PLL);
133 when DKL_DPLLs => Dekel_Phy.Free (PLL);
134 when Invalid_PLL => null;
135 end case;
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600136 end Free;
137
138 procedure All_Off is
139 begin
140 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
Tim Wawrzynczak68deeb42022-09-09 10:59:08 -0600141 Combo_Phy.All_Off;
142 Dekel_Phy.All_Off;
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600143 end All_Off;
144
145 function Register_Value (PLL : T) return Word32
146 is
147 begin
148 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
Tim Wawrzynczak68deeb42022-09-09 10:59:08 -0600149
150 -- Only required for combo ports
151 if PLL in Combo_DPLLs then
152 return Combo_Phy.Register_Value (PLL);
153 end if;
154
155 return 0;
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600156 end Register_Value;
157end HW.GFX.GMA.PLLs;