2006-01-02 17:18:39 +11:00
/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*- */
/*
2005-04-16 15:20:36 -07:00
* 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 >
*/
2019-07-16 08:42:08 +02:00
# include <drm/drm_device.h>
# include <drm/drm_print.h>
# include <drm/drm_vblank.h>
2012-10-02 18:01:07 +01:00
# include <drm/r128_drm.h>
2019-07-16 08:42:08 +02:00
2005-04-16 15:20:36 -07:00
# include "r128_drv.h"
2015-09-24 18:35:31 +02:00
u32 r128_get_vblank_counter ( struct drm_device * dev , unsigned int pipe )
2008-09-30 12:14:26 -07:00
{
const drm_r128_private_t * dev_priv = dev - > dev_private ;
2015-09-24 18:35:31 +02:00
if ( pipe ! = 0 )
2008-09-30 12:14:26 -07:00
return 0 ;
return atomic_read ( & dev_priv - > vbl_received ) ;
}
2013-12-11 11:34:42 +01:00
irqreturn_t r128_driver_irq_handler ( int irq , void * arg )
2005-04-16 15:20:36 -07:00
{
2007-07-11 16:09:54 +10:00
struct drm_device * dev = ( struct drm_device * ) 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 ) ;
2008-09-30 12:14:26 -07:00
atomic_inc ( & dev_priv - > vbl_received ) ;
drm_handle_vblank ( dev , 0 ) ;
2005-04-16 15:20:36 -07:00
return IRQ_HANDLED ;
}
return IRQ_NONE ;
}
2015-09-24 18:35:31 +02:00
int r128_enable_vblank ( struct drm_device * dev , unsigned int pipe )
2005-04-16 15:20:36 -07:00
{
2008-09-30 12:14:26 -07:00
drm_r128_private_t * dev_priv = dev - > dev_private ;
2005-04-16 15:20:36 -07:00
2015-09-24 18:35:31 +02:00
if ( pipe ! = 0 ) {
DRM_ERROR ( " %s: bad crtc %u \n " , __func__ , pipe ) ;
2008-09-30 12:14:26 -07:00
return - EINVAL ;
}
2008-04-22 16:03:07 +10:00
2008-09-30 12:14:26 -07:00
R128_WRITE ( R128_GEN_INT_CNTL , R128_CRTC_VBLANK_INT_EN ) ;
return 0 ;
}
2015-09-24 18:35:31 +02:00
void r128_disable_vblank ( struct drm_device * dev , unsigned int pipe )
2008-09-30 12:14:26 -07:00
{
2015-09-24 18:35:31 +02:00
if ( pipe ! = 0 )
DRM_ERROR ( " %s: bad crtc %u \n " , __func__ , pipe ) ;
2005-04-16 15:20:36 -07:00
2008-09-30 12:14:26 -07:00
/*
* 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 ) ;
*/
2005-04-16 15:20:36 -07:00
}
2010-07-12 13:44:23 +02:00
void r128_driver_irq_preinstall ( struct drm_device * dev )
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
/* 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
}
2008-09-30 12:14:26 -07:00
int r128_driver_irq_postinstall ( struct drm_device * dev )
2005-09-25 14:28:13 +10:00
{
2008-11-18 09:30:25 -08:00
return 0 ;
2005-04-16 15:20:36 -07:00
}
2010-07-12 13:44:23 +02:00
void r128_driver_irq_uninstall ( struct drm_device * dev )
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
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
}