gma: Update transcoder setup for TGL
Tiger Lake requires configuration (but not enablement) of the
transcoder during the modeset sequence itself, so this patch adds a
new Config option to accommodate that and refactors the transcoder
setup into two new procedures. There should be no functional
differences for other generations.
Signed-off-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Signed-off-by: Jeremy Compostella <jeremy.compostella@intel.com>
Change-Id: I4d7e2a24c54fcd9994f44bb0b10924dce48068e5
Reviewed-on: https://review.coreboot.org/c/libgfxinit/+/67493
Tested-by: Nico Huber <nico.h@gmx.de>
Reviewed-by: Nico Huber <nico.h@gmx.de>
diff --git a/common/hw-gfx-gma-transcoder.adb b/common/hw-gfx-gma-transcoder.adb
index e74d769..9e85b75 100644
--- a/common/hw-gfx-gma-transcoder.adb
+++ b/common/hw-gfx-gma-transcoder.adb
@@ -15,6 +15,7 @@
with HW.Debug;
with GNAT.Source_Info;
+with HW.GFX.GMA.Config_Helpers;
with HW.GFX.GMA.DP_Info;
package body HW.GFX.GMA.Transcoder is
@@ -38,6 +39,7 @@
----------------------------------------------------------------------------
TRANS_CLK_SEL_PORT_NONE : constant := 0 * 2 ** 29;
+ TRANS_CLK_SEL_MASK : constant := 16#f000_0000#;
type TRANS_CLK_SEL_PORT_Array is
array (Digital_Port) of Word32;
@@ -48,6 +50,19 @@
DIGI_D => 4 * 2 ** 29,
DIGI_E => 5 * 2 ** 29);
+ function TGL_TRANS_CLK_SEL_PORT (Port : TGL_Digital_Port) return Word32 is
+ (case Port is
+ when DIGI_A => 1 * 2 ** 28,
+ when DIGI_B => 2 * 2 ** 28,
+ when DIGI_C => 3 * 2 ** 28,
+ when DDI_TC1 => 4 * 2 ** 28,
+ when DDI_TC2 => 5 * 2 ** 28,
+ when DDI_TC3 => 6 * 2 ** 28,
+ when DDI_TC4 => 7 * 2 ** 28,
+ when DDI_TC5 => 8 * 2 ** 28,
+ when DDI_TC6 => 9 * 2 ** 28,
+ when others => 0);
+
TRANS_CONF_ENABLE : constant := 1 * 2 ** 31;
TRANS_CONF_ENABLED_STATUS : constant := 1 * 2 ** 30;
TRANS_CONF_ENABLE_DITHER : constant := 1 * 2 ** 4;
@@ -85,6 +100,21 @@
DIGI_D => 3 * 2 ** 28,
DIGI_E => 4 * 2 ** 28);
+ function TGL_DDI_FUNC_CTL_DDI_SELECT (Port : TGL_Digital_Port)
+ return Word32
+ is
+ (case Port is
+ when DIGI_A => 1 * 2 ** 27,
+ when DIGI_B => 2 * 2 ** 27,
+ when DIGI_C => 3 * 2 ** 27,
+ when DDI_TC1 => 4 * 2 ** 27,
+ when DDI_TC2 => 5 * 2 ** 27,
+ when DDI_TC3 => 6 * 2 ** 27,
+ when DDI_TC4 => 7 * 2 ** 27,
+ when DDI_TC5 => 8 * 2 ** 27,
+ when DDI_TC6 => 9 * 2 ** 27,
+ when others => 0);
+
type DDI_Mode_Array is array (Display_Type) of Word32;
DDI_FUNC_CTL_MODE_SELECT : constant DDI_Mode_Array :=
(VGA => DDI_FUNC_CTL_MODE_SELECT_FDI,
@@ -204,6 +234,7 @@
pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
if Config.Has_Trans_Clk_Sel and then
+ not Config.Need_Early_Transcoder_Setup and then
Trans.CLK_SEL /= Registers.Invalid_Register and then
Port_Cfg.Port in Digital_Port
then
@@ -228,6 +259,69 @@
----------------------------------------------------------------------------
+ procedure Enable_Pipe_Clock (Pipe : Pipe_Index; Port_Cfg : Port_Config)
+ is
+ use type HW.GFX.GMA.Registers.Registers_Invalid_Index;
+
+ Trans : Transcoder_Regs renames
+ Transcoders (Get_Idx (Pipe, Port_Cfg.Port));
+ begin
+ if Config.Need_Early_Transcoder_Setup and then
+ Trans.CLK_SEL /= Registers.Invalid_Register and then
+ Port_Cfg.Port in TGL_Digital_Port
+ then
+ Registers.Unset_And_Set_Mask
+ (Register => Trans.CLK_SEL,
+ Mask_Unset => TRANS_CLK_SEL_MASK,
+ Mask_Set => TGL_TRANS_CLK_SEL_PORT (Port_Cfg.Port));
+ end if;
+ end Enable_Pipe_Clock;
+
+ ----------------------------------------------------------------------------
+
+ procedure Configure (Pipe : Pipe_Index; Port_Cfg : Port_Config; Scale : Boolean)
+ is
+ Trans : Transcoder_Regs renames
+ Transcoders (Get_Idx (Pipe, Port_Cfg.Port));
+ Lane_Count : constant DP_Lane_Count :=
+ (if Port_Cfg.Is_FDI then Port_Cfg.FDI.Lane_Count else Port_Cfg.DP.Lane_Count);
+ EDP_Select : constant Word32 :=
+ (if Config.Has_TGL_DDI_Select
+ then 0
+ else
+ (if Pipe = Primary and
+ (not Config.Use_PDW_For_EDP_Scaling or else not Scale)
+ then
+ DDI_FUNC_CTL_EDP_SELECT_ALWAYS_ON
+ else
+ DDI_FUNC_CTL_EDP_SELECT (Pipe)));
+ DDI_Select : constant Word32 :=
+ (if Config.Has_TGL_DDI_Select and Port_Cfg.Port in TGL_Digital_Port then
+ TGL_DDI_FUNC_CTL_DDI_SELECT (Port_Cfg.Port)
+ else
+ (if Port_Cfg.Port in Digital_Port
+ then
+ DDI_FUNC_CTL_DDI_SELECT (Port_Cfg.Port)
+ else 0));
+ begin
+ pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
+ if Config.Has_Pipe_DDI_Func then
+ if Is_Digital_Port (Port_Cfg.Port) then
+ Registers.Write
+ (Register => Trans.DDI_FUNC_CTL,
+ Value => DDI_Select or
+ DDI_FUNC_CTL_MODE_SELECT (Port_Cfg.Display) or
+ DDI_FUNC_CTL_BPC (Port_Cfg.Mode.BPC) or
+ DDI_FUNC_CTL_VSYNC (Port_Cfg.Mode.V_Sync_Active_High) or
+ DDI_FUNC_CTL_HSYNC (Port_Cfg.Mode.H_Sync_Active_High) or
+ EDP_Select or
+ DDI_FUNC_CTL_PORT_WIDTH (Lane_Count));
+ end if;
+ end if;
+ end Configure;
+
+ ----------------------------------------------------------------------------
+
procedure On
(Pipe : Pipe_Index;
Port_Cfg : Port_Config;
@@ -236,27 +330,16 @@
is
Trans : Transcoder_Regs renames
Transcoders (Get_Idx (Pipe, Port_Cfg.Port));
- Lane_Count : constant DP_Lane_Count :=
- (if Port_Cfg.Is_FDI then Port_Cfg.FDI.Lane_Count else Port_Cfg.DP.Lane_Count);
- EDP_Select : constant Word32 :=
- (if Pipe = Primary and
- (not Config.Use_PDW_For_EDP_Scaling or else not Scale)
- then
- DDI_FUNC_CTL_EDP_SELECT_ALWAYS_ON
- else
- DDI_FUNC_CTL_EDP_SELECT (Pipe));
begin
- if Config.Has_Pipe_DDI_Func and Port_Cfg.Port in Digital_Port then
- Registers.Write
+ pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
+ if not Config.Need_Early_Transcoder_Setup then
+ Configure (Pipe, Port_Cfg, Scale);
+ end if;
+
+ if Config.Has_Pipe_DDI_Func and Is_Digital_Port (Port_Cfg.Port) then
+ Registers.Set_Mask
(Register => Trans.DDI_FUNC_CTL,
- Value => DDI_FUNC_CTL_ENABLE or
- DDI_FUNC_CTL_DDI_SELECT (Port_Cfg.Port) or
- DDI_FUNC_CTL_MODE_SELECT (Port_Cfg.Display) or
- DDI_FUNC_CTL_BPC (Port_Cfg.Mode.BPC) or
- DDI_FUNC_CTL_VSYNC (Port_Cfg.Mode.V_Sync_Active_High) or
- DDI_FUNC_CTL_HSYNC (Port_Cfg.Mode.H_Sync_Active_High) or
- EDP_Select or
- DDI_FUNC_CTL_PORT_WIDTH (Lane_Count));
+ Mask => DDI_FUNC_CTL_ENABLE);
end if;
Registers.Write
@@ -360,15 +443,20 @@
pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
if Config.Has_Per_Pipe_SRD then
- for P in Transcoder_Index loop
- Registers.Is_Set_Mask (SRD (P).CTL, SRD_CTL_ENABLE, Enabled);
- if Enabled then
- Registers.Unset_Mask (SRD (P).CTL, SRD_CTL_ENABLE);
- Registers.Wait_Unset_Mask (SRD (P).STATUS, SRD_STATUS_STATE_MASK);
+ declare
+ First_Transcoder : constant Transcoder_Index :=
+ (if Config.Has_EDP_Transcoder then Trans_EDP else Trans_A);
+ begin
+ for P in Transcoder_Index range First_Transcoder .. Transcoder_Index'Last loop
+ Registers.Is_Set_Mask (SRD (P).CTL, SRD_CTL_ENABLE, Enabled);
+ if Enabled then
+ Registers.Unset_Mask (SRD (P).CTL, SRD_CTL_ENABLE);
+ Registers.Wait_Unset_Mask (SRD (P).STATUS, SRD_STATUS_STATE_MASK);
- pragma Debug (Debug.Put_Line ("Disabled PSR."));
- end if;
- end loop;
+ pragma Debug (Debug.Put_Line ("Disabled PSR."));
+ end if;
+ end loop;
+ end;
else
Registers.Is_Set_Mask (Registers.SRD_CTL, SRD_CTL_ENABLE, Enabled);
if Enabled then