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 279 INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); 280 INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi); 281 INIT_WORK(&rdev->reset_work, radeon_irq_reset_work_func); 282 283 rdev->irq.installed = true; 284 r = drm_irq_install(rdev->ddev); 285 if (r) { 286 rdev->irq.installed = false; 287 flush_work(&rdev->hotplug_work); 288 return r; 289 } 290 291 DRM_INFO("radeon: irq initialized.\n"); 292 return 0; 293 } 294 295 /** 296 * radeon_irq_kms_fini - tear down driver interrupt info 297 * 298 * @rdev: radeon device pointer 299 * 300 * Tears down the work irq handlers, vblank handlers, MSIs, etc. (all asics). 301 */ 302 void radeon_irq_kms_fini(struct radeon_device *rdev) 303 { 304 drm_vblank_cleanup(rdev->ddev); 305 if (rdev->irq.installed) { 306 drm_irq_uninstall(rdev->ddev); 307 rdev->irq.installed = false; 308 if (rdev->msi_enabled) 309 pci_disable_msi(rdev->pdev); 310 flush_work(&rdev->hotplug_work); 311 } 312 } 313 314 /** 315 * radeon_irq_kms_sw_irq_get - enable software interrupt 316 * 317 * @rdev: radeon device pointer 318 * @ring: ring whose interrupt you want to enable 319 * 320 * Enables the software interrupt for a specific ring (all asics). 321 * The software interrupt is generally used to signal a fence on 322 * a particular ring. 323 */ 324 void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev, int ring) 325 { 326 unsigned long irqflags; 327 328 if (!rdev->ddev->irq_enabled) 329 return; 330 331 if (atomic_inc_return(&rdev->irq.ring_int[ring]) == 1) { 332 spin_lock_irqsave(&rdev->irq.lock, irqflags); 333 radeon_irq_set(rdev); 334 spin_unlock_irqrestore(&rdev->irq.lock, irqflags); 335 } 336 } 337 338 /** 339 * radeon_irq_kms_sw_irq_put - disable software interrupt 340 * 341 * @rdev: radeon device pointer 342 * @ring: ring whose interrupt you want to disable 343 * 344 * Disables the software interrupt for a specific ring (all asics). 345 * The software interrupt is generally used to signal a fence on 346 * a particular ring. 347 */ 348 void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev, int ring) 349 { 350 unsigned long irqflags; 351 352 if (!rdev->ddev->irq_enabled) 353 return; 354 355 if (atomic_dec_and_test(&rdev->irq.ring_int[ring])) { 356 spin_lock_irqsave(&rdev->irq.lock, irqflags); 357 radeon_irq_set(rdev); 358 spin_unlock_irqrestore(&rdev->irq.lock, irqflags); 359 } 360 } 361 362 /** 363 * radeon_irq_kms_pflip_irq_get - enable pageflip interrupt 364 * 365 * @rdev: radeon device pointer 366 * @crtc: crtc whose interrupt you want to enable 367 * 368 * Enables the pageflip interrupt for a specific crtc (all asics). 369 * For pageflips we use the vblank interrupt source. 370 */ 371 void radeon_irq_kms_pflip_irq_get(struct radeon_device *rdev, int crtc) 372 { 373 unsigned long irqflags; 374 375 if (crtc < 0 || crtc >= rdev->num_crtc) 376 return; 377 378 if (!rdev->ddev->irq_enabled) 379 return; 380 381 if (atomic_inc_return(&rdev->irq.pflip[crtc]) == 1) { 382 spin_lock_irqsave(&rdev->irq.lock, irqflags); 383 radeon_irq_set(rdev); 384 spin_unlock_irqrestore(&rdev->irq.lock, irqflags); 385 } 386 } 387 388 /** 389 * radeon_irq_kms_pflip_irq_put - disable pageflip interrupt 390 * 391 * @rdev: radeon device pointer 392 * @crtc: crtc whose interrupt you want to disable 393 * 394 * Disables the pageflip interrupt for a specific crtc (all asics). 395 * For pageflips we use the vblank interrupt source. 396 */ 397 void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc) 398 { 399 unsigned long irqflags; 400 401 if (crtc < 0 || crtc >= rdev->num_crtc) 402 return; 403 404 if (!rdev->ddev->irq_enabled) 405 return; 406 407 if (atomic_dec_and_test(&rdev->irq.pflip[crtc])) { 408 spin_lock_irqsave(&rdev->irq.lock, irqflags); 409 radeon_irq_set(rdev); 410 spin_unlock_irqrestore(&rdev->irq.lock, irqflags); 411 } 412 } 413 414 /** 415 * radeon_irq_kms_enable_afmt - enable audio format change interrupt 416 * 417 * @rdev: radeon device pointer 418 * @block: afmt block whose interrupt you want to enable 419 * 420 * Enables the afmt change interrupt for a specific afmt block (all asics). 421 */ 422 void radeon_irq_kms_enable_afmt(struct radeon_device *rdev, int block) 423 { 424 unsigned long irqflags; 425 426 if (!rdev->ddev->irq_enabled) 427 return; 428 429 spin_lock_irqsave(&rdev->irq.lock, irqflags); 430 rdev->irq.afmt[block] = true; 431 radeon_irq_set(rdev); 432 spin_unlock_irqrestore(&rdev->irq.lock, irqflags); 433 434 } 435 436 /** 437 * radeon_irq_kms_disable_afmt - disable audio format change interrupt 438 * 439 * @rdev: radeon device pointer 440 * @block: afmt block whose interrupt you want to disable 441 * 442 * Disables the afmt change interrupt for a specific afmt block (all asics). 443 */ 444 void radeon_irq_kms_disable_afmt(struct radeon_device *rdev, int block) 445 { 446 unsigned long irqflags; 447 448 if (!rdev->ddev->irq_enabled) 449 return; 450 451 spin_lock_irqsave(&rdev->irq.lock, irqflags); 452 rdev->irq.afmt[block] = false; 453 radeon_irq_set(rdev); 454 spin_unlock_irqrestore(&rdev->irq.lock, irqflags); 455 } 456 457 /** 458 * radeon_irq_kms_enable_hpd - enable hotplug detect interrupt 459 * 460 * @rdev: radeon device pointer 461 * @hpd_mask: mask of hpd pins you want to enable. 462 * 463 * Enables the hotplug detect interrupt for a specific hpd pin (all asics). 464 */ 465 void radeon_irq_kms_enable_hpd(struct radeon_device *rdev, unsigned hpd_mask) 466 { 467 unsigned long irqflags; 468 int i; 469 470 if (!rdev->ddev->irq_enabled) 471 return; 472 473 spin_lock_irqsave(&rdev->irq.lock, irqflags); 474 for (i = 0; i < RADEON_MAX_HPD_PINS; ++i) 475 rdev->irq.hpd[i] |= !!(hpd_mask & (1 << i)); 476 radeon_irq_set(rdev); 477 spin_unlock_irqrestore(&rdev->irq.lock, irqflags); 478 } 479 480 /** 481 * radeon_irq_kms_disable_hpd - disable hotplug detect interrupt 482 * 483 * @rdev: radeon device pointer 484 * @hpd_mask: mask of hpd pins you want to disable. 485 * 486 * Disables the hotplug detect interrupt for a specific hpd pin (all asics). 487 */ 488 void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask) 489 { 490 unsigned long irqflags; 491 int i; 492 493 if (!rdev->ddev->irq_enabled) 494 return; 495 496 spin_lock_irqsave(&rdev->irq.lock, irqflags); 497 for (i = 0; i < RADEON_MAX_HPD_PINS; ++i) 498 rdev->irq.hpd[i] &= !(hpd_mask & (1 << i)); 499 radeon_irq_set(rdev); 500 spin_unlock_irqrestore(&rdev->irq.lock, irqflags); 501 } 502 503