Nico Huber has submitted this change. ( https://review.coreboot.org/c/libgfxinit/+/35740 )
Change subject: gma ilk: Handle Ibex Peak DP correctly ......................................................................
gma ilk: Handle Ibex Peak DP correctly
We missed some bits specific to Ibex Peak DPs. Namely, the training pattern selection moved and we have to select the transcoder in the `DP_CTL` register as there is no separate DP transcoder register.
The latter is quirky, however. If a port (DP or HDMI) is disabled with the second transcoder selected. This selection sticks and the sibling port (e.g. DP2 to HDMI2) can't be enabled with the first transcoder. As a workaround, we are supposed to enable a port that was using the second transcoder with the first transcoder selected again.
Change-Id: I0c1fafc2ba113aeeaf4ace750b333cc270bca37c Signed-off-by: Nico Huber nico.h@gmx.de Reviewed-on: https://review.coreboot.org/c/libgfxinit/+/35740 Reviewed-by: Angel Pons th3fanbus@gmail.com --- M common/ironlake/hw-gfx-gma-connectors.adb M common/ironlake/hw-gfx-gma-pch-dp.adb M common/ironlake/hw-gfx-gma-pch-dp.ads M common/ironlake/hw-gfx-gma-pch-hdmi.adb 4 files changed, 77 insertions(+), 17 deletions(-)
Approvals: Nico Huber: Verified Angel Pons: Looks good to me, approved
diff --git a/common/ironlake/hw-gfx-gma-connectors.adb b/common/ironlake/hw-gfx-gma-connectors.adb index 9bb0b68..21eca97 100644 --- a/common/ironlake/hw-gfx-gma-connectors.adb +++ b/common/ironlake/hw-gfx-gma-connectors.adb @@ -88,7 +88,7 @@ elsif Port_Cfg.PCH_Port in PCH_HDMI_Port then PCH.HDMI.On (Port_Cfg, FDI_Port); elsif Port_Cfg.PCH_Port in PCH_DP_Port then - PCH.DP.On (Port_Cfg, Success); + PCH.DP.On (Port_Cfg, FDI_Port, Success); end if; end if; end; diff --git a/common/ironlake/hw-gfx-gma-pch-dp.adb b/common/ironlake/hw-gfx-gma-pch-dp.adb index 15d3720..72244d5 100644 --- a/common/ironlake/hw-gfx-gma-pch-dp.adb +++ b/common/ironlake/hw-gfx-gma-pch-dp.adb @@ -34,15 +34,25 @@ DP_CTL_PREEMPH_LEVEL_SET_SHIFT : constant := 22; DP_CTL_PREEMPH_LEVEL_SET_MASK : constant := 7 * 2 ** 22; DP_CTL_PORT_WIDTH_SHIFT : constant := 19; + DP_CTL_ENHANCED_FRAMING_ENABLE : constant := 1 * 2 ** 18; DP_CTL_PORT_REVERSAL : constant := 1 * 2 ** 15; - DP_CTL_LINK_TRAIN_MASK : constant := 7 * 2 ** 8; - DP_CTL_LINK_TRAIN_PAT1 : constant := 0 * 2 ** 8; - DP_CTL_LINK_TRAIN_PAT2 : constant := 1 * 2 ** 8; - DP_CTL_LINK_TRAIN_IDLE : constant := 2 * 2 ** 8; - DP_CTL_LINK_TRAIN_NORMAL : constant := 3 * 2 ** 8; DP_CTL_AUDIO_OUTPUT_ENABLE : constant := 1 * 2 ** 6; DP_CTL_PORT_DETECT : constant := 1 * 2 ** 2;
+ function DP_CTL_LINK_TRAIN_SHIFT return Natural is + (if Config.Has_Trans_DP_Ctl then 8 else 28); + + function DP_CTL_LINK_TRAIN_MASK return Word32 is + (if Config.Has_Trans_DP_Ctl then 7 * 2 ** 8 else 3 * 2 ** 28); + + function DP_CTL_LINK_TRAIN (Pat : DP_Info.Training_Pattern) return Word32 is + (case Pat is + when DP_Info.TP_1 => Shift_Left (0, DP_CTL_LINK_TRAIN_SHIFT), + when DP_Info.TP_2 => Shift_Left (1, DP_CTL_LINK_TRAIN_SHIFT), + when DP_Info.TP_3 => Shift_Left (1, DP_CTL_LINK_TRAIN_SHIFT), + when DP_Info.TP_Idle => Shift_Left (2, DP_CTL_LINK_TRAIN_SHIFT), + when DP_Info.TP_None => Shift_Left (3, DP_CTL_LINK_TRAIN_SHIFT)); + function DP_CTL_VSWING_LEVEL_SET (VS : DP_Info.DP_Voltage_Swing) return Word32 @@ -68,14 +78,6 @@ DP_CTL_PORT_WIDTH_SHIFT); end DP_CTL_PORT_WIDTH;
- type DP_CTL_LINK_TRAIN_Array is array (DP_Info.Training_Pattern) of Word32; - DP_CTL_LINK_TRAIN : constant DP_CTL_LINK_TRAIN_Array := - (DP_Info.TP_1 => DP_CTL_LINK_TRAIN_PAT1, - DP_Info.TP_2 => DP_CTL_LINK_TRAIN_PAT2, - DP_Info.TP_3 => DP_CTL_LINK_TRAIN_PAT2, - DP_Info.TP_Idle => DP_CTL_LINK_TRAIN_IDLE, - DP_Info.TP_None => DP_CTL_LINK_TRAIN_NORMAL); - ----------------------------------------------------------------------------
pragma Warnings (GNATprove, Off, "unused variable ""Port""", @@ -134,17 +136,43 @@
procedure Off (Port : PCH_DP_Port) is + With_Transcoder_B_Enabled : Boolean := False; begin pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
+ if not Config.Has_Trans_DP_Ctl then + -- Ensure transcoder select isn't set to B, + -- disabled DP may block HDMI otherwise. + Registers.Is_Set_Mask + (Register => DP_CTL (Port), + Mask => DP_CTL_DISPLAY_PORT_ENABLE or + PCH_TRANSCODER_SELECT (FDI_B), + Result => With_Transcoder_B_Enabled); + end if; + Registers.Unset_And_Set_Mask (Register => DP_CTL (Port), Mask_Unset => DP_CTL_LINK_TRAIN_MASK, - Mask_Set => DP_CTL_LINK_TRAIN_IDLE); + Mask_Set => DP_CTL_LINK_TRAIN (DP_Info.TP_Idle)); Registers.Posting_Read (DP_CTL (Port));
- Registers.Write (DP_CTL (Port), 0); + Registers.Unset_Mask (DP_CTL (Port), DP_CTL_DISPLAY_PORT_ENABLE); Registers.Posting_Read (DP_CTL (Port)); + + if not Config.Has_Trans_DP_Ctl and then With_Transcoder_B_Enabled then + -- Reenable with transcoder A selected to switch. + Registers.Unset_And_Set_Mask + (Register => DP_CTL (Port), + Mask_Unset => PCH_TRANSCODER_SELECT_MASK or + DP_CTL_LINK_TRAIN_MASK, + Mask_Set => DP_CTL_DISPLAY_PORT_ENABLE or + PCH_TRANSCODER_SELECT (FDI_A) or + DP_CTL_LINK_TRAIN (DP_Info.TP_1)); + Registers.Posting_Read (DP_CTL (Port)); + Registers.Unset_Mask (DP_CTL (Port), DP_CTL_DISPLAY_PORT_ENABLE); + Registers.Posting_Read (DP_CTL (Port)); + end if; + end Off; pragma Warnings (GNATprove, On, "unused variable ""Port"""); pragma Warnings (GNATprove, On, "unused variable ""Link"""); @@ -153,6 +181,7 @@
procedure On (Port_Cfg : in Port_Config; + FDI_Port : in FDI_Port_Type; Success : out Boolean) is function To_DP (Port : PCH_DP_Port) return DP_Port @@ -176,14 +205,23 @@ Set_Pattern => Set_Training_Pattern, Set_Signal_Levels => Set_Signal_Levels, Off => Off); + + DP_CTL_Transcoder_Select : constant Word32 := + (if Config.Has_Trans_DP_Ctl + then 0 else PCH_TRANSCODER_SELECT (FDI_Port)); + DP_CTL_Enhanced_Framing : constant Word32 := + (if Config.Has_Trans_DP_Ctl + then 0 else DP_CTL_ENHANCED_FRAMING_ENABLE); begin pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
Registers.Write (Register => DP_CTL (Port_Cfg.PCH_Port), Value => DP_CTL_DISPLAY_PORT_ENABLE or + DP_CTL_Transcoder_Select or DP_CTL_PORT_WIDTH (Port_Cfg.DP.Lane_Count) or - DP_CTL_LINK_TRAIN_PAT1); + DP_CTL_Enhanced_Framing or + DP_CTL_LINK_TRAIN (DP_Info.TP_1));
Training.Train_DP (Port => Port_Cfg.PCH_Port, diff --git a/common/ironlake/hw-gfx-gma-pch-dp.ads b/common/ironlake/hw-gfx-gma-pch-dp.ads index c2ab299..83c546d 100644 --- a/common/ironlake/hw-gfx-gma-pch-dp.ads +++ b/common/ironlake/hw-gfx-gma-pch-dp.ads @@ -17,6 +17,7 @@
procedure On (Port_Cfg : in Port_Config; + FDI_Port : in FDI_Port_Type; Success : out Boolean) with Pre => Port_Cfg.PCH_Port in PCH_DP_Port; diff --git a/common/ironlake/hw-gfx-gma-pch-hdmi.adb b/common/ironlake/hw-gfx-gma-pch-hdmi.adb index aaf7951..9426a86 100644 --- a/common/ironlake/hw-gfx-gma-pch-hdmi.adb +++ b/common/ironlake/hw-gfx-gma-pch-hdmi.adb @@ -72,14 +72,35 @@
procedure Off (Port : PCH_HDMI_Port) is + With_Transcoder_B_Enabled : Boolean := False; begin pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
+ if not Config.Has_Trans_DP_Ctl then + -- Ensure transcoder select isn't set to B, + -- disabled HDMI may block DP otherwise. + Registers.Is_Set_Mask + (Register => PCH_HDMI (Port), + Mask => PCH_HDMI_ENABLE or + PCH_TRANSCODER_SELECT (FDI_B), + Result => With_Transcoder_B_Enabled); + end if; + Registers.Unset_And_Set_Mask (Register => PCH_HDMI (Port), Mask_Unset => PCH_HDMI_MASK, Mask_Set => PCH_HDMI_HSYNC_ACTIVE_HIGH or PCH_HDMI_VSYNC_ACTIVE_HIGH); + Registers.Posting_Read (PCH_HDMI (Port)); + + if not Config.Has_Trans_DP_Ctl and then With_Transcoder_B_Enabled then + -- Reenable with transcoder A selected to switch. + Registers.Set_Mask (PCH_HDMI (Port), PCH_HDMI_ENABLE); + Registers.Posting_Read (PCH_HDMI (Port)); + Registers.Unset_Mask (PCH_HDMI (Port), PCH_HDMI_ENABLE); + Registers.Posting_Read (PCH_HDMI (Port)); + end if; + end Off;
procedure All_Off