diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h b/headers/private/graphics/intel_extreme/intel_extreme.h index 5d38cbcaaa..ecc59c57d5 100644 --- a/headers/private/graphics/intel_extreme/intel_extreme.h +++ b/headers/private/graphics/intel_extreme/intel_extreme.h @@ -227,6 +227,8 @@ struct intel_free_graphics_memory { // 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_A_DIGITAL_PORT 0xe1120 // INTEL_DISPLAY_A_DIGITAL_PORT +#define PCH_DISPLAY_B_DIGITAL_PORT 0xe1140 // INTEL_DISPLAY_B_DIGITAL_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 @@ -249,6 +251,9 @@ struct intel_free_graphics_memory { #define PCH_TRANSCODER_B_VBLANK 0xe1010 // INTEL_DISPLAY_B_VBLANK #define PCH_TRANSCODER_B_VSYNC 0xe1014 // INTEL_DISPLAY_B_VSYNC +#define PCH_LVDS_DETECTED (1 << 1) + + // SandyBridge (SNB) #define SNB_GRAPHICS_MEMORY_CONTROL 0x50 @@ -387,6 +392,8 @@ struct intel_free_graphics_memory { #define INTEL_DISPLAY_A_CONTROL 0x70180 #define INTEL_DISPLAY_A_BASE 0x70184 #define INTEL_DISPLAY_A_BYTES_PER_ROW 0x70188 +#define INTEL_DISPLAY_A_POS 0x7018c // reserved +#define INTEL_DISPLAY_A_PIPE_SIZE 0x70190 #define INTEL_DISPLAY_A_SURFACE 0x7019c // i965 and up only #define DISPLAY_CONTROL_ENABLED (1UL << 31) #define DISPLAY_CONTROL_GAMMA (1UL << 30) @@ -408,6 +415,7 @@ struct intel_free_graphics_memory { #define DISPLAY_PIPE_VBLANK_STATUS (1UL << 1) #define INTEL_DISPLAY_A_PLL 0x06014 +#define INTEL_DISPLAY_A_PLL_MULTIPLIER_DIVISOR 0x0601c #define INTEL_DISPLAY_A_PLL_DIVISOR_0 0x06040 #define INTEL_DISPLAY_A_PLL_DIVISOR_1 0x06044 @@ -428,7 +436,7 @@ struct intel_free_graphics_memory { #define INTEL_DISPLAY_B_CONTROL 0x71180 #define INTEL_DISPLAY_B_BASE 0x71184 #define INTEL_DISPLAY_B_BYTES_PER_ROW 0x71188 -#define INTEL_DISPLAY_B_POS 0x7118C +#define INTEL_DISPLAY_B_POS 0x7118c #define INTEL_DISPLAY_B_IMAGE_SIZE 0x6101c #define INTEL_DISPLAY_B_SURFACE 0x7119c // i965 and up only diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.cpp b/src/add-ons/accelerants/intel_extreme/accelerant.cpp index 209ce53a81..a3545ccd80 100644 --- a/src/add-ons/accelerants/intel_extreme/accelerant.cpp +++ b/src/add-ons/accelerants/intel_extreme/accelerant.cpp @@ -203,22 +203,27 @@ intel_init_accelerant(int device) if (read32(INTEL_DISPLAY_A_PIPE_CONTROL) & DISPLAY_PIPE_ENABLED) gInfo->head_mode |= HEAD_MODE_A_ANALOG; - uint32 lvds = read32(INTEL_DISPLAY_LVDS_PORT); + bool isSNB = gInfo->shared_info->device_type.InGroup(INTEL_TYPE_SNB); + int lvdsRegister = isSNB ? PCH_DISPLAY_LVDS_PORT : INTEL_DISPLAY_LVDS_PORT; + uint32 lvds = read32(lvdsRegister); // If we have an enabled display pipe we save the passed information and // assume it is the valid panel size.. // Later we query for proper EDID info if it exists, or figure something // else out. (Default modes, etc.) - if ((lvds & DISPLAY_PIPE_ENABLED) != 0) { + if ((isSNB && (lvds & PCH_LVDS_DETECTED) != 0) + || (!isSNB && (lvds & DISPLAY_PIPE_ENABLED) != 0)) { save_lvds_mode(); gInfo->head_mode |= HEAD_MODE_LVDS_PANEL; } TRACE(("head detected: %#x\n", gInfo->head_mode)); TRACE(("adpa: %08lx, dova: %08lx, dovb: %08lx, lvds: %08lx\n", - read32(INTEL_DISPLAY_A_ANALOG_PORT), - read32(INTEL_DISPLAY_A_DIGITAL_PORT), - read32(INTEL_DISPLAY_B_DIGITAL_PORT), read32(INTEL_DISPLAY_LVDS_PORT))); + read32(isSNB ? PCH_DISPLAY_A_ANALOG_PORT : INTEL_DISPLAY_A_ANALOG_PORT), + read32(isSNB ? PCH_DISPLAY_A_DIGITAL_PORT + : INTEL_DISPLAY_A_DIGITAL_PORT), + read32(isSNB ? PCH_DISPLAY_B_DIGITAL_PORT + : INTEL_DISPLAY_B_DIGITAL_PORT), read32(lvdsRegister))); status = create_mode_list(); if (status != B_OK) { diff --git a/src/add-ons/accelerants/intel_extreme/dpms.cpp b/src/add-ons/accelerants/intel_extreme/dpms.cpp index 03c4435f72..b45242a6c3 100644 --- a/src/add-ons/accelerants/intel_extreme/dpms.cpp +++ b/src/add-ons/accelerants/intel_extreme/dpms.cpp @@ -104,32 +104,35 @@ set_display_power_mode(uint32 mode) { uint32 monitorMode = 0; + bool isSNB = gInfo->shared_info->device_type.InGroup(INTEL_TYPE_SNB); if (mode == B_DPMS_ON) { - uint32 pll = read32(INTEL_DISPLAY_A_PLL); + int targetRegister = isSNB ? PCH_DISPLAY_A_PLL : INTEL_DISPLAY_A_PLL; + uint32 pll = read32(targetRegister); if ((pll & DISPLAY_PLL_ENABLED) == 0) { // reactivate PLL - write32(INTEL_DISPLAY_A_PLL, pll); - read32(INTEL_DISPLAY_A_PLL); + write32(targetRegister, pll); + read32(targetRegister); spin(150); - write32(INTEL_DISPLAY_A_PLL, pll | DISPLAY_PLL_ENABLED); - read32(INTEL_DISPLAY_A_PLL); + write32(targetRegister, pll | DISPLAY_PLL_ENABLED); + read32(targetRegister); spin(150); - write32(INTEL_DISPLAY_A_PLL, pll | DISPLAY_PLL_ENABLED); - read32(INTEL_DISPLAY_A_PLL); + write32(targetRegister, pll | DISPLAY_PLL_ENABLED); + read32(targetRegister); spin(150); } - pll = read32(INTEL_DISPLAY_B_PLL); + targetRegister = isSNB ? PCH_DISPLAY_B_PLL : INTEL_DISPLAY_B_PLL; + pll = read32(targetRegister); if ((pll & DISPLAY_PLL_ENABLED) == 0) { // reactivate PLL - write32(INTEL_DISPLAY_B_PLL, pll); - read32(INTEL_DISPLAY_B_PLL); + write32(targetRegister, pll); + read32(targetRegister); spin(150); - write32(INTEL_DISPLAY_B_PLL, pll | DISPLAY_PLL_ENABLED); - read32(INTEL_DISPLAY_B_PLL); + write32(targetRegister, pll | DISPLAY_PLL_ENABLED); + read32(targetRegister); spin(150); - write32(INTEL_DISPLAY_B_PLL, pll | DISPLAY_PLL_ENABLED); - read32(INTEL_DISPLAY_B_PLL); + write32(targetRegister, pll | DISPLAY_PLL_ENABLED); + read32(targetRegister); spin(150); } @@ -155,12 +158,16 @@ set_display_power_mode(uint32 mode) } if (gInfo->head_mode & HEAD_MODE_A_ANALOG) { - write32(INTEL_DISPLAY_A_ANALOG_PORT, (read32(INTEL_DISPLAY_A_ANALOG_PORT) + int targetRegister + = isSNB ? PCH_DISPLAY_A_ANALOG_PORT : INTEL_DISPLAY_A_ANALOG_PORT; + write32(targetRegister, (read32(targetRegister) & ~(DISPLAY_MONITOR_MODE_MASK | DISPLAY_MONITOR_PORT_ENABLED)) | monitorMode | (mode != B_DPMS_OFF ? DISPLAY_MONITOR_PORT_ENABLED : 0)); } if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) { - write32(INTEL_DISPLAY_B_DIGITAL_PORT, (read32(INTEL_DISPLAY_B_DIGITAL_PORT) + int targetRegister + = isSNB ? PCH_DISPLAY_B_DIGITAL_PORT : INTEL_DISPLAY_B_DIGITAL_PORT; + write32(targetRegister, (read32(targetRegister) & ~(DISPLAY_MONITOR_MODE_MASK | DISPLAY_MONITOR_PORT_ENABLED)) | (mode != B_DPMS_OFF ? DISPLAY_MONITOR_PORT_ENABLED : 0)); // TODO: monitorMode? @@ -173,18 +180,21 @@ set_display_power_mode(uint32 mode) } if (mode == B_DPMS_OFF) { - write32(INTEL_DISPLAY_A_PLL, read32(INTEL_DISPLAY_A_PLL) + int targetRegister = isSNB ? PCH_DISPLAY_A_PLL : INTEL_DISPLAY_A_PLL; + write32(targetRegister, read32(targetRegister) | DISPLAY_PLL_ENABLED); - write32(INTEL_DISPLAY_B_PLL, read32(INTEL_DISPLAY_B_PLL) + targetRegister = isSNB ? PCH_DISPLAY_B_PLL : INTEL_DISPLAY_B_PLL; + write32(targetRegister, read32(targetRegister) | DISPLAY_PLL_ENABLED); - read32(INTEL_DISPLAY_B_PLL); - // flush the eventually cached PCI bus writes + read32(targetRegister); + // flush the possibly cached PCI bus writes spin(150); } - if ((gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0) + // TODO: fix for SNB + if (!isSNB && (gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0) enable_lvds_panel(mode == B_DPMS_ON); read32(INTEL_DISPLAY_A_BASE);