gma pch lvds: Fully initialize port register

This very stale code only ever worked because it left old settings in-
tact (i.e. settings done by the Video BIOS). So initialize everything
needed for known LVDS displays to work.

TEST=none so far

Change-Id: If5dcc186ca1d4a07deb2ca78f018d613f5e029ad
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/17022
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
diff --git a/TODO b/TODO
index 7efa9e1..71b578a 100644
--- a/TODO
+++ b/TODO
@@ -2,4 +2,4 @@
 medium	DP	honor adjust requests also if training succeeded?
 unknown	DP	honor SINK_STATUS after training
 
-low	LVDS	sync polarity, 8bit colors, data format???
+low	LVDS	8bit colors, data format???
diff --git a/common/ironlake/hw-gfx-gma-pch-lvds.adb b/common/ironlake/hw-gfx-gma-pch-lvds.adb
index 6ad334e..9867b2f 100644
--- a/common/ironlake/hw-gfx-gma-pch-lvds.adb
+++ b/common/ironlake/hw-gfx-gma-pch-lvds.adb
@@ -1,5 +1,6 @@
 --
 -- Copyright (C) 2015-2016 secunet Security Networks AG
+-- Copyright (C) 2016 Nico Huber <nico.h@gmx.de>
 --
 -- 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
@@ -19,30 +20,44 @@
 
 package body HW.GFX.GMA.PCH.LVDS is
 
-   PCH_LVDS_ENABLE               : constant :=  1 * 2 ** 31;
-   PCH_LVDS_TWO_CHANNEL          : constant := 15 * 2 **  2;
-
-   PCH_LVDS_MASK : constant Word32 :=
-      PCH_TRANSCODER_SELECT_MASK or
-      PCH_LVDS_ENABLE or
-      PCH_LVDS_TWO_CHANNEL;
+   PCH_LVDS_ENABLE                     : constant :=  1 * 2 ** 31;
+   PCH_LVDS_VSYNC_POLARITY_INVERT      : constant :=  1 * 2 ** 21;
+   PCH_LVDS_HSYNC_POLARITY_INVERT      : constant :=  1 * 2 ** 20;
+   PCH_LVDS_CLK_A_DATA_A0A2_POWER_MASK : constant :=  3 * 2 **  8;
+   PCH_LVDS_CLK_A_DATA_A0A2_POWER_DOWN : constant :=  0 * 2 **  8;
+   PCH_LVDS_CLK_A_DATA_A0A2_POWER_UP   : constant :=  3 * 2 **  8;
+   PCH_LVDS_CLK_B_POWER_MASK           : constant :=  3 * 2 **  4;
+   PCH_LVDS_CLK_B_POWER_DOWN           : constant :=  0 * 2 **  4;
+   PCH_LVDS_CLK_B_POWER_UP             : constant :=  3 * 2 **  4;
+   PCH_LVDS_DATA_B0B2_POWER_MASK       : constant :=  3 * 2 **  2;
+   PCH_LVDS_DATA_B0B2_POWER_DOWN       : constant :=  0 * 2 **  2;
+   PCH_LVDS_DATA_B0B2_POWER_UP         : constant :=  3 * 2 **  2;
 
    ----------------------------------------------------------------------------
 
    procedure On (Port_Cfg : Port_Config; FDI_Port : FDI_Port_Type)
    is
+      Sync_Polarity : constant Word32 :=
+        (if Port_Cfg.Mode.H_Sync_Active_High then 0
+         else PCH_LVDS_HSYNC_POLARITY_INVERT) or
+        (if Port_Cfg.Mode.V_Sync_Active_High then 0
+         else PCH_LVDS_VSYNC_POLARITY_INVERT);
+
       Two_Channel : constant Word32 :=
         (if Port_Cfg.Mode.Dotclock >= Config.LVDS_Dual_Threshold then
-            PCH_LVDS_TWO_CHANNEL else 0);
+            PCH_LVDS_CLK_B_POWER_UP or PCH_LVDS_DATA_B0B2_POWER_UP else 0);
    begin
       pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
+      pragma Debug (Port_Cfg.Mode.BPC /= 6, Debug.Put_Line
+        ("WARNING: Only 18bpp LVDS mode implemented."));
 
-      Registers.Unset_And_Set_Mask
-         (Register   => Registers.PCH_LVDS,
-          Mask_Unset => PCH_LVDS_MASK,
-          Mask_Set   => PCH_LVDS_ENABLE or
-                        PCH_TRANSCODER_SELECT (FDI_Port) or
-                        Two_Channel);
+      Registers.Write
+        (Register => Registers.PCH_LVDS,
+         Value    => PCH_LVDS_ENABLE or
+                     PCH_TRANSCODER_SELECT (FDI_Port) or
+                     Sync_Polarity or
+                     PCH_LVDS_CLK_A_DATA_A0A2_POWER_UP or
+                     Two_Channel);
    end On;
 
    ----------------------------------------------------------------------------
@@ -52,7 +67,11 @@
    begin
       pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
 
-      Registers.Unset_Mask (Registers.PCH_LVDS, PCH_LVDS_ENABLE);
+      Registers.Write
+        (Register => Registers.PCH_LVDS,
+         Value    => PCH_LVDS_CLK_A_DATA_A0A2_POWER_DOWN or
+                     PCH_LVDS_CLK_B_POWER_DOWN or
+                     PCH_LVDS_DATA_B0B2_POWER_DOWN);
    end Off;
 
 end HW.GFX.GMA.PCH.LVDS;