Author: mmlr Date: 2011-10-14 21:11:29 +0200 (Fri, 14 Oct 2011) New Revision: 42850 Changeset: https://dev.haiku-os.org/changeset/42850 Modified: haiku/trunk/headers/private/graphics/intel_extreme/intel_extreme.h haiku/trunk/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp Log: Some more SandyBridge specifics to get V-blank interrupts going. Modified: haiku/trunk/headers/private/graphics/intel_extreme/intel_extreme.h =================================================================== --- haiku/trunk/headers/private/graphics/intel_extreme/intel_extreme.h 2011-10-14 18:34:45 UTC (rev 42849) +++ haiku/trunk/headers/private/graphics/intel_extreme/intel_extreme.h 2011-10-14 19:11:29 UTC (rev 42850) @@ -225,7 +225,11 @@ // 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_DE_POWER_MEASUREMENT 0x42400 +#define PCH_DE_INTERRUPT_STATUS 0x44000 // INTEL_INTERRUPT_STATUS +#define PCH_DE_INTERRUPT_MASK 0x44004 // INTEL_INTERRUPT_MASK +#define PCH_DE_INTERRUPT_IDENTITY 0x44008 // INTEL_INTERRUPT_IDENTITY +#define PCH_DE_INTERRUPT_ENABLED 0x4400c // INTEL_INTERRUPT_ENABLED #define PCH_DISPLAY_A_ANALOG_PORT 0xe1100 // INTEL_DISPLAY_A_ANALOG_PORT #define PCH_DISPLAY_A_DIGITAL_PORT 0xe1120 // INTEL_DISPLAY_A_DIGITAL_PORT #define PCH_DISPLAY_B_DIGITAL_PORT 0xe1140 // INTEL_DISPLAY_B_DIGITAL_PORT @@ -252,6 +256,8 @@ #define PCH_TRANSCODER_B_VSYNC 0xe1014 // INTEL_DISPLAY_B_VSYNC #define PCH_LVDS_DETECTED (1 << 1) +#define PCH_INTERRUPT_VBLANK_PIPEA (1 << 7) +#define PCH_INTERRUPT_VBLANK_PIPEB (1 << 15) // SandyBridge (SNB) 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-14 18:34:45 UTC (rev 42849) +++ haiku/trunk/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp 2011-10-14 19:11:29 UTC (rev 42850) @@ -76,13 +76,16 @@ { intel_info &info = *(intel_info *)data; - uint32 identity = read16(info.registers + INTEL_INTERRUPT_IDENTITY); + bool isSNB = info.device_type.InGroup(INTEL_TYPE_SNB); + uint32 identity = read16(info.registers + + (isSNB ? PCH_DE_INTERRUPT_IDENTITY : INTEL_INTERRUPT_IDENTITY)); if (identity == 0) return B_UNHANDLED_INTERRUPT; int32 handled = B_HANDLED_INTERRUPT; - if ((identity & INTERRUPT_VBLANK_PIPEA) != 0) { + uint32 mask = isSNB ? PCH_INTERRUPT_VBLANK_PIPEA : INTERRUPT_VBLANK_PIPEA; + if ((identity & mask) != 0) { handled = release_vblank_sem(info); // make sure we'll get another one of those @@ -90,7 +93,8 @@ DISPLAY_PIPE_VBLANK_STATUS | DISPLAY_PIPE_VBLANK_ENABLED); } - if ((identity & INTERRUPT_VBLANK_PIPEB) != 0) { + mask = isSNB ? PCH_INTERRUPT_VBLANK_PIPEB : INTERRUPT_VBLANK_PIPEB; + if ((identity & mask) != 0) { handled = release_vblank_sem(info); // make sure we'll get another one of those @@ -99,7 +103,8 @@ } // setting the bit clears it! - write16(info.registers + INTEL_INTERRUPT_IDENTITY, identity); + write16(info.registers + (isSNB ? PCH_DE_INTERRUPT_IDENTITY + : INTEL_INTERRUPT_IDENTITY), identity); return handled; } @@ -137,14 +142,22 @@ DISPLAY_PIPE_VBLANK_STATUS | DISPLAY_PIPE_VBLANK_ENABLED); write32(info.registers + INTEL_DISPLAY_B_PIPE_STATUS, DISPLAY_PIPE_VBLANK_STATUS | DISPLAY_PIPE_VBLANK_ENABLED); - write16(info.registers + INTEL_INTERRUPT_IDENTITY, ~0); + bool isSNB = info.device_type.InGroup(INTEL_TYPE_SNB); + write16(info.registers + (isSNB ? PCH_DE_INTERRUPT_IDENTITY + : INTEL_INTERRUPT_IDENTITY), ~0); + // enable interrupts - we only want VBLANK interrupts - write16(info.registers + INTEL_INTERRUPT_ENABLED, - read16(info.registers + INTEL_INTERRUPT_ENABLED) - | INTERRUPT_VBLANK_PIPEA | INTERRUPT_VBLANK_PIPEB); - write16(info.registers + INTEL_INTERRUPT_MASK, - ~(INTERRUPT_VBLANK_PIPEA | INTERRUPT_VBLANK_PIPEB)); + uint16 enable = isSNB + ? (PCH_INTERRUPT_VBLANK_PIPEA | PCH_INTERRUPT_VBLANK_PIPEB) + : (INTERRUPT_VBLANK_PIPEA | INTERRUPT_VBLANK_PIPEB); + + write16(info.registers + (isSNB ? PCH_DE_INTERRUPT_ENABLED + : INTEL_INTERRUPT_ENABLED), + read16(info.registers + (isSNB ? PCH_DE_INTERRUPT_ENABLED + : INTEL_INTERRUPT_ENABLED)) | enable); + write16(info.registers + (isSNB ? PCH_DE_INTERRUPT_MASK + : INTEL_INTERRUPT_MASK), ~enable); } } if (status < B_OK) { @@ -354,8 +367,11 @@ if (!info.fake_interrupts && info.shared_info->vblank_sem > 0) { // disable interrupt generation - write16(info.registers + INTEL_INTERRUPT_ENABLED, 0); - write16(info.registers + INTEL_INTERRUPT_MASK, ~0); + bool isSNB = info.device_type.InGroup(INTEL_TYPE_SNB); + write16(info.registers + (isSNB ? PCH_DE_INTERRUPT_ENABLED + : INTEL_INTERRUPT_ENABLED), 0); + write16(info.registers + (isSNB ? PCH_DE_INTERRUPT_MASK + : INTEL_INTERRUPT_MASK), ~0); remove_io_interrupt_handler(info.pci->u.h0.interrupt_line, intel_interrupt_handler, &info);