gma: Fix Ironlake panel fitting

Hardware doesn't like minimal horizontal gaps. Scale to full width if
the difference is at most three pixels.

Also, don't scale to odd widths. At least Haswell doesn't like it.

Change-Id: Ic1484eda0f6022cd8a37611fdfb9d2c50b390b72
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/26647
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
diff --git a/common/hw-gfx-gma-pipe_setup.adb b/common/hw-gfx-gma-pipe_setup.adb
index 4544e73..1ba4ee0 100644
--- a/common/hw-gfx-gma-pipe_setup.adb
+++ b/common/hw-gfx-gma-pipe_setup.adb
@@ -1,5 +1,5 @@
 --
--- Copyright (C) 2015-2016 secunet Security Networks AG
+-- Copyright (C) 2015-2018 secunet Security Networks AG
 --
 -- This program is free software; you can redistribute it and/or modify
 -- it under the terms of the GNU General Public License as published by
@@ -403,6 +403,7 @@
                when others              => 0) else 0);
 
       Width, Height : Pos32;
+      X, Y : Int32;
    begin
       -- Writes to WIN_SZ arm the PF registers.
 
@@ -413,14 +414,26 @@
          Max_Height  => Pos32 (Mode.V_Visible),
          Framebuffer => Framebuffer);
 
+      -- Do not scale to odd width (at least Haswell has trouble with this).
+      if Width < Pos32 (Mode.H_Visible) and Width mod 2 = 1 then
+         Width := Width + 1;
+      end if;
+
+      X := (Int32 (Mode.H_Visible) - Width) / 2;
+      Y := (Int32 (Mode.V_Visible) - Height) / 2;
+
+      -- Hardware is picky about minimal horizontal gaps.
+      if Pos32 (Mode.H_Visible) - Width <= 3 then
+         Width := Pos32(Mode.H_Visible);
+         X := 0;
+      end if;
+
       Registers.Write
         (Register => Controller.PF_CTRL,
          Value    => PF_CTRL_ENABLE or PF_Ctrl_Pipe_Sel or PF_CTRL_FILTER_MED);
       Registers.Write
         (Register => Controller.PF_WIN_POS,
-         Value    =>
-            Shift_Left (Word32 (Pos32 (Mode.H_Visible) - Width) / 2, 16) or
-            Word32 (Pos32 (Mode.V_Visible) - Height) / 2);
+         Value    => Shift_Left (Word32 (X), 16) or Word32 (Y));
       Registers.Write
         (Register => Controller.PF_WIN_SZ,
          Value    => Shift_Left (Word32 (Width), 16) or Word32 (Height));