Angel Pons has uploaded this change for review. ( https://review.coreboot.org/c/libgfxinit/+/44796 )
Change subject: baytrail: Add power and clocks support ......................................................................
baytrail: Add power and clocks support
Change-Id: I1e359882b78ed7436ec90f2ac8c4276f70eca1b0 Signed-off-by: Angel Pons th3fanbus@gmail.com --- M common/valleyview/Makefile.inc A common/valleyview/hw-gfx-gma-power_and_clocks.adb A common/valleyview/hw-gfx-gma-power_and_clocks.ads 3 files changed, 189 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/libgfxinit refs/changes/96/44796/1
diff --git a/common/valleyview/Makefile.inc b/common/valleyview/Makefile.inc index 39241c2..12d31d1 100644 --- a/common/valleyview/Makefile.inc +++ b/common/valleyview/Makefile.inc @@ -9,8 +9,6 @@ gfxinit-y += ../g45/hw-gfx-gma-gmch-vga.ads gfxinit-y += ../g45/hw-gfx-gma-port_detect.adb gfxinit-y += ../g45/hw-gfx-gma-gmch.ads -gfxinit-y += ../g45/hw-gfx-gma-power_and_clocks.ads -gfxinit-y += ../g45/hw-gfx-gma-power_and_clocks.adb
gfxinit-y += hw-gfx-gma-dpio.adb gfxinit-y += hw-gfx-gma-dpio.ads @@ -18,3 +16,5 @@ gfxinit-y += hw-gfx-gma-iosf.ads gfxinit-y += hw-gfx-gma-plls.adb gfxinit-y += hw-gfx-gma-plls.ads +gfxinit-y += hw-gfx-gma-power_and_clocks.ads +gfxinit-y += hw-gfx-gma-power_and_clocks.adb diff --git a/common/valleyview/hw-gfx-gma-power_and_clocks.adb b/common/valleyview/hw-gfx-gma-power_and_clocks.adb new file mode 100644 index 0000000..f77aef1 --- /dev/null +++ b/common/valleyview/hw-gfx-gma-power_and_clocks.adb @@ -0,0 +1,144 @@ +-- +-- Copyright (C) 2020 Angel Pons th3fanbus@gmail.com +-- +-- 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 HW.Time; +with HW.GFX.GMA.Config; +with HW.GFX.GMA.DPIO; +with HW.GFX.GMA.IOSF; +with HW.GFX.GMA.PLLs; +with HW.GFX.GMA.Registers; + +with HW.Debug; +with GNAT.Source_Info; + +package body HW.GFX.GMA.Power_And_Clocks is + + CCK_FUSE_REG : constant := 16#0008#; + CCK_DISPLAY_CLOCK_CONTROL : constant := 16#006b#; + CCK_DISPLAY_REF_CLOCK_CONTROL : constant := 16#006c#; + + CCK_FREQUENCY_VALUES : constant := 16#001f#; + CCK_FREQUENCY_STATUS : constant := 16#1f00#; + + PUNIT_PWRGT_CONTROL : constant := 16#0060#; + PUNIT_PWRGT_STATUS : constant := 16#0061#; + + PUNIT_PWRGT_DPIO_MSK : constant := 3 * 2 ** 6; + + DPIO_CTL_CMNRST : constant := 1 * 2 ** 0; + + -- intel_display.c: vlv_get_hpll_vco() + function Vlv_Get_HPLL_Vco return Int64 + is + Vco_Freq : constant array (0 .. 3) of Int64 := (800, 1600, 2000, 2400); + Hpll_Sel : Word32; + begin + -- Obtain SKU information + IOSF.Vlv_Cck_Read (CCK_FUSE_REG, Hpll_Sel); + + return 1_000_000 * Vco_Freq (Natural (Hpll_Sel and 3)); + end Vlv_Get_HPLL_Vco; + + -- intel_display.c: vlv_get_cck_clock() + function Vlv_Get_Cck_Clock + (Register : in Word32; + Ref_Freq : in Int64) return Int64 + is + Value : Word32; + Divider : Word32; + begin + IOSF.Vlv_Cck_Read (Register, Value); + Divider := Value and CCK_FREQUENCY_VALUES; + + if Divider * 2 ** 8 /= (Value and CCK_FREQUENCY_STATUS) then + pragma Debug (Debug.Put (GNAT.Source_Info.Enclosing_Entity)); + pragma Debug (Debug.Put_Line (" WARNING: Clock change in progress!")); + end if; + + return (Ref_Freq + Ref_Freq) / Int64 (Divider + 1); + end Vlv_Get_Cck_Clock; + + procedure Initialize + is + Hpll_Vco : Int64; + Value : Word32; + begin + pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); + + -- Power Gate Status: This register indicates the status of the voltage + -- islands for the various blocks that the PUNIT controls. This register + -- is updated by the firmware after servicing a request from the driver + -- to power up/down of the various islands. The requests are done through + -- an analogous Power Gate Control register with the same bit layout. + -- + -- Each island is controlled by a 2-bit field: + -- 00 -- no clock nor power gating + -- 01 -- clock gating + -- 10 -- reset + -- 11 -- power gating + IOSF.Vlv_Punit_Read (PUNIT_PWRGT_STATUS, Value); + + -- Check if we need to ungate the Gunit + if (Value and PUNIT_PWRGT_DPIO_MSK) /= 0 then + pragma Debug (Debug.Put_Line ("Gunit is not ungated! Ungating...")); + + IOSF.Vlv_Punit_Write (PUNIT_PWRGT_CONTROL, PUNIT_PWRGT_DPIO_MSK); + Time.M_Delay (2); + IOSF.Vlv_Punit_Write (PUNIT_PWRGT_CONTROL, 0); + Time.M_Delay (2); + IOSF.Vlv_Punit_Read (PUNIT_PWRGT_STATUS, Value); + end if; + + -- De-assert DPIO common reset + Registers.Set_Mask (Registers.VLV_DPIO_CTL, DPIO_CTL_CMNRST); + + -- Before we start anything on Display pipeline, let's ask the CCU to + -- give us Spread Spectrum + Bend for the display clocks. + IOSF.Vlv_Ccu_Read (16#0114#, Value); + IOSF.Vlv_Ccu_Write (16#0114#, Value or 16#0003_0003#); + + Hpll_Vco := Vlv_Get_HPLL_Vco; + + -- intel_cdclk.c: vlv_get_cdclk() + Config.CDClk := Vlv_Get_Cck_Clock (CCK_DISPLAY_CLOCK_CONTROL, Hpll_Vco); + Config.Max_CDClk := 400_000_000; + + -- intel_cdclk.c: vlv_hrawclk() + Config.Raw_Clock := Vlv_Get_Cck_Clock (CCK_DISPLAY_REF_CLOCK_CONTROL, Hpll_Vco); + + end Initialize; + + procedure Limit_Dotclocks + (Configs : in out Pipe_Configs; + CDClk_Switch : out Boolean) + is + begin + Config_Helpers.Limit_Dotclocks (Configs, Config.CDClk * 90 / 100); + CDClk_Switch := False; + end Limit_Dotclocks; + + procedure Post_All_Off is + begin + pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); + + -- Clear latency values to prevent flickering display without activity + Registers.Write (Registers.VLV_DDL1, 0); + Registers.Write (Registers.VLV_DDL2, 0); + + -- Assert DPIO common reset, clear SFR bypass and modesel bits + Registers.Write (Registers.VLV_DPIO_CTL, 0); + + end Post_All_Off; + +end HW.GFX.GMA.Power_And_Clocks; diff --git a/common/valleyview/hw-gfx-gma-power_and_clocks.ads b/common/valleyview/hw-gfx-gma-power_and_clocks.ads new file mode 100644 index 0000000..9997644 --- /dev/null +++ b/common/valleyview/hw-gfx-gma-power_and_clocks.ads @@ -0,0 +1,43 @@ +-- +-- Copyright (C) 2020 Angel Pons th3fanbus@gmail.com +-- +-- 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 HW.GFX.GMA.Config_Helpers; + +private package HW.GFX.GMA.Power_And_Clocks is + + procedure Initialize; + + procedure Limit_Dotclocks + (Configs : in out Pipe_Configs; + CDClk_Switch : out Boolean) + with + Post => + not CDClk_Switch and + Config_Helpers.Stable_FB (Configs'Old, Configs); + + procedure Update_CDClk (Configs : in out Pipe_Configs) is null; + + procedure Enable_CDClk is null; + + procedure Pre_All_Off is null; + + procedure Post_All_Off; + + procedure Power_Set_To (Configs : Pipe_Configs) is null; + + procedure Power_Up (Old_Configs, New_Configs : Pipe_Configs) is null; + + procedure Power_Down (Old_Configs, Tmp_Configs, New_Configs : Pipe_Configs) is null; + +end HW.GFX.GMA.Power_And_Clocks;