Initial upstream commit

The history contained unlicensed code so everything got squashed, sorry.

Change-Id: I9f5775208f9df6fb29074bf3bc498f68cb17b3a0
Signed-off-by: Nico Huber <nico.huber@secunet.com>
diff --git a/common/hw-gfx-gma.adb b/common/hw-gfx-gma.adb
new file mode 100644
index 0000000..d004381
--- /dev/null
+++ b/common/hw-gfx-gma.adb
@@ -0,0 +1,836 @@
+--
+-- Copyright (C) 2014-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; version 2 of the License.
+--
+-- 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.EDID;
+with HW.GFX.GMA.Config;
+with HW.GFX.GMA.DP_Info;
+with HW.GFX.GMA.Registers;
+with HW.GFX.GMA.Power_And_Clocks;
+with HW.GFX.GMA.Panel;
+with HW.GFX.GMA.PLLs;
+with HW.GFX.GMA.Port_Detect;
+with HW.GFX.GMA.Connectors;
+with HW.GFX.GMA.Connector_Info;
+with HW.GFX.GMA.Pipe_Setup;
+
+with System;
+
+with HW.Debug;
+with GNAT.Source_Info;
+
+use type HW.Word8;
+use type HW.Int32;
+
+package body HW.GFX.GMA
+   with Refined_State =>
+     (State =>
+        (Registers.Address_State,
+         PLLs.State, Panel.Panel_State,
+         Cur_Configs, Allocated_PLLs, DP_Links,
+         HPD_Delay, Wait_For_HPD),
+      Init_State => Initialized,
+      Config_State => Config.Valid_Port_GPU,
+      Device_State =>
+        (Registers.Register_State, Registers.GTT_State))
+is
+
+   subtype Port_Name is String (1 .. 8);
+   type Port_Name_Array is array (Port_Type) of Port_Name;
+   Port_Names : constant Port_Name_Array :=
+     (Disabled => "Disabled",
+      Internal => "Internal",
+      DP1      => "DP1     ",
+      DP2      => "DP2     ",
+      DP3      => "DP3     ",
+      Digital1 => "Digital1",
+      Digital2 => "Digital2",
+      Digital3 => "Digital3",
+      Analog   => "Analog  ");
+
+   package Display_Controller renames Pipe_Setup;
+
+   type PLLs_Type is array (Config_Index) of PLLs.T;
+
+   type Links_Type is array (Config_Index) of DP_Link;
+
+   type HPD_Type is array (Port_Type) of Boolean;
+   type HPD_Delay_Type is array (Port_Type) of Time.T;
+
+   Cur_Configs : Configs_Type;
+   Allocated_PLLs : PLLs_Type;
+   DP_Links : Links_Type;
+   HPD_Delay : HPD_Delay_Type;
+   Wait_For_HPD : HPD_Type;
+   Initialized : Boolean := False;
+
+   subtype Active_Port_Type is Port_Type range Port_Type'Succ (Disabled) .. Port_Type'Last;
+
+   ----------------------------------------------------------------------------
+
+   function To_GPU_Port
+     (Configs  : Configs_Type;
+      Idx      : Config_Index)
+      return GPU_Port
+   is
+   begin
+      return
+        (case Config.CPU is
+            when Ironlake .. Ivybridge => -- everything but eDP through FDI/PCH
+              (if Config.Internal_Is_EDP and then Configs (Idx).Port = Internal
+               then
+                  DIGI_A
+               else
+                 (case Idx is
+                     -- FDIs are fixed to the CPU pipe
+                     when Primary   => DIGI_B,
+                     when Secondary => DIGI_C,
+                     when Tertiary  => DIGI_D)),
+            when Haswell .. Skylake =>    -- everything but VGA directly on CPU
+              (case Configs (Idx).Port is
+                  when Disabled           => GPU_Port'First,
+                  when Internal           => DIGI_A,  -- LVDS not available
+                  when Digital1 | DP1     => DIGI_B,
+                  when Digital2 | DP2     => DIGI_C,
+                  when Digital3 | DP3     => DIGI_D,
+                  when Analog             => DIGI_E));
+   end To_GPU_Port;
+
+   function To_PCH_Port (Port : Active_Port_Type) return PCH_Port
+   is
+   begin
+      return
+        (case Port is
+            when Internal  => PCH_LVDS,   -- will be ignored if Internal is DP
+            when Analog    => PCH_DAC,
+            when Digital1  => PCH_HDMI_B,
+            when Digital2  => PCH_HDMI_C,
+            when Digital3  => PCH_HDMI_D,
+            when DP1       => PCH_DP_B,
+            when DP2       => PCH_DP_C,
+            when DP3       => PCH_DP_D);
+   end To_PCH_Port;
+
+   function To_Display_Type (Port : Active_Port_Type) return Display_Type
+   with Pre => True
+   is
+   begin
+      return
+        (case Port is
+            when Internal  => Config.Internal_Display,
+            when Analog    => VGA,
+            when Digital1 |
+                 Digital2 |
+                 Digital3  => HDMI,
+            when DP1 |
+                 DP2 |
+                 DP3       => DP);
+   end To_Display_Type;
+
+   procedure Configure_FDI_Link
+     (Port_Cfg : in out Port_Config;
+      Success  :    out Boolean)
+   with Pre => True
+   is
+      procedure Limit_Lane_Count
+      is
+         FDI_TX_CTL_FDI_TX_ENABLE : constant := 1 * 2 ** 31;
+         Enabled : Boolean;
+      begin
+         -- if DIGI_D enabled: (FDI names are off by one)
+         Registers.Is_Set_Mask
+           (Register => Registers.FDI_TX_CTL_C,
+            Mask     => FDI_TX_CTL_FDI_TX_ENABLE,
+            Result   => Enabled);
+         if Enabled then
+            Port_Cfg.FDI.Receiver_Caps.Max_Lane_Count := DP_Lane_Count_2;
+         end if;
+      end Limit_Lane_Count;
+   begin
+      Port_Cfg.FDI.Receiver_Caps.Max_Link_Rate    := DP_Bandwidth_2_7;
+      Port_Cfg.FDI.Receiver_Caps.Max_Lane_Count   :=
+         Config.FDI_Lane_Count (Port_Cfg.Port);
+      Port_Cfg.FDI.Receiver_Caps.Enhanced_Framing := True;
+      if Config.Has_FDI_C and then Port_Cfg.Port = DIGI_C then
+         Limit_Lane_Count;
+      end if;
+      DP_Info.Preferred_Link_Setting (Port_Cfg.FDI, Port_Cfg.Mode, Success);
+   end Configure_FDI_Link;
+
+   procedure Fill_Port_Config
+     (Port_Cfg :    out Port_Config;
+      Configs  : in     Configs_Type;
+      Idx      : in     Config_Index;
+      Success  :    out Boolean)
+   with Pre => True
+   is
+   begin
+      Success :=
+         Config.Supported_Pipe (Idx) and then
+         Config.Valid_Port (Configs (Idx).Port) and then
+         Configs (Idx).Port /= Disabled;
+
+      if Success then
+         declare
+            Port : constant Port_Type := Configs (Idx).Port;
+            Mode : constant Mode_Type := Configs (Idx).Mode;
+            Link : constant DP_Link := DP_Links (Idx);
+         begin
+            Port_Cfg := Port_Config'
+              (Port     => To_GPU_Port (Configs, Idx),
+               PCH_Port => To_PCH_Port (Port),
+               Display  => To_Display_Type (Port),
+               Mode     => Mode,
+               Is_FDI   => Config.FDI_Port (To_GPU_Port (Configs, Idx)),
+               FDI      => Default_DP,
+               DP       => Link);
+            if Port_Cfg.Mode.BPC = Auto_BPC then
+               Port_Cfg.Mode.BPC := Connector_Info.Default_BPC (Port_Cfg);
+            end if;
+         end;
+      else
+         Port_Cfg := Port_Config'
+           (Port     => GPU_Port'First,
+            PCH_Port => PCH_Port'First,
+            Display  => Display_Type'First,
+            Mode     => Invalid_Mode,
+            Is_FDI   => False,
+            FDI      => Default_DP,
+            DP       => Default_DP);
+      end if;
+   end Fill_Port_Config;
+
+   ----------------------------------------------------------------------------
+
+   function To_Controller
+      (Dsp_Config : Config_Index) return Display_Controller.Controller_Type
+   is
+      Result : Display_Controller.Controller_Type;
+   begin
+      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
+
+      case Dsp_Config is
+         when Primary =>
+            Result := Display_Controller.Controllers (Display_Controller.A);
+         when Secondary =>
+            Result := Display_Controller.Controllers (Display_Controller.B);
+         when Tertiary =>
+            Result := Display_Controller.Controllers (Display_Controller.C);
+      end case;
+      return Result;
+   end To_Controller;
+
+   ----------------------------------------------------------------------------
+
+   function To_Head
+     (N_Config : Config_Index;
+      Port     : Active_Port_Type)
+      return Display_Controller.Head_Type
+   is
+      Result : Display_Controller.Head_Type;
+   begin
+      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
+
+      if Config.Has_EDP_Pipe and then Port = Internal then
+         Result := Display_Controller.Heads (Display_Controller.Head_EDP);
+      else
+         case N_Config is
+            when Primary =>
+               Result := Display_Controller.Heads (Display_Controller.Head_A);
+            when Secondary =>
+               Result := Display_Controller.Heads (Display_Controller.Head_B);
+            when Tertiary =>
+               Result := Display_Controller.Heads (Display_Controller.Head_C);
+         end case;
+      end if;
+      return Result;
+   end To_Head;
+
+   ----------------------------------------------------------------------------
+
+   procedure Legacy_VGA_Off
+   is
+      Reg8 : Word8;
+   begin
+      -- disable legacy VGA plane, taking over control now
+      Port_IO.OutB (VGA_SR_INDEX, VGA_SR01);
+      Port_IO.InB  (Reg8, VGA_SR_DATA);
+      Port_IO.OutB (VGA_SR_DATA, Reg8 or 1 * 2 ** 5);
+      Time.U_Delay (100); -- PRM says 100us, Linux does 300
+      Registers.Set_Mask (Registers.VGACNTRL, 1 * 2 ** 31);
+   end Legacy_VGA_Off;
+
+   ----------------------------------------------------------------------------
+
+   function Port_Configured
+     (Configs  : Configs_Type;
+      Port     : Port_Type)
+      return Boolean
+   with
+      Global => null
+   is
+   begin
+      return Configs (Primary).Port    = Port or
+             Configs (Secondary).Port  = Port or
+             Configs (Tertiary).Port   = Port;
+   end Port_Configured;
+
+   procedure Scan_Ports
+     (Configs  :    out Configs_Type;
+      Ports    : in     Port_List)
+   is
+      Raw_EDID : EDID.Raw_EDID_Data := (others => 16#00#);
+      Port_Idx : Port_List_Range := Port_List_Range'First;
+      Port_Cfg : Port_Config;
+      Success  : Boolean := False;
+   begin
+      Configs := (Config_Index =>
+                    (Port        => Disabled,
+                     Mode        => Invalid_Mode,
+                     Framebuffer => Default_FB));
+
+      for Config_Idx in Config_Index loop
+         while Ports (Port_Idx) /= Disabled loop
+            if not Port_Configured (Configs, Ports (Port_Idx)) then
+               Configs (Config_Idx).Port := Ports (Port_Idx);
+               Fill_Port_Config (Port_Cfg, Configs, Config_Idx, Success);
+
+               if Success then
+                  -- May need power to probe port
+                  if Port_Cfg.Display = DP then
+                     Power_And_Clocks.Power_Up (Cur_Configs, Configs);
+                  end if;
+                  if Ports (Port_Idx) = Internal then
+                     Panel.On;
+                  end if;
+
+                  Connector_Info.Read_EDID (Raw_EDID, Port_Cfg, Success);
+               end if;
+
+               if Success and then EDID.Has_Preferred_Mode (Raw_EDID) then
+                  Configs (Config_Idx).Mode := EDID.Preferred_Mode (Raw_EDID);
+               else
+                  Configs (Config_Idx).Port := Disabled;
+
+                  if Ports (Port_Idx) = Internal and
+                     not Port_Configured (Cur_Configs, Internal)
+                  then
+                     Panel.Off;
+                  end if;
+               end if;
+            end if;
+
+            exit when Port_Idx = Port_List_Range'Last;
+            Port_Idx := Port_List_Range'Succ (Port_Idx);
+
+            exit when Success;
+         end loop;
+      end loop;
+
+      Power_And_Clocks.Power_Set_To (Cur_Configs);
+   end Scan_Ports;
+
+   procedure Auto_Configure
+     (Configs     : in out Configs_Type;
+      Keep_Power  : in     Boolean := False)
+   is
+      Raw_EDID : EDID.Raw_EDID_Data := (others => 16#00#);
+      Success : Boolean;
+
+      Config_Idx : Config_Index;
+      Port_Cfg : Port_Config;
+
+      function Free_Config return Boolean
+      with
+         Pre => True
+      is
+      begin
+         return Port_Configured (Configs, Disabled);
+      end Free_Config;
+
+      function First_Free_Config return Config_Index
+      with
+         Pre => Free_Config
+      is
+      begin
+         return (if Configs (Primary).Port = Disabled then Primary else
+                 (if Configs (Secondary).Port = Disabled then Secondary
+                  else Tertiary));
+      end First_Free_Config;
+   begin
+      -- TODO: Only check ports with hot-plug event?
+
+      if Config.Has_Internal_Display and then
+         not Keep_Power and then
+         not Port_Configured (Cur_Configs, Internal)
+      then
+         Panel.On (Wait => False);
+      end if;
+
+      -- Check if displays are still connected
+      for I in Config_Index loop
+         if Configs (I).Port /= Disabled then
+            Fill_Port_Config (Port_Cfg, Configs, I, Success);
+            if Success then
+               Connector_Info.Read_EDID
+                 (Raw_EDID => Raw_EDID,
+                  Port_Cfg => Port_Cfg,
+                  Success  => Success);
+            end if;
+            if not Success or else
+               not EDID.Has_Preferred_Mode (Raw_EDID) or else
+               Configs (I).Mode /= EDID.Preferred_Mode (Raw_EDID)
+            then
+               Configs (I).Port := Disabled;
+            end if;
+         end if;
+      end loop;
+
+      -- Add new displays as long as there is a free pipe config
+      for Port in Active_Port_Type loop
+         if Free_Config and then not Port_Configured (Configs, Port) then
+            Config_Idx := First_Free_Config;
+            Configs (Config_Idx).Port := Port;
+            Fill_Port_Config (Port_Cfg, Configs, Config_Idx, Success);
+
+            if Success then
+               -- Need power to probe port
+               if not Keep_Power and then To_Display_Type (Port) = DP then
+                  Power_And_Clocks.Power_Up (Cur_Configs, Configs);
+               end if;
+               if not Keep_Power and then Port = Internal then
+                  Panel.Wait_On;
+               end if;
+
+               Connector_Info.Read_EDID
+                 (Raw_EDID => Raw_EDID,
+                  Port_Cfg => Port_Cfg,
+                  Success  => Success);
+            end if;
+
+            if Success and then EDID.Has_Preferred_Mode (Raw_EDID) then
+               Configs (Config_Idx) := Config_Type'
+                 (Port        => Port,
+                  Framebuffer => Configs (Config_Idx).Framebuffer,
+                  Mode        => EDID.Preferred_Mode (Raw_EDID));
+            else
+               Configs (Config_Idx).Port := Disabled;
+            end if;
+         end if;
+      end loop;
+
+      if not Keep_Power then
+         Power_And_Clocks.Power_Set_To (Cur_Configs);
+
+         if Config.Has_Internal_Display and then
+            not Port_Configured (Cur_Configs, Internal)
+         then
+            Panel.Off;
+         end if;
+      end if;
+   end Auto_Configure;
+
+   ----------------------------------------------------------------------------
+
+   procedure Update_Outputs (Configs : Configs_Type)
+   is
+      Did_Power_Up : Boolean := False;
+
+      HPD, HPD_Delay_Over, Success : Boolean;
+      Old_Config, New_Config : Config_Type;
+      Old_Configs : Configs_Type;
+      Port_Cfg : Port_Config;
+
+      procedure Check_HPD
+        (Port_Cfg : in     Port_Config;
+         Port     : in     Port_Type;
+         Detected :    out Boolean)
+      is
+      begin
+         HPD_Delay_Over := Time.Timed_Out (HPD_Delay (Port));
+         if HPD_Delay_Over then
+            Port_Detect.Hotplug_Detect (Port_Cfg, Detected);
+            HPD_Delay (Port) := Time.MS_From_Now (333);
+         else
+            Detected := False;
+         end if;
+      end Check_HPD;
+   begin
+      Old_Configs := Cur_Configs;
+
+      for I in Config_Index loop
+         HPD := False;
+
+         Old_Config := Cur_Configs (I);
+         New_Config := Configs (I);
+
+         Fill_Port_Config (Port_Cfg, Old_Configs, I, Success);
+         if Success then
+            Check_HPD (Port_Cfg, Old_Config.Port, HPD);
+         end if;
+
+         -- Connector changed?
+         if (Success and then HPD) or
+            Old_Config.Port /= New_Config.Port or
+            Old_Config.Mode /= New_Config.Mode
+         then
+            if Old_Config.Port /= Disabled then
+               if Success then
+                  pragma Debug (Debug.New_Line);
+                  pragma Debug (Debug.Put_Line
+                    ("Disabling port " & Port_Names (Old_Config.Port)));
+
+                  Connectors.Pre_Off (Port_Cfg);
+
+                  Display_Controller.Off
+                    (To_Controller (I), To_Head (I, Old_Config.Port));
+
+                  Connectors.Post_Off (Port_Cfg);
+               end if;
+
+               -- Free PLL
+               PLLs.Free (Allocated_PLLs (I));
+
+               Cur_Configs (I).Port := Disabled;
+            end if;
+
+            if New_Config.Port /= Disabled then
+               Fill_Port_Config (Port_Cfg, Configs, I, Success);
+
+               if Success and then Wait_For_HPD (New_Config.Port) then
+                  Check_HPD (Port_Cfg, New_Config.Port, Success);
+                  Wait_For_HPD (New_Config.Port) := not Success;
+               end if;
+
+               if Success then
+                  pragma Debug (Debug.New_Line);
+                  pragma Debug (Debug.Put_Line
+                    ("Trying to enable port " & Port_Names (New_Config.Port)));
+
+                  if not Did_Power_Up then
+                     Power_And_Clocks.Power_Up (Old_Configs, Configs);
+                     Did_Power_Up := True;
+                  end if;
+
+                  if Port_Cfg.Is_FDI then
+                     Configure_FDI_Link (Port_Cfg, Success);
+                  end if;
+               end if;
+
+               if Success then
+                  Connector_Info.Preferred_Link_Setting
+                    (Port_Cfg => Port_Cfg,
+                     Success  => Success);
+               end if;
+
+               while Success loop
+                  pragma Loop_Invariant (New_Config.Port in Active_Port_Type);
+
+                  PLLs.Alloc
+                    (Port_Cfg => Port_Cfg,
+                     PLL      => Allocated_PLLs (I),
+                     Success  => Success);
+
+                  if Success then
+                     for Try in 1 .. 2 loop
+                        pragma Loop_Invariant
+                          (New_Config.Port in Active_Port_Type);
+
+                        Connectors.Pre_On
+                          (Port_Cfg    => Port_Cfg,
+                           PLL_Hint    => PLLs.Register_Value
+                                            (Allocated_PLLs (I)),
+                           Pipe_Hint   => Display_Controller.Get_Pipe_Hint
+                                            (To_Head (I, New_Config.Port)),
+                           Success     => Success);
+
+                        if Success then
+                           Display_Controller.On
+                             (Controller  => To_Controller (I),
+                              Head        => To_Head (I, New_Config.Port),
+                              Port_Cfg    => Port_Cfg,
+                              Framebuffer => New_Config.Framebuffer);
+
+                           Connectors.Post_On
+                             (Port_Cfg => Port_Cfg,
+                              PLL_Hint => PLLs.Register_Value
+                                            (Allocated_PLLs (I)),
+                              Success  => Success);
+
+                           if not Success then
+                              Display_Controller.Off
+                                (To_Controller (I),
+                                 To_Head (I, New_Config.Port));
+                              Connectors.Post_Off (Port_Cfg);
+                           end if;
+                        end if;
+
+                        exit when Success;
+                     end loop;
+                     exit when Success;   -- connection established => stop loop
+
+                     -- connection failed
+                     PLLs.Free (Allocated_PLLs (I));
+                  end if;
+
+                  Connector_Info.Next_Link_Setting
+                    (Port_Cfg => Port_Cfg,
+                     Success  => Success);
+               end loop;
+
+               if Success then
+                  pragma Debug (Debug.Put_Line
+                    ("Enabled port " & Port_Names (New_Config.Port)));
+                  Cur_Configs (I) := New_Config;
+                  DP_Links (I) := Port_Cfg.DP;
+               else
+                  Wait_For_HPD (New_Config.Port) := True;
+                  if New_Config.Port = Internal then
+                     Panel.Off;
+                  end if;
+               end if;
+            else
+               Cur_Configs (I) := New_Config;
+            end if;
+         elsif Old_Config.Framebuffer /= New_Config.Framebuffer and
+               Old_Config.Port /= Disabled
+         then
+            Display_Controller.Update_Offset
+              (Controller  => To_Controller (I),
+               Framebuffer => New_Config.Framebuffer);
+            Cur_Configs (I) := New_Config;
+         end if;
+      end loop;
+
+      if Did_Power_Up then
+         Power_And_Clocks.Power_Down (Old_Configs, Configs, Cur_Configs);
+      end if;
+
+   end Update_Outputs;
+
+   ----------------------------------------------------------------------------
+
+   procedure Initialize
+     (MMIO_Base   : in     Word64 := 0;
+      Write_Delay : in     Word64 := 0;
+      Success     :    out Boolean)
+   with
+      Refined_Global =>
+        (In_Out =>
+           (Config.Valid_Port_GPU,
+            Registers.Register_State, Port_IO.State),
+         Input =>
+           (Time.State),
+         Output =>
+           (Registers.Address_State,
+            PLLs.State, Panel.Panel_State,
+            Cur_Configs, Allocated_PLLs, DP_Links,
+            HPD_Delay, Wait_For_HPD, Initialized))
+   is
+      use type HW.Word64;
+
+      Now : constant Time.T := Time.Now;
+
+      procedure Check_Platform (Success : out Boolean)
+      is
+         Audio_VID_DID : Word32;
+      begin
+         case Config.CPU is
+            when Haswell .. Skylake =>
+               Registers.Read (Registers.AUD_VID_DID, Audio_VID_DID);
+            when Ironlake .. Ivybridge =>
+               Registers.Read (Registers.PCH_AUD_VID_DID, Audio_VID_DID);
+         end case;
+         Success :=
+           (case Config.CPU is
+               when Skylake      => Audio_VID_DID = 16#8086_2809#,
+               when Broadwell    => Audio_VID_DID = 16#8086_2808#,
+               when Haswell      => Audio_VID_DID = 16#8086_2807#,
+               when Ivybridge |
+                    Sandybridge  => Audio_VID_DID = 16#8086_2806# or
+                                    Audio_VID_DID = 16#8086_2805#,
+               when Ironlake     => Audio_VID_DID = 16#8086_2804#);  -- not sure
+      end Check_Platform;
+   begin
+      pragma Warnings (GNATprove, Off, "unused variable ""Write_Delay""",
+         Reason => "Write_Delay is used for debugging only");
+
+      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
+
+      pragma Debug (Debug.Set_Register_Write_Delay (Write_Delay));
+
+      Wait_For_HPD := HPD_Type'(others => False);
+      HPD_Delay := HPD_Delay_Type'(others => Now);
+      DP_Links := Links_Type'(others => HW.GFX.Default_DP);
+      Allocated_PLLs := (others => PLLs.Invalid);
+      Cur_Configs := Configs_Type'
+        (others => Config_Type'
+           (Port        => Disabled,
+            Framebuffer => HW.GFX.Default_FB,
+            Mode        => HW.GFX.Invalid_Mode));
+      Registers.Set_Register_Base
+        (if MMIO_Base /= 0 then
+            MMIO_Base
+         else
+            Config.Default_MMIO_Base);
+      PLLs.Initialize;
+
+      Check_Platform (Success);
+      if not Success then
+         pragma Debug (Debug.Put_Line ("ERROR: Incompatible CPU or PCH."));
+
+         Panel.Static_Init;   -- for flow analysis
+
+         Initialized := False;
+         return;
+      end if;
+
+      Panel.Setup_PP_Sequencer;
+      Port_Detect.Initialize;
+
+      Power_And_Clocks.Pre_All_Off;
+
+      Legacy_VGA_Off;
+
+      Connectors.Pre_All_Off;
+      Display_Controller.All_Off;
+      Connectors.Post_All_Off;
+      PLLs.All_Off;
+
+      Power_And_Clocks.Post_All_Off;
+
+      -------------------- Now restart from a clean state ---------------------
+      Power_And_Clocks.Initialize;
+
+      Initialized := True;
+
+   end Initialize;
+
+   function Is_Initialized return Boolean
+   with
+      Refined_Post => Is_Initialized'Result = Initialized
+   is
+   begin
+      return Initialized;
+   end Is_Initialized;
+
+   ----------------------------------------------------------------------------
+
+   procedure Write_GTT
+     (GTT_Page       : GTT_Range;
+      Device_Address : GTT_Address_Type;
+      Valid          : Boolean) is
+   begin
+      Registers.Write_GTT (GTT_Page, Device_Address, Valid);
+   end Write_GTT;
+
+   procedure Setup_Default_GTT (FB : Framebuffer_Type; Phys_FB : Word32)
+   is
+      FB_Size : constant Pos32 :=
+         FB.Stride * FB.Height * Pos32 (((FB.BPC * 4) / 8));
+      Phys_Addr : GTT_Address_Type := GTT_Address_Type (Phys_FB);
+   begin
+      for Idx in GTT_Range range 0 .. GTT_Range (((FB_Size + 4095) / 4096) - 1)
+      loop
+         Registers.Write_GTT
+           (GTT_Page       => Idx,
+            Device_Address => Phys_Addr,
+            Valid          => True);
+         Phys_Addr := Phys_Addr + 4096;
+      end loop;
+   end Setup_Default_GTT;
+
+   ----------------------------------------------------------------------------
+
+   procedure Dump_Configs (Configs : Configs_Type)
+   is
+      subtype Pipe_Name is String (1 .. 9);
+      type Pipe_Name_Array is array (Config_Index) of Pipe_Name;
+      Pipe_Names : constant Pipe_Name_Array :=
+        (Primary     => "Primary  ",
+         Secondary   => "Secondary",
+         Tertiary    => "Tertiary ");
+   begin
+      Debug.New_Line;
+      Debug.Put_Line ("CONFIG => ");
+      for Pipe in Config_Index loop
+         if Pipe = Config_Index'First then
+            Debug.Put ("  (");
+         else
+            Debug.Put ("   ");
+         end if;
+         Debug.Put_Line (Pipe_Names (Pipe) & " =>");
+         Debug.Put_Line
+           ("     (Port => " & Port_Names (Configs (Pipe).Port) & ",");
+         Debug.Put_Line ("      Framebuffer =>");
+         Debug.Put ("        (Width  => ");
+         Debug.Put_Int32 (Configs (Pipe).Framebuffer.Width);
+         Debug.Put_Line (",");
+         Debug.Put ("         Height => ");
+         Debug.Put_Int32 (Configs (Pipe).Framebuffer.Height);
+         Debug.Put_Line (",");
+         Debug.Put ("         Stride => ");
+         Debug.Put_Int32 (Configs (Pipe).Framebuffer.Stride);
+         Debug.Put_Line (",");
+         Debug.Put ("         Offset => ");
+         Debug.Put_Word32 (Configs (Pipe).Framebuffer.Offset);
+         Debug.Put_Line (",");
+         Debug.Put ("         BPC    => ");
+         Debug.Put_Int64 (Configs (Pipe).Framebuffer.BPC);
+         Debug.Put_Line ("),");
+         Debug.Put_Line ("      Mode =>");
+         Debug.Put ("        (Dotclock           => ");
+         Debug.Put_Int64 (Configs (Pipe).Mode.Dotclock);
+         Debug.Put_Line (",");
+         Debug.Put ("         H_Visible          => ");
+         Debug.Put_Int16 (Configs (Pipe).Mode.H_Visible);
+         Debug.Put_Line (",");
+         Debug.Put ("         H_Sync_Begin       => ");
+         Debug.Put_Int16 (Configs (Pipe).Mode.H_Sync_Begin);
+         Debug.Put_Line (",");
+         Debug.Put ("         H_Sync_End         => ");
+         Debug.Put_Int16 (Configs (Pipe).Mode.H_Sync_End);
+         Debug.Put_Line (",");
+         Debug.Put ("         H_Total            => ");
+         Debug.Put_Int16 (Configs (Pipe).Mode.H_Total);
+         Debug.Put_Line (",");
+         Debug.Put ("         V_Visible          => ");
+         Debug.Put_Int16 (Configs (Pipe).Mode.V_Visible);
+         Debug.Put_Line (",");
+         Debug.Put ("         V_Sync_Begin       => ");
+         Debug.Put_Int16 (Configs (Pipe).Mode.V_Sync_Begin);
+         Debug.Put_Line (",");
+         Debug.Put ("         V_Sync_End         => ");
+         Debug.Put_Int16 (Configs (Pipe).Mode.V_Sync_End);
+         Debug.Put_Line (",");
+         Debug.Put ("         V_Total            => ");
+         Debug.Put_Int16 (Configs (Pipe).Mode.V_Total);
+         Debug.Put_Line (",");
+         Debug.Put_Line ("         H_Sync_Active_High => " &
+           (if Configs (Pipe).Mode.H_Sync_Active_High
+            then "True,"
+            else "False,"));
+         Debug.Put_Line ("         V_Sync_Active_High => " &
+           (if Configs (Pipe).Mode.V_Sync_Active_High
+            then "True,"
+            else "False,"));
+         Debug.Put ("         BPC                => ");
+         Debug.Put_Int64 (Configs (Pipe).Mode.BPC);
+         if Pipe /= Config_Index'Last then
+            Debug.Put_Line (")),");
+         else
+            Debug.Put_Line (")));");
+         end if;
+      end loop;
+   end Dump_Configs;
+
+end HW.GFX.GMA;