gma broxton: Add final glue
Add new configuration flags for Broxton and hook up its DDI_Phy
implementation in the shared Haswell DDI code. Haswell and Skylake
get DDI_Phy stubs.
Tested (in Linux userspace) on ASRock J3455-ITX which exposes the
following ports:
o VGA through an active eDP to VGA converter chip
o HDMI 2.0 through an active DP to HDMI converter chip
o DVI-D connected to the SoC
Change-Id: If72b228c6a4c45487261e6e7435d281ec2d97f38
Signed-off-by: Nico Huber <nico.huber@secunet.com>
Reviewed-on: https://review.coreboot.org/18426
Tested-by: Nico Huber <nico.h@gmx.de>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
diff --git a/common/haswell_shared/Makefile.inc b/common/haswell_shared/Makefile.inc
index 45b505b..c9b7daa 100644
--- a/common/haswell_shared/Makefile.inc
+++ b/common/haswell_shared/Makefile.inc
@@ -1,6 +1,7 @@
gfxinit-y += hw-gfx-gma-connectors-ddi.adb
gfxinit-y += hw-gfx-gma-connectors-ddi.ads
gfxinit-y += hw-gfx-gma-connectors.adb
+gfxinit-y += hw-gfx-gma-ddi_phy_stub.ads
gfxinit-y += hw-gfx-gma-port_detect.adb
gfxinit-y += hw-gfx-gma-power_and_clocks_haswell.adb
gfxinit-y += hw-gfx-gma-power_and_clocks_haswell.ads
diff --git a/common/haswell_shared/hw-gfx-gma-connectors-ddi.adb b/common/haswell_shared/hw-gfx-gma-connectors-ddi.adb
index 31f0b4c..4440376 100644
--- a/common/haswell_shared/hw-gfx-gma-connectors-ddi.adb
+++ b/common/haswell_shared/hw-gfx-gma-connectors-ddi.adb
@@ -21,6 +21,7 @@
with HW.GFX.GMA.DP_Info;
with HW.GFX.GMA.DP_Aux_Ch;
with HW.GFX.GMA.SPLL;
+with HW.GFX.GMA.DDI_Phy;
with HW.Debug;
with GNAT.Source_Info;
@@ -179,7 +180,9 @@
is
begin
return
- (if (Config.Has_Low_Voltage_Swing and Config.EDP_Low_Voltage_Swing)
+ (if Config.Has_DDI_PHYs then
+ DDI_Phy.Max_V_Swing
+ elsif (Config.Has_Low_Voltage_Swing and Config.EDP_Low_Voltage_Swing)
and then Port = DIGI_A
then
DP_Info.VS_Level_3
@@ -196,11 +199,14 @@
is
begin
return
- (case Train_Set.Voltage_Swing is
- when DP_Info.VS_Level_0 => DP_Info.Emph_Level_3,
- when DP_Info.VS_Level_1 => DP_Info.Emph_Level_2,
- when DP_Info.VS_Level_2 => DP_Info.Emph_Level_1,
- when others => DP_Info.Emph_Level_0);
+ (if Config.Has_DDI_PHYs then
+ DDI_Phy.Max_Pre_Emph (Train_Set.Voltage_Swing)
+ else
+ (case Train_Set.Voltage_Swing is
+ when DP_Info.VS_Level_0 => DP_Info.Emph_Level_3,
+ when DP_Info.VS_Level_1 => DP_Info.Emph_Level_2,
+ when DP_Info.VS_Level_2 => DP_Info.Emph_Level_1,
+ when others => DP_Info.Emph_Level_0));
end Max_Pre_Emph;
pragma Warnings (GNATprove, On, "unused variable ""Port""");
@@ -262,39 +268,43 @@
Was_Enabled : Boolean;
Trans_Select : DDI_BUF_CTL_TRANS_SELECT_T;
begin
- case Train_Set.Voltage_Swing is
- when DP_Info.VS_Level_0 =>
- case Train_Set.Pre_Emph is
- when DP_Info.Emph_Level_0 => Trans_Select := 0;
- when DP_Info.Emph_Level_1 => Trans_Select := 1;
- when DP_Info.Emph_Level_2 => Trans_Select := 2;
- when DP_Info.Emph_Level_3 => Trans_Select := 3;
- end case;
- when DP_Info.VS_Level_1 =>
- case Train_Set.Pre_Emph is
- when DP_Info.Emph_Level_0 => Trans_Select := 4;
- when DP_Info.Emph_Level_1 => Trans_Select := 5;
- when DP_Info.Emph_Level_2 => Trans_Select := 6;
- when others => Trans_Select := 0;
- end case;
- when DP_Info.VS_Level_2 =>
- case Train_Set.Pre_Emph is
- when DP_Info.Emph_Level_0 => Trans_Select := 7;
- when DP_Info.Emph_Level_1 => Trans_Select := 8;
- when others => Trans_Select := 0;
- end case;
- when DP_Info.VS_Level_3 =>
- case Train_Set.Pre_Emph is
- when DP_Info.Emph_Level_0 => Trans_Select := 9;
- when others => Trans_Select := 0;
- end case;
- end case;
-
Registers.Is_Set_Mask
(Register => DDI_Regs (Port).BUF_CTL,
Mask => DDI_BUF_CTL_BUFFER_ENABLE,
Result => Was_Enabled);
+ if Config.Has_DDI_PHYs then
+ Trans_Select := 0;
+ else
+ case Train_Set.Voltage_Swing is
+ when DP_Info.VS_Level_0 =>
+ case Train_Set.Pre_Emph is
+ when DP_Info.Emph_Level_0 => Trans_Select := 0;
+ when DP_Info.Emph_Level_1 => Trans_Select := 1;
+ when DP_Info.Emph_Level_2 => Trans_Select := 2;
+ when DP_Info.Emph_Level_3 => Trans_Select := 3;
+ end case;
+ when DP_Info.VS_Level_1 =>
+ case Train_Set.Pre_Emph is
+ when DP_Info.Emph_Level_0 => Trans_Select := 4;
+ when DP_Info.Emph_Level_1 => Trans_Select := 5;
+ when DP_Info.Emph_Level_2 => Trans_Select := 6;
+ when others => Trans_Select := 0;
+ end case;
+ when DP_Info.VS_Level_2 =>
+ case Train_Set.Pre_Emph is
+ when DP_Info.Emph_Level_0 => Trans_Select := 7;
+ when DP_Info.Emph_Level_1 => Trans_Select := 8;
+ when others => Trans_Select := 0;
+ end case;
+ when DP_Info.VS_Level_3 =>
+ case Train_Set.Pre_Emph is
+ when DP_Info.Emph_Level_0 => Trans_Select := 9;
+ when others => Trans_Select := 0;
+ end case;
+ end case;
+ end if;
+
-- enable DDI buffer
Registers.Unset_And_Set_Mask
(Register => DDI_Regs (Port).BUF_CTL,
@@ -309,6 +319,10 @@
if not Was_Enabled then
Time.U_Delay (600); -- wait >= 518us (intel spec)
end if;
+
+ if Config.Has_DDI_PHYs then
+ DDI_Phy.Set_DP_Signal_Levels (Port, Train_Set);
+ end if;
end Set_Signal_Levels;
----------------------------------------------------------------------------
@@ -344,7 +358,7 @@
Registers.Write
(Register => DDI_Regs (Port).PORT_CLK_SEL,
Value => PORT_CLK_SEL_NONE);
- else
+ elsif not Config.Has_DDI_PHYs then
Registers.Set_Mask
(Register => Registers.DPLL_CTRL2,
Mask => DPLL_CTRL2_DDIx_CLOCK_OFF (Port));
@@ -472,7 +486,7 @@
Registers.Write
(Register => DDI_Regs (Port_Cfg.Port).PORT_CLK_SEL,
Value => PLL_Hint);
- else
+ elsif not Config.Has_DDI_PHYs then
Registers.Unset_And_Set_Mask
(Register => Registers.DPLL_CTRL2,
Mask_Unset => DPLL_CTRL2_DDIx_CLOCK_OFF (Port_Cfg.Port) or
@@ -489,6 +503,14 @@
(Port => Port_Cfg.Port,
Link => Port_Cfg.DP,
Success => Success);
+ elsif Config.Has_DDI_PHYs and then
+ Port_Cfg.Display = HDMI and then
+ Port_Cfg.Port in DDI_Phy.DDI_Phy_Port
+ then
+ DDI_Phy.Set_HDMI_Signal_Levels
+ (Port => Port_Cfg.Port,
+ Level => DDI_Phy.HDMI_Buf_Trans_Range'Last);
+ Success := True;
else
Success := True;
end if;
diff --git a/common/haswell_shared/hw-gfx-gma-ddi_phy_stub.ads b/common/haswell_shared/hw-gfx-gma-ddi_phy_stub.ads
new file mode 100644
index 0000000..b37e955
--- /dev/null
+++ b/common/haswell_shared/hw-gfx-gma-ddi_phy_stub.ads
@@ -0,0 +1,35 @@
+--
+-- Copyright (C) 2017 secunet Security Networks AG
+--
+-- 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.DP_Info;
+
+private package HW.GFX.GMA.DDI_Phy_Stub is
+
+ subtype DDI_Phy_Port is GPU_Port;
+
+ Max_V_Swing : constant DP_Info.DP_Voltage_Swing := DP_Info.VS_Level_0;
+
+ type Emph_Array is array (DP_Info.DP_Voltage_Swing) of DP_Info.DP_Pre_Emph;
+ Max_Pre_Emph : constant Emph_Array := (others => DP_Info.Emph_Level_0);
+
+ procedure Set_DP_Signal_Levels
+ (Port : Digital_Port;
+ Train_Set : DP_Info.Train_Set) is null;
+
+ type HDMI_Buf_Trans_Range is range 0 .. 9;
+ procedure Set_HDMI_Signal_Levels
+ (Port : DDI_Phy_Port;
+ Level : HDMI_Buf_Trans_Range) is null;
+
+end HW.GFX.GMA.DDI_Phy_Stub;
diff --git a/common/haswell_shared/hw-gfx-gma-port_detect.adb b/common/haswell_shared/hw-gfx-gma-port_detect.adb
index b8ba37d..d8a1d07 100644
--- a/common/haswell_shared/hw-gfx-gma-port_detect.adb
+++ b/common/haswell_shared/hw-gfx-gma-port_detect.adb
@@ -82,10 +82,14 @@
if Config.Internal_Is_EDP then
-- DDI_A
- Registers.Is_Set_Mask
- (Register => Registers.DDI_BUF_CTL_A,
- Mask => DDI_PORT_DETECTED (DIGI_A),
- Result => Internal_Detected);
+ if Config.Has_Presence_Straps then
+ Registers.Is_Set_Mask
+ (Register => Registers.DDI_BUF_CTL_A,
+ Mask => DDI_PORT_DETECTED (DIGI_A),
+ Result => Internal_Detected);
+ else
+ Internal_Detected := True; -- XXX: Linux' i915 contains a fixme.
+ end if;
if Internal_Detected then
if Config.Has_HOTPLUG_CTL then
Registers.Set_Mask
@@ -114,10 +118,14 @@
-- DDI_[BCD]
for Port in Ext_Digital_Port range DIGI_B .. Config.Last_Digital_Port loop
- Registers.Is_Set_Mask
- (Register => Registers.SFUSE_STRAP,
- Mask => DDI_PORT_DETECTED (Port),
- Result => DDI_Detected);
+ if Config.Has_Presence_Straps then
+ Registers.Is_Set_Mask
+ (Register => Registers.SFUSE_STRAP,
+ Mask => DDI_PORT_DETECTED (Port),
+ Result => DDI_Detected);
+ else
+ DDI_Detected := True;
+ end if;
Config.Valid_Port (To_HDMI_Port (Port)) :=
Config.Valid_Port (To_HDMI_Port (Port)) and DDI_Detected;
Config.Valid_Port (To_DP_Port (Port)) :=