From 7e9ea55a2f052cc939ba9bbf9edac39798344b7a Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 25 Oct 2007 17:14:53 -0700 Subject: Initial pass at porting MGA to vblank-rework This is currently only compile tested. --- shared-core/mga_irq.c | 79 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 23 deletions(-) (limited to 'shared-core/mga_irq.c') diff --git a/shared-core/mga_irq.c b/shared-core/mga_irq.c index 490d1fbb..a49a9b6e 100644 --- a/shared-core/mga_irq.c +++ b/shared-core/mga_irq.c @@ -36,6 +36,20 @@ #include "mga_drm.h" #include "mga_drv.h" +u32 mga_get_vblank_counter(drm_device_t *dev, int crtc) +{ + const drm_mga_private_t *const dev_priv = + (drm_mga_private_t *) dev->dev_private; + + if (crtc != 0) { + return 0; + } + + + return atomic_read(&dev_priv->vbl_received); +} + + irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) { drm_device_t *dev = (drm_device_t *) arg; @@ -48,9 +62,8 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) /* VBLANK interrupt */ if (status & MGA_VLINEPEN) { MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR); - atomic_inc(&dev->vbl_received); - DRM_WAKEUP(&dev->vbl_queue); - drm_vbl_send_signals(dev); + atomic_inc(&dev_priv->vbl_received); + drm_handle_vblank(dev, 0); handled = 1; } @@ -74,30 +87,41 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) handled = 1; } - if ( handled ) { - return IRQ_HANDLED; - } - return IRQ_NONE; + return (handled) ? IRQ_HANDLED : IRQ_NONE; } -int mga_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) + +int mga_enable_vblank(drm_device_t *dev, int crtc) { - unsigned int cur_vblank; - int ret = 0; + drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - /* 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... - */ - DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, - (((cur_vblank = atomic_read(&dev->vbl_received)) - - *sequence) <= (1 << 23))); + if (crtc != 0) { + DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", + crtc); + return 0; + } + + MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); + return 0; +} - *sequence = cur_vblank; - return ret; +void mga_disable_vblank(drm_device_t *dev, int crtc) +{ + if (crtc != 0) { + DRM_ERROR("tried to disable vblank on non-existent crtc %d\n", + crtc); + } + + /* Do *NOT* disable the vertical refresh interrupt. MGA doesn't have + * a nice hardware counter that tracks the number of refreshes when + * the interrupt is disabled, and the kernel doesn't know the refresh + * rate to calculate an estimate. + */ + /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */ } + int mga_driver_fence_wait(drm_device_t * dev, unsigned int *sequence) { drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; @@ -127,16 +151,25 @@ void mga_driver_irq_preinstall(drm_device_t * dev) MGA_WRITE(MGA_ICLEAR, ~0); } -void mga_driver_irq_postinstall(drm_device_t * dev) +int mga_driver_irq_postinstall(drm_device_t * dev) { drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; + int ret; - DRM_INIT_WAITQUEUE( &dev_priv->fence_queue ); + ret = drm_vblank_init(dev, 1); + if (ret) + return ret; - /* Turn on vertical blank interrupt and soft trap interrupt. */ - MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); + DRM_INIT_WAITQUEUE(&dev_priv->fence_queue); + + /* Turn on soft trap interrupt. Vertical blank interrupts are enabled + * in mga_enable_vblank. + */ + MGA_WRITE(MGA_IEN, MGA_SOFTRAPEN); + return 0; } + void mga_driver_irq_uninstall(drm_device_t * dev) { drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; -- cgit v1.2.3