--
-- 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;
with HW.GFX.GMA.PCH.Lynxpoint;

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 Post_All_Off is
   begin
      -- Reset CLKOUT_DP to disabled state
      PCH.Lynxpoint.Disable_Clkout_DP;
      PCH.Lynxpoint.Unbend_Clkout_DP;
   end Post_All_Off;

   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;

      -- Configure CLKOUT_DP for FDI
      if Config.Has_DDI_E then
         PCH.Lynxpoint.Enable_Clkout_DP_And_FDI_mPHY;
      end if;
   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;
