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