Some more SandyBridge specifics to get V-blank interrupts going.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42850 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
2cc1b10386
commit
395d16a9bd
@ -225,7 +225,11 @@ struct intel_free_graphics_memory {
|
||||
// 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 @@ struct intel_free_graphics_memory {
|
||||
#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)
|
||||
|
@ -76,13 +76,16 @@ intel_interrupt_handler(void *data)
|
||||
{
|
||||
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 @@ intel_interrupt_handler(void *data)
|
||||
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 @@ intel_interrupt_handler(void *data)
|
||||
}
|
||||
|
||||
// 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 @@ init_interrupt_handler(intel_info &info)
|
||||
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 @@ intel_extreme_uninit(intel_info &info)
|
||||
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user