gma: Automatically update CDClk and dot clocks
Dot clocks should be limited, depending on CDClk. This comes with a
caveat: if a display only works at a specific refresh rate, we will
likely fail without knowing. It seems to be better, though, to try
at least. We can implement a config switch controlling this beha-
viour, later, if needed.
If we can raise / lower CDClk with a given set of dot clocks, we
have to disable all pipes first, then switch CDClk, and finally
enable all pipes with their new configuration.
Calling Update_Outputs() with all pipe configs disabled may disable
the CDClk. So we have to ensure it is enabled when trying to probe
for displays.
Change-Id: I375f2bd37c921cd5ed4b0094247df5a34a087188
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/c/libgfxinit/+/35719
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
diff --git a/common/hw-gfx-gma-display_probing.adb b/common/hw-gfx-gma-display_probing.adb
index d21b277..74e2ad8 100644
--- a/common/hw-gfx-gma-display_probing.adb
+++ b/common/hw-gfx-gma-display_probing.adb
@@ -63,12 +63,13 @@
for I in 1 .. 2 loop
if Config_Helpers.To_Display_Type (Port) = DP then
- -- May need power to read edid
+ -- May need power and CDClk to read EDID
declare
Temp_Configs : Pipe_Configs := Cur_Configs;
begin
Temp_Configs (Primary).Port := Port;
Power_And_Clocks.Power_Up (Cur_Configs, Temp_Configs);
+ Power_And_Clocks.Enable_CDClk;
end;
declare
diff --git a/common/hw-gfx-gma.adb b/common/hw-gfx-gma.adb
index 3221e3e..8d58841 100644
--- a/common/hw-gfx-gma.adb
+++ b/common/hw-gfx-gma.adb
@@ -223,6 +223,7 @@
Display_Controller.Null_Scaler_Reservation;
Update_Power : Boolean := False;
+ Update_CDClk : Boolean;
Old_Configs,
New_Configs : Pipe_Configs;
@@ -280,6 +281,10 @@
(New_Configs (P).Framebuffer, New_Configs (P).Mode));
end loop;
+ -- limit dotclocks to maximum CDClk, if we are about
+ -- to switch CDClk, all pipes have to be disabled
+ Power_And_Clocks.Limit_Dotclocks (New_Configs, Update_CDClk);
+
-- disable all pipes that changed or had a hot-plug event
for Pipe in Pipe_Index loop
declare
@@ -290,7 +295,10 @@
if Cur_Config.Port /= Disabled then
Check_HPD (Cur_Config.Port, Unplug_Detected);
- if Full_Update (Cur_Config, New_Config) or Unplug_Detected then
+ if Update_CDClk or
+ Unplug_Detected or
+ Full_Update (Cur_Config, New_Config)
+ then
Disable_Output (Pipe, Cur_Config);
Cur_Config.Port := Disabled;
Update_Power := True;
@@ -299,6 +307,11 @@
end;
end loop;
+ -- switch CDClk if necessary and possible, limit dotclocks accordingly
+ if Update_CDClk then
+ Power_And_Clocks.Update_CDClk (New_Configs);
+ end if;
+
-- enable all pipes that changed and should be active
for Pipe in Pipe_Index loop
declare