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 <linux/irq.h> 29 #include <drm/drmP.h> 30 #include <drm/drm_crtc_helper.h> 31 #include <drm/amdgpu_drm.h> 32 #include "amdgpu.h" 33 #include "amdgpu_ih.h" 34 #include "atom.h" 35 #include "amdgpu_connectors.h" 36 #include "amdgpu_trace.h" 37 38 #include <linux/pm_runtime.h> 39 40 #ifdef CONFIG_DRM_AMD_DC 41 #include "amdgpu_dm_irq.h" 42 #endif 43 44 #define AMDGPU_WAIT_IDLE_TIMEOUT 200 45 46 /* 47 * Handle hotplug events outside the interrupt handler proper. 48 */ 49 /** 50 * amdgpu_hotplug_work_func - display hotplug work handler 51 * 52 * @work: work struct 53 * 54 * This is the hot plug event work handler (all asics). 55 * The work gets scheduled from the irq handler if there 56 * was a hot plug interrupt. It walks the connector table 57 * and calls the hotplug handler for each one, then sends 58 * a drm hotplug event to alert userspace. 59 */ 60 static void amdgpu_hotplug_work_func(struct work_struct *work) 61 { 62 struct amdgpu_device *adev = container_of(work, struct amdgpu_device, 63 hotplug_work); 64 struct drm_device *dev = adev->ddev; 65 struct drm_mode_config *mode_config = &dev->mode_config; 66 struct drm_connector *connector; 67 68 mutex_lock(&mode_config->mutex); 69 list_for_each_entry(connector, &mode_config->connector_list, head) 70 amdgpu_connector_hotplug(connector); 71 mutex_unlock(&mode_config->mutex); 72 /* Just fire off a uevent and let userspace tell us what to do */ 73 drm_helper_hpd_irq_event(dev); 74 } 75 76 /** 77 * amdgpu_irq_reset_work_func - execute gpu reset 78 * 79 * @work: work struct 80 * 81 * Execute scheduled gpu reset (cayman+). 82 * This function is called when the irq handler 83 * thinks we need a gpu reset. 84 */ 85 static void amdgpu_irq_reset_work_func(struct work_struct *work) 86 { 87 struct amdgpu_device *adev = container_of(work, struct amdgpu_device, 88 reset_work); 89 90 if (!amdgpu_sriov_vf(adev)) 91 amdgpu_device_gpu_recover(adev, NULL, false); 92 } 93 94 /* Disable *all* interrupts */ 95 static void amdgpu_irq_disable_all(struct amdgpu_device *adev) 96 { 97 unsigned long irqflags; 98 unsigned i, j, k; 99 int r; 100 101 spin_lock_irqsave(&adev->irq.lock, irqflags); 102 for (i = 0; i < AMDGPU_IH_CLIENTID_MAX; ++i) { 103 if (!adev->irq.client[i].sources) 104 continue; 105 106 for (j = 0; j < AMDGPU_MAX_IRQ_SRC_ID; ++j) { 107 struct amdgpu_irq_src *src = adev->irq.client[i].sources[j]; 108 109 if (!src || !src->funcs->set || !src->num_types) 110 continue; 111 112 for (k = 0; k < src->num_types; ++k) { 113 atomic_set(&src->enabled_types[k], 0); 114 r = src->funcs->set(adev, src, k, 115 AMDGPU_IRQ_STATE_DISABLE); 116 if (r) 117 DRM_ERROR("error disabling interrupt (%d)\n", 118 r); 119 } 120 } 121 } 122 spin_unlock_irqrestore(&adev->irq.lock, irqflags); 123 } 124 125 /** 126 * amdgpu_irq_preinstall - drm irq preinstall callback 127 * 128 * @dev: drm dev pointer 129 * 130 * Gets the hw ready to enable irqs (all asics). 131 * This function disables all interrupt sources on the GPU. 132 */ 133 void amdgpu_irq_preinstall(struct drm_device *dev) 134 { 135 struct amdgpu_device *adev = dev->dev_private; 136 137 /* Disable *all* interrupts */ 138 amdgpu_irq_disable_all(adev); 139 /* Clear bits */ 140 amdgpu_ih_process(adev); 141 } 142 143 /** 144 * amdgpu_irq_postinstall - drm irq preinstall callback 145 * 146 * @dev: drm dev pointer 147 * 148 * Handles stuff to be done after enabling irqs (all asics). 149 * Returns 0 on success. 150 */ 151 int amdgpu_irq_postinstall(struct drm_device *dev) 152 { 153 dev->max_vblank_count = 0x00ffffff; 154 return 0; 155 } 156 157 /** 158 * amdgpu_irq_uninstall - drm irq uninstall callback 159 * 160 * @dev: drm dev pointer 161 * 162 * This function disables all interrupt sources on the GPU (all asics). 163 */ 164 void amdgpu_irq_uninstall(struct drm_device *dev) 165 { 166 struct amdgpu_device *adev = dev->dev_private; 167 168 if (adev == NULL) { 169 return; 170 } 171 amdgpu_irq_disable_all(adev); 172 } 173 174 /** 175 * amdgpu_irq_handler - irq handler 176 * 177 * @int irq, void *arg: args 178 * 179 * This is the irq handler for the amdgpu driver (all asics). 180 */ 181 irqreturn_t amdgpu_irq_handler(int irq, void *arg) 182 { 183 struct drm_device *dev = (struct drm_device *) arg; 184 struct amdgpu_device *adev = dev->dev_private; 185 irqreturn_t ret; 186 187 ret = amdgpu_ih_process(adev); 188 if (ret == IRQ_HANDLED) 189 pm_runtime_mark_last_busy(dev->dev); 190 return ret; 191 } 192 193 /** 194 * amdgpu_msi_ok - asic specific msi checks 195 * 196 * @adev: amdgpu device pointer 197 * 198 * Handles asic specific MSI checks to determine if 199 * MSIs should be enabled on a particular chip (all asics). 200 * Returns true if MSIs should be enabled, false if MSIs 201 * should not be enabled. 202 */ 203 static bool amdgpu_msi_ok(struct amdgpu_device *adev) 204 { 205 /* force MSI on */ 206 if (amdgpu_msi == 1) 207 return true; 208 else if (amdgpu_msi == 0) 209 return false; 210 211 return true; 212 } 213 214 /** 215 * amdgpu_irq_init - init driver interrupt info 216 * 217 * @adev: amdgpu device pointer 218 * 219 * Sets up the work irq handlers, vblank init, MSIs, etc. (all asics). 220 * Returns 0 for success, error for failure. 221 */ 222 int amdgpu_irq_init(struct amdgpu_device *adev) 223 { 224 int r = 0; 225 226 spin_lock_init(&adev->irq.lock); 227 228 /* enable msi */ 229 adev->irq.msi_enabled = false; 230 231 if (amdgpu_msi_ok(adev)) { 232 int ret = pci_enable_msi(adev->pdev); 233 if (!ret) { 234 adev->irq.msi_enabled = true; 235 dev_dbg(adev->dev, "amdgpu: using MSI.\n"); 236 } 237 } 238 239 if (!amdgpu_device_has_dc_support(adev)) { 240 if (!adev->enable_virtual_display) 241 /* Disable vblank irqs aggressively for power-saving */ 242 /* XXX: can this be enabled for DC? */ 243 adev->ddev->vblank_disable_immediate = true; 244 245 r = drm_vblank_init(adev->ddev, adev->mode_info.num_crtc); 246 if (r) 247 return r; 248 249 /* pre DCE11 */ 250 INIT_WORK(&adev->hotplug_work, 251 amdgpu_hotplug_work_func); 252 } 253 254 INIT_WORK(&adev->reset_work, amdgpu_irq_reset_work_func); 255 256 adev->irq.installed = true; 257 r = drm_irq_install(adev->ddev, adev->ddev->pdev->irq); 258 if (r) { 259 adev->irq.installed = false; 260 if (!amdgpu_device_has_dc_support(adev)) 261 flush_work(&adev->hotplug_work); 262 cancel_work_sync(&adev->reset_work); 263 return r; 264 } 265 266 DRM_DEBUG("amdgpu: irq initialized.\n"); 267 return 0; 268 } 269 270 /** 271 * amdgpu_irq_fini - tear down driver interrupt info 272 * 273 * @adev: amdgpu device pointer 274 * 275 * Tears down the work irq handlers, vblank handlers, MSIs, etc. (all asics). 276 */ 277 void amdgpu_irq_fini(struct amdgpu_device *adev) 278 { 279 unsigned i, j; 280 281 if (adev->irq.installed) { 282 drm_irq_uninstall(adev->ddev); 283 adev->irq.installed = false; 284 if (adev->irq.msi_enabled) 285 pci_disable_msi(adev->pdev); 286 if (!amdgpu_device_has_dc_support(adev)) 287 flush_work(&adev->hotplug_work); 288 cancel_work_sync(&adev->reset_work); 289 } 290 291 for (i = 0; i < AMDGPU_IH_CLIENTID_MAX; ++i) { 292 if (!adev->irq.client[i].sources) 293 continue; 294 295 for (j = 0; j < AMDGPU_MAX_IRQ_SRC_ID; ++j) { 296 struct amdgpu_irq_src *src = adev->irq.client[i].sources[j]; 297 298 if (!src) 299 continue; 300 301 kfree(src->enabled_types); 302 src->enabled_types = NULL; 303 if (src->data) { 304 kfree(src->data); 305 kfree(src); 306 adev->irq.client[i].sources[j] = NULL; 307 } 308 } 309 kfree(adev->irq.client[i].sources); 310 } 311 } 312 313 /** 314 * amdgpu_irq_add_id - register irq source 315 * 316 * @adev: amdgpu device pointer 317 * @src_id: source id for this source 318 * @source: irq source 319 * 320 */ 321 int amdgpu_irq_add_id(struct amdgpu_device *adev, 322 unsigned client_id, unsigned src_id, 323 struct amdgpu_irq_src *source) 324 { 325 if (client_id >= AMDGPU_IH_CLIENTID_MAX) 326 return -EINVAL; 327 328 if (src_id >= AMDGPU_MAX_IRQ_SRC_ID) 329 return -EINVAL; 330 331 if (!source->funcs) 332 return -EINVAL; 333 334 if (!adev->irq.client[client_id].sources) { 335 adev->irq.client[client_id].sources = 336 kcalloc(AMDGPU_MAX_IRQ_SRC_ID, 337 sizeof(struct amdgpu_irq_src *), 338 GFP_KERNEL); 339 if (!adev->irq.client[client_id].sources) 340 return -ENOMEM; 341 } 342 343 if (adev->irq.client[client_id].sources[src_id] != NULL) 344 return -EINVAL; 345 346 if (source->num_types && !source->enabled_types) { 347 atomic_t *types; 348 349 types = kcalloc(source->num_types, sizeof(atomic_t), 350 GFP_KERNEL); 351 if (!types) 352 return -ENOMEM; 353 354 source->enabled_types = types; 355 } 356 357 adev->irq.client[client_id].sources[src_id] = source; 358 return 0; 359 } 360 361 /** 362 * amdgpu_irq_dispatch - dispatch irq to IP blocks 363 * 364 * @adev: amdgpu device pointer 365 * @entry: interrupt vector 366 * 367 * Dispatches the irq to the different IP blocks 368 */ 369 void amdgpu_irq_dispatch(struct amdgpu_device *adev, 370 struct amdgpu_iv_entry *entry) 371 { 372 unsigned client_id = entry->client_id; 373 unsigned src_id = entry->src_id; 374 struct amdgpu_irq_src *src; 375 int r; 376 377 trace_amdgpu_iv(entry); 378 379 if (client_id >= AMDGPU_IH_CLIENTID_MAX) { 380 DRM_DEBUG("Invalid client_id in IV: %d\n", client_id); 381 return; 382 } 383 384 if (src_id >= AMDGPU_MAX_IRQ_SRC_ID) { 385 DRM_DEBUG("Invalid src_id in IV: %d\n", src_id); 386 return; 387 } 388 389 if (adev->irq.virq[src_id]) { 390 generic_handle_irq(irq_find_mapping(adev->irq.domain, src_id)); 391 } else { 392 if (!adev->irq.client[client_id].sources) { 393 DRM_DEBUG("Unregistered interrupt client_id: %d src_id: %d\n", 394 client_id, src_id); 395 return; 396 } 397 398 src = adev->irq.client[client_id].sources[src_id]; 399 if (!src) { 400 DRM_DEBUG("Unhandled interrupt src_id: %d\n", src_id); 401 return; 402 } 403 404 r = src->funcs->process(adev, src, entry); 405 if (r) 406 DRM_ERROR("error processing interrupt (%d)\n", r); 407 } 408 } 409 410 /** 411 * amdgpu_irq_update - update hw interrupt state 412 * 413 * @adev: amdgpu device pointer 414 * @src: interrupt src you want to enable 415 * @type: type of interrupt you want to update 416 * 417 * Updates the interrupt state for a specific src (all asics). 418 */ 419 int amdgpu_irq_update(struct amdgpu_device *adev, 420 struct amdgpu_irq_src *src, unsigned type) 421 { 422 unsigned long irqflags; 423 enum amdgpu_interrupt_state state; 424 int r; 425 426 spin_lock_irqsave(&adev->irq.lock, irqflags); 427 428 /* we need to determine after taking the lock, otherwise 429 we might disable just enabled interrupts again */ 430 if (amdgpu_irq_enabled(adev, src, type)) 431 state = AMDGPU_IRQ_STATE_ENABLE; 432 else 433 state = AMDGPU_IRQ_STATE_DISABLE; 434 435 r = src->funcs->set(adev, src, type, state); 436 spin_unlock_irqrestore(&adev->irq.lock, irqflags); 437 return r; 438 } 439 440 void amdgpu_irq_gpu_reset_resume_helper(struct amdgpu_device *adev) 441 { 442 int i, j, k; 443 444 for (i = 0; i < AMDGPU_IH_CLIENTID_MAX; ++i) { 445 if (!adev->irq.client[i].sources) 446 continue; 447 448 for (j = 0; j < AMDGPU_MAX_IRQ_SRC_ID; ++j) { 449 struct amdgpu_irq_src *src = adev->irq.client[i].sources[j]; 450 451 if (!src) 452 continue; 453 for (k = 0; k < src->num_types; k++) 454 amdgpu_irq_update(adev, src, k); 455 } 456 } 457 } 458 459 /** 460 * amdgpu_irq_get - enable interrupt 461 * 462 * @adev: amdgpu device pointer 463 * @src: interrupt src you want to enable 464 * @type: type of interrupt you want to enable 465 * 466 * Enables the interrupt type for a specific src (all asics). 467 */ 468 int amdgpu_irq_get(struct amdgpu_device *adev, struct amdgpu_irq_src *src, 469 unsigned type) 470 { 471 if (!adev->ddev->irq_enabled) 472 return -ENOENT; 473 474 if (type >= src->num_types) 475 return -EINVAL; 476 477 if (!src->enabled_types || !src->funcs->set) 478 return -EINVAL; 479 480 if (atomic_inc_return(&src->enabled_types[type]) == 1) 481 return amdgpu_irq_update(adev, src, type); 482 483 return 0; 484 } 485 486 /** 487 * amdgpu_irq_put - disable interrupt 488 * 489 * @adev: amdgpu device pointer 490 * @src: interrupt src you want to disable 491 * @type: type of interrupt you want to disable 492 * 493 * Disables the interrupt type for a specific src (all asics). 494 */ 495 int amdgpu_irq_put(struct amdgpu_device *adev, struct amdgpu_irq_src *src, 496 unsigned type) 497 { 498 if (!adev->ddev->irq_enabled) 499 return -ENOENT; 500 501 if (type >= src->num_types) 502 return -EINVAL; 503 504 if (!src->enabled_types || !src->funcs->set) 505 return -EINVAL; 506 507 if (atomic_dec_and_test(&src->enabled_types[type])) 508 return amdgpu_irq_update(adev, src, type); 509 510 return 0; 511 } 512 513 /** 514 * amdgpu_irq_enabled - test if irq is enabled or not 515 * 516 * @adev: amdgpu device pointer 517 * @idx: interrupt src you want to test 518 * 519 * Tests if the given interrupt source is enabled or not 520 */ 521 bool amdgpu_irq_enabled(struct amdgpu_device *adev, struct amdgpu_irq_src *src, 522 unsigned type) 523 { 524 if (!adev->ddev->irq_enabled) 525 return false; 526 527 if (type >= src->num_types) 528 return false; 529 530 if (!src->enabled_types || !src->funcs->set) 531 return false; 532 533 return !!atomic_read(&src->enabled_types[type]); 534 } 535 536 /* gen irq */ 537 static void amdgpu_irq_mask(struct irq_data *irqd) 538 { 539 /* XXX */ 540 } 541 542 static void amdgpu_irq_unmask(struct irq_data *irqd) 543 { 544 /* XXX */ 545 } 546 547 static struct irq_chip amdgpu_irq_chip = { 548 .name = "amdgpu-ih", 549 .irq_mask = amdgpu_irq_mask, 550 .irq_unmask = amdgpu_irq_unmask, 551 }; 552 553 static int amdgpu_irqdomain_map(struct irq_domain *d, 554 unsigned int irq, irq_hw_number_t hwirq) 555 { 556 if (hwirq >= AMDGPU_MAX_IRQ_SRC_ID) 557 return -EPERM; 558 559 irq_set_chip_and_handler(irq, 560 &amdgpu_irq_chip, handle_simple_irq); 561 return 0; 562 } 563 564 static const struct irq_domain_ops amdgpu_hw_irqdomain_ops = { 565 .map = amdgpu_irqdomain_map, 566 }; 567 568 /** 569 * amdgpu_irq_add_domain - create a linear irq domain 570 * 571 * @adev: amdgpu device pointer 572 * 573 * Create an irq domain for GPU interrupt sources 574 * that may be driven by another driver (e.g., ACP). 575 */ 576 int amdgpu_irq_add_domain(struct amdgpu_device *adev) 577 { 578 adev->irq.domain = irq_domain_add_linear(NULL, AMDGPU_MAX_IRQ_SRC_ID, 579 &amdgpu_hw_irqdomain_ops, adev); 580 if (!adev->irq.domain) { 581 DRM_ERROR("GPU irq add domain failed\n"); 582 return -ENODEV; 583 } 584 585 return 0; 586 } 587 588 /** 589 * amdgpu_irq_remove_domain - remove the irq domain 590 * 591 * @adev: amdgpu device pointer 592 * 593 * Remove the irq domain for GPU interrupt sources 594 * that may be driven by another driver (e.g., ACP). 595 */ 596 void amdgpu_irq_remove_domain(struct amdgpu_device *adev) 597 { 598 if (adev->irq.domain) { 599 irq_domain_remove(adev->irq.domain); 600 adev->irq.domain = NULL; 601 } 602 } 603 604 /** 605 * amdgpu_irq_create_mapping - create a mapping between a domain irq and a 606 * Linux irq 607 * 608 * @adev: amdgpu device pointer 609 * @src_id: IH source id 610 * 611 * Create a mapping between a domain irq (GPU IH src id) and a Linux irq 612 * Use this for components that generate a GPU interrupt, but are driven 613 * by a different driver (e.g., ACP). 614 * Returns the Linux irq. 615 */ 616 unsigned amdgpu_irq_create_mapping(struct amdgpu_device *adev, unsigned src_id) 617 { 618 adev->irq.virq[src_id] = irq_create_mapping(adev->irq.domain, src_id); 619 620 return adev->irq.virq[src_id]; 621 } 622