blob: 3a91bdd1873b4d707f1099be93581f680ac7ad8b [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
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
15with HW.GFX.GMA.PLLs.LCPLL;
16with HW.GFX.GMA.PLLs.WRPLL;
17
18with HW.Debug;
19with GNAT.Source_Info;
20
21package body HW.GFX.GMA.PLLs
22with
23 Refined_State => (State => PLLs)
24is
25
26 type Count_Range is new Natural range 0 .. 2;
27
28 type PLL_State is record
29 Use_Count : Count_Range;
30 Mode : Mode_Type;
31 end record;
32
33 type PLL_State_Array is array (WRPLLs) of PLL_State;
34
35 PLLs : PLL_State_Array;
36
37 procedure Initialize
38 is
39 begin
40 PLLs := (WRPLLs => (Use_Count => 0, Mode => Invalid_Mode));
41 end Initialize;
42
43 procedure Alloc_Configurable
44 (Mode : in Mode_Type;
45 PLL : out T;
46 Success : out Boolean)
47 with
48 Pre => True
49 is
50 begin
51 -- try to find shareable PLL
52 for P in WRPLLs loop
53 Success := PLLs (P).Use_Count /= 0 and
54 PLLs (P).Use_Count /= Count_Range'Last and
55 PLLs (P).Mode = Mode;
56 if Success then
57 PLL := P;
58 PLLs (PLL).Use_Count := PLLs (PLL).Use_Count + 1;
59 return;
60 end if;
61 end loop;
62
63 -- try to find free PLL
64 for P in WRPLLs loop
65 if PLLs (P).Use_Count = 0 then
66 PLL := P;
67 WRPLL.On (PLL, Mode.Dotclock, Success);
68 if Success then
69 PLLs (PLL) := (Use_Count => 1, Mode => Mode);
70 end if;
71 return;
72 end if;
73 end loop;
74
75 PLL := Invalid;
76 end Alloc_Configurable;
77
78 procedure Alloc
79 (Port_Cfg : in Port_Config;
80 PLL : out T;
81 Success : out Boolean)
82 is
83 begin
84 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
85
86 if Port_Cfg.Port = DIGI_E then
87 PLL := Invalid;
88 Success := True;
89 elsif Port_Cfg.Display = DP then
90 PLL := LCPLL.Fixed_LCPLLs (Port_Cfg.DP.Bandwidth);
91 Success := True;
92 else
93 Alloc_Configurable (Port_Cfg.Mode, PLL, Success);
94 end if;
95 end Alloc;
96
97 procedure Free (PLL : T)
98 is
99 begin
100 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
101
102 if PLL in WRPLLs then
103 if PLLs (PLL).Use_Count /= 0 then
104 PLLs (PLL).Use_Count := PLLs (PLL).Use_Count - 1;
105 if PLLs (PLL).Use_Count = 0 then
106 WRPLL.Off (PLL);
107 end if;
108 end if;
109 end if;
110 end Free;
111
112 procedure All_Off
113 is
114 begin
115 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
116
117 for PLL in WRPLLs loop
118 WRPLL.Off (PLL);
119 end loop;
120 end All_Off;
121
122 function Register_Value (PLL : T) return Word32
123 is
124 begin
125 return
126 (if PLL in LCPLLs then LCPLL.Register_Value (PLL)
127 elsif PLL in WRPLLs then WRPLL.Register_Value (PLL)
128 else 0);
129 end Register_Value;
130
131end HW.GFX.GMA.PLLs;