153 lines
4.1 KiB
Ada
153 lines
4.1 KiB
Ada
--
|
|
-- Copyright (C) 2015-2016 secunet Security Networks AG
|
|
--
|
|
-- This program is free software; you can redistribute it and/or modify
|
|
-- it under the terms of the GNU General Public License as published by
|
|
-- the Free Software Foundation; either version 2 of the License, or
|
|
-- (at your option) any later version.
|
|
--
|
|
-- This program is distributed in the hope that it will be useful,
|
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
-- GNU General Public License for more details.
|
|
--
|
|
|
|
with HW.GFX.GMA.PLLs.DPLL_0;
|
|
with HW.GFX.GMA.PLLs.DPLL;
|
|
|
|
with HW.Debug;
|
|
with GNAT.Source_Info;
|
|
|
|
package body HW.GFX.GMA.PLLs
|
|
with
|
|
Refined_State => (State => PLLs)
|
|
is
|
|
|
|
type Count_Range is new Natural range 0 .. 2;
|
|
|
|
type PLL_State is record
|
|
Use_Count : Count_Range;
|
|
Used_For_DP : Boolean;
|
|
Link_Rate : DP_Bandwidth;
|
|
Mode : Mode_Type;
|
|
end record;
|
|
|
|
type PLL_State_Array is array (Configurable_DPLLs) of PLL_State;
|
|
|
|
PLLs : PLL_State_Array;
|
|
|
|
procedure Initialize
|
|
is
|
|
begin
|
|
PLLs :=
|
|
(Configurable_DPLLs =>
|
|
(Use_Count => 0,
|
|
Used_For_DP => False,
|
|
Link_Rate => DP_Bandwidth'First,
|
|
Mode => Invalid_Mode));
|
|
end Initialize;
|
|
|
|
procedure Alloc_Configurable
|
|
(Port_Cfg : in Port_Config;
|
|
PLL : out T;
|
|
Success : out Boolean)
|
|
with
|
|
Pre => True
|
|
is
|
|
function Config_Matches (PE : PLL_State) return Boolean
|
|
is
|
|
begin
|
|
return
|
|
PE.Used_For_DP = (Port_Cfg.Display = DP) and
|
|
((PE.Used_For_DP and PE.Link_Rate = Port_Cfg.DP.Bandwidth) or
|
|
(not PE.Used_For_DP and PE.Mode = Port_Cfg.Mode));
|
|
end Config_Matches;
|
|
begin
|
|
-- try to find shareable PLL
|
|
for P in Configurable_DPLLs loop
|
|
Success := PLLs (P).Use_Count /= 0 and
|
|
PLLs (P).Use_Count /= Count_Range'Last and
|
|
Config_Matches (PLLs (P));
|
|
if Success then
|
|
PLL := P;
|
|
PLLs (PLL).Use_Count := PLLs (PLL).Use_Count + 1;
|
|
return;
|
|
end if;
|
|
end loop;
|
|
|
|
-- try to find free PLL
|
|
for P in Configurable_DPLLs loop
|
|
if PLLs (P).Use_Count = 0 then
|
|
PLL := P;
|
|
DPLL.On (PLL, Port_Cfg, Success);
|
|
if Success then
|
|
PLLs (PLL) :=
|
|
(Use_Count => 1,
|
|
Used_For_DP => Port_Cfg.Display = DP,
|
|
Link_Rate => Port_Cfg.DP.Bandwidth,
|
|
Mode => Port_Cfg.Mode);
|
|
end if;
|
|
return;
|
|
end if;
|
|
end loop;
|
|
|
|
PLL := Invalid;
|
|
end Alloc_Configurable;
|
|
|
|
procedure Alloc
|
|
(Port_Cfg : in Port_Config;
|
|
PLL : out T;
|
|
Success : out Boolean)
|
|
is
|
|
begin
|
|
pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
|
|
|
|
if Port_Cfg.Port = DIGI_A then
|
|
DPLL_0.Check_Link_Rate (Port_Cfg.DP.Bandwidth, Success);
|
|
else
|
|
Success := False;
|
|
end if;
|
|
|
|
if Success then
|
|
PLL := DPLL0;
|
|
else
|
|
Alloc_Configurable (Port_Cfg, PLL, Success);
|
|
end if;
|
|
end Alloc;
|
|
|
|
procedure Free (PLL : T)
|
|
is
|
|
begin
|
|
pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
|
|
|
|
if PLL in Configurable_DPLLs then
|
|
if PLLs (PLL).Use_Count /= 0 then
|
|
PLLs (PLL).Use_Count := PLLs (PLL).Use_Count - 1;
|
|
if PLLs (PLL).Use_Count = 0 then
|
|
DPLL.Off (PLL);
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end Free;
|
|
|
|
procedure All_Off
|
|
is
|
|
begin
|
|
pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
|
|
|
|
for PLL in Configurable_DPLLs loop
|
|
DPLL.Off (PLL);
|
|
end loop;
|
|
end All_Off;
|
|
|
|
function Register_Value (PLL : T) return Word32
|
|
is
|
|
begin
|
|
return
|
|
(if PLL = DPLL0 then DPLL_0.Register_Value
|
|
elsif PLL in Configurable_DPLLs then DPLL.Register_Value (PLL)
|
|
else 0);
|
|
end Register_Value;
|
|
|
|
end HW.GFX.GMA.PLLs;
|