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/hw-gfx-gma-registers.adb b/common/hw-gfx-gma-registers.adb
index eb12b0d..a59a4f7 100644
--- a/common/hw-gfx-gma-registers.adb
+++ b/common/hw-gfx-gma-registers.adb
@@ -45,13 +45,19 @@
 
    ----------------------------------------------------------------------------
 
+   MMIO_GTT_32_Size : constant := 16#20_0000#;
+   -- Limit Broadwell+ to 4MiB to have a stable
+   -- interface (i.e. same number of entries):
+   MMIO_GTT_64_Size : constant := 16#40_0000#;
+
    type GTT_PTE_32 is mod 2 ** 32;
    type GTT_Registers_32 is array (GTT_Range) of GTT_PTE_32
    with
       Volatile_Components,
       Size => MMIO_GTT_32_Size * 8;
    package GTT_32 is new MMIO_Range
-     (Base_Addr   => Config.Default_MMIO_Base + MMIO_GTT_32_Offset,
+     (Base_Addr   =>
+        Config.Default_MMIO_Base + Word64 (Config.Default_MMIO_GTT_32_Offset),
       Element_T   => GTT_PTE_32,
       Index_T     => GTT_Range,
       Array_T     => GTT_Registers_32);
@@ -62,7 +68,7 @@
       Volatile_Components,
       Size => MMIO_GTT_64_Size * 8;
    package GTT_64 is new MMIO_Range
-     (Base_Addr   => Config.Default_MMIO_Base + MMIO_GTT_64_Offset,
+     (Base_Addr   => Config.Default_MMIO_Base + Word64 (Config.MMIO_GTT_64_Offset),
       Element_T   => GTT_PTE_64,
       Index_T     => GTT_Range,
       Array_T     => GTT_Registers_64);
@@ -347,6 +353,14 @@
       pragma Debug (Verbose, Debug.Put_Line (Registers_Index'Image (Register)));
    end Read;
 
+   procedure Read_AUD_VID_DID (Value : out Word32)
+   is
+   begin
+      Regs.Read
+        (Value,
+         Registers_Range (Config.AUD_VID_DID_Offset / Register_Width));
+   end Read_AUD_VID_DID;
+
    ----------------------------------------------------------------------------
 
    -- Read a specific register to post a previous write
@@ -566,8 +580,9 @@
    begin
       Regs.Set_Base_Address (Base);
       if GTT_Base = 0 then
-         GTT_32.Set_Base_Address (Base + MMIO_GTT_32_Offset);
-         GTT_64.Set_Base_Address (Base + MMIO_GTT_64_Offset);
+         GTT_32.Set_Base_Address
+           (Base + Word64 (Config.Default_MMIO_GTT_32_Offset));
+         GTT_64.Set_Base_Address (Base + Word64 (Config.MMIO_GTT_64_Offset));
       else
          GTT_32.Set_Base_Address (GTT_Base);
          GTT_64.Set_Base_Address (GTT_Base);