Angel Pons has uploaded this change for review.

View Change

[HACK] Switch LSPCON to PCON mode

Change-Id: I3c9e67caf9511d62b19c0c175e8e75080fb7ac7d
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
---
M common/hw-gfx-dp_aux_ch.adb
M common/hw-gfx-dp_aux_ch.ads
M common/hw-gfx-dp_info.adb
3 files changed, 156 insertions(+), 0 deletions(-)

git pull ssh://review.coreboot.org:29418/libgfxinit refs/changes/31/46631/1
diff --git a/common/hw-gfx-dp_aux_ch.adb b/common/hw-gfx-dp_aux_ch.adb
index b8eb510..7406d5e 100644
--- a/common/hw-gfx-dp_aux_ch.adb
+++ b/common/hw-gfx-dp_aux_ch.adb
@@ -371,6 +371,42 @@

----------------------------------------------------------------------------

+ procedure I2C_Write_Byte
+ (Port : in T;
+ Address : in I2C.Transfer_Address;
+ Offset : in Word8;
+ Value : in Word8;
+ Success : out Boolean)
+ is
+ Index_Payload : constant DP_Defs.Aux_Payload := (Offset, Value, others => 16#00#);
+
+ Length : constant I2C.Transfer_Length := 1;
+ Data : constant I2C.Transfer_Data := (Value, others => 16#00#);
+ begin
+ Do_I2C_Write (Port, Address, 1 + Length, Index_Payload, Success);
+ end I2C_Write_Byte;
+
+ procedure I2C_Read_Byte
+ (Port : in T;
+ Address : in I2C.Transfer_Address;
+ Offset : in Word8;
+ Value : out Word8;
+ Success : out Boolean)
+ is
+ Index_Payload : constant DP_Defs.Aux_Payload := (Offset, others => 16#00#);
+
+ Length : I2C.Transfer_Length := 1;
+ Data : I2C.Transfer_Data := (others => 16#00#);
+ begin
+ Do_I2C_Write (Port, Address, 1, Index_Payload, Success);
+
+ if Success then
+ Do_I2C_Read (Port, Address, Length, Data, Success);
+ Success := Success and Length = 1;
+ end if;
+ Value := Data (0);
+ end I2C_Read_Byte;
+
procedure I2C_Read
(Port : in T;
Address : in I2C.Transfer_Address;
diff --git a/common/hw-gfx-dp_aux_ch.ads b/common/hw-gfx-dp_aux_ch.ads
index 85fddd0..78709a8 100644
--- a/common/hw-gfx-dp_aux_ch.ads
+++ b/common/hw-gfx-dp_aux_ch.ads
@@ -45,6 +45,20 @@

----------------------------------------------------------------------------

+ procedure I2C_Write_Byte
+ (Port : in T;
+ Address : in I2C.Transfer_Address;
+ Offset : in Word8;
+ Value : in Word8;
+ Success : out Boolean);
+
+ procedure I2C_Read_Byte
+ (Port : in T;
+ Address : in I2C.Transfer_Address;
+ Offset : in Word8;
+ Value : out Word8;
+ Success : out Boolean);
+
procedure I2C_Read
(Port : in T;
Address : in I2C.Transfer_Address;
diff --git a/common/hw-gfx-dp_info.adb b/common/hw-gfx-dp_info.adb
index bf09933..93a1caf 100644
--- a/common/hw-gfx-dp_info.adb
+++ b/common/hw-gfx-dp_info.adb
@@ -15,15 +15,115 @@
with Ada.Unchecked_Conversion;

with HW.Debug;
+with HW.Time;
with GNAT.Source_Info;

with HW.GFX.DP_Defs;
+with HW.GFX.I2C;

use type HW.Word8;
use type HW.Word16;

package body HW.GFX.DP_Info is

+ procedure Read_Lspcon_Mode
+ (Port : in T;
+ Mode : out Word8;
+ Success : out Boolean)
+ is
+ begin
+ pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
+
+ for I in 1 .. 6 loop
+ Aux_Ch.I2C_Read_Byte
+ (Port => Port,
+ Address => 16#40#,
+ Offset => 16#41#,
+ Value => Mode,
+ Success => Success);
+ exit when Success;
+ Time.U_Delay (500);
+ end loop;
+ end Read_Lspcon_Mode;
+
+ procedure Write_Lspcon_Mode
+ (Port : in T;
+ Mode : in Word8;
+ Success : out Boolean)
+ is
+ begin
+ pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
+
+ for I in 1 .. 6 loop
+ Aux_Ch.I2C_Write_Byte
+ (Port => Port,
+ Address => 16#40#,
+ Offset => 16#40#,
+ Value => 16#01#,
+ Success => Success);
+ exit when Success;
+ Time.U_Delay (500);
+ end loop;
+ end Write_Lspcon_Mode;
+
+ procedure Set_Lspcon_To_Pcon_Mode (Port : in T; Success : out Boolean)
+ is
+ Timeout : constant Natural := 20;
+ Lspcon_Mode : Word8;
+ begin
+ pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
+
+ Read_Lspcon_Mode
+ (Port => Port,
+ Mode => Lspcon_Mode,
+ Success => Success);
+
+ if not Success then
+ pragma Debug (Debug.Put_Line ("Could not determine LSPCON mode."));
+ return;
+ end if;
+
+ pragma Debug (Debug.Put_Line ("Current LSPCON mode: " & Lspcon_Mode'Image));
+
+ if Lspcon_Mode /= 0 then
+ pragma Debug (Debug.Put_Line ("LSPCON mode is good enough."));
+ return;
+ end if;
+
+ -- Change to PCON mode if necessary
+ Write_Lspcon_Mode
+ (Port => Port,
+ Mode => Lspcon_Mode,
+ Success => Success);
+
+ if not Success then
+ pragma Debug (Debug.Put_Line ("Could not write new LSPCON mode."));
+ return;
+ end if;
+
+ for I in 1 .. Timeout loop
+ Read_Lspcon_Mode
+ (Port => Port,
+ Mode => Lspcon_Mode,
+ Success => Success);
+ if not Success then
+ pragma Debug (Debug.Put_Line ("Could not determine new LSPCON mode."));
+ return;
+ end if;
+ if Lspcon_Mode /= 0 then
+ pragma Debug (Debug.Put_Line ("Successfully set LSPCON to PCON mode."));
+ pragma Debug (Debug.Put_Line ("Current LSPCON mode: " & Lspcon_Mode'Image));
+ return;
+ end if;
+ Time.M_Delay (100);
+ end loop;
+ if Success then
+ pragma Debug (Debug.Put_Line ("Timed out waiting for LSPCON mode change."));
+ pragma Debug (Debug.Put_Line ("Current LSPCON mode: " & Lspcon_Mode'Image));
+ Success := False;
+ end if;
+ end Set_Lspcon_To_Pcon_Mode;
+
procedure Read_Caps
(Link : in out DP_Link;
Port : in T;
@@ -36,6 +136,12 @@
begin
pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));

+ Set_Lspcon_To_Pcon_Mode (Port, Success);
+
+ if not Success then
+ pragma Debug (Debug.Put_Line ("Could not change LSPCON mode."));
+ end if;
+
Length := Caps_Size;
Aux_Ch.Aux_Read
(Port => Port,

To view, visit change 46631. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: libgfxinit
Gerrit-Branch: master
Gerrit-Change-Id: I3c9e67caf9511d62b19c0c175e8e75080fb7ac7d
Gerrit-Change-Number: 46631
Gerrit-PatchSet: 1
Gerrit-Owner: Angel Pons <th3fanbus@gmail.com>
Gerrit-MessageType: newchange