gma g45: Add support for Intel GM965 (Crestline)

Add GM965 as a new CPU type under the G45 generation. GM965 shares
the GMCH display architecture with G45/GM45 (no PCH, same connector
registers) but differs in PLL limits, VCO/CDClk tables, and register
field encoding.

Key differences from G45/GM45:
 - PLL limits: Uses i9xx limits (VCO 1.4-2.8 GHz) instead of g4x
   limits. Add I9XX_LVDS_Limits; refactor Calculate_Clock_Parameters
   to take Limits as a parameter, with a new Select_Limits function.
 - VCO: Uses Crestline (CL) VCO tables with different frequencies
   and divisors than GM45's Cantiga (CTG) tables.
 - CDClk: GCFGC register decoding uses bits 12:8 minus 1 (3 possible
   divisor selections), unlike GM45's single bit 12.
 - No native DisplayPort (SDVO B/C only).
 - No HD Audio (G4X_AUD_VID_DID reads as 0).
 - Has integrated LVDS transmitter (mobile platform).
 - PCI IDs: 0x2a02 (I965_GM), 0x2a12 (I965_GME).

All implementation details cross-referenced against the Linux kernel
i915 driver (intel_dpll.c, intel_cdclk.c, intel_display_device.c).

Change-Id: I0d5d698cc1c2aa84778f0fc6c2752cb5ce4f1cb2
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.sourcearcade.org/c/libgfxinit/+/499
Reviewed-by: Nico Huber <nico.h@gmx.de>
Tested-by: Nico Huber <nico.h@gmx.de>
diff --git a/common/g45/hw-gfx-gma-port_detect.adb b/common/g45/hw-gfx-gma-port_detect.adb
index 45ed2dd..6fdb527 100644
--- a/common/g45/hw-gfx-gma-port_detect.adb
+++ b/common/g45/hw-gfx-gma-port_detect.adb
@@ -74,25 +74,27 @@
 
    begin
       Config.Valid_Port (Analog) := True;
-      Config.Valid_Port (LVDS)   := Config.GMCH_GM45;
-      for HDMI_Port in GMCH_HDMI_Port loop
-         Registers.Is_Set_Mask
-           (Register => GMCH_HDMI (HDMI_Port),
-            Mask     => PORT_DETECTED,
-            Result   => Detected);
-         Config.Valid_Port (To_HDMI_Port (HDMI_Port)) := Detected;
-         hotplug_mask_set := hotplug_mask_set or
-           (if Detected then HDMI_PORT_HOTPLUG_EN (HDMI_Port) else 0);
-      end loop;
-      for DP_Port in GMCH_DP_Port loop
-         Registers.Is_Set_Mask
-           (Register => GMCH_DP (DP_Port),
-            Mask     => PORT_DETECTED,
-            Result   => Detected);
-         Config.Valid_Port (To_DP_Port (DP_Port)) := Detected;
-         hotplug_mask_set := hotplug_mask_set or
-           (if Detected then DP_PORT_HOTPLUG_EN (DP_Port) else 0);
-      end loop;
+      Config.Valid_Port (LVDS)   := Config.GMCH_GM45 or Config.GMCH_GM965;
+      if not Config.GMCH_GM965 then
+         for HDMI_Port in GMCH_HDMI_Port loop
+            Registers.Is_Set_Mask
+              (Register => GMCH_HDMI (HDMI_Port),
+               Mask     => PORT_DETECTED,
+               Result   => Detected);
+            Config.Valid_Port (To_HDMI_Port (HDMI_Port)) := Detected;
+            hotplug_mask_set := hotplug_mask_set or
+              (if Detected then HDMI_PORT_HOTPLUG_EN (HDMI_Port) else 0);
+         end loop;
+         for DP_Port in GMCH_DP_Port loop
+            Registers.Is_Set_Mask
+              (Register => GMCH_DP (DP_Port),
+               Mask     => PORT_DETECTED,
+               Result   => Detected);
+            Config.Valid_Port (To_DP_Port (DP_Port)) := Detected;
+            hotplug_mask_set := hotplug_mask_set or
+              (if Detected then DP_PORT_HOTPLUG_EN (DP_Port) else 0);
+         end loop;
+      end if;
       Registers.Write
         (Register => Registers.PORT_HOTPLUG_EN,
          Value => hotplug_mask_set);