aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/radeon_irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/drm/radeon_irq.c')
-rw-r--r--drivers/char/drm/radeon_irq.c127
1 files changed, 63 insertions, 64 deletions
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
index 40474a65f56d..d60519de887b 100644
--- a/drivers/char/drm/radeon_irq.c
+++ b/drivers/char/drm/radeon_irq.c
@@ -1,7 +1,7 @@
1/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*- 1/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*-
2 * 2 *
3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. 3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4 * 4 *
5 * The Weather Channel (TM) funded Tungsten Graphics to develop the 5 * The Weather Channel (TM) funded Tungsten Graphics to develop the
6 * initial release of the Radeon 8500 driver under the XFree86 license. 6 * initial release of the Radeon 8500 driver under the XFree86 license.
7 * This notice must be preserved. 7 * This notice must be preserved.
@@ -35,7 +35,8 @@
35#include "radeon_drm.h" 35#include "radeon_drm.h"
36#include "radeon_drv.h" 36#include "radeon_drv.h"
37 37
38static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 mask) 38static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv,
39 u32 mask)
39{ 40{
40 u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask; 41 u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask;
41 if (irqs) 42 if (irqs)
@@ -61,37 +62,37 @@ static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u3
61 * tied to dma at all, this is just a hangover from dri prehistory. 62 * tied to dma at all, this is just a hangover from dri prehistory.
62 */ 63 */
63 64
64irqreturn_t radeon_driver_irq_handler( DRM_IRQ_ARGS ) 65irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
65{ 66{
66 drm_device_t *dev = (drm_device_t *) arg; 67 drm_device_t *dev = (drm_device_t *) arg;
67 drm_radeon_private_t *dev_priv = 68 drm_radeon_private_t *dev_priv =
68 (drm_radeon_private_t *)dev->dev_private; 69 (drm_radeon_private_t *) dev->dev_private;
69 u32 stat; 70 u32 stat;
70 71
71 /* Only consider the bits we're interested in - others could be used 72 /* Only consider the bits we're interested in - others could be used
72 * outside the DRM 73 * outside the DRM
73 */ 74 */
74 stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | 75 stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
75 RADEON_CRTC_VBLANK_STAT)); 76 RADEON_CRTC_VBLANK_STAT));
76 if (!stat) 77 if (!stat)
77 return IRQ_NONE; 78 return IRQ_NONE;
78 79
79 /* SW interrupt */ 80 /* SW interrupt */
80 if (stat & RADEON_SW_INT_TEST) { 81 if (stat & RADEON_SW_INT_TEST) {
81 DRM_WAKEUP( &dev_priv->swi_queue ); 82 DRM_WAKEUP(&dev_priv->swi_queue);
82 } 83 }
83 84
84 /* VBLANK interrupt */ 85 /* VBLANK interrupt */
85 if (stat & RADEON_CRTC_VBLANK_STAT) { 86 if (stat & RADEON_CRTC_VBLANK_STAT) {
86 atomic_inc(&dev->vbl_received); 87 atomic_inc(&dev->vbl_received);
87 DRM_WAKEUP(&dev->vbl_queue); 88 DRM_WAKEUP(&dev->vbl_queue);
88 drm_vbl_send_signals( dev ); 89 drm_vbl_send_signals(dev);
89 } 90 }
90 91
91 return IRQ_HANDLED; 92 return IRQ_HANDLED;
92} 93}
93 94
94static int radeon_emit_irq(drm_device_t *dev) 95static int radeon_emit_irq(drm_device_t * dev)
95{ 96{
96 drm_radeon_private_t *dev_priv = dev->dev_private; 97 drm_radeon_private_t *dev_priv = dev->dev_private;
97 unsigned int ret; 98 unsigned int ret;
@@ -100,42 +101,41 @@ static int radeon_emit_irq(drm_device_t *dev)
100 atomic_inc(&dev_priv->swi_emitted); 101 atomic_inc(&dev_priv->swi_emitted);
101 ret = atomic_read(&dev_priv->swi_emitted); 102 ret = atomic_read(&dev_priv->swi_emitted);
102 103
103 BEGIN_RING( 4 ); 104 BEGIN_RING(4);
104 OUT_RING_REG( RADEON_LAST_SWI_REG, ret ); 105 OUT_RING_REG(RADEON_LAST_SWI_REG, ret);
105 OUT_RING_REG( RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE ); 106 OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE);
106 ADVANCE_RING(); 107 ADVANCE_RING();
107 COMMIT_RING(); 108 COMMIT_RING();
108 109
109 return ret; 110 return ret;
110} 111}
111 112
112 113static int radeon_wait_irq(drm_device_t * dev, int swi_nr)
113static int radeon_wait_irq(drm_device_t *dev, int swi_nr)
114{ 114{
115 drm_radeon_private_t *dev_priv = 115 drm_radeon_private_t *dev_priv =
116 (drm_radeon_private_t *)dev->dev_private; 116 (drm_radeon_private_t *) dev->dev_private;
117 int ret = 0; 117 int ret = 0;
118 118
119 if (RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr) 119 if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr)
120 return 0; 120 return 0;
121 121
122 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 122 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
123 123
124 DRM_WAIT_ON( ret, dev_priv->swi_queue, 3 * DRM_HZ, 124 DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ,
125 RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr ); 125 RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr);
126 126
127 return ret; 127 return ret;
128} 128}
129 129
130int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) 130int radeon_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
131{ 131{
132 drm_radeon_private_t *dev_priv = 132 drm_radeon_private_t *dev_priv =
133 (drm_radeon_private_t *)dev->dev_private; 133 (drm_radeon_private_t *) dev->dev_private;
134 unsigned int cur_vblank; 134 unsigned int cur_vblank;
135 int ret = 0; 135 int ret = 0;
136 136
137 if ( !dev_priv ) { 137 if (!dev_priv) {
138 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 138 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
139 return DRM_ERR(EINVAL); 139 return DRM_ERR(EINVAL);
140 } 140 }
141 141
@@ -145,101 +145,100 @@ int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
145 145
146 /* Assume that the user has missed the current sequence number 146 /* Assume that the user has missed the current sequence number
147 * by about a day rather than she wants to wait for years 147 * by about a day rather than she wants to wait for years
148 * using vertical blanks... 148 * using vertical blanks...
149 */ 149 */
150 DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ, 150 DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
151 ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) ) 151 (((cur_vblank = atomic_read(&dev->vbl_received))
152 - *sequence ) <= (1<<23) ) ); 152 - *sequence) <= (1 << 23)));
153 153
154 *sequence = cur_vblank; 154 *sequence = cur_vblank;
155 155
156 return ret; 156 return ret;
157} 157}
158 158
159
160/* Needs the lock as it touches the ring. 159/* Needs the lock as it touches the ring.
161 */ 160 */
162int radeon_irq_emit( DRM_IOCTL_ARGS ) 161int radeon_irq_emit(DRM_IOCTL_ARGS)
163{ 162{
164 DRM_DEVICE; 163 DRM_DEVICE;
165 drm_radeon_private_t *dev_priv = dev->dev_private; 164 drm_radeon_private_t *dev_priv = dev->dev_private;
166 drm_radeon_irq_emit_t emit; 165 drm_radeon_irq_emit_t emit;
167 int result; 166 int result;
168 167
169 LOCK_TEST_WITH_RETURN( dev, filp ); 168 LOCK_TEST_WITH_RETURN(dev, filp);
170 169
171 if ( !dev_priv ) { 170 if (!dev_priv) {
172 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 171 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
173 return DRM_ERR(EINVAL); 172 return DRM_ERR(EINVAL);
174 } 173 }
175 174
176 DRM_COPY_FROM_USER_IOCTL( emit, (drm_radeon_irq_emit_t __user *)data, 175 DRM_COPY_FROM_USER_IOCTL(emit, (drm_radeon_irq_emit_t __user *) data,
177 sizeof(emit) ); 176 sizeof(emit));
178 177
179 result = radeon_emit_irq( dev ); 178 result = radeon_emit_irq(dev);
180 179
181 if ( DRM_COPY_TO_USER( emit.irq_seq, &result, sizeof(int) ) ) { 180 if (DRM_COPY_TO_USER(emit.irq_seq, &result, sizeof(int))) {
182 DRM_ERROR( "copy_to_user\n" ); 181 DRM_ERROR("copy_to_user\n");
183 return DRM_ERR(EFAULT); 182 return DRM_ERR(EFAULT);
184 } 183 }
185 184
186 return 0; 185 return 0;
187} 186}
188 187
189
190/* Doesn't need the hardware lock. 188/* Doesn't need the hardware lock.
191 */ 189 */
192int radeon_irq_wait( DRM_IOCTL_ARGS ) 190int radeon_irq_wait(DRM_IOCTL_ARGS)
193{ 191{
194 DRM_DEVICE; 192 DRM_DEVICE;
195 drm_radeon_private_t *dev_priv = dev->dev_private; 193 drm_radeon_private_t *dev_priv = dev->dev_private;
196 drm_radeon_irq_wait_t irqwait; 194 drm_radeon_irq_wait_t irqwait;
197 195
198 if ( !dev_priv ) { 196 if (!dev_priv) {
199 DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); 197 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
200 return DRM_ERR(EINVAL); 198 return DRM_ERR(EINVAL);
201 } 199 }
202 200
203 DRM_COPY_FROM_USER_IOCTL( irqwait, (drm_radeon_irq_wait_t __user*)data, 201 DRM_COPY_FROM_USER_IOCTL(irqwait, (drm_radeon_irq_wait_t __user *) data,
204 sizeof(irqwait) ); 202 sizeof(irqwait));
205 203
206 return radeon_wait_irq( dev, irqwait.irq_seq ); 204 return radeon_wait_irq(dev, irqwait.irq_seq);
207} 205}
208 206
209
210/* drm_dma.h hooks 207/* drm_dma.h hooks
211*/ 208*/
212void radeon_driver_irq_preinstall( drm_device_t *dev ) { 209void radeon_driver_irq_preinstall(drm_device_t * dev)
210{
213 drm_radeon_private_t *dev_priv = 211 drm_radeon_private_t *dev_priv =
214 (drm_radeon_private_t *)dev->dev_private; 212 (drm_radeon_private_t *) dev->dev_private;
215 213
216 /* Disable *all* interrupts */ 214 /* Disable *all* interrupts */
217 RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); 215 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
218 216
219 /* Clear bits if they're already high */ 217 /* Clear bits if they're already high */
220 radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | 218 radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
221 RADEON_CRTC_VBLANK_STAT)); 219 RADEON_CRTC_VBLANK_STAT));
222} 220}
223 221
224void radeon_driver_irq_postinstall( drm_device_t *dev ) { 222void radeon_driver_irq_postinstall(drm_device_t * dev)
223{
225 drm_radeon_private_t *dev_priv = 224 drm_radeon_private_t *dev_priv =
226 (drm_radeon_private_t *)dev->dev_private; 225 (drm_radeon_private_t *) dev->dev_private;
227 226
228 atomic_set(&dev_priv->swi_emitted, 0); 227 atomic_set(&dev_priv->swi_emitted, 0);
229 DRM_INIT_WAITQUEUE( &dev_priv->swi_queue ); 228 DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
230 229
231 /* Turn on SW and VBL ints */ 230 /* Turn on SW and VBL ints */
232 RADEON_WRITE( RADEON_GEN_INT_CNTL, 231 RADEON_WRITE(RADEON_GEN_INT_CNTL,
233 RADEON_CRTC_VBLANK_MASK | 232 RADEON_CRTC_VBLANK_MASK | RADEON_SW_INT_ENABLE);
234 RADEON_SW_INT_ENABLE );
235} 233}
236 234
237void radeon_driver_irq_uninstall( drm_device_t *dev ) { 235void radeon_driver_irq_uninstall(drm_device_t * dev)
236{
238 drm_radeon_private_t *dev_priv = 237 drm_radeon_private_t *dev_priv =
239 (drm_radeon_private_t *)dev->dev_private; 238 (drm_radeon_private_t *) dev->dev_private;
240 if (!dev_priv) 239 if (!dev_priv)
241 return; 240 return;
242 241
243 /* Disable *all* interrupts */ 242 /* Disable *all* interrupts */
244 RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); 243 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
245} 244}