diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2008-04-22 02:03:07 -0400 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2008-04-26 04:01:07 -0400 |
commit | ac741ab71bb39e6977694ac0cc26678d8673cda4 (patch) | |
tree | f82e08399a0da5accba930444744b269479185dd /drivers/char/drm/drmP.h | |
parent | 2c14f28be2a3f2a2e9861b156d64fbe2bc7000c3 (diff) |
drm/vbl rework: rework how the drm deals with vblank.
Other Authors: Michel Dänzer <michel@tungstengraphics.com>
mga: Ian Romanick <idr@us.ibm.com>
via: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
This re-works the DRM internals to provide a better interface for drivers
to expose vblank on multiple crtcs.
It also includes work done by Michel on making i915 triple buffering and pageflipping work properly.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/char/drm/drmP.h')
-rw-r--r-- | drivers/char/drm/drmP.h | 91 |
1 files changed, 74 insertions, 17 deletions
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 5446235094d8..ecee3547a13f 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -100,10 +100,8 @@ struct drm_device; | |||
100 | #define DRIVER_HAVE_DMA 0x20 | 100 | #define DRIVER_HAVE_DMA 0x20 |
101 | #define DRIVER_HAVE_IRQ 0x40 | 101 | #define DRIVER_HAVE_IRQ 0x40 |
102 | #define DRIVER_IRQ_SHARED 0x80 | 102 | #define DRIVER_IRQ_SHARED 0x80 |
103 | #define DRIVER_IRQ_VBL 0x100 | ||
104 | #define DRIVER_DMA_QUEUE 0x200 | 103 | #define DRIVER_DMA_QUEUE 0x200 |
105 | #define DRIVER_FB_DMA 0x400 | 104 | #define DRIVER_FB_DMA 0x400 |
106 | #define DRIVER_IRQ_VBL2 0x800 | ||
107 | 105 | ||
108 | /***********************************************************************/ | 106 | /***********************************************************************/ |
109 | /** \name Begin the DRM... */ | 107 | /** \name Begin the DRM... */ |
@@ -579,10 +577,52 @@ struct drm_driver { | |||
579 | int (*context_dtor) (struct drm_device *dev, int context); | 577 | int (*context_dtor) (struct drm_device *dev, int context); |
580 | int (*kernel_context_switch) (struct drm_device *dev, int old, | 578 | int (*kernel_context_switch) (struct drm_device *dev, int old, |
581 | int new); | 579 | int new); |
582 | void (*kernel_context_switch_unlock) (struct drm_device *dev); | 580 | void (*kernel_context_switch_unlock) (struct drm_device * dev); |
583 | int (*vblank_wait) (struct drm_device *dev, unsigned int *sequence); | 581 | /** |
584 | int (*vblank_wait2) (struct drm_device *dev, unsigned int *sequence); | 582 | * get_vblank_counter - get raw hardware vblank counter |
585 | int (*dri_library_name) (struct drm_device *dev, char *buf); | 583 | * @dev: DRM device |
584 | * @crtc: counter to fetch | ||
585 | * | ||
586 | * Driver callback for fetching a raw hardware vblank counter | ||
587 | * for @crtc. If a device doesn't have a hardware counter, the | ||
588 | * driver can simply return the value of drm_vblank_count and | ||
589 | * make the enable_vblank() and disable_vblank() hooks into no-ops, | ||
590 | * leaving interrupts enabled at all times. | ||
591 | * | ||
592 | * Wraparound handling and loss of events due to modesetting is dealt | ||
593 | * with in the DRM core code. | ||
594 | * | ||
595 | * RETURNS | ||
596 | * Raw vblank counter value. | ||
597 | */ | ||
598 | u32 (*get_vblank_counter) (struct drm_device *dev, int crtc); | ||
599 | |||
600 | /** | ||
601 | * enable_vblank - enable vblank interrupt events | ||
602 | * @dev: DRM device | ||
603 | * @crtc: which irq to enable | ||
604 | * | ||
605 | * Enable vblank interrupts for @crtc. If the device doesn't have | ||
606 | * a hardware vblank counter, this routine should be a no-op, since | ||
607 | * interrupts will have to stay on to keep the count accurate. | ||
608 | * | ||
609 | * RETURNS | ||
610 | * Zero on success, appropriate errno if the given @crtc's vblank | ||
611 | * interrupt cannot be enabled. | ||
612 | */ | ||
613 | int (*enable_vblank) (struct drm_device *dev, int crtc); | ||
614 | |||
615 | /** | ||
616 | * disable_vblank - disable vblank interrupt events | ||
617 | * @dev: DRM device | ||
618 | * @crtc: which irq to enable | ||
619 | * | ||
620 | * Disable vblank interrupts for @crtc. If the device doesn't have | ||
621 | * a hardware vblank counter, this routine should be a no-op, since | ||
622 | * interrupts will have to stay on to keep the count accurate. | ||
623 | */ | ||
624 | void (*disable_vblank) (struct drm_device *dev, int crtc); | ||
625 | int (*dri_library_name) (struct drm_device *dev, char * buf); | ||
586 | 626 | ||
587 | /** | 627 | /** |
588 | * Called by \c drm_device_is_agp. Typically used to determine if a | 628 | * Called by \c drm_device_is_agp. Typically used to determine if a |
@@ -601,7 +641,7 @@ struct drm_driver { | |||
601 | 641 | ||
602 | irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); | 642 | irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); |
603 | void (*irq_preinstall) (struct drm_device *dev); | 643 | void (*irq_preinstall) (struct drm_device *dev); |
604 | void (*irq_postinstall) (struct drm_device *dev); | 644 | int (*irq_postinstall) (struct drm_device *dev); |
605 | void (*irq_uninstall) (struct drm_device *dev); | 645 | void (*irq_uninstall) (struct drm_device *dev); |
606 | void (*reclaim_buffers) (struct drm_device *dev, | 646 | void (*reclaim_buffers) (struct drm_device *dev, |
607 | struct drm_file * file_priv); | 647 | struct drm_file * file_priv); |
@@ -730,13 +770,21 @@ struct drm_device { | |||
730 | /** \name VBLANK IRQ support */ | 770 | /** \name VBLANK IRQ support */ |
731 | /*@{ */ | 771 | /*@{ */ |
732 | 772 | ||
733 | wait_queue_head_t vbl_queue; /**< VBLANK wait queue */ | 773 | wait_queue_head_t *vbl_queue; /**< VBLANK wait queue */ |
734 | atomic_t vbl_received; | 774 | atomic_t *_vblank_count; /**< number of VBLANK interrupts (driver must alloc the right number of counters) */ |
735 | atomic_t vbl_received2; /**< number of secondary VBLANK interrupts */ | ||
736 | spinlock_t vbl_lock; | 775 | spinlock_t vbl_lock; |
737 | struct list_head vbl_sigs; /**< signal list to send on VBLANK */ | 776 | struct list_head *vbl_sigs; /**< signal list to send on VBLANK */ |
738 | struct list_head vbl_sigs2; /**< signals to send on secondary VBLANK */ | 777 | atomic_t vbl_signal_pending; /* number of signals pending on all crtcs*/ |
739 | unsigned int vbl_pending; | 778 | atomic_t *vblank_refcount; /* number of users of vblank interrupts per crtc */ |
779 | u32 *last_vblank; /* protected by dev->vbl_lock, used */ | ||
780 | /* for wraparound handling */ | ||
781 | u32 *vblank_offset; /* used to track how many vblanks */ | ||
782 | int *vblank_enabled; /* so we don't call enable more than | ||
783 | once per disable */ | ||
784 | u32 *vblank_premodeset; /* were lost during modeset */ | ||
785 | struct timer_list vblank_disable_timer; | ||
786 | |||
787 | unsigned long max_vblank_count; /**< size of vblank counter register */ | ||
740 | spinlock_t tasklet_lock; /**< For drm_locked_tasklet */ | 788 | spinlock_t tasklet_lock; /**< For drm_locked_tasklet */ |
741 | void (*locked_tasklet_func)(struct drm_device *dev); | 789 | void (*locked_tasklet_func)(struct drm_device *dev); |
742 | 790 | ||
@@ -756,6 +804,7 @@ struct drm_device { | |||
756 | #ifdef __alpha__ | 804 | #ifdef __alpha__ |
757 | struct pci_controller *hose; | 805 | struct pci_controller *hose; |
758 | #endif | 806 | #endif |
807 | int num_crtcs; /**< Number of CRTCs on this device */ | ||
759 | struct drm_sg_mem *sg; /**< Scatter gather memory */ | 808 | struct drm_sg_mem *sg; /**< Scatter gather memory */ |
760 | void *dev_private; /**< device private data */ | 809 | void *dev_private; /**< device private data */ |
761 | struct drm_sigdata sigdata; /**< For block_all_signals */ | 810 | struct drm_sigdata sigdata; /**< For block_all_signals */ |
@@ -990,11 +1039,19 @@ extern void drm_driver_irq_preinstall(struct drm_device *dev); | |||
990 | extern void drm_driver_irq_postinstall(struct drm_device *dev); | 1039 | extern void drm_driver_irq_postinstall(struct drm_device *dev); |
991 | extern void drm_driver_irq_uninstall(struct drm_device *dev); | 1040 | extern void drm_driver_irq_uninstall(struct drm_device *dev); |
992 | 1041 | ||
993 | extern int drm_wait_vblank(struct drm_device *dev, void *data, | 1042 | extern int drm_vblank_init(struct drm_device *dev, int num_crtcs); |
994 | struct drm_file *file_priv); | 1043 | extern int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *filp); |
995 | extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq); | 1044 | extern int drm_vblank_wait(struct drm_device * dev, unsigned int *vbl_seq); |
996 | extern void drm_vbl_send_signals(struct drm_device *dev); | ||
997 | extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*)); | 1045 | extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*)); |
1046 | extern u32 drm_vblank_count(struct drm_device *dev, int crtc); | ||
1047 | extern void drm_update_vblank_count(struct drm_device *dev, int crtc); | ||
1048 | extern void drm_handle_vblank(struct drm_device *dev, int crtc); | ||
1049 | extern int drm_vblank_get(struct drm_device *dev, int crtc); | ||
1050 | extern void drm_vblank_put(struct drm_device *dev, int crtc); | ||
1051 | |||
1052 | /* Modesetting support */ | ||
1053 | extern int drm_modeset_ctl(struct drm_device *dev, void *data, | ||
1054 | struct drm_file *file_priv); | ||
998 | 1055 | ||
999 | /* AGP/GART support (drm_agpsupport.h) */ | 1056 | /* AGP/GART support (drm_agpsupport.h) */ |
1000 | extern struct drm_agp_head *drm_agp_init(struct drm_device *dev); | 1057 | extern struct drm_agp_head *drm_agp_init(struct drm_device *dev); |