[haiku-commits] r42839 - in haiku/trunk: headers/private/graphics/intel_extreme src/add-ons/accelerants/intel_extreme src/add-ons/kernel/busses/agp_gart src/add-ons/kernel/drivers/graphics/intel_extreme

  • From: mmlr@xxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 13 Oct 2011 11:07:34 +0200 (CEST)

Author: mmlr
Date: 2011-10-13 11:07:33 +0200 (Thu, 13 Oct 2011)
New Revision: 42839
Changeset: https://dev.haiku-os.org/changeset/42839

Modified:
   haiku/trunk/headers/private/graphics/intel_extreme/intel_extreme.h
   haiku/trunk/src/add-ons/accelerants/intel_extreme/hooks.cpp
   haiku/trunk/src/add-ons/accelerants/intel_extreme/mode.cpp
   haiku/trunk/src/add-ons/kernel/busses/agp_gart/intel_gart.cpp
   haiku/trunk/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.cpp
   
haiku/trunk/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp
Log:
* Add preliminary support for one SandyBridge mobile integrated graphics device
  (the one in my new ThinkPad X1). The PLL is still off a bit so it has a few
  blurry stripes, but EDID and mode setting basically works.
* Starting with IronLake the north/south bridge or (G)MCH/ICH setup was moved
  into a platform control hub (PCH) which means that many registers previously
  located in the GMCH are now in the PCH and have a new address.
* I'm committing this mostly because this way the additions are more easy to
  follow. It is a bit messy and I'll clean it up more and possibly make it a
  bit more generic. Also most of these changes actually apply to IronLake and up
  and aren't SandyBridge specific, so a few of those additions will still get a
  broader scope and new chips will be added.


Modified: haiku/trunk/headers/private/graphics/intel_extreme/intel_extreme.h
===================================================================
--- haiku/trunk/headers/private/graphics/intel_extreme/intel_extreme.h  
2011-10-13 08:43:56 UTC (rev 42838)
+++ haiku/trunk/headers/private/graphics/intel_extreme/intel_extreme.h  
2011-10-13 09:07:33 UTC (rev 42839)
@@ -18,13 +18,13 @@
 
 #define VENDOR_ID_INTEL                        0x8086
 
-#define INTEL_TYPE_FAMILY_MASK 0xf000
-#define INTEL_TYPE_GROUP_MASK  0xfff0
-#define INTEL_TYPE_MODEL_MASK  0xffff
+#define INTEL_TYPE_FAMILY_MASK 0x000f0000
+#define INTEL_TYPE_GROUP_MASK  0x000ffff0
+#define INTEL_TYPE_MODEL_MASK  0x000fffff
 // families
-#define INTEL_TYPE_7xx                 0x1000
-#define INTEL_TYPE_8xx                 0x2000
-#define INTEL_TYPE_9xx                 0x4000
+#define INTEL_TYPE_7xx                 0x00010000
+#define INTEL_TYPE_8xx                 0x00020000
+#define INTEL_TYPE_9xx                 0x00040000
 // groups
 #define INTEL_TYPE_83x                 (INTEL_TYPE_8xx | 0x0010)
 #define INTEL_TYPE_85x                 (INTEL_TYPE_8xx | 0x0020)
@@ -34,6 +34,7 @@
 #define INTEL_TYPE_Gxx                 (INTEL_TYPE_9xx | 0x0200)
 #define INTEL_TYPE_G4x                 (INTEL_TYPE_9xx | 0x0400)
 #define INTEL_TYPE_IGD                 (INTEL_TYPE_9xx | 0x0800)
+#define INTEL_TYPE_SNB                 (INTEL_TYPE_9xx | 0x1000)
 // models
 #define INTEL_TYPE_MOBILE              0x0008
 #define INTEL_TYPE_915                 (INTEL_TYPE_91x)
@@ -47,6 +48,8 @@
 #define INTEL_TYPE_GM45                        (INTEL_TYPE_G4x | 
INTEL_TYPE_MOBILE)
 #define INTEL_TYPE_IGDG                        (INTEL_TYPE_IGD)
 #define INTEL_TYPE_IGDGM               (INTEL_TYPE_IGD | INTEL_TYPE_MOBILE)
+#define INTEL_TYPE_SNBG                        (INTEL_TYPE_SNB)
+#define INTEL_TYPE_SNBGM               (INTEL_TYPE_SNB | INTEL_TYPE_MOBILE)
 
 #define DEVICE_NAME                            "intel_extreme"
 #define INTEL_ACCELERANT_NAME  "intel_extreme.accelerant"
@@ -218,7 +221,60 @@
 #define G4X_STOLEN_MEMORY_224MB                        0xc0
 #define G4X_STOLEN_MEMORY_352MB                        0xd0
 
