diff options
Diffstat (limited to 'drivers/char/drm/radeon_irq.c')
-rw-r--r-- | drivers/char/drm/radeon_irq.c | 127 |
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 | ||
38 | static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 mask) | 38 | static __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 | ||
64 | irqreturn_t radeon_driver_irq_handler( DRM_IRQ_ARGS ) | 65 | irqreturn_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 | ||
94 | static int radeon_emit_irq(drm_device_t *dev) | 95 | static 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 | 113 | static int radeon_wait_irq(drm_device_t * dev, int swi_nr) | |
113 | static 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 | ||
130 | int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) | 130 | int 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 | */ |
162 | int radeon_irq_emit( DRM_IOCTL_ARGS ) | 161 | int 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 | */ |
192 | int radeon_irq_wait( DRM_IOCTL_ARGS ) | 190 | int 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 | */ |
212 | void radeon_driver_irq_preinstall( drm_device_t *dev ) { | 209 | void 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 | ||
224 | void radeon_driver_irq_postinstall( drm_device_t *dev ) { | 222 | void 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 | ||
237 | void radeon_driver_irq_uninstall( drm_device_t *dev ) { | 235 | void 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 | } |