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