Nico Huber has submitted this change. ( https://review.coreboot.org/c/libgfxinit/+/35869 )
Change subject: dp_info: read eDP 1.4+ DPCD link rates ......................................................................
dp_info: read eDP 1.4+ DPCD link rates
This is required for google/eve (Pixelbook), where only this new method of reporting the link rate is supported, and the Max_Link_Rate in the regular DPCD struct is 0x00.
Change-Id: I52b4d8ad94564904854b502f300b812c41a9751a Signed-off-by: Greg V greg@unrelenting.technology Reviewed-on: https://review.coreboot.org/c/libgfxinit/+/35869 Tested-by: Nico Huber nico.h@gmx.de Reviewed-by: Nico Huber nico.h@gmx.de --- M common/hw-gfx-dp_info.adb M common/hw-gfx-dp_info.ads M common/hw-gfx-gma-connector_info.adb 3 files changed, 96 insertions(+), 0 deletions(-)
Approvals: Nico Huber: Verified; Looks good to me, approved
diff --git a/common/hw-gfx-dp_info.adb b/common/hw-gfx-dp_info.adb index d45826d..bf09933 100644 --- a/common/hw-gfx-dp_info.adb +++ b/common/hw-gfx-dp_info.adb @@ -20,6 +20,7 @@ with HW.GFX.DP_Defs;
use type HW.Word8; +use type HW.Word16;
package body HW.GFX.DP_Info is
@@ -86,6 +87,93 @@ end if; end Read_Caps;
+ function Read_LE16 + (Raw_Payload : DP_Defs.Aux_Payload; + Offset : DP_Defs.Aux_Payload_Index) + return Word16 + with + Pre => Offset < DP_Defs.Aux_Payload_Index'Last + is + begin + return Shift_Left (Word16 (Raw_Payload (Offset + 1)), 8) or + Word16 (Raw_Payload (Offset)); + end Read_LE16; + + procedure Read_eDP_Rates + (Link : in out DP_Link; + Port : in T) + is + Data : DP_Defs.Aux_Payload; + Length : DP_Defs.Aux_Payload_Length; + Max_Rate : Natural; + Success : Boolean; + + Caps_Size : constant := 3; + Rates_Size : constant := 16; + eDP_Rev_1_4 : constant := 3; + begin + pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); + + Length := Caps_Size; + Aux_Ch.Aux_Read + (Port => Port, + Address => 16#00700#, + Length => Length, + Data => Data, + Success => Success); + Success := Success and Length = Caps_Size; + if not Success or Data (0) < eDP_Rev_1_4 then + return; + end if; + + Length := Rates_Size; + Aux_Ch.Aux_Read + (Port => Port, + Address => 16#00010#, + Length => Length, + Data => Data, + Success => Success); + Success := Success and Length = Rates_Size; + if not Success then + return; + end if; + + pragma Debug (Debug.New_Line); + pragma Debug (Debug.Put_Line ("DPCD eDP 1.4+ link rates:")); + + -- TODO: support individual link rates (storing them all) + + Max_Rate := Natural'First; + for I in 0 .. Length / 2 - 1 loop + pragma Loop_Invariant (Max_Rate <= Natural (Word16'Last)); + declare + Rate : constant Word16 := Read_LE16 (Data, I * 2); + begin + exit when Rate = 0; -- prematurely exit the loop + pragma Debug (Debug.Put (" - ")); + pragma Debug (Debug.Put_Int8 (Int8 (I))); + pragma Debug (Debug.Put (": ")); + pragma Debug (Debug.Put_Word16 (Rate)); + pragma Debug (Debug.New_Line); + if Natural (Rate) > Max_Rate then + Max_Rate := Natural (Rate); + end if; + end; + end loop; + pragma Debug (Debug.New_Line); + + -- convert to KHz + Max_Rate := Max_Rate * 20; + + if Max_Rate >= 540_000 then + Link.Receiver_Caps.Max_Link_Rate := DP_Bandwidth_5_4; + elsif Max_Rate >= 270_000 then + Link.Receiver_Caps.Max_Link_Rate := DP_Bandwidth_2_7; + elsif Max_Rate >= 162_000 then + Link.Receiver_Caps.Max_Link_Rate := DP_Bandwidth_1_62; + end if; + end Read_eDP_Rates; + procedure Minimum_Lane_Count (Link : in out DP_Link; Mode : in Mode_Type; diff --git a/common/hw-gfx-dp_info.ads b/common/hw-gfx-dp_info.ads index aa10c4c..6d22bcc 100644 --- a/common/hw-gfx-dp_info.ads +++ b/common/hw-gfx-dp_info.ads @@ -81,6 +81,10 @@ Port : in T; Success : out Boolean);
+ procedure Read_eDP_Rates + (Link : in out DP_Link; + Port : in T); + procedure Preferred_Link_Setting (Link : in out DP_Link; Mode : in Mode_Type; diff --git a/common/hw-gfx-gma-connector_info.adb b/common/hw-gfx-gma-connector_info.adb index e8357be..3ce807e 100644 --- a/common/hw-gfx-gma-connector_info.adb +++ b/common/hw-gfx-gma-connector_info.adb @@ -51,6 +51,10 @@ Port => DP_Port, Success => Success); if Success then + DP_Info.Read_eDP_Rates + (Link => Port_Cfg.DP, + Port => DP_Port); + DP_Info.Preferred_Link_Setting (Link => Port_Cfg.DP, Mode => Port_Cfg.Mode,