mga_irq.c revision 119098
1112015Sanholt/* mga_irq.c -- IRQ handling for radeon -*- linux-c -*- 2112015Sanholt * 3112015Sanholt * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. 4112015Sanholt * 5112015Sanholt * The Weather Channel (TM) funded Tungsten Graphics to develop the 6112015Sanholt * initial release of the Radeon 8500 driver under the XFree86 license. 7112015Sanholt * This notice must be preserved. 8112015Sanholt * 9112015Sanholt * Permission is hereby granted, free of charge, to any person obtaining a 10112015Sanholt * copy of this software and associated documentation files (the "Software"), 11112015Sanholt * to deal in the Software without restriction, including without limitation 12112015Sanholt * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13112015Sanholt * and/or sell copies of the Software, and to permit persons to whom the 14112015Sanholt * Software is furnished to do so, subject to the following conditions: 15112015Sanholt * 16112015Sanholt * The above copyright notice and this permission notice (including the next 17112015Sanholt * paragraph) shall be included in all copies or substantial portions of the 18112015Sanholt * Software. 19112015Sanholt * 20112015Sanholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21112015Sanholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22112015Sanholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23112015Sanholt * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 24112015Sanholt * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 25112015Sanholt * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26112015Sanholt * DEALINGS IN THE SOFTWARE. 27112015Sanholt * 28112015Sanholt * Authors: 29112015Sanholt * Keith Whitwell <keith@tungstengraphics.com> 30112015Sanholt * Eric Anholt <anholt@FreeBSD.org> 31112015Sanholt * 32112015Sanholt * $FreeBSD: head/sys/dev/drm/mga_irq.c 119098 2003-08-19 02:57:31Z anholt $ 33112015Sanholt */ 34112015Sanholt 35112015Sanholt#include "dev/drm/mga.h" 36112015Sanholt#include "dev/drm/drmP.h" 37112015Sanholt#include "dev/drm/drm.h" 38112015Sanholt#include "dev/drm/mga_drm.h" 39112015Sanholt#include "dev/drm/mga_drv.h" 40112015Sanholt 41119098Sanholtirqreturn_t mga_dma_service( DRM_IRQ_ARGS ) 42112015Sanholt{ 43112015Sanholt drm_device_t *dev = (drm_device_t *) arg; 44112015Sanholt drm_mga_private_t *dev_priv = 45112015Sanholt (drm_mga_private_t *)dev->dev_private; 46112015Sanholt int status; 47112015Sanholt 48112015Sanholt status = MGA_READ( MGA_STATUS ); 49112015Sanholt 50112015Sanholt /* VBLANK interrupt */ 51112015Sanholt if ( status & MGA_VLINEPEN ) { 52112015Sanholt MGA_WRITE( MGA_ICLEAR, MGA_VLINEICLR ); 53112015Sanholt atomic_inc(&dev->vbl_received); 54112015Sanholt DRM_WAKEUP(&dev->vbl_queue); 55112015Sanholt DRM(vbl_send_signals)( dev ); 56119098Sanholt return IRQ_HANDLED; 57112015Sanholt } 58119098Sanholt return IRQ_NONE; 59112015Sanholt} 60112015Sanholt 61112015Sanholtint mga_vblank_wait(drm_device_t *dev, unsigned int *sequence) 62112015Sanholt{ 63112015Sanholt unsigned int cur_vblank; 64112015Sanholt int ret = 0; 65112015Sanholt 66112015Sanholt /* Assume that the user has missed the current sequence number 67112015Sanholt * by about a day rather than she wants to wait for years 68112015Sanholt * using vertical blanks... 69112015Sanholt */ 70112015Sanholt DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ, 71112015Sanholt ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) ) 72112015Sanholt - *sequence ) <= (1<<23) ) ); 73112015Sanholt 74112015Sanholt *sequence = cur_vblank; 75112015Sanholt 76112015Sanholt return ret; 77112015Sanholt} 78112015Sanholt 79112015Sanholtvoid mga_driver_irq_preinstall( drm_device_t *dev ) { 80112015Sanholt drm_mga_private_t *dev_priv = 81112015Sanholt (drm_mga_private_t *)dev->dev_private; 82112015Sanholt 83112015Sanholt /* Disable *all* interrupts */ 84112015Sanholt MGA_WRITE( MGA_IEN, 0 ); 85112015Sanholt /* Clear bits if they're already high */ 86112015Sanholt MGA_WRITE( MGA_ICLEAR, ~0 ); 87112015Sanholt} 88112015Sanholt 89112015Sanholtvoid mga_driver_irq_postinstall( drm_device_t *dev ) { 90112015Sanholt drm_mga_private_t *dev_priv = 91112015Sanholt (drm_mga_private_t *)dev->dev_private; 92112015Sanholt 93112015Sanholt /* Turn on VBL interrupt */ 94112015Sanholt MGA_WRITE( MGA_IEN, MGA_VLINEIEN ); 95112015Sanholt} 96112015Sanholt 97112015Sanholtvoid mga_driver_irq_uninstall( drm_device_t *dev ) { 98112015Sanholt drm_mga_private_t *dev_priv = 99112015Sanholt (drm_mga_private_t *)dev->dev_private; 100119098Sanholt if (!dev_priv) 101119098Sanholt return; 102119098Sanholt 103119098Sanholt /* Disable *all* interrupts */ 104119098Sanholt MGA_WRITE( MGA_IEN, 0 ); 105112015Sanholt} 106