blob: 45faa66c11a2f2c2ffdbc59a6ca4b23108599ba0 [file] [log] [blame]
Nico Huber83693c82016-10-08 22:17:55 +02001--
2-- Copyright (C) 2015-2016 secunet Security Networks AG
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; version 2 of the License.
7--
8-- This program is distributed in the hope that it will be useful,
9-- but WITHOUT ANY WARRANTY; without even the implied warranty of
10-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11-- GNU General Public License for more details.
12--
13
14with HW.GFX.GMA.PLLs.LCPLL;
15with HW.GFX.GMA.PLLs.WRPLL;
16
17with HW.Debug;
18with GNAT.Source_Info;
19
20package body HW.GFX.GMA.PLLs
21with
22 Refined_State => (State => PLLs)
23is
24
25 type Count_Range is new Natural range 0 .. 2;
26
27 type PLL_State is record
28 Use_Count : Count_Range;
29 Mode : Mode_Type;
30 end record;
31
32 type PLL_State_Array is array (WRPLLs) of PLL_State;
33
34 PLLs : PLL_State_Array;
35
36 procedure Initialize
37 is
38 begin
39 PLLs := (WRPLLs => (Use_Count => 0, Mode => Invalid_Mode));
40 end Initialize;
41
42 procedure Alloc_Configurable
43 (Mode : in Mode_Type;
44 PLL : out T;
45 Success : out Boolean)
46 with
47 Pre => True
48 is
49 begin
50 -- try to find shareable PLL
51 for P in WRPLLs loop
52 Success := PLLs (P).Use_Count /= 0 and
53 PLLs (P).Use_Count /= Count_Range'Last and
54 PLLs (P).Mode = Mode;
55 if Success then
56 PLL := P;
57 PLLs (PLL).Use_Count := PLLs (PLL).Use_Count + 1;
58 return;
59 end if;
60 end loop;
61
62 -- try to find free PLL
63 for P in WRPLLs loop
64 if PLLs (P).Use_Count = 0 then
65 PLL := P;
66 WRPLL.On (PLL, Mode.Dotclock, Success);
67 if Success then
68 PLLs (PLL) := (Use_Count => 1, Mode => Mode);
69 end if;
70 return;
71 end if;
72 end loop;
73
74 PLL := Invalid;
75 end Alloc_Configurable;
76
77 procedure Alloc
78 (Port_Cfg : in Port_Config;
79 PLL : out T;
80 Success : out Boolean)
81 is
82 begin
83 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
84
85 if Port_Cfg.Port = DIGI_E then
86 PLL := Invalid;
87 Success := True;
88 elsif Port_Cfg.Display = DP then
89 PLL := LCPLL.Fixed_LCPLLs (Port_Cfg.DP.Bandwidth);
90 Success := True;
91 else
92 Alloc_Configurable (Port_Cfg.Mode, PLL, Success);
93 end if;
94 end Alloc;
95
96 procedure Free (PLL : T)
97 is
98 begin
99 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
100
101 if PLL in WRPLLs then
102 if PLLs (PLL).Use_Count /= 0 then
103 PLLs (PLL).Use_Count := PLLs (PLL).Use_Count - 1;
104 if PLLs (PLL).Use_Count = 0 then
105 WRPLL.Off (PLL);
106 end if;
107 end if;
108 end if;
109 end Free;
110
111 procedure All_Off
112 is
113 begin
114 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
115
116 for PLL in WRPLLs loop
117 WRPLL.Off (PLL);
118 end loop;
119 end All_Off;
120
121 function Register_Value (PLL : T) return Word32
122 is
123 begin
124 return
125 (if PLL in LCPLLs then LCPLL.Register_Value (PLL)
126 elsif PLL in WRPLLs then WRPLL.Register_Value (PLL)
127 else 0);
128 end Register_Value;
129
130end HW.GFX.GMA.PLLs;