diff options
author | Eric Hustvedt <ehustvedt@cecropia.com> | 2006-06-20 14:36:42 -0400 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2006-07-03 18:59:47 +1000 |
commit | f80d0d23f2010b7682e06449345e8199a2b2619c (patch) | |
tree | 4562504d7d10a87a9da62bdb0098850fd1fb13c9 | |
parent | 37bced38b3d09c3de7c871790eddde81a3ce57cb (diff) |
intelfb: add vsync interrupt support
[05/05] intelfb: Honor FB_ACTIVATE_VBL for display panning
Extends the intelfb_vsync struct to store panning offset. The interrupt service routine uses the stored panning offset if a pan is requested for the vsync. intelfbhw_disable_irq also pans the display if there is a pending request.
Signed-off-by: Eric Hustvedt <ehustvedt@cecropia.com>
-rw-r--r-- | drivers/video/intelfb/intelfb.h | 2 | ||||
-rw-r--r-- | drivers/video/intelfb/intelfbdrv.c | 2 | ||||
-rw-r--r-- | drivers/video/intelfb/intelfbhw.c | 16 |
3 files changed, 19 insertions, 1 deletions
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h index 65ac37071a0..abd4c5632e3 100644 --- a/drivers/video/intelfb/intelfb.h +++ b/drivers/video/intelfb/intelfb.h @@ -211,6 +211,8 @@ struct intelfb_heap_data { struct intelfb_vsync { wait_queue_head_t wait; unsigned int count; + int pan_display; + u32 pan_offset; }; struct intelfb_info { diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 08f8241bb92..9e93f820a93 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c @@ -900,6 +900,8 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) init_waitqueue_head(&dinfo->vsync.wait); spin_lock_init(&dinfo->int_lock); dinfo->irq_flags = 0; + dinfo->vsync.pan_display = 0; + dinfo->vsync.pan_offset = 0; return 0; diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c index 0f9631c2ad3..8038f558611 100644 --- a/drivers/video/intelfb/intelfbhw.c +++ b/drivers/video/intelfb/intelfbhw.c @@ -371,7 +371,13 @@ intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) offset += dinfo->fb.offset << 12; - OUTREG(DSPABASE, offset); + dinfo->vsync.pan_offset = offset; + if ((var->activate & FB_ACTIVATE_VBL) && !intelfbhw_enable_irq(dinfo, 0)) { + dinfo->vsync.pan_display = 1; + } else { + dinfo->vsync.pan_display = 0; + OUTREG(DSPABASE, offset); + } return 0; } @@ -1965,6 +1971,10 @@ intelfbhw_irq(int irq, void *dev_id, struct pt_regs *fp) { if (tmp & VSYNC_PIPE_A_INTERRUPT) { dinfo->vsync.count++; + if (dinfo->vsync.pan_display) { + dinfo->vsync.pan_display = 0; + OUTREG(DSPABASE, dinfo->vsync.pan_offset); + } wake_up_interruptible(&dinfo->vsync.wait); handled = 1; } @@ -2007,6 +2017,10 @@ intelfbhw_disable_irq(struct intelfb_info *dinfo) { u16 tmp; if (test_and_clear_bit(0, &dinfo->irq_flags)) { + if (dinfo->vsync.pan_display) { + dinfo->vsync.pan_display = 0; + OUTREG(DSPABASE, dinfo->vsync.pan_offset); + } spin_lock_irq(&dinfo->int_lock); OUTREG16(HWSTAM, 0xffff); OUTREG16(IMR, 0xffff); |