gma adl: Implement TC ownership/connection handling
The ownership handling and hot-plug status moved from FIA registers
into DDI_BUF_CTL and new TCSS_DDI_STATUS registers.
Change-Id: I04c1341ceb7339ec4a06450b2d9ce07b27688904
Signed-off-by: Nico Huber <nico.huber@secunet.com>
Reviewed-on: https://review.sourcearcade.org/c/libgfxinit/+/506
Tested-by: Ada SPARK <gnatbot@sourcearcade.org>
Reviewed-by: Thomas Heijligen <src@posteo.de>
diff --git a/common/tigerlake/hw-gfx-gma-connectors-tc.adb b/common/tigerlake/hw-gfx-gma-connectors-tc.adb
index bd0e991..84eb4b0 100644
--- a/common/tigerlake/hw-gfx-gma-connectors-tc.adb
+++ b/common/tigerlake/hw-gfx-gma-connectors-tc.adb
@@ -31,7 +31,6 @@
function HIP_INDEX_VAL (P : USBC_Port; Val : Word32) return Word32 is
(Val * 2 ** (8 * ((GPU_Port'Pos (P) - GPU_Port'Pos (DDI_TC1)) mod 4)));
- type Port_Regs_Array is array (USBC_Port) of Registers.Registers_Index;
DKL_DP_MODE : constant Port_Regs_Array :=
(DDI_TC1 => Registers.DKL_DP_MODE_1,
DDI_TC2 => Registers.DKL_DP_MODE_2,
@@ -56,27 +55,6 @@
TCCOLD_UNBLOCK_REQ : constant := 16#01#;
TCCOLD_BLOCK_RESULT_FAIL : constant := 16#01#;
- DDI_BUF_CTL_BUFFER_ENABLE : constant := 1 * 2 ** 31;
- DDI_BUF_CTL_TRANS_SELECT_MASK : constant := 16#f# * 2 ** 24;
- DDI_BUF_CTL_PORT_REVERSAL : constant := 1 * 2 ** 16;
- DDI_BUF_CTL_PORT_WIDTH_MASK : constant := 7 * 2 ** 1;
- DDI_BUF_CTL_PORT_WIDTH_1_LANE : constant := 0 * 2 ** 1;
- DDI_BUF_CTL_PORT_WIDTH_2_LANES : constant := 1 * 2 ** 1;
- DDI_BUF_CTL_PORT_WIDTH_4_LANES : constant := 3 * 2 ** 1;
- DDI_BUF_CTL_IDLE_STATUS : constant := 1 * 2 ** 7;
-
- DDI_BUF_CTL_PORT_WIDTH : constant array (DP_Lane_Count) of Word32 :=
- (HW.GFX.DP_Lane_Count_1 => DDI_BUF_CTL_PORT_WIDTH_1_LANE,
- HW.GFX.DP_Lane_Count_2 => DDI_BUF_CTL_PORT_WIDTH_2_LANES,
- HW.GFX.DP_Lane_Count_4 => DDI_BUF_CTL_PORT_WIDTH_4_LANES);
- DDI_BUF_CTL : constant Port_Regs_Array :=
- (DDI_TC1 => Registers.DDI_BUF_CTL_USBC1,
- DDI_TC2 => Registers.DDI_BUF_CTL_USBC2,
- DDI_TC3 => Registers.DDI_BUF_CTL_USBC3,
- DDI_TC4 => Registers.DDI_BUF_CTL_USBC4,
- DDI_TC5 => Registers.DDI_BUF_CTL_USBC5,
- DDI_TC6 => Registers.DDI_BUF_CTL_USBC6);
-
type Buffer_Trans is record
Vswing_Control : Word32;
Preshoot_Control : Word32;
diff --git a/common/tigerlake/hw-gfx-gma-connectors-tc.ads b/common/tigerlake/hw-gfx-gma-connectors-tc.ads
index 25f30eb..9e637d0 100644
--- a/common/tigerlake/hw-gfx-gma-connectors-tc.ads
+++ b/common/tigerlake/hw-gfx-gma-connectors-tc.ads
@@ -36,6 +36,30 @@
-- And so far, no SKU needs more.
subtype Valid_TC_Port is USBC_Port range DDI_TC1 .. Config.Last_TC_Port;
+ type Port_Regs_Array is array (USBC_Port) of Registers.Registers_Index;
+
+ DDI_BUF_CTL_BUFFER_ENABLE : constant := 1 * 2 ** 31;
+ DDI_BUF_CTL_TRANS_SELECT_MASK : constant := 16#f# * 2 ** 24;
+ DDI_BUF_CTL_PORT_REVERSAL : constant := 1 * 2 ** 16;
+ DDI_BUF_CTL_PORT_WIDTH_MASK : constant := 7 * 2 ** 1;
+ DDI_BUF_CTL_PORT_WIDTH_1_LANE : constant := 0 * 2 ** 1;
+ DDI_BUF_CTL_PORT_WIDTH_2_LANES : constant := 1 * 2 ** 1;
+ DDI_BUF_CTL_PORT_WIDTH_4_LANES : constant := 3 * 2 ** 1;
+ DDI_BUF_CTL_IDLE_STATUS : constant := 1 * 2 ** 7;
+ DDI_BUF_CTL_TC_PHY_OWNERSHIP : constant := 1 * 2 ** 6;
+
+ DDI_BUF_CTL_PORT_WIDTH : constant array (DP_Lane_Count) of Word32 :=
+ (HW.GFX.DP_Lane_Count_1 => DDI_BUF_CTL_PORT_WIDTH_1_LANE,
+ HW.GFX.DP_Lane_Count_2 => DDI_BUF_CTL_PORT_WIDTH_2_LANES,
+ HW.GFX.DP_Lane_Count_4 => DDI_BUF_CTL_PORT_WIDTH_4_LANES);
+ DDI_BUF_CTL : constant Port_Regs_Array :=
+ (DDI_TC1 => Registers.DDI_BUF_CTL_USBC1,
+ DDI_TC2 => Registers.DDI_BUF_CTL_USBC2,
+ DDI_TC3 => Registers.DDI_BUF_CTL_USBC3,
+ DDI_TC4 => Registers.DDI_BUF_CTL_USBC4,
+ DDI_TC5 => Registers.DDI_BUF_CTL_USBC5,
+ DDI_TC6 => Registers.DDI_BUF_CTL_USBC6);
+
type Fia_Regs_Record is record
PORT_TX_DFLEXDPMLE1 : Registers.Registers_Index;
PORT_TX_DFLEXDPSP : Registers.Registers_Index;
diff --git a/common/tigerlake/xelpd/hw-gfx-gma-connectors-tc-ownership.adb b/common/tigerlake/xelpd/hw-gfx-gma-connectors-tc-ownership.adb
index 4e509ad..c3b1d2b 100644
--- a/common/tigerlake/xelpd/hw-gfx-gma-connectors-tc-ownership.adb
+++ b/common/tigerlake/xelpd/hw-gfx-gma-connectors-tc-ownership.adb
@@ -14,24 +14,78 @@
with HW.GFX.GMA.Config;
with HW.GFX.GMA.Registers;
+with HW.GFX.DP_Info;
+with HW.GFX.GMA.PCode;
with HW.Debug;
with GNAT.Source_Info;
+use type HW.Word64;
+
package body HW.GFX.GMA.Connectors.TC.Ownership is
+ type Port_Regs_Array is array (Valid_TC_Port) of Registers.Registers_Index;
+
+ TCSS_DDI_STATUS : constant Port_Regs_Array :=
+ Port_Regs_Array'
+ (DDI_TC1 => Registers.TCSS_DDI_STATUS_1,
+ DDI_TC2 => Registers.TCSS_DDI_STATUS_2,
+ DDI_TC3 => Registers.TCSS_DDI_STATUS_3,
+ DDI_TC4 => Registers.TCSS_DDI_STATUS_4);
+
+ TCSS_DDI_STATUS_HPD_LIVE_STATUS_ALT : constant := 1 * 2 ** 0;
+ TCSS_DDI_STATUS_READY : constant := 1 * 2 ** 2;
+
procedure Claim
(Port : in USBC_Port;
DP_Alt : in Boolean;
Success : out Boolean)
is
begin
- Success := False;
+ pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
+
+ if Port not in Valid_TC_Port then
+ Success := False;
+ return;
+ end if;
+
+ if not DP_Alt then
+ -- For legacy ports, this is supposed
+ -- to be initialized once during boot.
+ Registers.Wait_Set_Mask
+ (Register => TCSS_DDI_STATUS (Port),
+ Mask => TCSS_DDI_STATUS_READY,
+ TOut_MS => 100);
+ end if;
+
+ Registers.Is_Set_Mask
+ (Register => TCSS_DDI_STATUS (Port),
+ Mask => TCSS_DDI_STATUS_READY,
+ Result => Success);
+ if not Success then
+ pragma Debug (Debug.Put_Line ("DP PHY mode status not complete"));
+ return;
+ end if;
+
+ Registers.Set_Mask
+ (Register => DDI_BUF_CTL (Port),
+ Mask => DDI_BUF_CTL_TC_PHY_OWNERSHIP);
end Claim;
- procedure Claimed (Port : USBC_Port; Is_Claimed : out Boolean) is
+ procedure Claimed (Port : USBC_Port; Is_Claimed : out Boolean)
+ with
+ Refined_Post => (if Is_Claimed then Port in Valid_TC_Port)
+ is
begin
- Is_Claimed := False;
+ if Port not in Valid_TC_Port then
+ Is_Claimed := False;
+ return;
+ end if;
+
+ Registers.Is_Set_Mask
+ (Register => DDI_BUF_CTL (Port),
+ Mask => DDI_BUF_CTL_TC_PHY_OWNERSHIP,
+ Result => Is_Claimed);
end Claimed;
---------------------------------------------------------------------
@@ -42,10 +96,42 @@
Lanes : in DP_Lane_Count;
Success : out Boolean)
is
+ Assigned_Lanes : DP_Lane_Count;
begin
- Success := False;
+ pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
+
+ Claimed (Port, Success);
+ if not Success then
+ pragma Debug (Debug.Put_Line ("Tried to connect to unclaimed port."));
+ return;
+ end if;
+
+ if DP_Alt then
+ Registers.Is_Set_Mask
+ (Register => TCSS_DDI_STATUS (Port),
+ Mask => TCSS_DDI_STATUS_HPD_LIVE_STATUS_ALT,
+ Result => Success);
+ if not Success then
+ pragma Debug (Debug.Put_Line ("DP-Alt is not connected."));
+ return;
+ end if;
+
+ Get_Lane_Assignment_Count (Port, Assigned_Lanes);
+ Set_Lane_Count (Port, Assigned_Lanes);
+ else
+ Set_Lane_Count (Port, Lanes);
+ end if;
end Connect;
- procedure Disconnect (Port : USBC_Port) is null;
+ procedure Disconnect (Port : USBC_Port) is
+ begin
+ pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
+
+ if Port in Valid_TC_Port then
+ Registers.Unset_Mask
+ (Register => DDI_BUF_CTL (Port),
+ Mask => DDI_BUF_CTL_TC_PHY_OWNERSHIP);
+ end if;
+ end Disconnect;
end HW.GFX.GMA.Connectors.TC.Ownership;