gma config_helpers: Add dot-clock helper functions

Highest_Dotclock() returns the highest dot clock in a set of
pipe configurations.

Limit_Dotclocks() reduces any dot clock to the given maximum
if it exceeds the latter. To prove that Limit_Dotclocks() only
changes timing, we introduce Stable_FB().

Change-Id: Iaa25e774d38c7af12150523739d902cf8e758674
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/c/libgfxinit/+/35529
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
diff --git a/common/hw-gfx-gma-config_helpers.ads b/common/hw-gfx-gma-config_helpers.ads
index 7bbf423..f02b6e5 100644
--- a/common/hw-gfx-gma-config_helpers.ads
+++ b/common/hw-gfx-gma-config_helpers.ads
@@ -60,4 +60,25 @@
    with
       Post => (if Validate_Config'Result then Valid_FB (FB, Mode));
 
+   -- For still active pipes, ensure only timings
+   -- changed that don't affect FB validity.
+   function Stable_FB (Old_C, New_C : Pipe_Configs) return Boolean is
+     (for all P in Pipe_Index =>
+         New_C (P).Port = Disabled or
+           (New_C (P).Port = Old_C (P).Port and
+            New_C (P).Framebuffer = Old_C (P).Framebuffer and
+            New_C (P).Cursor = Old_C (P).Cursor and
+            New_C (P).Mode.H_Visible = Old_C (P).Mode.H_Visible and
+            New_C (P).Mode.V_Visible = Old_C (P).Mode.V_Visible));
+
+   ----------------------------------------------------------------------------
+
+   function Highest_Dotclock (Configs : Pipe_Configs) return Frequency_Type;
+
+   procedure Limit_Dotclocks
+     (Configs  : in out Pipe_Configs;
+      Max      : in     Frequency_Type)
+   with
+      Post => Stable_FB (Configs'Old, Configs);
+
 end HW.GFX.GMA.Config_Helpers;