From 5dbaf4bb1d30b27f5b8988a28820beda48f3a46c Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Wed, 8 Jan 2020 17:24:58 +0100 Subject: [PATCH] gma bxt panel: Allow to use secondary panel control logic Broxton has control logic for two panels. Reflect that. Flow analysis fails if we initialize globals in Setup_PP_Sequencer. Hence, move the call to Static_Init out. Change-Id: Ie84d21a07a0f064f993a54b277e051b8d1ca541c Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/libgfxinit/+/38276 Tested-by: Nico Huber Reviewed-by: Angel Pons --- common/Makefile.inc | 5 + common/hw-gfx-gma-config.ads.template | 3 +- common/hw-gfx-gma-panel.adb | 161 ++++++++++++++++---------- common/hw-gfx-gma-panel.ads | 8 +- common/hw-gfx-gma.adb | 4 +- common/hw-gfx-gma.ads | 4 +- configs/broxton | 3 +- 7 files changed, 116 insertions(+), 72 deletions(-) diff --git a/common/Makefile.inc b/common/Makefile.inc index 9378f41..af6dc11 100644 --- a/common/Makefile.inc +++ b/common/Makefile.inc @@ -47,10 +47,13 @@ gfxinit-y += hw-gfx.ads gfxinit-y += hw-gfx-framebuffer_filler.adb gfxinit-y += hw-gfx-framebuffer_filler.ads +CONFIG_GFX_GMA_PANEL_2_PORT ?= Disabled + CONFIG_GFX_GMA_GENERATION := $(call strip_quotes,$(CONFIG_GFX_GMA_GENERATION)) CONFIG_GFX_GMA_CPU := $(call strip_quotes,$(CONFIG_GFX_GMA_CPU)) CONFIG_GFX_GMA_CPU_VARIANT := $(call strip_quotes,$(CONFIG_GFX_GMA_CPU_VARIANT)) CONFIG_GFX_GMA_PANEL_1_PORT := $(call strip_quotes,$(CONFIG_GFX_GMA_PANEL_1_PORT)) +CONFIG_GFX_GMA_PANEL_2_PORT := $(call strip_quotes,$(CONFIG_GFX_GMA_PANEL_2_PORT)) CONFIG_GFX_GMA_ANALOG_I2C_PORT := $(call strip_quotes,$(CONFIG_GFX_GMA_ANALOG_I2C_PORT)) _GEN_NONCONST := $(strip \ @@ -73,6 +76,7 @@ $(hw-gfx-gma-config-ads): $(dir)/hw-gfx-gma-config.ads.template $(cnf) printf " GENERATE $(patsubst /%,%,$(subst $(obj)/,,$@))\n" sed -e's/<>/$(CONFIG_GFX_GMA_GENERATION)/' \ -e's/<>/$(CONFIG_GFX_GMA_PANEL_1_PORT)/' \ + -e's/<>/$(CONFIG_GFX_GMA_PANEL_2_PORT)/' \ -e's/<>/$(CONFIG_GFX_GMA_ANALOG_I2C_PORT)/' \ -e's/<>/$(CONFIG_GFX_GMA_DEFAULT_MMIO)/' \ -e'/constant Gen_CPU\(_Var\)\?/d' \ @@ -91,6 +95,7 @@ $(hw-gfx-gma-config-ads): $(dir)/hw-gfx-gma-config.ads.template $(cnf) -e's/<>/$(CONFIG_GFX_GMA_CPU)/' \ -e's/<>/$(CONFIG_GFX_GMA_CPU_VARIANT)/' \ -e's/<>/$(CONFIG_GFX_GMA_PANEL_1_PORT)/' \ + -e's/<>/$(CONFIG_GFX_GMA_PANEL_2_PORT)/' \ -e's/<>/$(CONFIG_GFX_GMA_ANALOG_I2C_PORT)/' \ -e's/<>/$(CONFIG_GFX_GMA_DEFAULT_MMIO)/' \ -e":s$$(printf '\n ')/,$$/{N;s/,\n.*Dyn_CPU\(_Var\)\?[^,)]*//;ts$$(printf '\n ')P;D;}" \ diff --git a/common/hw-gfx-gma-config.ads.template b/common/hw-gfx-gma-config.ads.template index 39fa825..8cd3cff 100644 --- a/common/hw-gfx-gma-config.ads.template +++ b/common/hw-gfx-gma-config.ads.template @@ -44,7 +44,8 @@ private package HW.GFX.GMA.Config is CPU_Var : constant Gen_CPU_Variant := <>; Panel_Ports : constant array (Valid_Panels) of Port_Type := - (Panel_1 => <>); + (Panel_1 => <>, + Panel_2 => <>); Analog_I2C_Port : constant PCH_Port := <>; diff --git a/common/hw-gfx-gma-panel.adb b/common/hw-gfx-gma-panel.adb index 3d6b342..e343deb 100644 --- a/common/hw-gfx-gma-panel.adb +++ b/common/hw-gfx-gma-panel.adb @@ -38,7 +38,7 @@ is BL_Off_To_Power_Down => 50_000, Power_Cycle_Delay => 510_000); - Delays_US : Panel_Power_Delays; + Delays_US : array (Valid_Panels) of Panel_Power_Delays; ---------------------------------------------------------------------------- @@ -53,8 +53,9 @@ is -- and the hardware power sequencer. The latter option would be less error -- prone, as the hardware might just don't work as expected. - Power_Cycle_Timer : Time.T; - Power_Up_Timer : Time.T; + type Panel_Times is array (Valid_Panels) of Time.T; + Power_Cycle_Timer : Panel_Times; + Power_Up_Timer : Panel_Times; ---------------------------------------------------------------------------- @@ -97,18 +98,28 @@ is DIVISOR : Registers.Registers_Index; end record; - Panel_PP_Regs : constant PP_Regs := (if Config.Has_PCH_Panel_Power then - (STATUS => Registers.PCH_PP_STATUS, - CONTROL => Registers.PCH_PP_CONTROL, - ON_DELAYS => Registers.PCH_PP_ON_DELAYS, - OFF_DELAYS => Registers.PCH_PP_OFF_DELAYS, - DIVISOR => Registers.PCH_PP_DIVISOR) - else - (STATUS => Registers.GMCH_PP_STATUS, - CONTROL => Registers.GMCH_PP_CONTROL, - ON_DELAYS => Registers.GMCH_PP_ON_DELAYS, - OFF_DELAYS => Registers.GMCH_PP_OFF_DELAYS, - DIVISOR => Registers.GMCH_PP_DIVISOR)); + PP : constant array (Valid_Panels) of PP_Regs := + (if Config.Has_PCH_Panel_Power then + (Panel_1 => + (STATUS => Registers.PCH_PP_STATUS, + CONTROL => Registers.PCH_PP_CONTROL, + ON_DELAYS => Registers.PCH_PP_ON_DELAYS, + OFF_DELAYS => Registers.PCH_PP_OFF_DELAYS, + DIVISOR => Registers.PCH_PP_DIVISOR), + Panel_2 => + (STATUS => Registers.BXT_PP_STATUS_2, + CONTROL => Registers.BXT_PP_CONTROL_2, + ON_DELAYS => Registers.BXT_PP_ON_DELAYS_2, + OFF_DELAYS => Registers.BXT_PP_OFF_DELAYS_2, + DIVISOR => Registers.PCH_PP_DIVISOR)) -- won't be used + + else + (Panel_1 .. Panel_2 => + (STATUS => Registers.GMCH_PP_STATUS, + CONTROL => Registers.GMCH_PP_CONTROL, + ON_DELAYS => Registers.GMCH_PP_ON_DELAYS, + OFF_DELAYS => Registers.GMCH_PP_OFF_DELAYS, + DIVISOR => Registers.GMCH_PP_DIVISOR))); function PCH_PP_ON_DELAYS_PWR_UP (US : Natural) return Word32 is begin @@ -160,6 +171,22 @@ is BXT_BLC_PWM_CTL_ENABLE : constant := 16#00_0001# * 2 ** 31; + type BLC_Regs is record + CTL : Registers.Registers_Index; + FREQ : Registers.Registers_Index; + DUTY : Registers.Registers_Index; + end record; + + BLC : constant array (Valid_Panels) of BLC_Regs := + (Panel_1 => + (CTL => Registers.BXT_BLC_PWM_CTL_1, + FREQ => Registers.BXT_BLC_PWM_FREQ_1, + DUTY => Registers.BXT_BLC_PWM_DUTY_1), + Panel_2 => + (CTL => Registers.BXT_BLC_PWM_CTL_2, + FREQ => Registers.BXT_BLC_PWM_FREQ_2, + DUTY => Registers.BXT_BLC_PWM_DUTY_2)); + ---------------------------------------------------------------------------- procedure Static_Init @@ -168,11 +195,12 @@ is (Output => (Power_Cycle_Timer, Power_Up_Timer, Delays_US), Input => (Time.State)) is + Now : constant Time.T := Time.Now; begin - Power_Cycle_Timer := Time.Now; + Power_Cycle_Timer := (others => Now); Power_Up_Timer := Power_Cycle_Timer; - Delays_US := Default_EDP_Delays_US; + Delays_US := (others => Default_EDP_Delays_US); end Static_Init; ---------------------------------------------------------------------------- @@ -189,7 +217,7 @@ is end loop; end Check_PP_Delays; - procedure Setup_PP_Sequencer (Default_Delays : Boolean := False) + procedure Setup_PP_Sequencer (Panel : Valid_Panels; Default_Delays : Boolean) is Power_Delay, Port_Select : Word32; @@ -197,35 +225,34 @@ is begin pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); - Static_Init; - if Default_Delays then Override_Delays := True; else - Registers.Read (Panel_PP_Regs.ON_DELAYS, Power_Delay); - Delays_US (Power_Up_Delay) := 100 * Natural + Registers.Read (PP (Panel).ON_DELAYS, Power_Delay); + Delays_US (Panel) (Power_Up_Delay) := 100 * Natural (Shift_Right (Power_Delay and PCH_PP_ON_DELAYS_PWR_UP_MASK, 16)); - Delays_US (Power_Up_To_BL_On) := 100 * Natural + Delays_US (Panel) (Power_Up_To_BL_On) := 100 * Natural (Power_Delay and PCH_PP_ON_DELAYS_PWR_UP_BL_ON_MASK); - Registers.Read (Panel_PP_Regs.OFF_DELAYS, Power_Delay); - Delays_US (Power_Down_Delay) := 100 * Natural + Registers.Read (PP (Panel).OFF_DELAYS, Power_Delay); + Delays_US (Panel) (Power_Down_Delay) := 100 * Natural (Shift_Right (Power_Delay and PCH_PP_OFF_DELAYS_PWR_DOWN_MASK, 16)); - Delays_US (BL_Off_To_Power_Down) := 100 * Natural + Delays_US (Panel) (BL_Off_To_Power_Down) := 100 * Natural (Power_Delay and PCH_PP_OFF_DELAYS_BL_OFF_PWR_DOWN_MASK); if Config.Has_PP_Divisor_Reg then - Registers.Read (Panel_PP_Regs.DIVISOR, Power_Delay); + Registers.Read (PP (Panel).DIVISOR, Power_Delay); else - Registers.Read (Panel_PP_Regs.CONTROL, Power_Delay); - Power_Delay := Shift_Right (Power_Delay, BXT_PP_CONTROL_PWR_CYC_DELAY_SHIFT); + Registers.Read (PP (Panel).CONTROL, Power_Delay); + Power_Delay := Shift_Right + (Power_Delay, BXT_PP_CONTROL_PWR_CYC_DELAY_SHIFT); end if; if (Power_Delay and PCH_PP_DIVISOR_PWR_CYC_DELAY_MASK) > 1 then - Delays_US (Power_Cycle_Delay) := 100_000 * (Natural + Delays_US (Panel) (Power_Cycle_Delay) := 100_000 * (Natural (Power_Delay and PCH_PP_DIVISOR_PWR_CYC_DELAY_MASK) - 1); end if; - Check_PP_Delays (Delays_US, Override_Delays); + Check_PP_Delays (Delays_US (Panel), Override_Delays); end if; if Override_Delays then @@ -243,51 +270,63 @@ is -- Force power-up to backlight-on delay to 100us as recommended by PRM. Registers.Unset_And_Set_Mask - (Register => Panel_PP_Regs.ON_DELAYS, + (Register => PP (Panel).ON_DELAYS, Mask_Unset => PCH_PP_ON_DELAYS_PORT_SELECT_MASK or PCH_PP_ON_DELAYS_PWR_UP_MASK or PCH_PP_ON_DELAYS_PWR_UP_BL_ON_MASK, Mask_Set => Port_Select or - PCH_PP_ON_DELAYS_PWR_UP (Delays_US (Power_Up_Delay)) + PCH_PP_ON_DELAYS_PWR_UP + (Delays_US (Panel) (Power_Up_Delay)) or PCH_PP_ON_DELAYS_PWR_UP_BL_ON (100)); Registers.Unset_And_Set_Mask - (Register => Panel_PP_Regs.OFF_DELAYS, + (Register => PP (Panel).OFF_DELAYS, Mask_Unset => PCH_PP_OFF_DELAYS_PWR_DOWN_MASK or PCH_PP_OFF_DELAYS_BL_OFF_PWR_DOWN_MASK, Mask_Set => PCH_PP_OFF_DELAYS_PWR_DOWN - (Delays_US (Power_Down_Delay)) or + (Delays_US (Panel) (Power_Down_Delay)) or PCH_PP_OFF_DELAYS_BL_OFF_PWR_DOWN - (Delays_US (BL_Off_To_Power_Down))); + (Delays_US (Panel) (BL_Off_To_Power_Down))); if Config.Has_PP_Divisor_Reg then Registers.Unset_And_Set_Mask - (Register => Panel_PP_Regs.DIVISOR, + (Register => PP (Panel).DIVISOR, Mask_Unset => PCH_PP_DIVISOR_PWR_CYC_DELAY_MASK, Mask_Set => PCH_PP_DIVISOR_PWR_CYC_DELAY - (Delays_US (Power_Cycle_Delay))); + (Delays_US (Panel) (Power_Cycle_Delay))); else Registers.Unset_And_Set_Mask - (Register => Panel_PP_Regs.CONTROL, + (Register => PP (Panel).CONTROL, Mask_Unset => BXT_PP_CONTROL_PWR_CYC_DELAY_MASK, Mask_Set => BXT_PP_CONTROL_PWR_CYC_DELAY - (Delays_US (Power_Cycle_Delay))); + (Delays_US (Panel) (Power_Cycle_Delay))); end if; end if; if Config.Has_PP_Write_Protection then Registers.Unset_And_Set_Mask - (Register => Panel_PP_Regs.CONTROL, + (Register => PP (Panel).CONTROL, Mask_Unset => PCH_PP_CONTROL_WRITE_PROTECT_MASK, Mask_Set => PCH_PP_CONTROL_WRITE_PROTECT_KEY or PCH_PP_CONTROL_POWER_DOWN_ON_RESET); else Registers.Set_Mask - (Register => Panel_PP_Regs.CONTROL, + (Register => PP (Panel).CONTROL, Mask => PCH_PP_CONTROL_POWER_DOWN_ON_RESET); end if; end Setup_PP_Sequencer; + procedure Setup_PP_Sequencer (Default_Delays : Boolean := False) is + begin + pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); + + for Panel in Valid_Panels loop + if Config.Panel_Ports (Panel) /= Disabled then + Setup_PP_Sequencer (Panel, Default_Delays); + end if; + end loop; + end Setup_PP_Sequencer; + ---------------------------------------------------------------------------- procedure VDD_Override (Panel : Panel_Control) is @@ -315,14 +354,15 @@ is pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); - Registers.Is_Set_Mask (Panel_PP_Regs.CONTROL, PCH_PP_CONTROL_TARGET_ON, Was_On); + Registers.Is_Set_Mask (PP (Panel).CONTROL, PCH_PP_CONTROL_TARGET_ON, Was_On); if not Was_On then - Time.Delay_Until (Power_Cycle_Timer); + Time.Delay_Until (Power_Cycle_Timer (Panel)); end if; - Registers.Set_Mask (Panel_PP_Regs.CONTROL, PCH_PP_CONTROL_TARGET_ON); + Registers.Set_Mask (PP (Panel).CONTROL, PCH_PP_CONTROL_TARGET_ON); if not Was_On then - Power_Up_Timer := Time.US_From_Now (Delays_US (Power_Up_Delay)); + Power_Up_Timer (Panel) := + Time.US_From_Now (Delays_US (Panel) (Power_Up_Delay)); end if; if Wait then Wait_On (Panel); @@ -337,13 +377,13 @@ is pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); - Time.Delay_Until (Power_Up_Timer); + Time.Delay_Until (Power_Up_Timer (Panel)); Registers.Wait_Unset_Mask - (Register => Panel_PP_Regs.STATUS, + (Register => PP (Panel).STATUS, Mask => PCH_PP_STATUS_PWR_SEQ_PROGRESS_MASK, TOut_MS => 300); - Registers.Unset_Mask (Panel_PP_Regs.CONTROL, PCH_PP_CONTROL_VDD_OVERRIDE); + Registers.Unset_Mask (PP (Panel).CONTROL, PCH_PP_CONTROL_VDD_OVERRIDE); end Wait_On; procedure Off (Panel : Panel_Control) @@ -356,20 +396,21 @@ is pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); - Registers.Is_Set_Mask (Panel_PP_Regs.CONTROL, PCH_PP_CONTROL_TARGET_ON, Was_On); + Registers.Is_Set_Mask (PP (Panel).CONTROL, PCH_PP_CONTROL_TARGET_ON, Was_On); Registers.Unset_Mask - (Register => Panel_PP_Regs.CONTROL, + (Register => PP (Panel).CONTROL, Mask => PCH_PP_CONTROL_TARGET_ON or PCH_PP_CONTROL_VDD_OVERRIDE); if Was_On then - Time.U_Delay (Delays_US (Power_Down_Delay)); + Time.U_Delay (Delays_US (Panel) (Power_Down_Delay)); end if; Registers.Wait_Unset_Mask - (Register => Panel_PP_Regs.STATUS, + (Register => PP (Panel).STATUS, Mask => PCH_PP_STATUS_PWR_SEQ_PROGRESS_MASK, TOut_MS => 600); if Was_On then - Power_Cycle_Timer := Time.US_From_Now (Delays_US (Power_Cycle_Delay)); + Power_Cycle_Timer (Panel) := + Time.US_From_Now (Delays_US (Panel) (Power_Cycle_Delay)); end if; end Off; @@ -385,11 +426,11 @@ is if Config.Has_New_Backlight_Control then Registers.Set_Mask - (Register => Registers.BXT_BLC_PWM_CTL_1, + (Register => BLC (Panel).CTL, Mask => BXT_BLC_PWM_CTL_ENABLE); else Registers.Set_Mask - (Register => Panel_PP_Regs.CONTROL, + (Register => PP (Panel).CONTROL, Mask => PCH_PP_CONTROL_BACKLIGHT_ENABLE); end if; end Backlight_On; @@ -404,11 +445,11 @@ is if Config.Has_New_Backlight_Control then Registers.Unset_Mask - (Register => Registers.BXT_BLC_PWM_CTL_1, + (Register => BLC (Panel).CTL, Mask => BXT_BLC_PWM_CTL_ENABLE); else Registers.Unset_Mask - (Register => Panel_PP_Regs.CONTROL, + (Register => PP (Panel).CONTROL, Mask => PCH_PP_CONTROL_BACKLIGHT_ENABLE); end if; end Backlight_Off; @@ -422,7 +463,7 @@ is pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); if Config.Has_New_Backlight_Control then - Registers.Write (Registers.BXT_BLC_PWM_DUTY_1, Level); + Registers.Write (BLC (Panel).DUTY, Level); else Registers.Unset_And_Set_Mask (Register => Registers.BLC_PWM_CPU_CTL, @@ -441,7 +482,7 @@ is pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); if Config.Has_New_Backlight_Control then - Registers.Read (Registers.BXT_BLC_PWM_FREQ_1, Level); + Registers.Read (BLC (Panel).FREQ, Level); else Registers.Read (Registers.BLC_PWM_PCH_CTL2, Level); Level := Shift_Right (Level, PCH_BLC_PWM_CTL2_BL_MOD_FREQ_SHIFT); diff --git a/common/hw-gfx-gma-panel.ads b/common/hw-gfx-gma-panel.ads index 2a97f0e..7d69e56 100644 --- a/common/hw-gfx-gma-panel.ads +++ b/common/hw-gfx-gma-panel.ads @@ -29,14 +29,10 @@ is procedure Setup_PP_Sequencer (Default_Delays : Boolean := False) with Global => - (Input => Time.State, - In_Out => Registers.Register_State, - Output => Panel_State), + (In_Out => (Panel_State, Registers.Register_State)), Depends => ((Panel_State, Registers.Register_State) => - (Time.State, Registers.Register_State, Default_Delays)), - Pre => True, - Post => True; + (Panel_State, Registers.Register_State, Default_Delays)); ---------------------------------------------------------------------------- diff --git a/common/hw-gfx-gma.adb b/common/hw-gfx-gma.adb index 04caa61..be623e4 100644 --- a/common/hw-gfx-gma.adb +++ b/common/hw-gfx-gma.adb @@ -502,11 +502,11 @@ is end if; end if; + Panel.Static_Init; -- early for flow analysis + if not Success then pragma Debug (Debug.Put_Line ("ERROR: Incompatible CPU or PCH.")); - Panel.Static_Init; -- for flow analysis - Initialized := False; return; end if; diff --git a/common/hw-gfx-gma.ads b/common/hw-gfx-gma.ads index 0c44434..1215fc5 100644 --- a/common/hw-gfx-gma.ads +++ b/common/hw-gfx-gma.ads @@ -253,8 +253,8 @@ private subtype PCH_HDMI_Port is PCH_Port range PCH_HDMI_B .. PCH_HDMI_D; subtype PCH_DP_Port is PCH_Port range PCH_DP_B .. PCH_DP_D; - type Panel_Control is (No_Panel, Panel_1); - subtype Valid_Panels is Panel_Control range Panel_1 .. Panel_1; + type Panel_Control is (No_Panel, Panel_1, Panel_2); + subtype Valid_Panels is Panel_Control range Panel_1 .. Panel_2; type Port_Config is record diff --git a/configs/broxton b/configs/broxton index 35a6f6c..5d3b859 100644 --- a/configs/broxton +++ b/configs/broxton @@ -2,6 +2,7 @@ CONFIG_GFX_GMA_DYN_CPU = CONFIG_GFX_GMA_GENERATION = Broxton CONFIG_GFX_GMA_CPU = Broxton CONFIG_GFX_GMA_CPU_VARIANT = Normal # N/A -CONFIG_GFX_GMA_PANEL_1_PORT = eDP +CONFIG_GFX_GMA_PANEL_1_PORT = Disabled +CONFIG_GFX_GMA_PANEL_2_PORT = eDP CONFIG_GFX_GMA_ANALOG_I2C_PORT = PCH_DAC # N/A CONFIG_GFX_GMA_DEFAULT_MMIO = 16\#e000_0000\#