mach64_irq.c revision 145132
1/* mach64_irq.c -- IRQ handling for ATI Mach64 -*- linux-c -*- 2 * Created: Tue Feb 25, 2003 by Leif Delgass, based on radeon_irq.c/r128_irq.c 3 * 4 * Copyright (C) The Weather Channel, Inc. 2002. 5 * Copyright 2003 Leif Delgass 6 * All Rights Reserved. 7 * 8 * The Weather Channel (TM) funded Tungsten Graphics to develop the 9 * initial release of the Radeon 8500 driver under the XFree86 license. 10 * This notice must be preserved. 11 * 12 * Permission is hereby granted, free of charge, to any person obtaining a 13 * copy of this software and associated documentation files (the "Software"), 14 * to deal in the Software without restriction, including without limitation 15 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 16 * and/or sell copies of the Software, and to permit persons to whom the 17 * Software is furnished to do so, subject to the following conditions: 18 * 19 * The above copyright notice and this permission notice (including the next 20 * paragraph) shall be included in all copies or substantial portions of the 21 * Software. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 26 * THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 27 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 28 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 29 * DEALINGS IN THE SOFTWARE. 30 * 31 * Authors: 32 * Keith Whitwell <keith@tungstengraphics.com> 33 * Eric Anholt <anholt@FreeBSD.org> 34 * Leif Delgass <ldelgass@retinalburn.net> 35 * 36 * $FreeBSD: head/sys/dev/drm/mach64_irq.c 145132 2005-04-16 03:44:47Z anholt $ 37 */ 38 39#include "dev/drm/drmP.h" 40#include "dev/drm/drm.h" 41#include "dev/drm/mach64_drm.h" 42#include "dev/drm/mach64_drv.h" 43 44irqreturn_t mach64_driver_irq_handler(DRM_IRQ_ARGS) 45{ 46 drm_device_t *dev = (drm_device_t *) arg; 47 drm_mach64_private_t *dev_priv = 48 (drm_mach64_private_t *) dev->dev_private; 49 int status; 50 51 status = MACH64_READ(MACH64_CRTC_INT_CNTL); 52 53 /* VBLANK interrupt */ 54 if (status & MACH64_CRTC_VBLANK_INT) { 55 /* Mask off all interrupt ack bits before setting the ack bit, since 56 * there may be other handlers outside the DRM. 57 * 58 * NOTE: On mach64, you need to keep the enable bits set when doing 59 * the ack, despite what the docs say about not acking and enabling 60 * in a single write. 61 */ 62 MACH64_WRITE(MACH64_CRTC_INT_CNTL, 63 (status & ~MACH64_CRTC_INT_ACKS) 64 | MACH64_CRTC_VBLANK_INT); 65 66 atomic_inc(&dev->vbl_received); 67 DRM_WAKEUP(&dev->vbl_queue); 68 drm_vbl_send_signals(dev); 69 return IRQ_HANDLED; 70 } 71 return IRQ_NONE; 72} 73 74int mach64_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) 75{ 76 unsigned int cur_vblank; 77 int ret = 0; 78 79 /* Assume that the user has missed the current sequence number 80 * by about a day rather than she wants to wait for years 81 * using vertical blanks... 82 */ 83 DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, 84 (((cur_vblank = atomic_read(&dev->vbl_received)) 85 - *sequence) <= (1 << 23))); 86 87 *sequence = cur_vblank; 88 89 return ret; 90} 91 92/* drm_dma.h hooks 93*/ 94void mach64_driver_irq_preinstall(drm_device_t * dev) 95{ 96 drm_mach64_private_t *dev_priv = 97 (drm_mach64_private_t *) dev->dev_private; 98 99 u32 status = MACH64_READ(MACH64_CRTC_INT_CNTL); 100 101 DRM_DEBUG("before install CRTC_INT_CTNL: 0x%08x\n", status); 102 103 /* Disable and clear VBLANK interrupt */ 104 MACH64_WRITE(MACH64_CRTC_INT_CNTL, (status & ~MACH64_CRTC_VBLANK_INT_EN) 105 | MACH64_CRTC_VBLANK_INT); 106} 107 108void mach64_driver_irq_postinstall(drm_device_t * dev) 109{ 110 drm_mach64_private_t *dev_priv = 111 (drm_mach64_private_t *) dev->dev_private; 112 113 /* Turn on VBLANK interrupt */ 114 MACH64_WRITE(MACH64_CRTC_INT_CNTL, MACH64_READ(MACH64_CRTC_INT_CNTL) 115 | MACH64_CRTC_VBLANK_INT_EN); 116 117 DRM_DEBUG("after install CRTC_INT_CTNL: 0x%08x\n", 118 MACH64_READ(MACH64_CRTC_INT_CNTL)); 119 120} 121 122void mach64_driver_irq_uninstall(drm_device_t * dev) 123{ 124 drm_mach64_private_t *dev_priv = 125 (drm_mach64_private_t *) dev->dev_private; 126 if (!dev_priv) 127 return; 128 129 /* Disable and clear VBLANK interrupt */ 130 MACH64_WRITE(MACH64_CRTC_INT_CNTL, 131 (MACH64_READ(MACH64_CRTC_INT_CNTL) & 132 ~MACH64_CRTC_VBLANK_INT_EN) 133 | MACH64_CRTC_VBLANK_INT); 134 135 DRM_DEBUG("after uninstall CRTC_INT_CTNL: 0x%08x\n", 136 MACH64_READ(MACH64_CRTC_INT_CNTL)); 137} 138