+// PCH - Platform Control Hub - Newer hardware moves from a MCH/ICH based setup
+// to a PCH based one, that means anything that used to communicate via (G)MCH
+// registers needs to use different ones on PCH based platforms (Ironlake and
+// up, SandyBridge, etc.).
+#define PCH_DE_INTERRUPT_ENABLE                        0x4400c // 
INTEL_INTERRUPT_ENABLED
+#define PCH_DISPLAY_A_ANALOG_PORT              0xe1100 // 
INTEL_DISPLAY_A_ANALOG_PORT
+#define PCH_DISPLAY_LVDS_PORT                  0xe1180 // 
INTEL_DISPLAY_LVDS_PORT
+#define PCH_I2C_IO_A                                   0xc5010 // 
INTEL_I2C_IO_A
+#define PCH_I2C_IO_C                                   0xc5018 // 
INTEL_I2C_IO_C
+#define PCH_DISPLAY_A_PLL                              0xc6014 // 
INTEL_DISPLAY_A_PLL
+#define PCH_DISPLAY_B_PLL                              0xc6018 // 
INTEL_DISPLAY_B_PLL
+#define PCH_DISPLAY_A_PLL_DIVISOR_0            0xc6040 // 
INTEL_DISPLAY_A_PLL_DIVISOR_0
+#define PCH_DISPLAY_A_PLL_DIVISOR_1            0xc6044 // 
INTEL_DISPLAY_A_PLL_DIVISOR_1
+#define PCH_DISPLAY_B_PLL_DIVISOR_0            0xc6048 // 
INTEL_DISPLAY_B_PLL_DIVISOR_0
+#define PCH_DISPLAY_B_PLL_DIVISOR_1            0xc604c // 
INTEL_DISPLAY_B_PLL_DIVISOR_1
+#define PCH_TRANSCODER_A_HTOTAL                        0xe0000 // 
INTEL_DISPLAY_A_HTOTAL
+#define PCH_TRANSCODER_A_HBLANK                        0xe0004 // 
INTEL_DISPLAY_A_HBLANK
+#define PCH_TRANSCODER_A_HSYNC                 0xe0008 // INTEL_DISPLAY_A_HSYNC
+#define PCH_TRANSCODER_A_VTOTAL                        0xe000c // 
INTEL_DISPLAY_A_VTOTAL
+#define PCH_TRANSCODER_A_VBLANK                        0xe0010 // 
INTEL_DISPLAY_A_VBLANK
+#define PCH_TRANSCODER_A_VSYNC                 0xe0014 // INTEL_DISPLAY_A_VSYNC
+#define PCH_TRANSCODER_B_HTOTAL                        0xe1000 // 
INTEL_DISPLAY_B_HTOTAL
+#define PCH_TRANSCODER_B_HBLANK                        0xe1004 // 
INTEL_DISPLAY_B_HBLANK
+#define PCH_TRANSCODER_B_HSYNC                 0xe1008 // INTEL_DISPLAY_B_HSYNC
+#define PCH_TRANSCODER_B_VTOTAL                        0xe100c // 
INTEL_DISPLAY_B_VTOTAL
+#define PCH_TRANSCODER_B_VBLANK                        0xe1010 // 
INTEL_DISPLAY_B_VBLANK
+#define PCH_TRANSCODER_B_VSYNC                 0xe1014 // INTEL_DISPLAY_B_VSYNC
 
+// SandyBridge (SNB)
+#define SNB_GRAPHICS_MEMORY_CONTROL            0x50
+
+#define SNB_STOLEN_MEMORY_MASK                 0xf8
+#define SNB_STOLEN_MEMORY_32MB                 (1 << 3)
+#define SNB_STOLEN_MEMORY_64MB                 (2 << 3)
+#define SNB_STOLEN_MEMORY_96MB                 (3 << 3)
+#define SNB_STOLEN_MEMORY_128MB                        (4 << 3)
+#define SNB_STOLEN_MEMORY_160MB                        (5 << 3)
+#define SNB_STOLEN_MEMORY_192MB                        (6 << 3)
+#define SNB_STOLEN_MEMORY_224MB                        (7 << 3)
+#define SNB_STOLEN_MEMORY_256MB                        (8 << 3)
+#define SNB_STOLEN_MEMORY_288MB                        (9 << 3)
+#define SNB_STOLEN_MEMORY_320MB                        (10 << 3)
+#define SNB_STOLEN_MEMORY_352MB                        (11 << 3)
+#define SNB_STOLEN_MEMORY_384MB                        (12 << 3)
+#define SNB_STOLEN_MEMORY_416MB                        (13 << 3)
+#define SNB_STOLEN_MEMORY_448MB                        (14 << 3)
+#define SNB_STOLEN_MEMORY_480MB                        (15 << 3)
+#define SNB_STOLEN_MEMORY_512MB                        (16 << 3)
+
+#define SNB_GTT_SIZE_MASK                              (3 << 8)
+#define SNB_GTT_SIZE_NONE                              (0 << 8)
+#define SNB_GTT_SIZE_1MB                               (1 << 8)
+#define SNB_GTT_SIZE_2MB                               (2 << 8)
+
 // graphics page translation table
 #define INTEL_PAGE_TABLE_CONTROL               0x02020
 #define PAGE_TABLE_ENABLED                             0x00000001

Modified: haiku/trunk/src/add-ons/accelerants/intel_extreme/hooks.cpp
===================================================================
--- haiku/trunk/src/add-ons/accelerants/intel_extreme/hooks.cpp 2011-10-13 
08:43:56 UTC (rev 42838)
+++ haiku/trunk/src/add-ons/accelerants/intel_extreme/hooks.cpp 2011-10-13 
09:07:33 UTC (rev 42839)
@@ -115,7 +115,8 @@
                                || 
