From a8e3ab4f46ab0b3b122831f12680453eb412e04c Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Fri, 26 Nov 2010 20:36:40 +0000 Subject: [PATCH] Enable the VBlank interrupt on pipe B for LVDS panels. This gets it working for me. Most stuff using BDirectWindowand synced drawing should now work better (\n and TVBack demos for example) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39655 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../graphics/intel_extreme/intel_extreme.h | 4 ++- .../graphics/intel_extreme/intel_extreme.cpp | 31 +++++++++++++------ 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h b/headers/private/graphics/intel_extreme/intel_extreme.h index d34fd0fe3d..f16217488b 100644 --- a/headers/private/graphics/intel_extreme/intel_extreme.h +++ b/headers/private/graphics/intel_extreme/intel_extreme.h @@ -247,7 +247,8 @@ struct intel_free_graphics_memory { #define INTEL_INTERRUPT_IDENTITY 0x020a4 #define INTEL_INTERRUPT_MASK 0x020a8 #define INTEL_INTERRUPT_STATUS 0x020ac -#define INTERRUPT_VBLANK (1 << 7) +#define INTERRUPT_VBLANK_PIPEA (1 << 7) +#define INTERRUPT_VBLANK_PIPEB (1 << 5) // ring buffer #define INTEL_PRIMARY_RING_BUFFER 0x02030 @@ -358,6 +359,7 @@ struct intel_free_graphics_memory { #define INTEL_DISPLAY_B_PIPE_SIZE 0x71190 #define INTEL_DISPLAY_B_PIPE_CONTROL 0x71008 +#define INTEL_DISPLAY_B_PIPE_STATUS 0x71024 #define INTEL_DISPLAY_B_CONTROL 0x71180 #define INTEL_DISPLAY_B_BASE 0x71184 diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp index f946906c54..07cff4e6f0 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp @@ -82,12 +82,20 @@ intel_interrupt_handler(void *data) int32 handled = B_HANDLED_INTERRUPT; - if ((identity & INTERRUPT_VBLANK) != 0) { + if ((identity & INTERRUPT_VBLANK_PIPEA) != 0) { handled = release_vblank_sem(info); // make sure we'll get another one of those write32(info.registers + INTEL_DISPLAY_A_PIPE_STATUS, - DISPLAY_PIPE_VBLANK_STATUS); + DISPLAY_PIPE_VBLANK_STATUS | DISPLAY_PIPE_VBLANK_ENABLED); + } + + if ((identity & INTERRUPT_VBLANK_PIPEB) != 0) { + handled = release_vblank_sem(info); + + // make sure we'll get another one of those + write32(info.registers + INTEL_DISPLAY_B_PIPE_STATUS, + DISPLAY_PIPE_VBLANK_STATUS | DISPLAY_PIPE_VBLANK_ENABLED); } // setting the bit clears it! @@ -111,9 +119,8 @@ init_interrupt_handler(intel_info &info) thread_id thread = find_thread(NULL); thread_info threadInfo; if (get_thread_info(thread, &threadInfo) != B_OK - || set_sem_owner(info.shared_info->vblank_sem, threadInfo.team) != B_OK) { + || set_sem_owner(info.shared_info->vblank_sem, threadInfo.team) != B_OK) status = B_ERROR; - } if (status == B_OK && info.pci->u.h0.interrupt_pin != 0x00 && info.pci->u.h0.interrupt_line != 0xff) { @@ -124,15 +131,18 @@ init_interrupt_handler(intel_info &info) status = install_io_interrupt_handler(info.pci->u.h0.interrupt_line, &intel_interrupt_handler, (void *)&info, 0); if (status == B_OK) { + write32(info.registers + INTEL_DISPLAY_A_PIPE_STATUS, + 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); + // enable interrupts - we only want VBLANK interrupts write16(info.registers + INTEL_INTERRUPT_ENABLED, read16(info.registers + INTEL_INTERRUPT_ENABLED) - | INTERRUPT_VBLANK); - write16(info.registers + INTEL_INTERRUPT_MASK, ~INTERRUPT_VBLANK); - - write32(info.registers + INTEL_DISPLAY_A_PIPE_STATUS, - DISPLAY_PIPE_VBLANK_STATUS); - write16(info.registers + INTEL_INTERRUPT_IDENTITY, ~0); + | INTERRUPT_VBLANK_PIPEA | INTERRUPT_VBLANK_PIPEB); + write16(info.registers + INTEL_INTERRUPT_MASK, + ~(INTERRUPT_VBLANK_PIPEA | INTERRUPT_VBLANK_PIPEB)); } } if (status < B_OK) { @@ -142,6 +152,7 @@ init_interrupt_handler(intel_info &info) info.fake_interrupts = true; // TODO: fake interrupts! + TRACE((DEVICE_NAME "Fake interrupt mode (no PCI interrupt line assigned)")); status = B_ERROR; }