2005-04-16 15:20:36 -07:00
/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*-
*
* Copyright ( C ) The Weather Channel , Inc . 2002. All Rights Reserved .
2005-09-25 14:28:13 +10:00
*
2005-04-16 15:20:36 -07:00
* 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 .
*
* Permission is hereby granted , free of charge , to any person obtaining a
* copy of this software and associated documentation files ( the " Software " ) ,
* to deal in the Software without restriction , including without limitation
* the rights to use , copy , modify , merge , publish , distribute , sublicense ,
* and / or sell copies of the Software , and to permit persons to whom the
* Software is furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice ( including the next
* paragraph ) shall be included in all copies or substantial portions of the
* Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* PRECISION INSIGHT AND / OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM , DAMAGES OR
* OTHER LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE ,
* ARISING FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE .
*
* Authors :
* Keith Whitwell < keith @ tungstengraphics . com >
* Eric Anholt < anholt @ FreeBSD . org >
*/
# include "drmP.h"
# include "drm.h"
# include "r128_drm.h"
# include "r128_drv.h"
2005-09-25 14:28:13 +10:00
irqreturn_t r128_driver_irq_handler ( DRM_IRQ_ARGS )
2005-04-16 15:20:36 -07:00
{
drm_device_t * dev = ( drm_device_t * ) arg ;
2005-09-25 14:28:13 +10:00
drm_r128_private_t * dev_priv = ( drm_r128_private_t * ) dev - > dev_private ;
2005-04-16 15:20:36 -07:00
int status ;
2005-09-25 14:28:13 +10:00
status = R128_READ ( R128_GEN_INT_STATUS ) ;
2005-04-16 15:20:36 -07:00
/* VBLANK interrupt */
2005-09-25 14:28:13 +10:00
if ( status & R128_CRTC_VBLANK_INT ) {
R128_WRITE ( R128_GEN_INT_STATUS , R128_CRTC_VBLANK_INT_AK ) ;
2005-04-16 15:20:36 -07:00
atomic_inc ( & dev - > vbl_received ) ;
DRM_WAKEUP ( & dev - > vbl_queue ) ;
2005-09-25 14:28:13 +10:00
drm_vbl_send_signals ( dev ) ;
2005-04-16 15:20:36 -07:00
return IRQ_HANDLED ;
}
return IRQ_NONE ;
}
2005-09-25 14:28:13 +10:00
int r128_driver_vblank_wait ( drm_device_t * dev , unsigned int * sequence )
2005-04-16 15:20:36 -07:00
{
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
2005-09-25 14:28:13 +10:00
* using vertical blanks . . .
2005-04-16 15:20:36 -07:00
*/
2005-09-25 14:28:13 +10:00
DRM_WAIT_ON ( ret , dev - > vbl_queue , 3 * DRM_HZ ,
( ( ( cur_vblank = atomic_read ( & dev - > vbl_received ) )
- * sequence ) < = ( 1 < < 23 ) ) ) ;
2005-04-16 15:20:36 -07:00
* sequence = cur_vblank ;
return ret ;
}
2005-09-25 14:28:13 +10:00
void r128_driver_irq_preinstall ( drm_device_t * dev )
{
drm_r128_private_t * dev_priv = ( drm_r128_private_t * ) dev - > dev_private ;
2005-04-16 15:20:36 -07:00
/* Disable *all* interrupts */
2005-09-25 14:28:13 +10:00
R128_WRITE ( R128_GEN_INT_CNTL , 0 ) ;
2005-04-16 15:20:36 -07:00
/* Clear vblank bit if it's already high */
2005-09-25 14:28:13 +10:00
R128_WRITE ( R128_GEN_INT_STATUS , R128_CRTC_VBLANK_INT_AK ) ;
2005-04-16 15:20:36 -07:00
}
2005-09-25 14:28:13 +10:00
void r128_driver_irq_postinstall ( drm_device_t * dev )
{
drm_r128_private_t * dev_priv = ( drm_r128_private_t * ) dev - > dev_private ;
2005-04-16 15:20:36 -07:00
/* Turn on VBL interrupt */
2005-09-25 14:28:13 +10:00
R128_WRITE ( R128_GEN_INT_CNTL , R128_CRTC_VBLANK_INT_EN ) ;
2005-04-16 15:20:36 -07:00
}
2005-09-25 14:28:13 +10:00
void r128_driver_irq_uninstall ( drm_device_t * dev )
{
drm_r128_private_t * dev_priv = ( drm_r128_private_t * ) dev - > dev_private ;
2005-04-16 15:20:36 -07:00
if ( ! dev_priv )
return ;
/* Disable *all* interrupts */
2005-09-25 14:28:13 +10:00
R128_WRITE ( R128_GEN_INT_CNTL , 0 ) ;
2005-04-16 15:20:36 -07:00
}