gInfo->shared_info->device_type.InGroup(INTEL_TYPE_94x)
                                || 
gInfo->shared_info->device_type.IsModel(INTEL_TYPE_965M)
                                || 
gInfo->shared_info->device_type.InGroup(INTEL_TYPE_G4x)
-                               || 
gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD))
+                               || 
gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD)
+                               || 
gInfo->shared_info->device_type.InGroup(INTEL_TYPE_SNB))
                                return NULL;
 
                        return (void*)intel_allocate_overlay_buffer;

Modified: haiku/trunk/src/add-ons/accelerants/intel_extreme/mode.cpp
===================================================================
--- haiku/trunk/src/add-ons/accelerants/intel_extreme/mode.cpp  2011-10-13 
08:43:56 UTC (rev 42838)
+++ haiku/trunk/src/add-ons/accelerants/intel_extreme/mode.cpp  2011-10-13 
09:07:33 UTC (rev 42839)
@@ -132,7 +132,8 @@
        }
 
        if (sharedInfo.device_type.InGroup(INTEL_TYPE_96x)
-               || sharedInfo.device_type.InGroup(INTEL_TYPE_G4x)) {
+               || sharedInfo.device_type.InGroup(INTEL_TYPE_G4x)
+               || sharedInfo.device_type.InGroup(INTEL_TYPE_SNB)) {
                write32(baseRegister, mode.v_display_start * 
sharedInfo.bytes_per_row
                        + mode.h_display_start * (sharedInfo.bits_per_pixel + 
7) / 8);
                read32(baseRegister);
@@ -153,8 +154,10 @@
 status_t
 create_mode_list(void)
 {
+       bool isSNB = gInfo->shared_info->device_type.InGroup(INTEL_TYPE_SNB);
+
        i2c_bus bus;
-       bus.cookie = (void*)INTEL_I2C_IO_A;
+       bus.cookie = (void*)(isSNB ? PCH_I2C_IO_A : INTEL_I2C_IO_A);
        bus.set_signals = &set_i2c_signals;
        bus.get_signals = &get_i2c_signals;
        ddc2_init_timing(&bus);
@@ -166,7 +169,7 @@
        } else {
                TRACE(("intel_extreme: getting EDID on port A (analog) failed : 
%s. "
                        "Trying on port C (lvds)\n", strerror(error)));
-               bus.cookie = (void*)INTEL_I2C_IO_C;
+               bus.cookie = (void*)(isSNB ? PCH_I2C_IO_C : INTEL_I2C_IO_C);
                error = ddc2_read_edid1(&bus, &gInfo->edid_info, NULL, NULL);
                if (error == B_OK) {
                        edid_dump(&gInfo->edid_info);
@@ -234,10 +237,19 @@
        // Note, the limits are taken from the X driver; they have not yet been
        // tested
 
-       if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_G4x)) {
+       if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_SNB)) {
                // TODO: support LVDS output limits as well
                static const pll_limits kLimits = {
                        // p, p1, p2, high,   n,   m, m1, m2
+                       {  5,  1, 10, false,  1,  79, 12,  5},  // min
+                       { 80,  8,  5, true,   5, 127, 22,  9},  // max
+                       225000, 1760000, 3510000
+               };
+               limits = kLimits;
+       } else if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_G4x)) {
+               // TODO: support LVDS output limits as well
+               static const pll_limits kLimits = {
+                       // p, p1, p2, high,   n,   m, m1, m2
                        { 10,  1, 10, false,  1, 104, 17,  5},  // min
                        { 30,  3, 10, true,   4, 138, 23, 11},  // max
                        270000, 1750000, 3500000
@@ -312,8 +324,12 @@
 
        TRACE(("required MHz: %g\n", requestedPixelClock));
 
+       bool isSNB = gInfo->shared_info->device_type.InGroup(INTEL_TYPE_SNB);
+
        if (isLVDS) {
-               if ((read32(INTEL_DISPLAY_LVDS_PORT) & LVDS_CLKB_POWER_MASK)
+               int targetRegister
+                       = isSNB ? PCH_DISPLAY_LVDS_PORT : 
INTEL_DISPLAY_LVDS_PORT;
+               if ((read32(targetRegister) & LVDS_CLKB_POWER_MASK)
                                == LVDS_CLKB_POWER_UP)
                        divisors.post2 = LVDS_POST2_RATE_FAST;
                else
@@ -402,6 +418,26 @@
                vSyncRegister = INTEL_DISPLAY_B_VSYNC;
                imageSizeRegister = INTEL_DISPLAY_B_IMAGE_SIZE;
                controlRegister = INTEL_DISPLAY_B_CONTROL;
+       } else if (pllRegister == PCH_DISPLAY_A_PLL) {
+               pllDivisor = read32((pll & DISPLAY_PLL_DIVISOR_1) != 0
+                       ? PCH_DISPLAY_A_PLL_DIVISOR_1 : 
PCH_DISPLAY_A_PLL_DIVISOR_0);
+
+               hTotalRegister = PCH_TRANSCODER_A_HTOTAL;
+               vTotalRegister = PCH_TRANSCODER_A_VTOTAL;
+               hSyncRegister = PCH_TRANSCODER_A_HSYNC;
+               vSyncRegister = PCH_TRANSCODER_A_VSYNC;
+               imageSizeRegister = INTEL_DISPLAY_A_IMAGE_SIZE;
+               controlRegister = INTEL_DISPLAY_A_CONTROL;
+       } else if (pllRegister == PCH_DISPLAY_B_PLL) {
+               pllDivisor = read32((pll & DISPLAY_PLL_DIVISOR_1) != 0
+                       ? PCH_DISPLAY_B_PLL_DIVISOR_1 : 
PCH_DISPLAY_B_PLL_DIVISOR_0);
+
+               hTotalRegister = PCH_TRANSCODER_B_HTOTAL;
+               vTotalRegister = PCH_TRANSCODER_B_VTOTAL;
+               hSyncRegister = PCH_TRANSCODER_B_HSYNC;
+               vSyncRegister = PCH_TRANSCODER_B_VSYNC;
+               imageSizeRegister = INTEL_DISPLAY_B_IMAGE_SIZE;
+               controlRegister = INTEL_DISPLAY_B_CONTROL;
        } else {
                // TODO: not supported
                return;
@@ -529,9 +565,12 @@
 void
 save_lvds_mode(void)
 {
+       bool isSNB = gInfo->shared_info->device_type.InGroup(INTEL_TYPE_SNB);
+
        // dump currently programmed mode.
        display_mode biosMode;
-       retrieve_current_mode(biosMode, INTEL_DISPLAY_B_PLL);
+       retrieve_current_mode(biosMode,
+               isSNB ? PCH_DISPLAY_B_PLL : INTEL_DISPLAY_B_PLL);
        gInfo->lvds_panel_mode = biosMode;
 }
 
@@ -645,7 +684,7 @@
        // centering, since the data from propose_display_mode will not 
actually be
        // used as is in this case.
        if (sanitize_display_mode(target)) {
-               TRACE(("intel_extreme: invalid mode set!"));
+               TRACE(("intel_extreme: invalid mode set!\n"));
                return B_BAD_VALUE;
        }
 
@@ -710,6 +749,9 @@
        write32(INTEL_VGA_DISPLAY_CONTROL, VGA_DISPLAY_DISABLED);
        read32(INTEL_VGA_DISPLAY_CONTROL);
 
+       bool isSNB = gInfo->shared_info->device_type.InGroup(INTEL_TYPE_SNB);
+       int targetRegister;
+
        if ((gInfo->head_mode & HEAD_MODE_B_DIGITAL) != 0) {
                // For LVDS panels, we actually always set the native mode in 
hardware
                // Then we use the panel fitter to scale the picture to that.
@@ -761,9 +803,11 @@
 
                // Compute bitmask from p1 value
                if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD)) {
-                       dpll |= (1 << (divisors.post1 - 1)) << 
DISPLAY_PLL_IGD_POST1_DIVISOR_SHIFT;
+                       dpll |= (1 << (divisors.post1 - 1))
+                               << DISPLAY_PLL_IGD_POST1_DIVISOR_SHIFT;
                } else {
-                       dpll |= (1 << (divisors.post1 - 1)) << 
DISPLAY_PLL_POST1_DIVISOR_SHIFT;
+                       dpll |= (1 << (divisors.post1 - 1))
+                               << DISPLAY_PLL_POST1_DIVISOR_SHIFT;
                }
                switch (divisors.post2) {
                        case 5:
@@ -785,7 +829,8 @@
                                        | (((divisors.m2 - 2) << 
DISPLAY_PLL_M2_DIVISOR_SHIFT)
                                                & 
DISPLAY_PLL_IGD_M2_DIVISOR_MASK));
                        } else {
-                               write32(INTEL_DISPLAY_B_PLL_DIVISOR_0,
+                               write32(isSNB ? PCH_DISPLAY_B_PLL_DIVISOR_0
+                                               : INTEL_DISPLAY_B_PLL_DIVISOR_0,
                                        (((divisors.n - 2) << 
DISPLAY_PLL_N_DIVISOR_SHIFT)
                                                & DISPLAY_PLL_N_DIVISOR_MASK)
                                        | (((divisors.m1 - 2) << 
DISPLAY_PLL_M1_DIVISOR_SHIFT)
@@ -793,13 +838,16 @@
                                        | (((divisors.m2 - 2) << 
DISPLAY_PLL_M2_DIVISOR_SHIFT)
                                                & DISPLAY_PLL_M2_DIVISOR_MASK));
                        }
-                       write32(INTEL_DISPLAY_B_PLL, dpll & 
~DISPLAY_PLL_ENABLED);
-                       read32(INTEL_DISPLAY_B_PLL);
+                       targetRegister = isSNB ? PCH_DISPLAY_B_PLL : 
INTEL_DISPLAY_B_PLL;
+                       write32(targetRegister, dpll & ~DISPLAY_PLL_ENABLED);
+                       read32(targetRegister);
                        spin(150);
                }
 
-               uint32 lvds = read32(INTEL_DISPLAY_LVDS_PORT)
-                       | LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | 
LVDS_PIPEB_SELECT;
+               targetRegister
+                       = isSNB ? PCH_DISPLAY_LVDS_PORT : 
INTEL_DISPLAY_LVDS_PORT;
+               uint32 lvds = read32(targetRegister) | LVDS_PORT_EN
+                       | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT;
 
                lvds |= LVDS_18BIT_DITHER;
                        // TODO: do not do this if the connected panel is 24-bit
@@ -815,8 +863,8 @@
                else
                        lvds &= ~( LVDS_B0B3PAIRS_POWER_UP | 
LVDS_CLKB_POWER_UP);
 
-               write32(INTEL_DISPLAY_LVDS_PORT, lvds);
-               read32(INTEL_DISPLAY_LVDS_PORT);
+               write32(targetRegister, lvds);
+               read32(targetRegister);
 
                if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD)) {
                        write32(INTEL_DISPLAY_B_PLL_DIVISOR_0,
@@ -825,7 +873,8 @@
                                | (((divisors.m2 - 2) << 
DISPLAY_PLL_M2_DIVISOR_SHIFT)
                                        & DISPLAY_PLL_IGD_M2_DIVISOR_MASK));
                } else {
-                       write32(INTEL_DISPLAY_B_PLL_DIVISOR_0,
+                       write32(isSNB ? PCH_DISPLAY_B_PLL_DIVISOR_0
+                                       : INTEL_DISPLAY_B_PLL_DIVISOR_0,
                                (((divisors.n - 2) << 
DISPLAY_PLL_N_DIVISOR_SHIFT)
                                        & DISPLAY_PLL_N_DIVISOR_MASK)
                                | (((divisors.m1 - 2) << 
DISPLAY_PLL_M1_DIVISOR_SHIFT)
@@ -834,8 +883,9 @@
                                        & DISPLAY_PLL_M2_DIVISOR_MASK));
                }
 
-               write32(INTEL_DISPLAY_B_PLL, dpll);
-               read32(INTEL_DISPLAY_B_PLL);
+               targetRegister = isSNB ? PCH_DISPLAY_B_PLL : 
INTEL_DISPLAY_B_PLL;
+               write32(targetRegister, dpll);
+               read32(targetRegister);
 
                // Wait for the clocks to stabilize
                spin(150);
@@ -855,9 +905,9 @@
                        write32(INTEL_DISPLAY_B_PLL_MULTIPLIER_DIVISOR, (0 << 
24)
                                | ((pixelMultiply - 1) << 8));
                } else
-                       write32(INTEL_DISPLAY_B_PLL, dpll);
+                       write32(targetRegister, dpll);
 
-               read32(INTEL_DISPLAY_B_PLL);
+               read32(targetRegister);
                spin(150);
 
                // update timing parameters
@@ -878,14 +928,14 @@
                                + (hardwareTarget.timing.h_total
                                - target.timing.h_display) / 2;
 
-                       write32(INTEL_DISPLAY_B_HTOTAL,
+                       write32(isSNB ? PCH_TRANSCODER_B_HTOTAL : 
INTEL_DISPLAY_B_HTOTAL,
                                ((uint32)(hardwareTarget.timing.h_total - 1) << 
16)
                                | ((uint32)target.timing.h_display - 1));
-                       write32(INTEL_DISPLAY_B_HBLANK,
+                       write32(isSNB ? PCH_TRANSCODER_B_HBLANK : 
INTEL_DISPLAY_B_HBLANK,
                                ((uint32)(hardwareTarget.timing.h_total - 
borderWidth / 2 - 1)
                                        << 16)
                                | ((uint32)target.timing.h_display + 
borderWidth / 2 - 1));
-                       write32(INTEL_DISPLAY_B_HSYNC,
+                       write32(isSNB ? PCH_TRANSCODER_B_HSYNC : 
INTEL_DISPLAY_B_HSYNC,
                                ((uint32)(syncCenter + syncWidth / 2 - 1) << 16)
                                | ((uint32)syncCenter - syncWidth / 2 - 1));
 
@@ -899,16 +949,16 @@
                                + (hardwareTarget.timing.v_total
                                - target.timing.v_display) / 2;
 
-                       write32(INTEL_DISPLAY_B_VTOTAL,
+                       write32(isSNB ? PCH_TRANSCODER_B_VTOTAL : 
INTEL_DISPLAY_B_VTOTAL,
                                ((uint32)(hardwareTarget.timing.v_total - 1) << 
16)
                                | ((uint32)target.timing.v_display - 1));
-                       write32(INTEL_DISPLAY_B_VBLANK,
+                       write32(isSNB ? PCH_TRANSCODER_B_VBLANK : 
INTEL_DISPLAY_B_VBLANK,
                                ((uint32)(hardwareTarget.timing.v_total - 
borderHeight / 2 - 1)
                                        << 16)
                                | ((uint32)target.timing.v_display
                                        + borderHeight / 2 - 1));
-                       write32(INTEL_DISPLAY_B_VSYNC, ((uint32)(syncCenter
-                                       + syncHeight / 2 - 1) << 16)
+                       write32(isSNB ? PCH_TRANSCODER_B_VSYNC : 
INTEL_DISPLAY_B_VSYNC,
+                               ((uint32)(syncCenter + syncHeight / 2 - 1) << 
16)
                                | ((uint32)syncCenter - syncHeight / 2 - 1));
 
                        // This is useful for debugging: it sets the border to 
red, so you
@@ -916,23 +966,23 @@
                        // sync)
                        // write32(0x61020, 0x00FF0000);
                } else {
-                       write32(INTEL_DISPLAY_B_HTOTAL,
+                       write32(isSNB ? PCH_TRANSCODER_B_HTOTAL : 
INTEL_DISPLAY_B_HTOTAL,
                                ((uint32)(target.timing.h_total - 1) << 16)
                                | ((uint32)target.timing.h_display - 1));
-                       write32(INTEL_DISPLAY_B_HBLANK,
+                       write32(isSNB ? PCH_TRANSCODER_B_HBLANK : 
INTEL_DISPLAY_B_HBLANK,
                                ((uint32)(target.timing.h_total - 1) << 16)
                                | ((uint32)target.timing.h_display - 1));
-                       write32(INTEL_DISPLAY_B_HSYNC, (
-                               (uint32)(target.timing.h_sync_end - 1) << 16)
+                       write32(isSNB ? PCH_TRANSCODER_B_HSYNC : 
INTEL_DISPLAY_B_HSYNC,
+                               ((uint32)(target.timing.h_sync_end - 1) << 16)
                                | ((uint32)target.timing.h_sync_start - 1));
 
-                       write32(INTEL_DISPLAY_B_VTOTAL,
+                       write32(isSNB ? PCH_TRANSCODER_B_VTOTAL : 
INTEL_DISPLAY_B_VTOTAL,
                                ((uint32)(target.timing.v_total - 1) << 16)
                                | ((uint32)target.timing.v_display - 1));
-                       write32(INTEL_DISPLAY_B_VBLANK,
+                       write32(isSNB ? PCH_TRANSCODER_B_VBLANK : 
INTEL_DISPLAY_B_VBLANK,
                                ((uint32)(target.timing.v_total - 1) << 16)
                                | ((uint32)target.timing.v_display - 1));
-                       write32(INTEL_DISPLAY_B_VSYNC, (
+                       write32(isSNB ? PCH_TRANSCODER_B_VSYNC : 
INTEL_DISPLAY_B_VSYNC, (
                                (uint32)(target.timing.v_sync_end - 1) << 16)
                                | ((uint32)target.timing.v_sync_start - 1));
                }
@@ -966,7 +1016,8 @@
                                | (((divisors.m2 - 2) << 
DISPLAY_PLL_M2_DIVISOR_SHIFT)
                                        & DISPLAY_PLL_IGD_M2_DIVISOR_MASK));
                } else {
-                       write32(INTEL_DISPLAY_A_PLL_DIVISOR_0,
+                       write32(isSNB ? PCH_DISPLAY_A_PLL_DIVISOR_0
+                                       : INTEL_DISPLAY_A_PLL_DIVISOR_0,
                                (((divisors.n - 2) << 
DISPLAY_PLL_N_DIVISOR_SHIFT)
                                        & DISPLAY_PLL_N_DIVISOR_MASK)
                                | (((divisors.m1 - 2) << 
DISPLAY_PLL_M1_DIVISOR_SHIFT)
@@ -1008,31 +1059,32 @@
                                pll |= DISPLAY_PLL_POST1_DIVIDE_2;
                }
 
-               write32(INTEL_DISPLAY_A_PLL, pll);
-               read32(INTEL_DISPLAY_A_PLL);
+               targetRegister = isSNB ? PCH_DISPLAY_A_PLL : 
INTEL_DISPLAY_A_PLL;
+               write32(targetRegister, pll);
+               read32(targetRegister);
                spin(150);
-               write32(INTEL_DISPLAY_A_PLL, pll);
-               read32(INTEL_DISPLAY_A_PLL);
+               write32(targetRegister, pll);
+               read32(targetRegister);
                spin(150);
 
                // update timing parameters
-               write32(INTEL_DISPLAY_A_HTOTAL,
+               write32(isSNB ? PCH_TRANSCODER_A_HTOTAL : 
INTEL_DISPLAY_A_HTOTAL,
                        ((uint32)(target.timing.h_total - 1) << 16)
                        | ((uint32)target.timing.h_display - 1));
-               write32(INTEL_DISPLAY_A_HBLANK,
+               write32(isSNB ? PCH_TRANSCODER_A_HBLANK : 
INTEL_DISPLAY_A_HBLANK,
                        ((uint32)(target.timing.h_total - 1) << 16)
                        | ((uint32)target.timing.h_display - 1));
-               write32(INTEL_DISPLAY_A_HSYNC,
+               write32(isSNB ? PCH_TRANSCODER_A_HSYNC : INTEL_DISPLAY_A_HSYNC,
                        ((uint32)(target.timing.h_sync_end - 1) << 16)
                        | ((uint32)target.timing.h_sync_start - 1));
 
-               write32(INTEL_DISPLAY_A_VTOTAL,
+               write32(isSNB ? PCH_TRANSCODER_A_VTOTAL : 
INTEL_DISPLAY_A_VTOTAL,
                        ((uint32)(target.timing.v_total - 1) << 16)
                        | ((uint32)target.timing.v_display - 1));
-               write32(INTEL_DISPLAY_A_VBLANK,
+               write32(isSNB ? PCH_TRANSCODER_A_VBLANK : 
INTEL_DISPLAY_A_VBLANK,
                        ((uint32)(target.timing.v_total - 1) << 16)
                        | ((uint32)target.timing.v_display - 1));
-               write32(INTEL_DISPLAY_A_VSYNC,
+               write32(isSNB ? PCH_TRANSCODER_A_VSYNC : INTEL_DISPLAY_A_VSYNC,
                        ((uint32)(target.timing.v_sync_end - 1) << 16)
                        | ((uint32)target.timing.v_sync_start - 1));
 
@@ -1040,8 +1092,10 @@
                        ((uint32)(target.timing.h_display - 1) << 16)
                        | ((uint32)target.timing.v_display - 1));
 
-               write32(INTEL_DISPLAY_A_ANALOG_PORT,
-                       (read32(INTEL_DISPLAY_A_ANALOG_PORT)
+               targetRegister
+                       = isSNB ? PCH_DISPLAY_A_ANALOG_PORT : 
INTEL_DISPLAY_A_ANALOG_PORT;
+               write32(targetRegister,
+                       (read32(targetRegister)
                                & ~(DISPLAY_MONITOR_POLARITY_MASK
                                        | DISPLAY_MONITOR_VGA_POLARITY))
                        | ((target.timing.flags & B_POSITIVE_HSYNC) != 0
@@ -1097,7 +1151,9 @@
 {
        TRACE(("intel_get_display_mode()\n"));
 
-       retrieve_current_mode(*_currentMode, INTEL_DISPLAY_A_PLL);
+       bool isSNB = gInfo->shared_info->device_type.InGroup(INTEL_TYPE_SNB);
+       retrieve_current_mode(*_currentMode,
+               isSNB ? PCH_DISPLAY_A_PLL : INTEL_DISPLAY_A_PLL);
        return B_OK;
 }
 

Modified: haiku/trunk/src/add-ons/kernel/busses/agp_gart/intel_gart.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/busses/agp_gart/intel_gart.cpp       
2011-10-13 08:43:56 UTC (rev 42838)
+++ haiku/trunk/src/add-ons/kernel/busses/agp_gart/intel_gart.cpp       
2011-10-13 09:07:33 UTC (rev 42839)
@@ -77,9 +77,11 @@
        {0x2e30, 0x2e32, INTEL_TYPE_G45, "G41"},
        {0x2e40, 0x2e42, INTEL_TYPE_G45, "B43"},
        {0x2e90, 0x2e92, INTEL_TYPE_G45, "B43"},
-       
+
        {0xa000, 0xa001, INTEL_TYPE_IGDG, "Atom_Dx10"},
        {0xa010, 0xa011, INTEL_TYPE_IGDGM, "Atom_N4x0"},
+
+       {0x0104, 0x0126, INTEL_TYPE_SNBGM, "SNBGM"},
 };
 
 struct intel_info {
@@ -131,8 +133,11 @@
 determine_memory_sizes(intel_info &info, size_t &gttSize, size_t &stolenSize)
 {
        // read stolen memory from the PCI configuration of the PCI bridge
-       uint16 memoryConfig = get_pci_config(info.bridge,
-               INTEL_GRAPHICS_MEMORY_CONTROL, 2);
+       uint8 controlRegister = INTEL_GRAPHICS_MEMORY_CONTROL;
+       if ((info.type & INTEL_TYPE_GROUP_MASK) == INTEL_TYPE_SNB)
+               controlRegister = SNB_GRAPHICS_MEMORY_CONTROL;
+
+       uint16 memoryConfig = get_pci_config(info.bridge, controlRegister, 2);
        size_t memorySize = 1 << 20; // 1 MB
        gttSize = 0;
        stolenSize = 0;
@@ -178,6 +183,18 @@
                                gttSize = 4 << 20;
                                break;
                }
+       } else if ((info.type & INTEL_TYPE_GROUP_MASK) == INTEL_TYPE_SNB) {
+               switch (memoryConfig & SNB_GTT_SIZE_MASK) {
+                       case SNB_GTT_SIZE_NONE:
+                               gttSize = 0;
+                               break;
+                       case SNB_GTT_SIZE_1MB:
+                               gttSize = 1 << 20;
+                               break;
+                       case SNB_GTT_SIZE_2MB:
+                               gttSize = 2 << 20;
+                               break;
+               }
        } else {
                // older models have the GTT as large as their frame buffer 
mapping
                // TODO: check if the i9xx version works with the i8xx chips as 
well
@@ -191,7 +208,7 @@
                } else if ((info.type & INTEL_TYPE_9xx) != 0)
                        frameBufferSize = 
info.display.u.h0.base_register_sizes[2];
 
-               TRACE(("frame buffer size %lu MB\n", frameBufferSize >> 20));
+               TRACE("frame buffer size %lu MB\n", frameBufferSize >> 20);
                gttSize = frameBufferSize / 1024;
        }
 
@@ -214,6 +231,57 @@
                                memorySize *= 8;
                                break;
                }
+       } else if ((info.type & INTEL_TYPE_GROUP_MASK) == INTEL_TYPE_SNB) {
+               switch (memoryConfig & SNB_STOLEN_MEMORY_MASK) {
+                       case SNB_STOLEN_MEMORY_32MB:
+                               memorySize *= 32;
+                               break;
+                       case SNB_STOLEN_MEMORY_64MB:
+                               memorySize *= 64;
+                               break;
+                       case SNB_STOLEN_MEMORY_96MB:
+                               memorySize *= 96;
+                               break;
+                       case SNB_STOLEN_MEMORY_128MB:
+                               memorySize *= 128;
+                               break;
+                       case SNB_STOLEN_MEMORY_160MB:
+                               memorySize *= 160;
+                               break;
+                       case SNB_STOLEN_MEMORY_192MB:
+                               memorySize *= 192;
+                               break;
+                       case SNB_STOLEN_MEMORY_224MB:
+                               memorySize *= 224;
+                               break;
+                       case SNB_STOLEN_MEMORY_256MB:
+                               memorySize *= 256;
+                               break;
+                       case SNB_STOLEN_MEMORY_288MB:
+                               memorySize *= 288;
+                               break;
+                       case SNB_STOLEN_MEMORY_320MB:
+                               memorySize *= 320;
+                               break;
+                       case SNB_STOLEN_MEMORY_352MB:
+                               memorySize *= 352;
+                               break;
+                       case SNB_STOLEN_MEMORY_384MB:
+                               memorySize *= 384;
+                               break;
+                       case SNB_STOLEN_MEMORY_416MB:
+                               memorySize *= 416;
+                               break;
+                       case SNB_STOLEN_MEMORY_448MB:
+                               memorySize *= 448;
+                               break;
+                       case SNB_STOLEN_MEMORY_480MB:
+                               memorySize *= 480;
+                               break;
+                       case SNB_STOLEN_MEMORY_512MB:
+                               memorySize *= 512;
+                               break;
+               }
        } else if (info.type == INTEL_TYPE_85x
                || (info.type & INTEL_TYPE_9xx) == INTEL_TYPE_9xx) {
                switch (memoryConfig & STOLEN_MEMORY_MASK) {
@@ -325,7 +393,8 @@
                return B_ERROR;
 
        if ((info.type & INTEL_TYPE_FAMILY_MASK) == INTEL_TYPE_9xx) {
-               if ((info.type & INTEL_TYPE_GROUP_MASK) == INTEL_TYPE_G4x) {
+               if ((info.type & INTEL_TYPE_GROUP_MASK) == INTEL_TYPE_G4x
+                       || (info.type & INTEL_TYPE_GROUP_MASK) == 
INTEL_TYPE_SNB) {
                        info.gtt_physical_base = 
info.display.u.h0.base_registers[mmioIndex]
                                        + (2UL << 20);
                } else

Modified: 
haiku/trunk/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.cpp    
2011-10-13 08:43:56 UTC (rev 42838)
+++ haiku/trunk/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.cpp    
2011-10-13 09:07:33 UTC (rev 42839)
@@ -69,9 +69,11 @@
        {0x2e32, INTEL_TYPE_G45, "G41"},
        {0x2e42, INTEL_TYPE_G45, "B43"},
        {0x2e92, INTEL_TYPE_G45, "B43"},
-       
+
        {0xa001, INTEL_TYPE_IGDG, "Atom_Dx10"},
        {0xa011, INTEL_TYPE_IGDGM, "Atom_N4x0"},
+
+       {0x0126, INTEL_TYPE_SNBGM, "SNBGM"},
 };
 
 int32 api_version = B_CUR_DRIVER_API_VERSION;

Modified: 
haiku/trunk/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp
===================================================================
--- 
haiku/trunk/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp 
    2011-10-13 08:43:56 UTC (rev 42838)
+++ 
haiku/trunk/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp 
    2011-10-13 09:07:33 UTC (rev 42839)
@@ -257,6 +257,9 @@
        if (info.pci->device_id == 0x2a02 || info.pci->device_id == 0x2a12) {
                dprintf("i965GM/i965GME quirk\n");
                write32(info.registers + 0x6204, (1L << 29));
+       } else if (info.device_type.InGroup(INTEL_TYPE_SNB)) {
+               dprintf("SNB clock gating\n");
+               write32(info.registers + 0x42020, (1L << 28) | (1L << 7) | (1L 
<< 5));
        } else if (info.device_type.InGroup(INTEL_TYPE_G4x)) {
                dprintf("G4x clock gating\n");
                write32(info.registers + 0x6204, 0);


Other related posts:

  • » [haiku-commits] r42839 - in haiku/trunk: headers/private/graphics/intel_extreme src/add-ons/accelerants/intel_extreme src/add-ons/kernel/busses/agp_gart src/add-ons/kernel/drivers/graphics/intel_extreme - mmlr