aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_irq.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq.c268
1 files changed, 168 insertions, 100 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c
index ee40d197deb7..5079f7054a2f 100644
--- a/drivers/gpu/drm/radeon/radeon_irq.c
+++ b/drivers/gpu/drm/radeon/radeon_irq.c
@@ -27,7 +27,7 @@
27 * 27 *
28 * Authors: 28 * Authors:
29 * Keith Whitwell <keith@tungstengraphics.com> 29 * Keith Whitwell <keith@tungstengraphics.com>
30 * Michel Dänzer <michel@daenzer.net> 30 * Michel Dzer <michel@daenzer.net>
31 */ 31 */
32 32
33#include "drmP.h" 33#include "drmP.h"
@@ -35,12 +35,128 @@
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, 38void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state)
39 u32 mask)
40{ 39{
41 u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask; 40 drm_radeon_private_t *dev_priv = dev->dev_private;
41
42 if (state)
43 dev_priv->irq_enable_reg |= mask;
44 else
45 dev_priv->irq_enable_reg &= ~mask;
46
47 RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
48}
49
50static void r500_vbl_irq_set_state(struct drm_device *dev, u32 mask, int state)
51{
52 drm_radeon_private_t *dev_priv = dev->dev_private;
53
54 if (state)
55 dev_priv->r500_disp_irq_reg |= mask;
56 else
57 dev_priv->r500_disp_irq_reg &= ~mask;
58
59 RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg);
60}
61
62int radeon_enable_vblank(struct drm_device *dev, int crtc)
63{
64 drm_radeon_private_t *dev_priv = dev->dev_private;
65
66 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
67 switch (crtc) {
68 case 0:
69 r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 1);
70 break;
71 case 1:
72 r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 1);
73 break;
74 default:
75 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
76 crtc);
77 return EINVAL;
78 }
79 } else {
80 switch (crtc) {
81 case 0:
82 radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1);
83 break;
84 case 1:
85 radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1);
86 break;
87 default:
88 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
89 crtc);
90 return EINVAL;
91 }
92 }
93
94 return 0;
95}
96
97void radeon_disable_vblank(struct drm_device *dev, int crtc)
98{
99 drm_radeon_private_t *dev_priv = dev->dev_private;
100
101 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
102 switch (crtc) {
103 case 0:
104 r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 0);
105 break;
106 case 1:
107 r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 0);
108 break;
109 default:
110 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
111 crtc);
112 break;
113 }
114 } else {
115 switch (crtc) {
116 case 0:
117 radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0);
118 break;
119 case 1:
120 radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0);
121 break;
122 default:
123 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
124 crtc);
125 break;
126 }
127 }
128}
129
130static inline u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 *r500_disp_int)
131{
132 u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS);
133 u32 irq_mask = RADEON_SW_INT_TEST;
134
135 *r500_disp_int = 0;
136 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
137 /* vbl interrupts in a different place */
138
139 if (irqs & R500_DISPLAY_INT_STATUS) {
140 /* if a display interrupt */
141 u32 disp_irq;
142
143 disp_irq = RADEON_READ(R500_DISP_INTERRUPT_STATUS);
144
145 *r500_disp_int = disp_irq;
146 if (disp_irq & R500_D1_VBLANK_INTERRUPT)
147 RADEON_WRITE(R500_D1MODE_VBLANK_STATUS, R500_VBLANK_ACK);
148 if (disp_irq & R500_D2_VBLANK_INTERRUPT)
149 RADEON_WRITE(R500_D2MODE_VBLANK_STATUS, R500_VBLANK_ACK);
150 }
151 irq_mask |= R500_DISPLAY_INT_STATUS;
152 } else
153 irq_mask |= RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT;
154
155 irqs &= irq_mask;
156
42 if (irqs) 157 if (irqs)
43 RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs); 158 RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs);
159
44 return irqs; 160 return irqs;
45} 161}
46 162
@@ -68,44 +184,33 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
68 drm_radeon_private_t *dev_priv = 184 drm_radeon_private_t *dev_priv =
69 (drm_radeon_private_t *) dev->dev_private; 185 (drm_radeon_private_t *) dev->dev_private;
70 u32 stat; 186 u32 stat;
187 u32 r500_disp_int;
71 188
72 /* Only consider the bits we're interested in - others could be used 189 /* Only consider the bits we're interested in - others could be used
73 * outside the DRM 190 * outside the DRM
74 */ 191 */
75 stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | 192 stat = radeon_acknowledge_irqs(dev_priv, &r500_disp_int);
76 RADEON_CRTC_VBLANK_STAT |
77 RADEON_CRTC2_VBLANK_STAT));
78 if (!stat) 193 if (!stat)
79 return IRQ_NONE; 194 return IRQ_NONE;
80 195
81 stat &= dev_priv->irq_enable_reg; 196 stat &= dev_priv->irq_enable_reg;
82 197
83 /* SW interrupt */ 198 /* SW interrupt */
84 if (stat & RADEON_SW_INT_TEST) { 199 if (stat & RADEON_SW_INT_TEST)
85 DRM_WAKEUP(&dev_priv->swi_queue); 200 DRM_WAKEUP(&dev_priv->swi_queue);
86 }
87 201
88 /* VBLANK interrupt */ 202 /* VBLANK interrupt */
89 if (stat & (RADEON_CRTC_VBLANK_STAT|RADEON_CRTC2_VBLANK_STAT)) { 203 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
90 int vblank_crtc = dev_priv->vblank_crtc; 204 if (r500_disp_int & R500_D1_VBLANK_INTERRUPT)
91 205 drm_handle_vblank(dev, 0);
92 if ((vblank_crtc & 206 if (r500_disp_int & R500_D2_VBLANK_INTERRUPT)
93 (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) == 207 drm_handle_vblank(dev, 1);
94 (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { 208 } else {
95 if (stat & RADEON_CRTC_VBLANK_STAT) 209 if (stat & RADEON_CRTC_VBLANK_STAT)
96 atomic_inc(&dev->vbl_received); 210 drm_handle_vblank(dev, 0);
97 if (stat & RADEON_CRTC2_VBLANK_STAT) 211 if (stat & RADEON_CRTC2_VBLANK_STAT)
98 atomic_inc(&dev->vbl_received2); 212 drm_handle_vblank(dev, 1);
99 } else if (((stat & RADEON_CRTC_VBLANK_STAT) &&
100 (vblank_crtc & DRM_RADEON_VBLANK_CRTC1)) ||
101 ((stat & RADEON_CRTC2_VBLANK_STAT) &&
102 (vblank_crtc & DRM_RADEON_VBLANK_CRTC2)))
103 atomic_inc(&dev->vbl_received);
104
105 DRM_WAKEUP(&dev->vbl_queue);
106 drm_vbl_send_signals(dev);
107 } 213 }
108
109 return IRQ_HANDLED; 214 return IRQ_HANDLED;
110} 215}
111 216
@@ -144,54 +249,31 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr)
144 return ret; 249 return ret;
145} 250}
146 251
147static int radeon_driver_vblank_do_wait(struct drm_device * dev, 252u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc)
148 unsigned int *sequence, int crtc)
149{ 253{
150 drm_radeon_private_t *dev_priv = 254 drm_radeon_private_t *dev_priv = dev->dev_private;
151 (drm_radeon_private_t *) dev->dev_private; 255
152 unsigned int cur_vblank;
153 int ret = 0;
154 int ack = 0;
155 atomic_t *counter;
156 if (!dev_priv) { 256 if (!dev_priv) {
157 DRM_ERROR("called with no initialization\n"); 257 DRM_ERROR("called with no initialization\n");
158 return -EINVAL; 258 return -EINVAL;
159 } 259 }
160 260
161 if (crtc == DRM_RADEON_VBLANK_CRTC1) { 261 if (crtc < 0 || crtc > 1) {
162 counter = &dev->vbl_received; 262 DRM_ERROR("Invalid crtc %d\n", crtc);
163 ack |= RADEON_CRTC_VBLANK_STAT;
164 } else if (crtc == DRM_RADEON_VBLANK_CRTC2) {
165 counter = &dev->vbl_received2;
166 ack |= RADEON_CRTC2_VBLANK_STAT;
167 } else
168 return -EINVAL; 263 return -EINVAL;
264 }
169 265
170 radeon_acknowledge_irqs(dev_priv, ack); 266 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
171 267 if (crtc == 0)
172 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 268 return RADEON_READ(R500_D1CRTC_FRAME_COUNT);
173 269 else
174 /* Assume that the user has missed the current sequence number 270 return RADEON_READ(R500_D2CRTC_FRAME_COUNT);
175 * by about a day rather than she wants to wait for years 271 } else {
176 * using vertical blanks... 272 if (crtc == 0)
177 */ 273 return RADEON_READ(RADEON_CRTC_CRNT_FRAME);
178 DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, 274 else
179 (((cur_vblank = atomic_read(counter)) 275 return RADEON_READ(RADEON_CRTC2_CRNT_FRAME);
180 - *sequence) <= (1 << 23))); 276 }
181
182 *sequence = cur_vblank;
183
184 return ret;
185}
186
187int radeon_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
188{
189 return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1);
190}
191
192int radeon_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
193{
194 return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2);
195} 277}
196 278
197/* Needs the lock as it touches the ring. 279/* Needs the lock as it touches the ring.
@@ -234,46 +316,41 @@ int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_pr
234 return radeon_wait_irq(dev, irqwait->irq_seq); 316 return radeon_wait_irq(dev, irqwait->irq_seq);
235} 317}
236 318
237void radeon_enable_interrupt(struct drm_device *dev)
238{
239 drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
240
241 dev_priv->irq_enable_reg = RADEON_SW_INT_ENABLE;
242 if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC1)
243 dev_priv->irq_enable_reg |= RADEON_CRTC_VBLANK_MASK;
244
245 if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC2)
246 dev_priv->irq_enable_reg |= RADEON_CRTC2_VBLANK_MASK;
247
248 RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
249 dev_priv->irq_enabled = 1;
250}
251
252/* drm_dma.h hooks 319/* drm_dma.h hooks
253*/ 320*/
254void radeon_driver_irq_preinstall(struct drm_device * dev) 321void radeon_driver_irq_preinstall(struct drm_device * dev)
255{ 322{
256 drm_radeon_private_t *dev_priv = 323 drm_radeon_private_t *dev_priv =
257 (drm_radeon_private_t *) dev->dev_private; 324 (drm_radeon_private_t *) dev->dev_private;
325 u32 dummy;
258 326
259 /* Disable *all* interrupts */ 327 /* Disable *all* interrupts */
328 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
329 RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
260 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); 330 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
261 331
262 /* Clear bits if they're already high */ 332 /* Clear bits if they're already high */
263 radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | 333 radeon_acknowledge_irqs(dev_priv, &dummy);
264 RADEON_CRTC_VBLANK_STAT |
265 RADEON_CRTC2_VBLANK_STAT));
266} 334}
267 335
268void radeon_driver_irq_postinstall(struct drm_device * dev) 336int radeon_driver_irq_postinstall(struct drm_device *dev)
269{ 337{
270 drm_radeon_private_t *dev_priv = 338 drm_radeon_private_t *dev_priv =
271 (drm_radeon_private_t *) dev->dev_private; 339 (drm_radeon_private_t *) dev->dev_private;
340 int ret;
272 341
273 atomic_set(&dev_priv->swi_emitted, 0); 342 atomic_set(&dev_priv->swi_emitted, 0);
274 DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); 343 DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
275 344
276 radeon_enable_interrupt(dev); 345 ret = drm_vblank_init(dev, 2);
346 if (ret)
347 return ret;
348
349 dev->max_vblank_count = 0x001fffff;
350
351 radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
352
353 return 0;
277} 354}
278 355
279void radeon_driver_irq_uninstall(struct drm_device * dev) 356void radeon_driver_irq_uninstall(struct drm_device * dev)
@@ -285,6 +362,8 @@ void radeon_driver_irq_uninstall(struct drm_device * dev)
285 362
286 dev_priv->irq_enabled = 0; 363 dev_priv->irq_enabled = 0;
287 364
365 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
366 RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
288 /* Disable *all* interrupts */ 367 /* Disable *all* interrupts */
289 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); 368 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
290} 369}
@@ -293,18 +372,8 @@ void radeon_driver_irq_uninstall(struct drm_device * dev)
293int radeon_vblank_crtc_get(struct drm_device *dev) 372int radeon_vblank_crtc_get(struct drm_device *dev)
294{ 373{
295 drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; 374 drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
296 u32 flag;
297 u32 value;
298
299 flag = RADEON_READ(RADEON_GEN_INT_CNTL);
300 value = 0;
301
302 if (flag & RADEON_CRTC_VBLANK_MASK)
303 value |= DRM_RADEON_VBLANK_CRTC1;
304 375
305 if (flag & RADEON_CRTC2_VBLANK_MASK) 376 return dev_priv->vblank_crtc;
306 value |= DRM_RADEON_VBLANK_CRTC2;
307 return value;
308} 377}
309 378
310int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value) 379int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value)
@@ -315,6 +384,5 @@ int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value)
315 return -EINVAL; 384 return -EINVAL;
316 } 385 }
317 dev_priv->vblank_crtc = (unsigned int)value; 386 dev_priv->vblank_crtc = (unsigned int)value;
318 radeon_enable_interrupt(dev);
319 return 0; 387 return 0;
320} 388}