Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.7-rc7 400 lines 11 kB view raw
1/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*- */ 2/* 3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. 4 * 5 * The Weather Channel (TM) funded Tungsten Graphics to develop the 6 * initial release of the Radeon 8500 driver under the XFree86 license. 7 * This notice must be preserved. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the "Software"), 11 * to deal in the Software without restriction, including without limitation 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 * and/or sell copies of the Software, and to permit persons to whom the 14 * Software is furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice (including the next 17 * paragraph) shall be included in all copies or substantial portions of the 18 * Software. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 * DEALINGS IN THE SOFTWARE. 27 * 28 * Authors: 29 * Keith Whitwell <keith@tungstengraphics.com> 30 * Michel D�zer <michel@daenzer.net> 31 */ 32 33#include <drm/drmP.h> 34#include <drm/radeon_drm.h> 35#include "radeon_drv.h" 36 37void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state) 38{ 39 drm_radeon_private_t *dev_priv = dev->dev_private; 40 41 if (state) 42 dev_priv->irq_enable_reg |= mask; 43 else 44 dev_priv->irq_enable_reg &= ~mask; 45 46 if (dev->irq_enabled) 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 if (dev->irq_enabled) 60 RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg); 61} 62 63int radeon_enable_vblank(struct drm_device *dev, int crtc) 64{ 65 drm_radeon_private_t *dev_priv = dev->dev_private; 66 67 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { 68 switch (crtc) { 69 case 0: 70 r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 1); 71 break; 72 case 1: 73 r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 1); 74 break; 75 default: 76 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", 77 crtc); 78 return -EINVAL; 79 } 80 } else { 81 switch (crtc) { 82 case 0: 83 radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1); 84 break; 85 case 1: 86 radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1); 87 break; 88 default: 89 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", 90 crtc); 91 return -EINVAL; 92 } 93 } 94 95 return 0; 96} 97 98void radeon_disable_vblank(struct drm_device *dev, int crtc) 99{ 100 drm_radeon_private_t *dev_priv = dev->dev_private; 101 102 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { 103 switch (crtc) { 104 case 0: 105 r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 0); 106 break; 107 case 1: 108 r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 0); 109 break; 110 default: 111 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", 112 crtc); 113 break; 114 } 115 } else { 116 switch (crtc) { 117 case 0: 118 radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0); 119 break; 120 case 1: 121 radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0); 122 break; 123 default: 124 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", 125 crtc); 126 break; 127 } 128 } 129} 130 131static u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 *r500_disp_int) 132{ 133 u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS); 134 u32 irq_mask = RADEON_SW_INT_TEST; 135 136 *r500_disp_int = 0; 137 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { 138 /* vbl interrupts in a different place */ 139 140 if (irqs & R500_DISPLAY_INT_STATUS) { 141 /* if a display interrupt */ 142 u32 disp_irq; 143 144 disp_irq = RADEON_READ(R500_DISP_INTERRUPT_STATUS); 145 146 *r500_disp_int = disp_irq; 147 if (disp_irq & R500_D1_VBLANK_INTERRUPT) 148 RADEON_WRITE(R500_D1MODE_VBLANK_STATUS, R500_VBLANK_ACK); 149 if (disp_irq & R500_D2_VBLANK_INTERRUPT) 150 RADEON_WRITE(R500_D2MODE_VBLANK_STATUS, R500_VBLANK_ACK); 151 } 152 irq_mask |= R500_DISPLAY_INT_STATUS; 153 } else 154 irq_mask |= RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT; 155 156 irqs &= irq_mask; 157 158 if (irqs) 159 RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs); 160 161 return irqs; 162} 163 164/* Interrupts - Used for device synchronization and flushing in the 165 * following circumstances: 166 * 167 * - Exclusive FB access with hw idle: 168 * - Wait for GUI Idle (?) interrupt, then do normal flush. 169 * 170 * - Frame throttling, NV_fence: 171 * - Drop marker irq's into command stream ahead of time. 172 * - Wait on irq's with lock *not held* 173 * - Check each for termination condition 174 * 175 * - Internally in cp_getbuffer, etc: 176 * - as above, but wait with lock held??? 177 * 178 * NOTE: These functions are misleadingly named -- the irq's aren't 179 * tied to dma at all, this is just a hangover from dri prehistory. 180 */ 181 182irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) 183{ 184 struct drm_device *dev = (struct drm_device *) arg; 185 drm_radeon_private_t *dev_priv = 186 (drm_radeon_private_t *) dev->dev_private; 187 u32 stat; 188 u32 r500_disp_int; 189 190 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 191 return IRQ_NONE; 192 193 /* Only consider the bits we're interested in - others could be used 194 * outside the DRM 195 */ 196 stat = radeon_acknowledge_irqs(dev_priv, &r500_disp_int); 197 if (!stat) 198 return IRQ_NONE; 199 200 stat &= dev_priv->irq_enable_reg; 201 202 /* SW interrupt */ 203 if (stat & RADEON_SW_INT_TEST) 204 DRM_WAKEUP(&dev_priv->swi_queue); 205 206 /* VBLANK interrupt */ 207 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { 208 if (r500_disp_int & R500_D1_VBLANK_INTERRUPT) 209 drm_handle_vblank(dev, 0); 210 if (r500_disp_int & R500_D2_VBLANK_INTERRUPT) 211 drm_handle_vblank(dev, 1); 212 } else { 213 if (stat & RADEON_CRTC_VBLANK_STAT) 214 drm_handle_vblank(dev, 0); 215 if (stat & RADEON_CRTC2_VBLANK_STAT) 216 drm_handle_vblank(dev, 1); 217 } 218 return IRQ_HANDLED; 219} 220 221static int radeon_emit_irq(struct drm_device * dev) 222{ 223 drm_radeon_private_t *dev_priv = dev->dev_private; 224 unsigned int ret; 225 RING_LOCALS; 226 227 atomic_inc(&dev_priv->swi_emitted); 228 ret = atomic_read(&dev_priv->swi_emitted); 229 230 BEGIN_RING(4); 231 OUT_RING_REG(RADEON_LAST_SWI_REG, ret); 232 OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE); 233 ADVANCE_RING(); 234 COMMIT_RING(); 235 236 return ret; 237} 238 239static int radeon_wait_irq(struct drm_device * dev, int swi_nr) 240{ 241 drm_radeon_private_t *dev_priv = 242 (drm_radeon_private_t *) dev->dev_private; 243 int ret = 0; 244 245 if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr) 246 return 0; 247 248 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 249 250 DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ, 251 RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr); 252 253 return ret; 254} 255 256u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc) 257{ 258 drm_radeon_private_t *dev_priv = dev->dev_private; 259 260 if (!dev_priv) { 261 DRM_ERROR("called with no initialization\n"); 262 return -EINVAL; 263 } 264 265 if (crtc < 0 || crtc > 1) { 266 DRM_ERROR("Invalid crtc %d\n", crtc); 267 return -EINVAL; 268 } 269 270 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { 271 if (crtc == 0) 272 return RADEON_READ(R500_D1CRTC_FRAME_COUNT); 273 else 274 return RADEON_READ(R500_D2CRTC_FRAME_COUNT); 275 } else { 276 if (crtc == 0) 277 return RADEON_READ(RADEON_CRTC_CRNT_FRAME); 278 else 279 return RADEON_READ(RADEON_CRTC2_CRNT_FRAME); 280 } 281} 282 283/* Needs the lock as it touches the ring. 284 */ 285int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv) 286{ 287 drm_radeon_private_t *dev_priv = dev->dev_private; 288 drm_radeon_irq_emit_t *emit = data; 289 int result; 290 291 if (!dev_priv) { 292 DRM_ERROR("called with no initialization\n"); 293 return -EINVAL; 294 } 295 296 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 297 return -EINVAL; 298 299 LOCK_TEST_WITH_RETURN(dev, file_priv); 300 301 result = radeon_emit_irq(dev); 302 303 if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) { 304 DRM_ERROR("copy_to_user\n"); 305 return -EFAULT; 306 } 307 308 return 0; 309} 310 311/* Doesn't need the hardware lock. 312 */ 313int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv) 314{ 315 drm_radeon_private_t *dev_priv = dev->dev_private; 316 drm_radeon_irq_wait_t *irqwait = data; 317 318 if (!dev_priv) { 319 DRM_ERROR("called with no initialization\n"); 320 return -EINVAL; 321 } 322 323 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 324 return -EINVAL; 325 326 return radeon_wait_irq(dev, irqwait->irq_seq); 327} 328 329/* drm_dma.h hooks 330*/ 331void radeon_driver_irq_preinstall(struct drm_device * dev) 332{ 333 drm_radeon_private_t *dev_priv = 334 (drm_radeon_private_t *) dev->dev_private; 335 u32 dummy; 336 337 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 338 return; 339 340 /* Disable *all* interrupts */ 341 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) 342 RADEON_WRITE(R500_DxMODE_INT_MASK, 0); 343 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); 344 345 /* Clear bits if they're already high */ 346 radeon_acknowledge_irqs(dev_priv, &dummy); 347} 348 349int radeon_driver_irq_postinstall(struct drm_device *dev) 350{ 351 drm_radeon_private_t *dev_priv = 352 (drm_radeon_private_t *) dev->dev_private; 353 354 atomic_set(&dev_priv->swi_emitted, 0); 355 DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); 356 357 dev->max_vblank_count = 0x001fffff; 358 359 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 360 return 0; 361 362 radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); 363 364 return 0; 365} 366 367void radeon_driver_irq_uninstall(struct drm_device * dev) 368{ 369 drm_radeon_private_t *dev_priv = 370 (drm_radeon_private_t *) dev->dev_private; 371 if (!dev_priv) 372 return; 373 374 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) 375 return; 376 377 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) 378 RADEON_WRITE(R500_DxMODE_INT_MASK, 0); 379 /* Disable *all* interrupts */ 380 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); 381} 382 383 384int radeon_vblank_crtc_get(struct drm_device *dev) 385{ 386 drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; 387 388 return dev_priv->vblank_crtc; 389} 390 391int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value) 392{ 393 drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; 394 if (value & ~(DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { 395 DRM_ERROR("called with invalid crtc 0x%x\n", (unsigned int)value); 396 return -EINVAL; 397 } 398 dev_priv->vblank_crtc = (unsigned int)value; 399 return 0; 400}