diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h b/headers/private/graphics/intel_extreme/intel_extreme.h index f29566145b..a77398f3fc 100644 --- a/headers/private/graphics/intel_extreme/intel_extreme.h +++ b/headers/private/graphics/intel_extreme/intel_extreme.h @@ -521,8 +521,10 @@ struct intel_free_graphics_memory { #define DISPLAY_PLL_POST1_DIVIDE_2 (1UL << 21) #define DISPLAY_PLL_POST1_DIVISOR_MASK 0x001f0000 #define DISPLAY_PLL_9xx_POST1_DIVISOR_MASK 0x00ff0000 +#define DISPLAY_PLL_SNB_FP0_POST1_DIVISOR_MASK 0x000000ff #define DISPLAY_PLL_IGD_POST1_DIVISOR_MASK 0x00ff8000 #define DISPLAY_PLL_POST1_DIVISOR_SHIFT 16 +#define DISPLAY_PLL_SNB_FP0_POST1_DIVISOR_SHIFT 0 #define DISPLAY_PLL_IGD_POST1_DIVISOR_SHIFT 15 #define DISPLAY_PLL_DIVISOR_1 (1UL << 8) #define DISPLAY_PLL_N_DIVISOR_MASK 0x001f0000 @@ -647,8 +649,7 @@ struct intel_free_graphics_memory { // planes #define INTEL_PIPE_ENABLED (1UL << 31) -#define INTEL_PIPE_CONTROL 0x0008 -#define INTEL_PIPE_STATUS 0x0024 +#define INTEL_PIPE_STATE (1UL << 30) #define INTEL_PLANE_OFFSET 0x1000 @@ -719,12 +720,6 @@ struct intel_free_graphics_memory { #define INTEL_DISPLAY_A_PALETTE (0xa000 | REGS_NORTH_SHARED) #define INTEL_DISPLAY_B_PALETTE (0xa800 | REGS_NORTH_SHARED) -// PLL registers -#define INTEL_DISPLAY_A_PLL (0x6014 | REGS_SOUTH_SHARED) -#define INTEL_DISPLAY_B_PLL (0x6018 | REGS_SOUTH_SHARED) -#define CHV_DISPLAY_C_PLL (0x6030 | REGS_SOUTH_SHARED) -#define SNB_DPLL_SEL (0x7000 | REGS_SOUTH_SHARED) - // Ironlake PCH reference clk control #define PCH_DREF_CONTROL (0x6200 | REGS_SOUTH_SHARED) #define DREF_CONTROL_MASK 0x7fc3 @@ -749,9 +744,13 @@ struct intel_free_graphics_memory { #define DREF_SSC4_DISABLE (0 << 0) #define DREF_SSC4_ENABLE (1 << 0) +// PLL registers // Multiplier Divisor +#define INTEL_DISPLAY_A_PLL (0x6014 | REGS_SOUTH_SHARED) +#define INTEL_DISPLAY_B_PLL (0x6018 | REGS_SOUTH_SHARED) #define INTEL_DISPLAY_A_PLL_MD (0x601C | REGS_SOUTH_SHARED) #define INTEL_DISPLAY_B_PLL_MD (0x6020 | REGS_SOUTH_SHARED) +#define CHV_DISPLAY_C_PLL (0x6030 | REGS_SOUTH_SHARED) #define CHV_DISPLAY_B_PLL_MD (0x603C | REGS_SOUTH_SHARED) #define INTEL_DISPLAY_A_PLL_DIVISOR_0 (0x6040 | REGS_SOUTH_SHARED) @@ -759,6 +758,8 @@ struct intel_free_graphics_memory { #define INTEL_DISPLAY_B_PLL_DIVISOR_0 (0x6048 | REGS_SOUTH_SHARED) #define INTEL_DISPLAY_B_PLL_DIVISOR_1 (0x604c | REGS_SOUTH_SHARED) +#define SNB_DPLL_SEL (0x7000 | REGS_SOUTH_SHARED) + // i2c #define INTEL_I2C_IO_A (0x5010 | REGS_SOUTH_SHARED) #define INTEL_I2C_IO_B (0x5014 | REGS_SOUTH_SHARED) diff --git a/src/add-ons/accelerants/intel_extreme/Pipes.cpp b/src/add-ons/accelerants/intel_extreme/Pipes.cpp index 8b34bbe6e5..1fa06121de 100644 --- a/src/add-ons/accelerants/intel_extreme/Pipes.cpp +++ b/src/add-ons/accelerants/intel_extreme/Pipes.cpp @@ -138,6 +138,12 @@ Pipe::Configure(display_mode* mode) write32(INTEL_DISPLAY_A_PIPE_CONTROL + fPipeOffset, pipeControl); read32(INTEL_DISPLAY_A_PIPE_CONTROL + fPipeOffset); #endif + + // According to SandyBridge modesetting sequence, pipe must be enabled + // before PLL are configured. + addr_t pipeReg = INTEL_DISPLAY_A_PIPE_CONTROL + fPipeOffset; + write32(pipeReg, read32(pipeReg) | INTEL_PIPE_ENABLED); + } @@ -320,6 +326,13 @@ Pipe::ConfigureClocks(const pll_divisors& divisors, uint32 pixelClock, // & DISPLAY_PLL_9xx_POST1_DIVISOR_MASK; } + // Also configure the FP0 divisor on SandyBridge + if (gInfo->shared_info->device_type.Generation() == 6) { + pll |= ((1 << (divisors.p1 - 1)) + << DISPLAY_PLL_SNB_FP0_POST1_DIVISOR_SHIFT) + & DISPLAY_PLL_SNB_FP0_POST1_DIVISOR_MASK; + } + if (divisors.p2 == 5 || divisors.p2 == 7) pll |= DISPLAY_PLL_DIVIDE_HIGH; @@ -339,12 +352,17 @@ Pipe::ConfigureClocks(const pll_divisors& divisors, uint32 pixelClock, pll |= DISPLAY_PLL_POST1_DIVIDE_2; } - // Allow the PLL to warm up by masking its bit. write32(pllControl, pll & ~DISPLAY_PLL_NO_VGA_CONTROL); + // FIXME what is this doing? Why put the PLL back under VGA_CONTROL + // here? read32(pllControl); spin(150); + + // Configure and enable the PLL write32(pllControl, pll); read32(pllControl); + + // Allow the PLL to warm up. spin(150); if (gInfo->shared_info->device_type.Generation() >= 6) { diff --git a/src/add-ons/accelerants/intel_extreme/Ports.cpp b/src/add-ons/accelerants/intel_extreme/Ports.cpp index ba8c99ac74..acdca8213e 100644 --- a/src/add-ons/accelerants/intel_extreme/Ports.cpp +++ b/src/add-ons/accelerants/intel_extreme/Ports.cpp @@ -381,9 +381,10 @@ LVDSPort::PipePreference() // Ideally we could just return INTEL_PIPE_ANY for the newer devices, but // this doesn't quite work yet. - // For Ibex Point and Sandy Bridge, read the existing LVDS configuration - // and just reuse that (it seems our attempt to change it doesn't work, - // anyway) + // For Ibex Point and SandyBridge, read the existing LVDS configuration and + // just reuse that (it seems our attempt to change it doesn't work, anyway) + // On SandyBridge, there is a transcoder C that can't be used by the LVDS + // port (but A and B would be fine). if (gInfo->shared_info->device_type.Generation() <= 6) { uint32 portState = read32(_PortRegister()); if (portState & DISPLAY_MONITOR_PIPE_B) @@ -392,9 +393,9 @@ LVDSPort::PipePreference() return INTEL_PIPE_A; } - // For later PCH versions, assume pipe B for now. Note that later devices - // add a pipe C (but do they add a transcoder C?), so we'd need to handle - // that and the port register has a different format because of it. + // For later generations, assume pipe B for now. Note that later devices + // add a pipe C (and a transcoder C), so we'd need to handle that and the + // port register has a different format because of it. // (using PORT_TRANS_*_SEL_CPT to select which transcoder to use) return INTEL_PIPE_B; } diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.cpp b/src/add-ons/accelerants/intel_extreme/accelerant.cpp index ad9414f436..2ce15758aa 100644 --- a/src/add-ons/accelerants/intel_extreme/accelerant.cpp +++ b/src/add-ons/accelerants/intel_extreme/accelerant.cpp @@ -366,9 +366,6 @@ probe_ports() foundLVDS = true; gInfo->ports[gInfo->port_count++] = lvdsPort; gInfo->head_mode |= HEAD_MODE_LVDS_PANEL; - gInfo->head_mode |= HEAD_MODE_A_ANALOG; - // FIXME this should not be set, but without it, LVDS modesetting - // doesn't work on SandyBridge. Find out why it makes a difference. gInfo->head_mode |= HEAD_MODE_B_DIGITAL; } else delete lvdsPort; @@ -497,9 +494,6 @@ intel_init_accelerant(int device) setup_ring_buffer(info.primary_ring_buffer, "intel primary ring buffer"); - TRACE("pipe control for: 0x%" B_PRIx32 " 0x%" B_PRIx32 "\n", - read32(INTEL_PIPE_CONTROL), read32(INTEL_PIPE_CONTROL)); - // Probe all ports status = probe_ports(); diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.h b/src/add-ons/accelerants/intel_extreme/accelerant.h index 0b34dda2f1..0014fd79df 100644 --- a/src/add-ons/accelerants/intel_extreme/accelerant.h +++ b/src/add-ons/accelerants/intel_extreme/accelerant.h @@ -75,10 +75,7 @@ struct accelerant_info { #define HEAD_MODE_A_ANALOG 0x0001 #define HEAD_MODE_B_DIGITAL 0x0002 -#define HEAD_MODE_CLONE 0x0003 #define HEAD_MODE_LVDS_PANEL 0x0008 -#define HEAD_MODE_TESTING 0x1000 -#define HEAD_MODE_STIPPI 0x2000 extern accelerant_info* gInfo; diff --git a/src/add-ons/accelerants/intel_extreme/mode.cpp b/src/add-ons/accelerants/intel_extreme/mode.cpp index 06e73a1b98..529dbf7961 100644 --- a/src/add-ons/accelerants/intel_extreme/mode.cpp +++ b/src/add-ons/accelerants/intel_extreme/mode.cpp @@ -210,9 +210,11 @@ void wait_for_vblank(void) { acquire_sem_etc(gInfo->shared_info->vblank_sem, 1, B_RELATIVE_TIMEOUT, - 25000); + 21000); // With the output turned off via DPMS, we might not get any interrupts - // anymore that's why we don't wait forever for it. + // anymore that's why we don't wait forever for it. At 50Hz, we're sure + // to get a vblank in at most 20ms, so there is no need to wait longer + // than that. } diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/device.cpp b/src/add-ons/kernel/drivers/graphics/intel_extreme/device.cpp index aaa891c48e..8ab3614c37 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/device.cpp +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/device.cpp @@ -120,51 +120,51 @@ dump_pipe_info(int argc, char** argv) kprintf("intel_extreme pipe configuration:\n"); value = read32(info, INTEL_DISPLAY_A_HTOTAL + pipeOffset); - kprintf(" HTOTAL start %" B_PRIu32 " end %" B_PRIu32 "\n", value >> 16, - value & 0xFFFF); + kprintf(" HTOTAL start %" B_PRIu32 " end %" B_PRIu32 "\n", + (value & 0xFFFF) + 1, (value >> 16) + 1); value = read32(info, INTEL_DISPLAY_A_HBLANK + pipeOffset); - kprintf(" HBLANK start %" B_PRIu32 " end %" B_PRIu32 "\n", value >> 16, - value & 0xFFFF); + kprintf(" HBLANK start %" B_PRIu32 " end %" B_PRIu32 "\n", + (value & 0xFFFF) + 1, (value >> 16) + 1); value = read32(info, INTEL_DISPLAY_A_HSYNC + pipeOffset); - kprintf(" HSYNC start %" B_PRIu32 " end %" B_PRIu32 "\n", value >> 16, - value & 0xFFFF); + kprintf(" HSYNC start %" B_PRIu32 " end %" B_PRIu32 "\n", + (value & 0xFFFF) + 1, (value >> 16) + 1); value = read32(info, INTEL_DISPLAY_A_VTOTAL + pipeOffset); - kprintf(" VTOTAL start %" B_PRIu32 " end %" B_PRIu32 "\n", value >> 16, - value & 0xFFFF); + kprintf(" VTOTAL start %" B_PRIu32 " end %" B_PRIu32 "\n", + (value & 0xFFFF) + 1, (value >> 16) + 1); value = read32(info, INTEL_DISPLAY_A_VBLANK + pipeOffset); - kprintf(" VBLANK start %" B_PRIu32 " end %" B_PRIu32 "\n", value >> 16, - value & 0xFFFF); + kprintf(" VBLANK start %" B_PRIu32 " end %" B_PRIu32 "\n", + (value & 0xFFFF) + 1, (value >> 16) + 1); value = read32(info, INTEL_DISPLAY_A_VSYNC + pipeOffset); - kprintf(" VSYNC start %" B_PRIu32 " end %" B_PRIu32 "\n", value >> 16, - value & 0xFFFF); + kprintf(" VSYNC start %" B_PRIu32 " end %" B_PRIu32 "\n", + (value & 0xFFFF) + 1, (value >> 16) + 1); value = read32(info, INTEL_DISPLAY_A_PIPE_SIZE + pipeOffset); - kprintf(" SIZE %" B_PRIu32 "x%" B_PRIu32 "\n", value >> 16, - value & 0xFFFF); + kprintf(" SIZE %" B_PRIu32 "x%" B_PRIu32 "\n", + (value & 0xFFFF) + 1, (value >> 16) + 1); if (info.pch_info != INTEL_PCH_NONE) { kprintf("intel_extreme transcoder configuration:\n"); value = read32(info, INTEL_TRANSCODER_A_HTOTAL + pipeOffset); - kprintf(" HTOTAL start %" B_PRIu32 " end %" B_PRIu32 "\n", value >> 16, - value & 0xFFFF); + kprintf(" HTOTAL start %" B_PRIu32 " end %" B_PRIu32 "\n", + (value & 0xFFFF) + 1, (value >> 16) + 1); value = read32(info, INTEL_TRANSCODER_A_HBLANK + pipeOffset); - kprintf(" HBLANK start %" B_PRIu32 " end %" B_PRIu32 "\n", value >> 16, - value & 0xFFFF); + kprintf(" HBLANK start %" B_PRIu32 " end %" B_PRIu32 "\n", + (value & 0xFFFF) + 1, (value >> 16) + 1); value = read32(info, INTEL_TRANSCODER_A_HSYNC + pipeOffset); - kprintf(" HSYNC start %" B_PRIu32 " end %" B_PRIu32 "\n", value >> 16, - value & 0xFFFF); + kprintf(" HSYNC start %" B_PRIu32 " end %" B_PRIu32 "\n", + (value & 0xFFFF) + 1, (value >> 16) + 1); value = read32(info, INTEL_TRANSCODER_A_VTOTAL + pipeOffset); - kprintf(" VTOTAL start %" B_PRIu32 " end %" B_PRIu32 "\n", value >> 16, - value & 0xFFFF); + kprintf(" VTOTAL start %" B_PRIu32 " end %" B_PRIu32 "\n", + (value & 0xFFFF) + 1, (value >> 16) + 1); value = read32(info, INTEL_TRANSCODER_A_VBLANK + pipeOffset); - kprintf(" VBLANK start %" B_PRIu32 " end %" B_PRIu32 "\n", value >> 16, - value & 0xFFFF); + kprintf(" VBLANK start %" B_PRIu32 " end %" B_PRIu32 "\n", + (value & 0xFFFF) + 1, (value >> 16) + 1); value = read32(info, INTEL_TRANSCODER_A_VSYNC + pipeOffset); - kprintf(" VSYNC start %" B_PRIu32 " end %" B_PRIu32 "\n", value >> 16, - value & 0xFFFF); + kprintf(" VSYNC start %" B_PRIu32 " end %" B_PRIu32 "\n", + (value & 0xFFFF) + 1, (value >> 16) + 1); value = read32(info, INTEL_TRANSCODER_A_IMAGE_SIZE + pipeOffset); - kprintf(" SIZE %" B_PRIu32 "x%" B_PRIu32 "\n", value >> 16, - value & 0xFFFF); + kprintf(" SIZE %" B_PRIu32 "x%" B_PRIu32 "\n", + (value & 0xFFFF) + 1, (value >> 16) + 1); } kprintf("intel_extreme display plane configuration:\n");