-/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*-
- *
+/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*- */
+/*
* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
- *
+ *
* The Weather Channel (TM) funded Tungsten Graphics to develop the
* initial release of the Radeon 8500 driver under the XFree86 license.
* This notice must be preserved.
* Eric Anholt <anholt@FreeBSD.org>
*/
-#include "r128.h"
#include "drmP.h"
#include "drm.h"
#include "r128_drm.h"
#include "r128_drv.h"
-void r128_dma_service( DRM_IRQ_ARGS )
+u32 r128_get_vblank_counter(struct drm_device *dev, int crtc)
{
- drm_device_t *dev = (drm_device_t *) arg;
- drm_r128_private_t *dev_priv =
- (drm_r128_private_t *)dev->dev_private;
+ const drm_r128_private_t *dev_priv = dev->dev_private;
+
+ if (crtc != 0)
+ return 0;
+
+ return atomic_read(&dev_priv->vbl_received);
+}
+
+irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS)
+{
+ struct drm_device *dev = (struct drm_device *) arg;
+ drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
int status;
- status = R128_READ( R128_GEN_INT_STATUS );
-
+ status = R128_READ(R128_GEN_INT_STATUS);
+
/* VBLANK interrupt */
- if ( status & R128_CRTC_VBLANK_INT ) {
- R128_WRITE( R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK );
- atomic_inc(&dev->vbl_received);
- DRM_WAKEUP(&dev->vbl_queue);
- DRM(vbl_send_signals)( dev );
+ if (status & R128_CRTC_VBLANK_INT) {
+ R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
+ atomic_inc(&dev_priv->vbl_received);
+ drm_handle_vblank(dev, 0);
+ return IRQ_HANDLED;
}
+ return IRQ_NONE;
}
-int DRM(vblank_wait)(drm_device_t *dev, unsigned int *sequence)
+int r128_enable_vblank(struct drm_device *dev, int crtc)
{
- unsigned int cur_vblank;
- int ret = 0;
+ drm_r128_private_t *dev_priv = 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("%s: bad crtc %d\n", __FUNCTION__, crtc);
+ return -EINVAL;
+ }
- *sequence = cur_vblank;
+ R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN);
+ return 0;
+}
- return ret;
+void r128_disable_vblank(struct drm_device *dev, int crtc)
+{
+ if (crtc != 0)
+ DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
+
+ /*
+ * FIXME: implement proper interrupt disable by using the vblank
+ * counter register (if available)
+ *
+ * R128_WRITE(R128_GEN_INT_CNTL,
+ * R128_READ(R128_GEN_INT_CNTL) & ~R128_CRTC_VBLANK_INT_EN);
+ */
}
-void r128_driver_irq_preinstall( drm_device_t *dev ) {
- drm_r128_private_t *dev_priv =
- (drm_r128_private_t *)dev->dev_private;
+void r128_driver_irq_preinstall(struct drm_device * dev)
+{
+ drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
/* Disable *all* interrupts */
- R128_WRITE( R128_GEN_INT_CNTL, 0 );
+ R128_WRITE(R128_GEN_INT_CNTL, 0);
/* Clear vblank bit if it's already high */
- R128_WRITE( R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK );
+ R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
}
-void r128_driver_irq_postinstall( drm_device_t *dev ) {
- drm_r128_private_t *dev_priv =
- (drm_r128_private_t *)dev->dev_private;
-
- /* Turn on VBL interrupt */
- R128_WRITE( R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN );
+int r128_driver_irq_postinstall(struct drm_device * dev)
+{
+ return drm_vblank_init(dev, 1);
}
-void r128_driver_irq_uninstall( drm_device_t *dev ) {
- drm_r128_private_t *dev_priv =
- (drm_r128_private_t *)dev->dev_private;
- if ( dev_priv ) {
- /* Disable *all* interrupts */
- R128_WRITE( R128_GEN_INT_CNTL, 0 );
- }
+void r128_driver_irq_uninstall(struct drm_device * dev)
+{
+ drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
+ if (!dev_priv)
+ return;
+
+ /* Disable *all* interrupts */
+ R128_WRITE(R128_GEN_INT_CNTL, 0);
}