Back to home page

OSCL-LXR

 
 

    


0001 /* r128_irq.c -- IRQ handling for radeon -*- linux-c -*- */
0002 /*
0003  * Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
0004  *
0005  * The Weather Channel (TM) funded Tungsten Graphics to develop the
0006  * initial release of the Radeon 8500 driver under the XFree86 license.
0007  * This notice must be preserved.
0008  *
0009  * Permission is hereby granted, free of charge, to any person obtaining a
0010  * copy of this software and associated documentation files (the "Software"),
0011  * to deal in the Software without restriction, including without limitation
0012  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0013  * and/or sell copies of the Software, and to permit persons to whom the
0014  * Software is furnished to do so, subject to the following conditions:
0015  *
0016  * The above copyright notice and this permission notice (including the next
0017  * paragraph) shall be included in all copies or substantial portions of the
0018  * Software.
0019  *
0020  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0021  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0022  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0023  * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
0024  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0025  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
0026  * DEALINGS IN THE SOFTWARE.
0027  *
0028  * Authors:
0029  *    Keith Whitwell <keith@tungstengraphics.com>
0030  *    Eric Anholt <anholt@FreeBSD.org>
0031  */
0032 
0033 #include <drm/drm_device.h>
0034 #include <drm/drm_print.h>
0035 #include <drm/drm_vblank.h>
0036 #include <drm/r128_drm.h>
0037 
0038 #include "r128_drv.h"
0039 
0040 u32 r128_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
0041 {
0042     const drm_r128_private_t *dev_priv = dev->dev_private;
0043 
0044     if (pipe != 0)
0045         return 0;
0046 
0047     return atomic_read(&dev_priv->vbl_received);
0048 }
0049 
0050 irqreturn_t r128_driver_irq_handler(int irq, void *arg)
0051 {
0052     struct drm_device *dev = (struct drm_device *) arg;
0053     drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
0054     int status;
0055 
0056     status = R128_READ(R128_GEN_INT_STATUS);
0057 
0058     /* VBLANK interrupt */
0059     if (status & R128_CRTC_VBLANK_INT) {
0060         R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
0061         atomic_inc(&dev_priv->vbl_received);
0062         drm_handle_vblank(dev, 0);
0063         return IRQ_HANDLED;
0064     }
0065     return IRQ_NONE;
0066 }
0067 
0068 int r128_enable_vblank(struct drm_device *dev, unsigned int pipe)
0069 {
0070     drm_r128_private_t *dev_priv = dev->dev_private;
0071 
0072     if (pipe != 0) {
0073         DRM_ERROR("%s:  bad crtc %u\n", __func__, pipe);
0074         return -EINVAL;
0075     }
0076 
0077     R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN);
0078     return 0;
0079 }
0080 
0081 void r128_disable_vblank(struct drm_device *dev, unsigned int pipe)
0082 {
0083     if (pipe != 0)
0084         DRM_ERROR("%s:  bad crtc %u\n", __func__, pipe);
0085 
0086     /*
0087      * FIXME: implement proper interrupt disable by using the vblank
0088      * counter register (if available)
0089      *
0090      * R128_WRITE(R128_GEN_INT_CNTL,
0091      *            R128_READ(R128_GEN_INT_CNTL) & ~R128_CRTC_VBLANK_INT_EN);
0092      */
0093 }
0094 
0095 void r128_driver_irq_preinstall(struct drm_device *dev)
0096 {
0097     drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
0098 
0099     /* Disable *all* interrupts */
0100     R128_WRITE(R128_GEN_INT_CNTL, 0);
0101     /* Clear vblank bit if it's already high */
0102     R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
0103 }
0104 
0105 int r128_driver_irq_postinstall(struct drm_device *dev)
0106 {
0107     return 0;
0108 }
0109 
0110 void r128_driver_irq_uninstall(struct drm_device *dev)
0111 {
0112     drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
0113     if (!dev_priv)
0114         return;
0115 
0116     /* Disable *all* interrupts */
0117     R128_WRITE(R128_GEN_INT_CNTL, 0);
0118 }