--
-- 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 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;
