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
This commit is contained in:
Adrien Destugues 2010-11-26 20:36:40 +00:00
parent 97d623045e
commit a8e3ab4f46
2 changed files with 24 additions and 11 deletions

View File

@ -247,7 +247,8 @@ struct intel_free_graphics_memory {
#define INTEL_INTERRUPT_IDENTITY 0x020a4 #define INTEL_INTERRUPT_IDENTITY 0x020a4
#define INTEL_INTERRUPT_MASK 0x020a8 #define INTEL_INTERRUPT_MASK 0x020a8
#define INTEL_INTERRUPT_STATUS 0x020ac #define INTEL_INTERRUPT_STATUS 0x020ac
#define INTERRUPT_VBLANK (1 << 7) #define INTERRUPT_VBLANK_PIPEA (1 << 7)
#define INTERRUPT_VBLANK_PIPEB (1 << 5)
// ring buffer // ring buffer
#define INTEL_PRIMARY_RING_BUFFER 0x02030 #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_SIZE 0x71190
#define INTEL_DISPLAY_B_PIPE_CONTROL 0x71008 #define INTEL_DISPLAY_B_PIPE_CONTROL 0x71008
#define INTEL_DISPLAY_B_PIPE_STATUS 0x71024
#define INTEL_DISPLAY_B_CONTROL 0x71180 #define INTEL_DISPLAY_B_CONTROL 0x71180
#define INTEL_DISPLAY_B_BASE 0x71184 #define INTEL_DISPLAY_B_BASE 0x71184

View File

@ -82,12 +82,20 @@ intel_interrupt_handler(void *data)
int32 handled = B_HANDLED_INTERRUPT; int32 handled = B_HANDLED_INTERRUPT;
if ((identity & INTERRUPT_VBLANK) != 0) { if ((identity & INTERRUPT_VBLANK_PIPEA) != 0) {
handled = release_vblank_sem(info); handled = release_vblank_sem(info);
// make sure we'll get another one of those // make sure we'll get another one of those
write32(info.registers + INTEL_DISPLAY_A_PIPE_STATUS, 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! // setting the bit clears it!
@ -111,9 +119,8 @@ init_interrupt_handler(intel_info &info)
thread_id thread = find_thread(NULL); thread_id thread = find_thread(NULL);
thread_info threadInfo; thread_info threadInfo;
if (get_thread_info(thread, &threadInfo) != B_OK 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; status = B_ERROR;
}
if (status == B_OK && info.pci->u.h0.interrupt_pin != 0x00 if (status == B_OK && info.pci->u.h0.interrupt_pin != 0x00
&& info.pci->u.h0.interrupt_line != 0xff) { && 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, status = install_io_interrupt_handler(info.pci->u.h0.interrupt_line,
&intel_interrupt_handler, (void *)&info, 0); &intel_interrupt_handler, (void *)&info, 0);
if (status == B_OK) { 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 // enable interrupts - we only want VBLANK interrupts
write16(info.registers + INTEL_INTERRUPT_ENABLED, write16(info.registers + INTEL_INTERRUPT_ENABLED,
read16(info.registers + INTEL_INTERRUPT_ENABLED) read16(info.registers + INTEL_INTERRUPT_ENABLED)
| INTERRUPT_VBLANK); | INTERRUPT_VBLANK_PIPEA | INTERRUPT_VBLANK_PIPEB);
write16(info.registers + INTEL_INTERRUPT_MASK, ~INTERRUPT_VBLANK); write16(info.registers + INTEL_INTERRUPT_MASK,
~(INTERRUPT_VBLANK_PIPEA | INTERRUPT_VBLANK_PIPEB));
write32(info.registers + INTEL_DISPLAY_A_PIPE_STATUS,
DISPLAY_PIPE_VBLANK_STATUS);
write16(info.registers + INTEL_INTERRUPT_IDENTITY, ~0);
} }
} }
if (status < B_OK) { if (status < B_OK) {
@ -142,6 +152,7 @@ init_interrupt_handler(intel_info &info)
info.fake_interrupts = true; info.fake_interrupts = true;
// TODO: fake interrupts! // TODO: fake interrupts!
TRACE((DEVICE_NAME "Fake interrupt mode (no PCI interrupt line assigned)"));
status = B_ERROR; status = B_ERROR;
} }