gma: Validate maximum scalable width

Change-Id: Iba8199a2451e1976ac8aa0f8632d0846fc0caeb4
Signed-off-by: Nico Huber <nico.huber@secunet.com>
Reviewed-on: https://review.coreboot.org/17261
Tested-by: Nico Huber <nico.h@gmx.de>
Reviewed-by: Martin Roth <martinroth@google.com>
diff --git a/common/hw-gfx-gma-config.ads.template b/common/hw-gfx-gma-config.ads.template
index 1ba66a2..7a83e77 100644
--- a/common/hw-gfx-gma-config.ads.template
+++ b/common/hw-gfx-gma-config.ads.template
@@ -228,4 +228,22 @@
                                  24_000_000),
          when Skylake      => 24_000_000);
 
+   ----------------------------------------------------------------------------
+
+   -- Maximum source width with enabled scaler. This only accounts
+   -- for simple 1:1 pipe:scaler mappings.
+
+   type Width_Per_Pipe is array (Config_Index) of Width_Type;
+
+   Maximum_Scalable_Width : constant Width_Per_Pipe :=
+     (case CPU is
+         when Ironlake..Haswell =>
+           (Primary     => 4096,
+            Secondary   => 2048,
+            Tertiary    => 2048),
+         when Broadwell..Skylake =>
+           (Primary     => 4096,
+            Secondary   => 4096,
+            Tertiary    => 4096));
+
 end HW.GFX.GMA.Config;
diff --git a/common/hw-gfx-gma.adb b/common/hw-gfx-gma.adb
index 1c0919f..691b775 100644
--- a/common/hw-gfx-gma.adb
+++ b/common/hw-gfx-gma.adb
@@ -179,17 +179,22 @@
 
    function Validate_Config
      (Framebuffer : Framebuffer_Type;
-      Port_Cfg    : Port_Config)
+      Port_Cfg    : Port_Config;
+      I           : Config_Index)
       return Boolean
    with Global => null
    is
    begin
       -- No downscaling
+      -- Respect maximum scalable width
       -- Only 32bpp RGB
       -- Stride must be a multiple of 64
       return
-         Framebuffer.Width <= Pos32 (Port_Cfg.Mode.H_Visible) and
-         Framebuffer.Height <= Pos32 (Port_Cfg.Mode.V_Visible) and
+         ((Framebuffer.Width = Pos32 (Port_Cfg.Mode.H_Visible) and
+           Framebuffer.Height = Pos32 (Port_Cfg.Mode.V_Visible)) or
+          (Framebuffer.Width <= Config.Maximum_Scalable_Width (I) and
+           Framebuffer.Width <= Pos32 (Port_Cfg.Mode.H_Visible) and
+           Framebuffer.Height <= Pos32 (Port_Cfg.Mode.V_Visible))) and
          Framebuffer.BPC = 8 and
          Framebuffer.Stride mod 64 = 0;
    end Validate_Config;
@@ -542,7 +547,7 @@
                Fill_Port_Config (Port_Cfg, Configs, I, Success);
 
                Success := Success and then
-                           Validate_Config (New_Config.Framebuffer, Port_Cfg);
+                          Validate_Config (New_Config.Framebuffer, Port_Cfg, I);
 
                if Success and then Wait_For_HPD (New_Config.Port) then
                   Check_HPD (Port_Cfg, New_Config.Port, Success);