Attention is currently required from: Tim Wawrzynczak.
Hello Tim Wawrzynczak,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/libgfxinit/+/82145?usp=email
to review the following change.
Change subject: gma tgl: Add port detection ......................................................................
gma tgl: Add port detection
Mostly just detecting the _ISR registers, but during initialization, this module also blocks TCCOLD so that Modular FIA registers can be accessed. Instead of keeping track of the state of TCCOLD all of the time (and enabling and re-enabling), this patch just blocks TCCOLD once during initializaton and leaves it that way.
Signed-off-by: Tim Wawrzynczak twawrzynczak@chromium.org Change-Id: I674e7c2dcd7738e3d76266ff36675dbd52fa5ae2 --- M common/tigerlake/hw-gfx-gma-port_detect.adb 1 file changed, 144 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/libgfxinit refs/changes/45/82145/1
diff --git a/common/tigerlake/hw-gfx-gma-port_detect.adb b/common/tigerlake/hw-gfx-gma-port_detect.adb index a0bad14..681172b 100644 --- a/common/tigerlake/hw-gfx-gma-port_detect.adb +++ b/common/tigerlake/hw-gfx-gma-port_detect.adb @@ -15,19 +15,134 @@ with HW.GFX.GMA.Config; with HW.GFX.GMA.Registers; with HW.GFX.GMA.Config_Helpers; +with HW.GFX.GMA.Connectors.TC;
with HW.Debug; with GNAT.Source_Info;
package body HW.GFX.GMA.Port_Detect is - procedure Initialize is + type Digital_Port_Value is array (Digital_Port) of Word32; + + function SDEISR_MASK (Port : Active_Port_Type) return Word32 + is (case Port is + when DP1 | HDMI1 => 16#1_0000#, + when DP2 | HDMI2 => 16#2_0000#, + when DP3 | HDMI3 => 16#4_0000#, + when others => 0); + + function DE_HPD_ISR_MASK (Port : Active_Port_Type) return Word32 + is (case Port is + when USBC1_DP | USBC1_HDMI => 16#01_0000#, + when USBC2_DP | USBC2_HDMI => 16#02_0000#, + when USBC3_DP | USBC3_HDMI => 16#04_0000#, + when USBC4_DP | USBC4_HDMI => 16#08_0000#, + when USBC5_DP | USBC5_HDMI => 16#10_0000#, + when USBC6_DP | USBC6_HDMI => 16#20_0000#, + when others => 0); + + function SHOTPLUG_CTL_DDI_HPD_ENABLE (Port : Combo_Port_Type) return Word32 + is (case Port is + when DP1 | HDMI1 => 16#008#, + when DP2 | HDMI2 => 16#080#, + when DP3 | HDMI3 => 16#800#); + + function SHOTPLUG_CTL_TC_DDI_HPD_ENABLE (Port : USBC_Port_Type) + return Word32 + is (case Port is + when USBC1_DP | USBC1_HDMI => 16#00_0008#, + when USBC2_DP | USBC2_HDMI => 16#00_0080#, + when USBC3_DP | USBC3_HDMI => 16#00_0800#, + when USBC4_DP | USBC4_HDMI => 16#00_8000#, + when USBC5_DP | USBC5_HDMI => 16#08_0000#, + when USBC6_DP | USBC6_HDMI => 16#80_0000#); + + function TC_HOTPLUG_CTL_HPD_ENABLE (Port : USBC_Port_Type) + return Word32 + is (SHOTPLUG_CTL_TC_DDI_HPD_ENABLE (Port)); + + procedure Initialize + is + INIT_DISPLAY_DETECTED : constant := 1 * 2 ** 0; + Internal_Detected : Boolean; + Success : Boolean; begin pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); + + -- only for DDI_A / eDP + if Config.Has_Presence_Straps and not Config.Ignore_Presence_Straps then + Registers.Is_Set_Mask + (Register => Registers.DDI_BUF_CTL_A, + Mask => INIT_DISPLAY_DETECTED, + Result => Internal_Detected); + else + Internal_Detected := True; + end if; + Config.Valid_Port (eDP) := Internal_Detected; + + Registers.Unset_And_Set_Mask + (Register => Registers.SHPD_FILTER_CNT, + Mask_Unset => 16#1_ffff#, + Mask_Set => 16#1d9#); + + -- Hotplug for combo ports + Registers.Set_Mask + (Register => Registers.SHOTPLUG_CTL, + Mask => + SHOTPLUG_CTL_DDI_HPD_ENABLE (DP1) or -- also HDMI1 + SHOTPLUG_CTL_DDI_HPD_ENABLE (DP2) or -- also HDMI2 + SHOTPLUG_CTL_DDI_HPD_ENABLE (DP3)); -- also HDMI3 + + -- Hotplug for Type-C ports in legacy mode + Registers.Set_Mask + (Register => Registers.SHOTPLUG_CTL_TC, + Mask => + SHOTPLUG_CTL_TC_DDI_HPD_ENABLE (USBC1_DP) or -- also USBC1_HDMI + SHOTPLUG_CTL_TC_DDI_HPD_ENABLE (USBC2_DP) or -- also USBC2_HDMI + SHOTPLUG_CTL_TC_DDI_HPD_ENABLE (USBC3_DP) or -- also USBC3_HDMI + SHOTPLUG_CTL_TC_DDI_HPD_ENABLE (USBC4_DP) or -- also USBC4_HDMI + SHOTPLUG_CTL_TC_DDI_HPD_ENABLE (USBC5_DP) or -- also USBC5_HDMI + SHOTPLUG_CTL_TC_DDI_HPD_ENABLE (USBC6_DP)); -- also USBC6_HDMI + + -- Hotplug for Type-C ports in DP-Alt mode + Registers.Set_Mask + (Register => Registers.TC_HOTPLUG_CTL, + Mask => + TC_HOTPLUG_CTL_HPD_ENABLE (USBC1_DP) or -- also USBC1_HDMI + TC_HOTPLUG_CTL_HPD_ENABLE (USBC2_DP) or -- also USBC2_HDMI + TC_HOTPLUG_CTL_HPD_ENABLE (USBC3_DP) or -- also USBC3_HDMI + TC_HOTPLUG_CTL_HPD_ENABLE (USBC4_DP) or -- also USBC4_HDMI + TC_HOTPLUG_CTL_HPD_ENABLE (USBC5_DP) or -- also USBC5_HDMI + TC_HOTPLUG_CTL_HPD_ENABLE (USBC6_DP)); -- also USBC6_HDMI + + -- Validity can only be detected via hotplug + for Port in DP1 .. HDMI3 loop + Config.Valid_Port (Port) := True; + end loop; + + -- For Type-C ports, we can check if the IOM PHY status is 'Complete'. + for Port in USBC1_DP .. USBC6_HDMI loop + Connectors.TC.Is_DP_Phy_Mode_Status_Complete + (Port => Config_Helpers.To_GPU_Port (Pipe_Index'First, Port), + Success => Config.Valid_Port (Port)); + end loop; + + -- TCCOLD should be blocked first before accessing FIA registers + -- during e.g. connect flows. It can be unblocked only after + -- done accessing FIA registers and there is no longer a + -- connection i.e., after all ports are disconnected. + -- In order to avoid keeping track of the state and constantly + -- blocking and unblocking, we just block it once at the beginning and + -- leave it that way. + Connectors.TC.TC_Cold_Request (Connectors.TC.Block, Success); + if not Success then + Debug.Put_Line ("Failed to bock TCCOLD, Type-C will not work!"); + for Port in USBC1_DP .. USBC6_HDMI loop + Config.Valid_Port (Port) := False; + end loop; + end if; end Initialize;
- pragma Warnings (Off, "unused variable ""Port""", - Reason => "Not yet implemented."); procedure Hotplug_Detect (Port : in Active_Port_Type; Detected : out Boolean) @@ -35,13 +150,37 @@ begin pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); Detected := False; + + if Port = eDP then + Detected := Config.Valid_Port (eDP); + return; + end if; + + -- DP-Alt HPD is in the north display hotplug registers + if Port in USBC_Port_Type then + Registers.Is_Set_Mask + (Register => Registers.GEN11_DE_HPD_ISR, + Mask => DE_HPD_ISR_MASK (Port), + Result => Detected); + end if; + + -- Legacy HDMI/DP hotplug is detected through the south display registers + if Port in Combo_Port_Type then + Registers.Is_Set_Mask + (Register => Registers.SDEISR, + Mask => SDEISR_MASK (Port), + Result => Detected); + end if; end Hotplug_Detect; - pragma Warnings (On, "unused variable ""Port""");
procedure Clear_Hotplug_Detect (Port : Active_Port_Type) is + Ignored_HPD : Boolean; begin - pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); + pragma Warnings (GNATprove, Off, "unused assignment to ""Ignored_HPD""", + Reason => "We want to clear pending events only"); + Port_Detect.Hotplug_Detect (Port, Ignored_HPD); + pragma Warnings (GNATprove, On, "unused assignment to ""Ignored_HPD"""); end Clear_Hotplug_Detect;
end HW.GFX.GMA.Port_Detect;