Nico Huber has uploaded this change for review. ( https://review.coreboot.org/c/libgfxinit/+/35528 )
Change subject: gma: Refactor Update_Outputs() ......................................................................
gma: Refactor Update_Outputs()
In Update_Outputs(), we used to have two steps, iterating over all available pipes: We disabled all pipes whose mode changed or that would be disabled otherwise. Then, we enabled all pipes with new modes.
As checks for validity of the configurations were only done on demand in the second step, that left us with no knowledge about what configs would actually be tried. To make this information available for future work, we add a validation in between the existing two. That gives us:
1. Disable pipes - whose mode changed - that were disconneced 2. Validate all new configs 3. Enable/update pipes with new configs
This way, we can make global decisions between 2. and 3. based on the new, _valid_ configurations.
The `Loop_Invariant` of 2. allows us to keep the validation in mind, to satisfy pre-conditions of the various steps ahead.
Change-Id: I079ae8f85c821a272b5d095c1ef437ee804aa9ac Signed-off-by: Nico Huber nico.h@gmx.de --- M common/hw-gfx-gma-config_helpers.ads M common/hw-gfx-gma.adb 2 files changed, 60 insertions(+), 50 deletions(-)
git pull ssh://review.coreboot.org:29418/libgfxinit refs/changes/28/35528/1
diff --git a/common/hw-gfx-gma-config_helpers.ads b/common/hw-gfx-gma-config_helpers.ads index 023b3e5..a2aeb06 100644 --- a/common/hw-gfx-gma-config_helpers.ads +++ b/common/hw-gfx-gma-config_helpers.ads @@ -33,7 +33,12 @@ Pipe : in Pipe_Index; Port : in Port_Type; Mode : in Mode_Type; - Success : out Boolean); + Success : out Boolean) + with + Post => + (if Success then + Port_Cfg.Mode.H_Visible = Mode.H_Visible and + Port_Cfg.Mode.V_Visible = Mode.V_Visible);
----------------------------------------------------------------------------
diff --git a/common/hw-gfx-gma.adb b/common/hw-gfx-gma.adb index de79fd3..462f5c4 100644 --- a/common/hw-gfx-gma.adb +++ b/common/hw-gfx-gma.adb @@ -96,10 +96,11 @@ Pipe_Cfg : in Pipe_Config; Success : out Boolean) with - Pre => Pipe_Cfg.Port in Active_Port_Type + Pre => + Pipe_Cfg.Port in Active_Port_Type and + Config_Helpers.Valid_FB (Pipe_Cfg.Framebuffer, Pipe_Cfg.Mode, Pipe) is Port_Cfg : Port_Config; - Scaler_Available : Boolean; begin pragma Debug (Debug.New_Line); pragma Debug (Debug.Put_Line @@ -109,12 +110,6 @@ (Port_Cfg, Pipe, Pipe_Cfg.Port, Pipe_Cfg.Mode, Success);
if Success then - Display_Controller.Scaler_Available (Scaler_Available, Pipe); - Success := Config_Helpers.Valid_Config - (Pipe_Cfg.Framebuffer, Port_Cfg.Mode, Pipe, Scaler_Available); - end if; - - if Success then Connector_Info.Preferred_Link_Setting (Port_Cfg, Success); end if;
@@ -221,19 +216,9 @@ end if; end Check_HPD;
- Power_Changed : Boolean := False; - Old_Configs : Pipe_Configs; - - -- Only called when we actually tried to change something - -- so we don't congest the log with unnecessary messages. - procedure Update_Power - is - begin - if not Power_Changed then - Power_And_Clocks.Power_Up (Old_Configs, Configs); - Power_Changed := True; - end if; - end Update_Power; + Update_Power : Boolean := False; + Old_Configs, + New_Configs : Pipe_Configs;
function Full_Update (Cur_Config, New_Config : Pipe_Config) return Boolean is @@ -253,13 +238,14 @@ end Full_Update; begin Old_Configs := Cur_Configs; + New_Configs := Configs;
-- disable all pipes that changed or had a hot-plug event for Pipe in Pipe_Index loop declare Unplug_Detected : Boolean; Cur_Config : Pipe_Config renames Cur_Configs (Pipe); - New_Config : Pipe_Config renames Configs (Pipe); + New_Config : Pipe_Config renames New_Configs (Pipe); begin if Cur_Config.Port /= Disabled then Check_HPD (Cur_Config.Port, Unplug_Detected); @@ -267,35 +253,60 @@ if Full_Update (Cur_Config, New_Config) or Unplug_Detected then Disable_Output (Pipe, Cur_Config); Cur_Config.Port := Disabled; - Update_Power; + Update_Power := True; end if; end if; end; end loop;
+ -- validate new configs, filter invalid configs and those waiting for HPD + for Pipe in Pipe_Index loop + declare + Success : Boolean := True; + Scaler_Available : Boolean; + Cur_Config : Pipe_Config renames Cur_Configs (Pipe); + New_Config : Pipe_Config renames New_Configs (Pipe); + begin + if New_Config.Port /= Disabled then + if Wait_For_HPD (New_Config.Port) then + Check_HPD (New_Config.Port, Success); + Wait_For_HPD (New_Config.Port) := not Success; + end if; + + if Success then + Display_Controller.Scaler_Available (Scaler_Available, Pipe); + Success := Config_Helpers.Valid_Config + (New_Config.Framebuffer, New_Config.Mode, + Pipe, Scaler_Available); + end if; + + if not Success then + New_Config.Port := Disabled; + end if; + end if; + end; + pragma Loop_Invariant + (for all P in Pipe_Index'First .. Pipe => + New_Configs (P).Port = Disabled or + Config_Helpers.Valid_FB + (New_Configs (P).Framebuffer, New_Configs (P).Mode, P)); + end loop; + -- enable all pipes that changed and should be active for Pipe in Pipe_Index loop declare Success : Boolean; - Scaler_Available : Boolean; Cur_Config : Pipe_Config renames Cur_Configs (Pipe); - New_Config : Pipe_Config renames Configs (Pipe); + New_Config : Pipe_Config renames New_Configs (Pipe); begin + -- full update if New_Config.Port /= Disabled and Full_Update (Cur_Config, New_Config) then - if Wait_For_HPD (New_Config.Port) then - Check_HPD (New_Config.Port, Success); - Wait_For_HPD (New_Config.Port) := not Success; - else - Success := True; - end if; + Power_And_Clocks.Power_Up (Old_Configs, New_Configs); + Update_Power := True;
- if Success then - Update_Power; - Enable_Output (Pipe, New_Config, Success); - end if; - + Enable_Output (Pipe, New_Config, Success); if Success then Cur_Config := New_Config; end if; @@ -304,23 +315,17 @@ elsif New_Config.Port /= Disabled and Cur_Config.Framebuffer /= New_Config.Framebuffer then - Display_Controller.Scaler_Available (Scaler_Available, Pipe); - if Config_Helpers.Valid_Config - (New_Config.Framebuffer, New_Config.Mode, - Pipe, Scaler_Available) - then - Display_Controller.Setup_FB - (Pipe, New_Config.Mode, New_Config.Framebuffer); - Display_Controller.Update_Cursor - (Pipe, New_Config.Framebuffer, New_Config.Cursor); - Cur_Config := New_Config; - end if; + Display_Controller.Setup_FB + (Pipe, New_Config.Mode, New_Config.Framebuffer); + Display_Controller.Update_Cursor + (Pipe, New_Config.Framebuffer, New_Config.Cursor); + Cur_Config := New_Config; end if; end; end loop;
- if Power_Changed then - Power_And_Clocks.Power_Down (Old_Configs, Configs, Cur_Configs); + if Update_Power then + Power_And_Clocks.Power_Down (Old_Configs, New_Configs, Cur_Configs); end if; end Update_Outputs;