diff --git a/common/haswell/hw-gfx-gma-power_and_clocks_haswell.adb b/common/haswell/hw-gfx-gma-power_and_clocks_haswell.adb
new file mode 100644
index 0000000..e261ace
--- /dev/null
+++ b/common/haswell/hw-gfx-gma-power_and_clocks_haswell.adb
@@ -0,0 +1,341 @@
+--
+-- Copyright (C) 2014-2018 secunet Security Networks AG
+-- Copyright (C) 2019 Nico Huber <nico.h@gmx.de>
+--
+-- 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 GNAT.Source_Info;
+
+with HW.Time;
+with HW.Debug;
+with HW.GFX.GMA.Config;
+with HW.GFX.GMA.PCode;
+with HW.GFX.GMA.Registers;
+with HW.GFX.GMA.Transcoder;
+
+package body HW.GFX.GMA.Power_And_Clocks_Haswell is
+
+   LCPLL_CTL_CD_FREQ_SEL_MASK          : constant := 3 * 2 ** 26;
+   LCPLL_CTL_CD_FREQ_SEL_450_MHZ       : constant := 0 * 2 ** 26;
+   LCPLL_CTL_CD_FREQ_SEL_HSW_ALTERNATE : constant := 1 * 2 ** 26;
+   LCPLL_CTL_CD_FREQ_SEL_BDW_540_MHZ   : constant := 1 * 2 ** 26;
+   LCPLL_CTL_CD_FREQ_SEL_BDW_337_5_MHZ : constant := 2 * 2 ** 26;
+   LCPLL_CTL_CD_FREQ_SEL_BDW_675_MHZ   : constant := 3 * 2 ** 26;
+   LCPLL_CTL_CD_SOURCE_SELECT_FCLK     : constant := 1 * 2 ** 21;
+   LCPLL_CTL_CD_SOURCE_FCLK_DONE       : constant := 1 * 2 ** 19;
+
+   function LCPLL_CTL_CD_FREQ_SEL_BDW (CDClk : Config.CDClk_Range) return Word32
+   is
+     (case CDClk is
+         when 675_000_000 => LCPLL_CTL_CD_FREQ_SEL_BDW_675_MHZ,
+         when 540_000_000 => LCPLL_CTL_CD_FREQ_SEL_BDW_540_MHZ,
+         when 450_000_000 => LCPLL_CTL_CD_FREQ_SEL_450_MHZ,
+         when others      => LCPLL_CTL_CD_FREQ_SEL_BDW_337_5_MHZ);
+
+   FUSE_STRAP_DISPLAY_CDCLK_LIMIT      : constant := 1 * 2 ** 24;
+
+   HSW_PCODE_DE_WRITE_FREQ             : constant := 16#17#;
+   BDW_PCODE_DISPLAY_FREQ_CHANGE       : constant := 16#18#;
+
+   ----------------------------------------------------------------------------
+
+   PWR_WELL_CTL_ENABLE_REQUEST   : constant := 1 * 2 ** 31;
+   PWR_WELL_CTL_DISABLE_REQUEST  : constant := 0 * 2 ** 31;
+   PWR_WELL_CTL_STATE_ENABLED    : constant := 1 * 2 ** 30;
+
+   ----------------------------------------------------------------------------
+
+   IPS_CTL_ENABLE          : constant := 1 * 2 ** 31;
+   DISPLAY_IPS_CONTROL     : constant := 16#19#;
+
+   ----------------------------------------------------------------------------
+
+   procedure IPS_Off
+   is
+      Enabled : Boolean;
+   begin
+      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
+
+      if Config.Has_IPS then
+         Registers.Is_Set_Mask (Registers.IPS_CTL, IPS_CTL_ENABLE, Enabled);
+         if Enabled then
+            if Config.Has_IPS_CTL_Mailbox then
+               PCode.Mailbox_Write (DISPLAY_IPS_CONTROL, 0, Wait_Ready => True);
+               Registers.Wait_Unset_Mask
+                 (Register => Registers.IPS_CTL,
+                  Mask     => IPS_CTL_ENABLE,
+                  TOut_MS  => 42);
+            else
+               Registers.Unset_Mask (Registers.IPS_CTL, IPS_CTL_ENABLE);
+            end if;
+
+            pragma Debug (Debug.Put_Line ("Disabled IPS."));
+            -- We have to wait until the next vblank here.
+            -- 20ms should be enough.
+            Time.M_Delay (20);
+         end if;
+      end if;
+   end IPS_Off;
+
+   ----------------------------------------------------------------------------
+
+   procedure PDW_Off
+   is
+      Ctl1, Ctl2, Ctl3, Ctl4 : Word32;
+   begin
+      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
+
+      Registers.Read (Registers.PWR_WELL_CTL_BIOS, Ctl1);
+      Registers.Read (Registers.PWR_WELL_CTL_DRIVER, Ctl2);
+      Registers.Read (Registers.PWR_WELL_CTL_KVMR, Ctl3);
+      Registers.Read (Registers.PWR_WELL_CTL_DEBUG, Ctl4);
+      pragma Debug (Registers.Posting_Read (Registers.PWR_WELL_CTL5)); --  Result for debugging only
+      pragma Debug (Registers.Posting_Read (Registers.PWR_WELL_CTL6)); --  Result for debugging only
+
+      if ((Ctl1 or Ctl2 or Ctl3 or Ctl4) and
+          PWR_WELL_CTL_ENABLE_REQUEST) /= 0
+      then
+         Registers.Wait_Set_Mask
+           (Registers.PWR_WELL_CTL_DRIVER, PWR_WELL_CTL_STATE_ENABLED);
+      end if;
+
+      if (Ctl1 and PWR_WELL_CTL_ENABLE_REQUEST) /= 0 then
+         Registers.Write (Registers.PWR_WELL_CTL_BIOS, PWR_WELL_CTL_DISABLE_REQUEST);
+      end if;
+
+      if (Ctl2 and PWR_WELL_CTL_ENABLE_REQUEST) /= 0 then
+         Registers.Write (Registers.PWR_WELL_CTL_DRIVER, PWR_WELL_CTL_DISABLE_REQUEST);
+      end if;
+   end PDW_Off;
+
+   procedure PDW_On
+   is
+      Ctl1, Ctl2, Ctl3, Ctl4 : Word32;
+   begin
+      pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
+
+      Registers.Read (Registers.PWR_WELL_CTL_BIOS, Ctl1);
+      Registers.Read (Registers.PWR_WELL_CTL_DRIVER, Ctl2);
+      Registers.Read (Registers.PWR_WELL_CTL_KVMR, Ctl3);
+      Registers.Read (Registers.PWR_WELL_CTL_DEBUG, Ctl4);
+      pragma Debug (Registers.Posting_Read (Registers.PWR_WELL_CTL5)); --  Result for debugging only
+      pragma Debug (Registers.Posting_Read (Registers.PWR_WELL_CTL6)); --  Result for debugging only
+
+      if ((Ctl1 or Ctl2 or Ctl3 or Ctl4) and
+          PWR_WELL_CTL_ENABLE_REQUEST) = 0
+      then
+         Registers.Wait_Unset_Mask
+           (Registers.PWR_WELL_CTL_DRIVER, PWR_WELL_CTL_STATE_ENABLED);
+      end if;
+
+      if (Ctl2 and PWR_WELL_CTL_ENABLE_REQUEST) = 0 then
+         Registers.Write (Registers.PWR_WELL_CTL_DRIVER, PWR_WELL_CTL_ENABLE_REQUEST);
+         Registers.Wait_Set_Mask
+           (Registers.PWR_WELL_CTL_DRIVER, PWR_WELL_CTL_STATE_ENABLED);
+      end if;
+   end PDW_On;
+
+   function Need_PDW (Checked_Configs : Pipe_Configs) return Boolean
+   is
+      Primary : Pipe_Config renames Checked_Configs (GMA.Primary);
+   begin
+      return
+         (Config.Use_PDW_For_EDP_Scaling and then
+          (Primary.Port = eDP and Requires_Scaling (Primary)))
+         or
+         (Primary.Port /= Disabled and Primary.Port /= eDP)
+         or
+         Checked_Configs (Secondary).Port /= Disabled
+         or
+         Checked_Configs (Tertiary).Port /= Disabled;
+   end Need_PDW;
+
+   ----------------------------------------------------------------------------
+
+   procedure Pre_All_Off is
+   begin
+      -- HSW: disable panel self refresh (PSR) on eDP if enabled
+         -- wait for PSR idling
+      Transcoder.PSR_Off;
+      IPS_Off;
+   end Pre_All_Off;
+
+   function Normalize_CDClk (CDClk : in Int64) return Config.CDClk_Range is
+     (   if CDClk <= 337_500_000 then 337_500_000
+      elsif CDClk <= 450_000_000 then 450_000_000
+      elsif CDClk <= 540_000_000 then 540_000_000
+                                 else 675_000_000);
+
+   procedure Get_Cur_CDClk (CDClk : out Config.CDClk_Range)
+   is
+      LCPLL_CTL : Word32;
+   begin
+      Registers.Read (Registers.LCPLL_CTL, LCPLL_CTL);
+      CDClk :=
+        (if Config.Has_Broadwell_CDClk then
+           (case LCPLL_CTL and LCPLL_CTL_CD_FREQ_SEL_MASK is
+               when LCPLL_CTL_CD_FREQ_SEL_BDW_540_MHZ    => 540_000_000,
+               when LCPLL_CTL_CD_FREQ_SEL_BDW_337_5_MHZ  => 337_500_000,
+               when LCPLL_CTL_CD_FREQ_SEL_BDW_675_MHZ    => 675_000_000,
+               when others                               => 450_000_000)
+         else
+           (case LCPLL_CTL and LCPLL_CTL_CD_FREQ_SEL_MASK is
+               when LCPLL_CTL_CD_FREQ_SEL_HSW_ALTERNATE =>
+                 (if    Config.Is_ULX  then 337_500_000
+                  elsif Config.Is_ULT  then 450_000_000
+                                       else 540_000_000),
+               when others => 450_000_000));
+   end Get_Cur_CDClk;
+
+   procedure Get_Max_CDClk (CDClk : out Config.CDClk_Range)
+   is
+      FUSE_STRAP : Word32;
+   begin
+      if Config.Has_Broadwell_CDClk then
+         Registers.Read (Registers.FUSE_STRAP, FUSE_STRAP);
+         CDClk :=
+           (if (FUSE_STRAP and FUSE_STRAP_DISPLAY_CDCLK_LIMIT) /= 0 then
+               450_000_000
+            elsif Config.Is_ULX then
+               450_000_000
+            elsif Config.Is_ULT then
+               540_000_000
+            else
+               675_000_000);
+      else
+         -- We may never switch CDClk on Haswell. So from our point
+         -- of view, the CDClk we start with is the maximum.
+         Get_Cur_CDClk (CDClk);
+      end if;
+   end Get_Max_CDClk;
+
+   procedure Set_CDClk (CDClk_In : Frequency_Type)
+   is
+      CDClk : constant Config.CDClk_Range :=
+         Normalize_CDClk (Frequency_Type'Min (CDClk_In, Config.Max_CDClk));
+      Success : Boolean;
+   begin
+      if not Config.Can_Switch_CDClk then
+         return;
+      end if;
+
+      PCode.Mailbox_Write
+        (MBox        => BDW_PCODE_DISPLAY_FREQ_CHANGE,
+         Command     => 0,
+         Wait_Ready  => True,
+         Success     => Success);
+
+      if not Success then
+         pragma Debug (Debug.Put_Line
+           ("ERROR: PCODE didn't acknowledge frequency change."));
+         return;
+      end if;
+
+      Registers.Set_Mask
+        (Register => Registers.LCPLL_CTL,
+         Mask     => LCPLL_CTL_CD_SOURCE_SELECT_FCLK);
+      Registers.Wait_Set_Mask
+        (Register => Registers.LCPLL_CTL,
+         Mask     => LCPLL_CTL_CD_SOURCE_FCLK_DONE);
+
+      Registers.Unset_And_Set_Mask
+        (Register    => Registers.LCPLL_CTL,
+         Mask_Unset  => LCPLL_CTL_CD_FREQ_SEL_MASK,
+         Mask_Set    => LCPLL_CTL_CD_FREQ_SEL_BDW (CDClk));
+      Registers.Posting_Read (Registers.LCPLL_CTL);
+
+      Registers.Unset_Mask
+        (Register => Registers.LCPLL_CTL,
+         Mask     => LCPLL_CTL_CD_SOURCE_SELECT_FCLK);
+      Registers.Wait_Unset_Mask
+        (Register => Registers.LCPLL_CTL,
+         Mask     => LCPLL_CTL_CD_SOURCE_FCLK_DONE);
+
+      PCode.Mailbox_Write
+        (MBox        => HSW_PCODE_DE_WRITE_FREQ,
+         Command     => (case CDClk is
+                           when 675_000_000 => 3,
+                           when 540_000_000 => 1,
+                           when 450_000_000 => 0,
+                           when others      => 2));
+
+      Registers.Write
+        (Register => Registers.CDCLK_FREQ,
+         Value    => Word32 (Div_Round_Closest (CDClk, 1_000_000) - 1));
+
+      Config.CDClk := CDClk;
+   end Set_CDClk;
+
+   procedure Initialize
+   is
+      CDClk : Config.CDClk_Range;
+   begin
+      -- HSW: disable power down well
+      PDW_Off;
+
+      Get_Cur_CDClk (CDClk);
+      Config.CDClk := CDClk;
+      Get_Max_CDClk (CDClk);
+      Config.Max_CDClk := CDClk;
+      Set_CDClk (Config.Default_CDClk_Freq);
+
+      Config.Raw_Clock := Config.Default_RawClk_Freq;
+   end Initialize;
+
+   procedure Limit_Dotclocks
+     (Configs        : in out Pipe_Configs;
+      CDClk_Switch   :    out Boolean)
+   is
+   begin
+      Config_Helpers.Limit_Dotclocks (Configs, Config.Max_CDClk);
+      CDClk_Switch :=
+         Config.Can_Switch_CDClk and then
+         Config.CDClk /= Normalize_CDClk
+           (Config_Helpers.Highest_Dotclock (Configs));
+   end Limit_Dotclocks;
+
+   procedure Update_CDClk (Configs : in out Pipe_Configs)
+   is
+      New_CDClk : constant Frequency_Type :=
+         Config_Helpers.Highest_Dotclock (Configs);
+   begin
+      Set_CDClk (New_CDClk);
+      Config_Helpers.Limit_Dotclocks (Configs, Config.CDClk);
+   end Update_CDClk;
+
+   procedure Power_Set_To (Configs : Pipe_Configs) is
+   begin
+      if Need_PDW (Configs) then
+         PDW_On;
+      else
+         PDW_Off;
+      end if;
+   end Power_Set_To;
+
+   procedure Power_Up (Old_Configs, New_Configs : Pipe_Configs) is
+   begin
+      if not Need_PDW (Old_Configs) and Need_PDW (New_Configs) then
+         PDW_On;
+      end if;
+   end Power_Up;
+
+   procedure Power_Down (Old_Configs, Tmp_Configs, New_Configs : Pipe_Configs)
+   is
+   begin
+      if (Need_PDW (Old_Configs) or Need_PDW (Tmp_Configs)) and
+         not Need_PDW (New_Configs)
+      then
+         PDW_Off;
+      end if;
+   end Power_Down;
+
+end HW.GFX.GMA.Power_And_Clocks_Haswell;
