1 /* 2 * Copyright 2008 Advanced Micro Devices, Inc. 3 * Copyright 2008 Red Hat Inc. 4 * Copyright 2009 Jerome Glisse. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: Dave Airlie 25 * Alex Deucher 26 * Jerome Glisse 27 */ 28 #include <drm/drmP.h> 29 #include <drm/drm_crtc_helper.h> 30 #include <drm/radeon_drm.h> 31 #include "radeon_reg.h" 32 #include "radeon.h" 33 #include "atom.h" 34 35 #define RADEON_WAIT_IDLE_TIMEOUT 200 36 37 /** 38 * radeon_driver_irq_handler_kms - irq handler for KMS 39 * 40 * @DRM_IRQ_ARGS: args 41 * 42 * This is the irq handler for the radeon KMS driver (all asics). 43 * radeon_irq_process is a macro that points to the per-asic 44 * irq handler callback. 45 */ 46 irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS) 47 { 48 struct drm_device *dev = (struct drm_device *) arg; 49 struct radeon_device *rdev = dev->dev_private; 50 51 return radeon_irq_process(rdev); 52 } 53 54 /* 55 * Handle hotplug events outside the interrupt handler proper. 56 */ 57 /** 58 * radeon_hotplug_work_func - display hotplug work handler 59 * 60 * @work: work struct 61 * 62 * This is the hot plug event work handler (all asics). 63 * The work gets scheduled from the irq handler if there 64 * was a hot plug interrupt. It walks the connector table 65 * and calls the hotplug handler for each one, then sends 66 * a drm hotplug event to alert userspace. 67 */ 68 static void radeon_hotplug_work_func(struct work_struct *work) 69 { 70 struct radeon_device *rdev = container_of(work, struct radeon_device, 71 hotplug_work); 72 struct drm_device *dev = rdev->ddev; 73 struct drm_mode_config *mode_config = &dev->mode_config; 74 struct drm_connector *connector; 75 76 if (mode_config->num_connector) { 77 list_for_each_entry(connector, &mode_config->connector_list, head) 78 radeon_connector_hotplug(connector); 79 } 80 /* Just fire off a uevent and let userspace tell us what to do */ 81 drm_helper_hpd_irq_event(dev); 82 } 83 84 /** 85 * radeon_irq_reset_work_func - execute gpu reset 86 * 87 * @work: work struct 88 * 89 * Execute scheduled gpu reset (cayman+). 90 * This function is called when the irq handler 91 * thinks we need a gpu reset. 92 */ 93 static void radeon_irq_reset_work_func(struct work_struct *work) 94 { 95 struct radeon_device *rdev = container_of(work, struct radeon_device, 96 reset_work); 97 98 radeon_gpu_reset(rdev); 99 } 100 101 /** 102 * radeon_driver_irq_preinstall_kms - drm irq preinstall callback 103 * 104 * @dev: drm dev pointer 105 * 106 * Gets the hw ready to enable irqs (all asics). 107 * This function disables all interrupt sources on the GPU. 108 */ 109 void radeon_driver_irq_preinstall_kms(struct drm_device *dev) 110 { 111 struct radeon_device *rdev = dev->dev_private; 112 unsigned long irqflags; 113 unsigned i; 114 115 spin_lock_irqsave(&rdev->irq.lock, irqflags); 116 /* Disable *all* interrupts */ 117 for (i = 0; i < RADEON_NUM_RINGS; i++) 118 atomic_set(&rdev->irq.ring_int[i], 0); 119 rdev->irq.dpm_thermal = false; 120 for (i = 0; i < RADEON_MAX_HPD_PINS; i++) 121 rdev->irq.hpd[i] = false; 122 for (i = 0; i < RADEON_MAX_CRTCS; i++) { 123 rdev->irq.crtc_vblank_int[i] = false; 124 atomic_set(&rdev->irq.pflip[i], 0); 125 rdev->irq.afmt[i] = false; 126 } 127 radeon_irq_set(rdev); 128 spin_unlock_irqrestore(&rdev->irq.lock, irqflags); 129 /* Clear bits */ 130 radeon_irq_process(rdev); 131 } 132 133 /** 134 * radeon_driver_irq_postinstall_kms - drm irq preinstall callback 135 * 136 * @dev: drm dev pointer 137 * 138 * Handles stuff to be done after enabling irqs (all asics). 139 * Returns 0 on success. 140 */ 141 int radeon_driver_irq_postinstall_kms(struct drm_device *dev) 142 { 143 dev->max_vblank_count = 0x001fffff; 144 return 0; 145 } 146 147 /** 148 * radeon_driver_irq_uninstall_kms - drm irq uninstall callback 149 * 150 * @dev: drm dev pointer 151 * 152 * This function disables all interrupt sources on the GPU (all asics). 153 */ 154 void radeon_driver_irq_uninstall_kms(struct drm_device *dev) 155 { 156 struct radeon_device *rdev = dev->dev_private; 157 unsigned long irqflags; 158 unsigned i; 159 160 if (rdev == NULL) { 161 return; 162 } 163 spin_lock_irqsave(&rdev->irq.lock, irqflags); 164 /* Disable *all* interrupts */ 165 for (i = 0; i < RADEON_NUM_RINGS; i++) 166 atomic_set(&rdev->irq.ring_int[i], 0); 167 rdev->irq.dpm_thermal = false; 168 for (i = 0; i < RADEON_MAX_HPD_PINS; i++) 169 rdev->irq.hpd[i] = false; 170 for (i = 0; i < RADEON_MAX_CRTCS; i++) { 171 rdev->irq.crtc_vblank_int[i] = false; 172 atomic_set(&rdev->irq.pflip[i], 0); 173 rdev->irq.afmt[i] = false; 174 } 175 radeon_irq_set(rdev); 176 spin_unlock_irqrestore(&rdev->irq.lock, irqflags); 177 } 178 179 /** 180 * radeon_msi_ok - asic specific msi checks 181 * 182 * @rdev: radeon device pointer 183 * 184 * Handles asic specific MSI checks to determine if 185 * MSIs should be enabled on a particular chip (all asics). 186 * Returns true if MSIs should be enabled, false if MSIs 187 * should not be enabled. 188 */ 189 static bool radeon_msi_ok(struct radeon_device *rdev) 190 { 191 /* RV370/RV380 was first asic with MSI support */ 192 if (rdev->family < CHIP_RV380) 193 return false; 194 195 /* MSIs don't work on AGP */ 196 if (rdev->flags & RADEON_IS_AGP) 197 return false; 198 199 /* force MSI on */ 200 if (radeon_msi == 1) 201 return true; 202 else if (radeon_msi == 0) 203 return false; 204 205 /* Quirks */ 206 /* HP RS690 only seems to work with MSIs. */ 207 if ((rdev->pdev->device == 0x791f) && 208 (rdev->pdev->subsystem_vendor == 0x103c) && 209 (rdev->pdev->subsystem_device == 0x30c2)) 210 return true; 211 212 /* Dell RS690 only seems to work with MSIs. */ 213 if ((rdev->pdev->device == 0x791f) && 214 (rdev->pdev->subsystem_vendor == 0x1028) && 215 (rdev->pdev->subsystem_device == 0x01fc)) 216 return true; 217 218 /* Dell RS690 only seems to work with MSIs. */ 219 if ((rdev->pdev->device == 0x791f) && 220 (rdev->pdev->subsystem_vendor == 0x1028) && 221 (rdev->pdev->subsystem_device == 0x01fd)) 222 return true; 223 224 /* Gateway RS690 only seems to work with MSIs. */ 225 if ((rdev->pdev->device == 0x791f) && 226 (rdev->pdev->subsystem_vendor == 0x107b) && 227 (rdev->pdev->subsystem_device == 0x0185)) 228 return true; 229 230 /* try and enable MSIs by default on all RS690s */ 231 if (rdev->family == CHIP_RS690) 232 return true; 233 234 /* RV515 seems to have MSI issues where it loses 235 * MSI rearms occasionally. This leads to lockups and freezes. 236 * disable it by default. 237 */ 238 if (rdev->family == CHIP_RV515) 239 return false; 240 if (rdev->flags & RADEON_IS_IGP) { 241 /* APUs work fine with MSIs */ 242 if (rdev->family >= CHIP_PALM) 243 return true; 244 /* lots of IGPs have problems with MSIs */ 245 return false; 246 } 247 248 return true; 249 } 250 251 /** 252 * radeon_irq_kms_init - init driver interrupt info 253 * 254 * @rdev: radeon device pointer 255 * 256 * Sets up the work irq handlers, vblank init, MSIs, etc. (all asics). 257 * Returns 0 for success, error for failure. 258 */ 259 int radeon_irq_kms_init(struct radeon_device *rdev) 260 { 261 int r = 0; 262 263 spin_lock_init(&rdev->irq.lock); 264 r = drm_vblank_init(rdev->ddev, rdev->num_crtc); 265 if (r) { 266 return r; 267 } 268 /* enable msi */ 269 rdev->msi_enabled = 0; 270 271 if (radeon_msi_ok(rdev)) { 272 int ret = pci_enable_msi(rdev->pdev); 273 if (!ret) { 274 rdev->msi_enabled = 1; 275 dev_info(rdev->dev, "radeon: using MSI.\n"); 276 } 277 } 278 rdev->irq.installed = true; 279 r = drm_irq_install(rdev->ddev); 280 if (r) { 281 rdev->irq.installed = false; 282 return r; 283 } 284 285 INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); 286 INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi); 287 INIT_WORK(&rdev->reset_work, radeon_irq_reset_work_func); 288 289 DRM_INFO("radeon: irq initialized.\n"); 290 return 0; 291 } 292 293 /** 294 * radeon_irq_kms_fini - tear down driver interrupt info 295 * 296 * @rdev: radeon device pointer 297 * 298 * Tears down the work irq handlers, vblank handlers, MSIs, etc. (all asics). 299 */ 300 void radeon_irq_kms_fini(struct radeon_device *rdev) 301 { 302 drm_vblank_cleanup(rdev->ddev); 303 if (rdev->irq.installed) { 304 drm_irq_uninstall(rdev->ddev); 305 rdev->irq.installed = false; 306 if (rdev->msi_enabled) 307 pci_disable_msi(rdev->pdev); 308 flush_work(&rdev->hotplug_work); 309 } 310 } 311 312 /** 313 * radeon_irq_kms_sw_irq_get - enable software interrupt 314 * 315 * @rdev: radeon device pointer 316 * @ring: ring whose interrupt you want to enable 317 * 318 * Enables the software interrupt for a specific ring (all asics). 319 * The software interrupt is generally used to signal a fence on 320 * a particular ring. 321 */ 322 void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev, int ring) 323 { 324 unsigned long irqflags; 325 326 if (!rdev->ddev->irq_enabled) 327 return; 328 329 if (atomic_inc_return(&rdev->irq.ring_int[ring]) == 1) { 330 spin_lock_irqsave(&rdev->irq.lock, irqflags); 331 radeon_irq_set(rdev); 332 spin_unlock_irqrestore(&rdev->irq.lock, irqflags); 333 } 334 } 335 336 /** 337 * radeon_irq_kms_sw_irq_put - disable software interrupt 338 * 339 * @rdev: radeon device pointer 340 * @ring: ring whose interrupt you want to disable 341 * 342 * Disables the software interrupt for a specific ring (all asics). 343 * The software interrupt is generally used to signal a fence on 344 * a particular ring. 345 */ 346 void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev, int ring) 347 { 348 unsigned long irqflags; 349 350 if (!rdev->ddev->irq_enabled) 351 return; 352 353 if (atomic_dec_and_test(&rdev->irq.ring_int[ring])) { 354 spin_lock_irqsave(&rdev->irq.lock, irqflags); 355 radeon_irq_set(rdev); 356 spin_unlock_irqrestore(&rdev->irq.lock, irqflags); 357 } 358 } 359 360 /** 361 * radeon_irq_kms_pflip_irq_get - enable pageflip interrupt 362 * 363 * @rdev: radeon device pointer 364 * @crtc: crtc whose interrupt you want to enable 365 * 366 * Enables the pageflip interrupt for a specific crtc (all asics). 367 * For pageflips we use the vblank interrupt source. 368 */ 369 void radeon_irq_kms_pflip_irq_get(struct radeon_device *rdev, int crtc) 370 { 371 unsigned long irqflags; 372 373 if (crtc < 0 || crtc >= rdev->num_crtc) 374 return; 375 376 if (!rdev->ddev->irq_enabled) 377 return; 378 379 if (atomic_inc_return(&rdev->irq.pflip[crtc]) == 1) { 380 spin_lock_irqsave(&rdev->irq.lock, irqflags); 381 radeon_irq_set(rdev); 382 spin_unlock_irqrestore(&rdev->irq.lock, irqflags); 383 } 384 } 385 386 /** 387 * radeon_irq_kms_pflip_irq_put - disable pageflip interrupt 388 * 389 * @rdev: radeon device pointer 390 * @crtc: crtc whose interrupt you want to disable 391 * 392 * Disables the pageflip interrupt for a specific crtc (all asics). 393 * For pageflips we use the vblank interrupt source. 394 */ 395 void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc) 396 { 397 unsigned long irqflags; 398 399 if (crtc < 0 || crtc >= rdev->num_crtc) 400 return; 401 402 if (!rdev->ddev->irq_enabled) 403 return; 404 405 if (atomic_dec_and_test(&rdev->irq.pflip[crtc])) { 406 spin_lock_irqsave(&rdev->irq.lock, irqflags); 407 radeon_irq_set(rdev); 408 spin_unlock_irqrestore(&rdev->irq.lock, irqflags); 409 } 410 } 411 412 /** 413 * radeon_irq_kms_enable_afmt - enable audio format change interrupt 414 * 415 * @rdev: radeon device pointer 416 * @block: afmt block whose interrupt you want to enable 417 * 418 * Enables the afmt change interrupt for a specific afmt block (all asics). 419 */ 420 void radeon_irq_kms_enable_afmt(struct radeon_device *rdev, int block) 421 { 422 unsigned long irqflags; 423 424 if (!rdev->ddev->irq_enabled) 425 return; 426 427 spin_lock_irqsave(&rdev->irq.lock, irqflags); 428 rdev->irq.afmt[block] = true; 429 radeon_irq_set(rdev); 430 spin_unlock_irqrestore(&rdev->irq.lock, irqflags); 431 432 } 433 434 /** 435 * radeon_irq_kms_disable_afmt - disable audio format change interrupt 436 * 437 * @rdev: radeon device pointer 438 * @block: afmt block whose interrupt you want to disable 439 * 440 * Disables the afmt change interrupt for a specific afmt block (all asics). 441 */ 442 void radeon_irq_kms_disable_afmt(struct radeon_device *rdev, int block) 443 { 444 unsigned long irqflags; 445 446 if (!rdev->ddev->irq_enabled) 447 return; 448 449 spin_lock_irqsave(&rdev->irq.lock, irqflags); 450 rdev->irq.afmt[block] = false; 451 radeon_irq_set(rdev); 452 spin_unlock_irqrestore(&rdev->irq.lock, irqflags); 453 } 454 455 /** 456 * radeon_irq_kms_enable_hpd - enable hotplug detect interrupt 457 * 458 * @rdev: radeon device pointer 459 * @hpd_mask: mask of hpd pins you want to enable. 460 * 461 * Enables the hotplug detect interrupt for a specific hpd pin (all asics). 462 */ 463 void radeon_irq_kms_enable_hpd(struct radeon_device *rdev, unsigned hpd_mask) 464 { 465 unsigned long irqflags; 466 int i; 467 468 if (!rdev->ddev->irq_enabled) 469 return; 470 471 spin_lock_irqsave(&rdev->irq.lock, irqflags); 472 for (i = 0; i < RADEON_MAX_HPD_PINS; ++i) 473 rdev->irq.hpd[i] |= !!(hpd_mask & (1 << i)); 474 radeon_irq_set(rdev); 475 spin_unlock_irqrestore(&rdev->irq.lock, irqflags); 476 } 477 478 /** 479 * radeon_irq_kms_disable_hpd - disable hotplug detect interrupt 480 * 481 * @rdev: radeon device pointer 482 * @hpd_mask: mask of hpd pins you want to disable. 483 * 484 * Disables the hotplug detect interrupt for a specific hpd pin (all asics). 485 */ 486 void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask) 487 { 488 unsigned long irqflags; 489 int i; 490 491 if (!rdev->ddev->irq_enabled) 492 return; 493 494 spin_lock_irqsave(&rdev->irq.lock, irqflags); 495 for (i = 0; i < RADEON_MAX_HPD_PINS; ++i) 496 rdev->irq.hpd[i] &= !(hpd_mask & (1 << i)); 497 radeon_irq_set(rdev); 498 spin_unlock_irqrestore(&rdev->irq.lock, irqflags); 499 } 500 501