BSD vblank framework.
parent
770d045d25
commit
97961e2c65
|
@ -464,6 +464,10 @@ struct drm_device {
|
|||
unsigned long last_switch; /* jiffies at last context switch */
|
||||
#if __FreeBSD_version >= 400005
|
||||
struct task task;
|
||||
#endif
|
||||
#if __HAVE_VBL_IRQ
|
||||
wait_queue_head_t vbl_queue; /* vbl wait channel */
|
||||
atomic_t vbl_received;
|
||||
#endif
|
||||
cycles_t ctx_start;
|
||||
cycles_t lck_start;
|
||||
|
@ -579,6 +583,9 @@ extern int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma);
|
|||
extern int DRM(irq_install)( drm_device_t *dev, int irq );
|
||||
extern int DRM(irq_uninstall)( drm_device_t *dev );
|
||||
extern void DRM(dma_service)( DRM_IRQ_ARGS );
|
||||
extern void DRM(driver_irq_preinstall)( drm_device_t *dev );
|
||||
extern void DRM(driver_irq_postinstall)( drm_device_t *dev );
|
||||
extern void DRM(driver_irq_uninstall)( drm_device_t *dev );
|
||||
#if __HAVE_DMA_IRQ_BH
|
||||
extern void DRM(dma_immediate_bh)( DRM_TASKQUEUE_ARGS );
|
||||
#endif
|
||||
|
@ -603,6 +610,9 @@ extern int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl,
|
|||
extern drm_buf_t *DRM(freelist_get)(drm_freelist_t *bl, int block);
|
||||
#endif
|
||||
#endif /* __HAVE_DMA */
|
||||
#if __HAVE_VBL_IRQ
|
||||
extern int DRM(vblank_wait)(drm_device_t *dev, unsigned int *vbl_seq);
|
||||
#endif
|
||||
|
||||
#if __REALLY_HAVE_AGP
|
||||
/* AGP/GART support (drm_agpsupport.h) */
|
||||
|
|
|
@ -532,7 +532,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
|
|||
#endif
|
||||
|
||||
/* Before installing handler */
|
||||
DRIVER_PREINSTALL();
|
||||
DRM(driver_irq_preinstall)( dev );
|
||||
|
||||
/* Install handler */
|
||||
rid = 0;
|
||||
|
@ -552,7 +552,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
|
|||
}
|
||||
|
||||
/* After installing handler */
|
||||
DRIVER_POSTINSTALL();
|
||||
DRM(driver_irq_postinstall)( dev );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -571,7 +571,7 @@ int DRM(irq_uninstall)( drm_device_t *dev )
|
|||
|
||||
DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq );
|
||||
|
||||
DRIVER_UNINSTALL();
|
||||
DRM(driver_irq_uninstall)( dev );
|
||||
|
||||
bus_teardown_intr(dev->device, dev->irqr, dev->irqh);
|
||||
bus_release_resource(dev->device, SYS_RES_IRQ, 0, dev->irqr);
|
||||
|
@ -596,6 +596,58 @@ int DRM(control)( DRM_IOCTL_ARGS )
|
|||
}
|
||||
}
|
||||
|
||||
#if __HAVE_VBL_IRQ
|
||||
|
||||
int DRM(vblank_wait)(drm_device_t *dev, unsigned int *sequence)
|
||||
{
|
||||
unsigned int cur_vblank;
|
||||
int ret = 0;
|
||||
|
||||
/* Assume that the user has missed the current sequence number by about
|
||||
* a day rather than she wants to wait for years using vertical blanks :)
|
||||
*/
|
||||
while ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) )
|
||||
+ ~*sequence + 1 ) > (1<<23) ) {
|
||||
ret = tsleep( &dev->vbl_queue, 3*hz, "rdnvbl", PZERO | PCATCH);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
*sequence = cur_vblank;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int DRM(wait_vblank)( DRM_IOCTL_ARGS )
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_wait_vblank_t vblwait;
|
||||
struct timeval now;
|
||||
int ret;
|
||||
|
||||
if (!dev->irq)
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( vblwait, (drm_wait_vblank_t *)data,
|
||||
sizeof(vblwait) );
|
||||
|
||||
if ( vblwait.type == _DRM_VBLANK_RELATIVE ) {
|
||||
vblwait.sequence += atomic_read( &dev->vbl_received );
|
||||
}
|
||||
|
||||
ret = DRM(vblank_wait)( dev, &vblwait.sequence );
|
||||
|
||||
microtime( &now );
|
||||
vblwait.tval_sec = now.tv_sec;
|
||||
vblwait.tval_usec = now.tv_usec;
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL( (drm_wait_vblank_t *)data, vblwait,
|
||||
sizeof(vblwait) );
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* __HAVE_VBL_IRQ */
|
||||
|
||||
#else
|
||||
|
||||
int DRM(control)( DRM_IOCTL_ARGS )
|
||||
|
@ -616,3 +668,4 @@ int DRM(control)( DRM_IOCTL_ARGS )
|
|||
#endif /* __HAVE_DMA_IRQ */
|
||||
|
||||
#endif /* __HAVE_DMA */
|
||||
|
||||
|
|
|
@ -217,6 +217,10 @@ static drm_ioctl_desc_t DRM(ioctls)[] = {
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { DRM(sg_free), 1, 1 },
|
||||
#endif
|
||||
|
||||
#if __HAVE_VBL_IRQ
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = { DRM(wait_vblank), 0, 0 },
|
||||
#endif
|
||||
|
||||
DRIVER_IOCTLS
|
||||
};
|
||||
|
||||
|
|
|
@ -407,6 +407,9 @@ extern int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS;
|
|||
#if __HAVE_DMA
|
||||
extern d_ioctl_t DRM(control);
|
||||
#endif
|
||||
#if __HAVE_VBL_IRQ
|
||||
extern d_ioctl_t DRM(wait_vblank);
|
||||
#endif
|
||||
|
||||
/* AGP/GART support (drm_agpsupport.h) */
|
||||
#if __REALLY_HAVE_AGP
|
||||
|
|
14
bsd/drm.h
14
bsd/drm.h
|
@ -345,6 +345,18 @@ typedef struct drm_irq_busid {
|
|||
int funcnum;
|
||||
} drm_irq_busid_t;
|
||||
|
||||
typedef enum {
|
||||
_DRM_VBLANK_ABSOLUTE = 0x0, /* Wait for specific vblank sequence number */
|
||||
_DRM_VBLANK_RELATIVE = 0x1 /* Wait for given number of vblanks */
|
||||
} drm_vblank_seq_type_t;
|
||||
|
||||
typedef struct drm_radeon_vbl_wait {
|
||||
drm_vblank_seq_type_t type;
|
||||
unsigned int sequence;
|
||||
long tval_sec;
|
||||
long tval_usec;
|
||||
} drm_wait_vblank_t;
|
||||
|
||||
typedef struct drm_agp_mode {
|
||||
unsigned long mode;
|
||||
} drm_agp_mode_t;
|
||||
|
@ -439,6 +451,8 @@ typedef struct drm_scatter_gather {
|
|||
#define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t)
|
||||
#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t)
|
||||
|
||||
#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, drm_wait_vblank_t)
|
||||
|
||||
/* Device specfic ioctls should only be in their respective headers
|
||||
* The device specific ioctl range is 0x40 to 0x79. */
|
||||
#define DRM_COMMAND_BASE 0x40
|
||||
|
|
10
bsd/drmP.h
10
bsd/drmP.h
|
@ -464,6 +464,10 @@ struct drm_device {
|
|||
unsigned long last_switch; /* jiffies at last context switch */
|
||||
#if __FreeBSD_version >= 400005
|
||||
struct task task;
|
||||
#endif
|
||||
#if __HAVE_VBL_IRQ
|
||||
wait_queue_head_t vbl_queue; /* vbl wait channel */
|
||||
atomic_t vbl_received;
|
||||
#endif
|
||||
cycles_t ctx_start;
|
||||
cycles_t lck_start;
|
||||
|
@ -579,6 +583,9 @@ extern int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma);
|
|||
extern int DRM(irq_install)( drm_device_t *dev, int irq );
|
||||
extern int DRM(irq_uninstall)( drm_device_t *dev );
|
||||
extern void DRM(dma_service)( DRM_IRQ_ARGS );
|
||||
extern void DRM(driver_irq_preinstall)( drm_device_t *dev );
|
||||
extern void DRM(driver_irq_postinstall)( drm_device_t *dev );
|
||||
extern void DRM(driver_irq_uninstall)( drm_device_t *dev );
|
||||
#if __HAVE_DMA_IRQ_BH
|
||||
extern void DRM(dma_immediate_bh)( DRM_TASKQUEUE_ARGS );
|
||||
#endif
|
||||
|
@ -603,6 +610,9 @@ extern int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl,
|
|||
extern drm_buf_t *DRM(freelist_get)(drm_freelist_t *bl, int block);
|
||||
#endif
|
||||
#endif /* __HAVE_DMA */
|
||||
#if __HAVE_VBL_IRQ
|
||||
extern int DRM(vblank_wait)(drm_device_t *dev, unsigned int *vbl_seq);
|
||||
#endif
|
||||
|
||||
#if __REALLY_HAVE_AGP
|
||||
/* AGP/GART support (drm_agpsupport.h) */
|
||||
|
|
|
@ -532,7 +532,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
|
|||
#endif
|
||||
|
||||
/* Before installing handler */
|
||||
DRIVER_PREINSTALL();
|
||||
DRM(driver_irq_preinstall)( dev );
|
||||
|
||||
/* Install handler */
|
||||
rid = 0;
|
||||
|
@ -552,7 +552,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
|
|||
}
|
||||
|
||||
/* After installing handler */
|
||||
DRIVER_POSTINSTALL();
|
||||
DRM(driver_irq_postinstall)( dev );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -571,7 +571,7 @@ int DRM(irq_uninstall)( drm_device_t *dev )
|
|||
|
||||
DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq );
|
||||
|
||||
DRIVER_UNINSTALL();
|
||||
DRM(driver_irq_uninstall)( dev );
|
||||
|
||||
bus_teardown_intr(dev->device, dev->irqr, dev->irqh);
|
||||
bus_release_resource(dev->device, SYS_RES_IRQ, 0, dev->irqr);
|
||||
|
@ -596,6 +596,58 @@ int DRM(control)( DRM_IOCTL_ARGS )
|
|||
}
|
||||
}
|
||||
|
||||
#if __HAVE_VBL_IRQ
|
||||
|
||||
int DRM(vblank_wait)(drm_device_t *dev, unsigned int *sequence)
|
||||
{
|
||||
unsigned int cur_vblank;
|
||||
int ret = 0;
|
||||
|
||||
/* Assume that the user has missed the current sequence number by about
|
||||
* a day rather than she wants to wait for years using vertical blanks :)
|
||||
*/
|
||||
while ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) )
|
||||
+ ~*sequence + 1 ) > (1<<23) ) {
|
||||
ret = tsleep( &dev->vbl_queue, 3*hz, "rdnvbl", PZERO | PCATCH);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
*sequence = cur_vblank;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int DRM(wait_vblank)( DRM_IOCTL_ARGS )
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_wait_vblank_t vblwait;
|
||||
struct timeval now;
|
||||
int ret;
|
||||
|
||||
if (!dev->irq)
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( vblwait, (drm_wait_vblank_t *)data,
|
||||
sizeof(vblwait) );
|
||||
|
||||
if ( vblwait.type == _DRM_VBLANK_RELATIVE ) {
|
||||
vblwait.sequence += atomic_read( &dev->vbl_received );
|
||||
}
|
||||
|
||||
ret = DRM(vblank_wait)( dev, &vblwait.sequence );
|
||||
|
||||
microtime( &now );
|
||||
vblwait.tval_sec = now.tv_sec;
|
||||
vblwait.tval_usec = now.tv_usec;
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL( (drm_wait_vblank_t *)data, vblwait,
|
||||
sizeof(vblwait) );
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* __HAVE_VBL_IRQ */
|
||||
|
||||
#else
|
||||
|
||||
int DRM(control)( DRM_IOCTL_ARGS )
|
||||
|
@ -616,3 +668,4 @@ int DRM(control)( DRM_IOCTL_ARGS )
|
|||
#endif /* __HAVE_DMA_IRQ */
|
||||
|
||||
#endif /* __HAVE_DMA */
|
||||
|
||||
|
|
|
@ -217,6 +217,10 @@ static drm_ioctl_desc_t DRM(ioctls)[] = {
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { DRM(sg_free), 1, 1 },
|
||||
#endif
|
||||
|
||||
#if __HAVE_VBL_IRQ
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = { DRM(wait_vblank), 0, 0 },
|
||||
#endif
|
||||
|
||||
DRIVER_IOCTLS
|
||||
};
|
||||
|
||||
|
|
|
@ -407,6 +407,9 @@ extern int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS;
|
|||
#if __HAVE_DMA
|
||||
extern d_ioctl_t DRM(control);
|
||||
#endif
|
||||
#if __HAVE_VBL_IRQ
|
||||
extern d_ioctl_t DRM(wait_vblank);
|
||||
#endif
|
||||
|
||||
/* AGP/GART support (drm_agpsupport.h) */
|
||||
#if __REALLY_HAVE_AGP
|
||||
|
|
22
bsd/gamma.h
22
bsd/gamma.h
|
@ -67,27 +67,5 @@
|
|||
|
||||
#define __HAVE_DMA_IRQ 1
|
||||
#define __HAVE_DMA_IRQ_BH 1
|
||||
#define DRIVER_PREINSTALL() do { \
|
||||
drm_gamma_private_t *dev_priv = \
|
||||
(drm_gamma_private_t *)dev->dev_private;\
|
||||
GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000000 ); \
|
||||
GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); \
|
||||
} while (0)
|
||||
|
||||
#define DRIVER_POSTINSTALL() do { \
|
||||
drm_gamma_private_t *dev_priv = \
|
||||
(drm_gamma_private_t *)dev->dev_private;\
|
||||
GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 ); \
|
||||
GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 ); \
|
||||
GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 ); \
|
||||
} while (0)
|
||||
|
||||
#define DRIVER_UNINSTALL() do { \
|
||||
drm_gamma_private_t *dev_priv = \
|
||||
(drm_gamma_private_t *)dev->dev_private;\
|
||||
GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 ); \
|
||||
GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 ); \
|
||||
GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 ); \
|
||||
} while (0)
|
||||
|
||||
#endif /* __GAMMA_H__ */
|
||||
|
|
|
@ -567,3 +567,45 @@ int gamma_dma( DRM_IOCTL_ARGS )
|
|||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
void DRM(driver_irq_preinstall)(drm_device_t *dev) {
|
||||
drm_gamma_private_t *dev_priv =
|
||||
(drm_gamma_private_t *)dev->dev_private;
|
||||
#if 1
|
||||
while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2);
|
||||
GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000004 );
|
||||
GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 );
|
||||
#else
|
||||
while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2);
|
||||
while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2);
|
||||
GAMMA_WRITE( GAMMA_GCOMMANDMODE, GAMMA_QUEUED_DMA_MODE );
|
||||
GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 );
|
||||
#endif
|
||||
}
|
||||
|
||||
void DRM(driver_irq_postinstall)(drm_device_t *dev) {
|
||||
drm_gamma_private_t *dev_priv =
|
||||
(drm_gamma_private_t *)dev->dev_private;
|
||||
#if 1
|
||||
while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2);
|
||||
while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3);
|
||||
GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 );
|
||||
GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 );
|
||||
GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 );
|
||||
#else
|
||||
while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2);
|
||||
while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2);
|
||||
GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002000 );
|
||||
GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000004 );
|
||||
#endif
|
||||
}
|
||||
|
||||
void DRM(driver_irq_uninstall)( drm_device_t *dev ) {
|
||||
drm_gamma_private_t *dev_priv =
|
||||
(drm_gamma_private_t *)dev->dev_private;
|
||||
while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2);
|
||||
while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3);
|
||||
GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 );
|
||||
GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 );
|
||||
GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 );
|
||||
}
|
||||
|
|
|
@ -195,7 +195,6 @@ extern int radeon_irq_wait( DRM_IOCTL_ARGS );
|
|||
extern int radeon_emit_and_wait_irq(drm_device_t *dev);
|
||||
extern int radeon_wait_irq(drm_device_t *dev, int swi_nr);
|
||||
extern int radeon_emit_irq(drm_device_t *dev);
|
||||
extern int radeon_vblank_wait(drm_device_t *dev, unsigned int *vbl_seq);
|
||||
|
||||
|
||||
/* Flags for stats.boxes
|
||||
|
|
|
@ -195,7 +195,6 @@ extern int radeon_irq_wait( DRM_IOCTL_ARGS );
|
|||
extern int radeon_emit_and_wait_irq(drm_device_t *dev);
|
||||
extern int radeon_wait_irq(drm_device_t *dev, int swi_nr);
|
||||
extern int radeon_emit_irq(drm_device_t *dev);
|
||||
extern int radeon_vblank_wait(drm_device_t *dev, unsigned int *vbl_seq);
|
||||
|
||||
|
||||
/* Flags for stats.boxes
|
||||
|
|
Loading…
Reference in New Issue