blob: 526a90ae26fcce7e770dd75d46b7f27e6d9bac63 [file] [log] [blame]
Nico Huber83693c82016-10-08 22:17:55 +02001--
Nico Huber25fdb152019-02-17 15:54:39 +01002-- Copyright (C) 2015-2016, 2019 secunet Security Networks AG
Nico Huber83693c82016-10-08 22:17:55 +02003--
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 Huber125a29e2016-10-18 00:23:54 +02006-- the Free Software Foundation; either version 2 of the License, or
7-- (at your option) any later version.
Nico Huber83693c82016-10-08 22:17:55 +02008--
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
Nico Huber25fdb152019-02-17 15:54:39 +010015with HW.GFX.GMA.Config;
Nico Huber83693c82016-10-08 22:17:55 +020016with HW.GFX.GMA.PLLs.LCPLL;
17with HW.GFX.GMA.PLLs.WRPLL;
18
19with HW.Debug;
20with GNAT.Source_Info;
21
22package body HW.GFX.GMA.PLLs
23with
24 Refined_State => (State => PLLs)
25is
26
27 type Count_Range is new Natural range 0 .. 2;
28
29 type PLL_State is record
30 Use_Count : Count_Range;
31 Mode : Mode_Type;
32 end record;
33
34 type PLL_State_Array is array (WRPLLs) of PLL_State;
35
36 PLLs : PLL_State_Array;
37
38 procedure Initialize
39 is
40 begin
41 PLLs := (WRPLLs => (Use_Count => 0, Mode => Invalid_Mode));
42 end Initialize;
43
44 procedure Alloc_Configurable
45 (Mode : in Mode_Type;
46 PLL : out T;
47 Success : out Boolean)
48 with
49 Pre => True
50 is
51 begin
52 -- try to find shareable PLL
53 for P in WRPLLs loop
54 Success := PLLs (P).Use_Count /= 0 and
55 PLLs (P).Use_Count /= Count_Range'Last and
56 PLLs (P).Mode = Mode;
57 if Success then
58 PLL := P;
59 PLLs (PLL).Use_Count := PLLs (PLL).Use_Count + 1;
60 return;
61 end if;
62 end loop;
63
64 -- try to find free PLL
65 for P in WRPLLs loop
66 if PLLs (P).Use_Count = 0 then
67 PLL := P;
68 WRPLL.On (PLL, Mode.Dotclock, Success);
69 if Success then
70 PLLs (PLL) := (Use_Count => 1, Mode => Mode);
71 end if;
72 return;
73 end if;
74 end loop;
75
76 PLL := Invalid;
77 end Alloc_Configurable;
78
79 procedure Alloc
80 (Port_Cfg : in Port_Config;
81 PLL : out T;
82 Success : out Boolean)
83 is
84 begin
85 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
86
87 if Port_Cfg.Port = DIGI_E then
88 PLL := Invalid;
89 Success := True;
90 elsif Port_Cfg.Display = DP then
Nico Huber25fdb152019-02-17 15:54:39 +010091 if Config.DP_Max_2_7_GHz and then
92 Port_Cfg.DP.Bandwidth > DP_Bandwidth_2_7
93 then
94 PLL := Invalid;
95 Success := False;
96 else
97 PLL := LCPLL.Fixed_LCPLLs (Port_Cfg.DP.Bandwidth);
98 Success := True;
99 end if;
Nico Huber83693c82016-10-08 22:17:55 +0200100 else
101 Alloc_Configurable (Port_Cfg.Mode, PLL, Success);
102 end if;
103 end Alloc;
104
105 procedure Free (PLL : T)
106 is
107 begin
108 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
109
110 if PLL in WRPLLs then
111 if PLLs (PLL).Use_Count /= 0 then
112 PLLs (PLL).Use_Count := PLLs (PLL).Use_Count - 1;
113 if PLLs (PLL).Use_Count = 0 then
114 WRPLL.Off (PLL);
115 end if;
116 end if;
117 end if;
118 end Free;
119
120 procedure All_Off
121 is
122 begin
123 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
124
125 for PLL in WRPLLs loop
126 WRPLL.Off (PLL);
127 end loop;
128 end All_Off;
129
130 function Register_Value (PLL : T) return Word32
131 is
132 begin
133 return
134 (if PLL in LCPLLs then LCPLL.Register_Value (PLL)
135 elsif PLL in WRPLLs then WRPLL.Register_Value (PLL)
136 else 0);
137 end Register_Value;
138
139end HW.GFX.GMA.PLLs;