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/amdgpu_drm.h> 31 #include "amdgpu.h" 32 #include "amdgpu_ih.h" 33 #include "atom.h" 34 #include "amdgpu_connectors.h" 35 36 #include <linux/pm_runtime.h> 37 38 #define AMDGPU_WAIT_IDLE_TIMEOUT 200 39 40 /* 41 * Handle hotplug events outside the interrupt handler proper. 42 */ 43 /** 44 * amdgpu_hotplug_work_func - display hotplug work handler 45 * 46 * @work: work struct 47 * 48 * This is the hot plug event work handler (all asics). 49 * The work gets scheduled from the irq handler if there 50 * was a hot plug interrupt. It walks the connector table 51 * and calls the hotplug handler for each one, then sends 52 * a drm hotplug event to alert userspace. 53 */ 54 static void amdgpu_hotplug_work_func(struct work_struct *work) 55 { 56 struct amdgpu_device *adev = container_of(work, struct amdgpu_device, 57 hotplug_work); 58 struct drm_device *dev = adev->ddev; 59 struct drm_mode_config *mode_config = &dev->mode_config; 60 struct drm_connector *connector; 61 62 mutex_lock(&mode_config->mutex); 63 if (mode_config->num_connector) { 64 list_for_each_entry(connector, &mode_config->connector_list, head) 65 amdgpu_connector_hotplug(connector); 66 } 67 mutex_unlock(&mode_config->mutex); 68 /* Just fire off a uevent and let userspace tell us what to do */ 69 drm_helper_hpd_irq_event(dev); 70 } 71 72 /** 73 * amdgpu_irq_reset_work_func - execute gpu reset 74 * 75 * @work: work struct 76 * 77 * Execute scheduled gpu reset (cayman+). 78 * This function is called when the irq handler 79 * thinks we need a gpu reset. 80 */ 81 static void amdgpu_irq_reset_work_func(struct work_struct *work) 82 { 83 struct amdgpu_device *adev = container_of(work, struct amdgpu_device, 84 reset_work); 85 86 amdgpu_gpu_reset(adev); 87 } 88 89 /* Disable *all* interrupts */ 90 static void amdgpu_irq_disable_all(struct amdgpu_device *adev) 91 { 92 unsigned long irqflags; 93 unsigned i, j; 94 int r; 95 96 spin_lock_irqsave(&adev->irq.lock, irqflags); 97 for (i = 0; i < AMDGPU_MAX_IRQ_SRC_ID; ++i) { 98 struct amdgpu_irq_src *src = adev->irq.sources[i]; 99 100 if (!src || !src->funcs->set || !src->num_types) 101 continue; 102 103 for (j = 0; j < src->num_types; ++j) { 104 atomic_set(&src->enabled_types[j], 0); 105 r = src->funcs->set(adev, src, j, 106 AMDGPU_IRQ_STATE_DISABLE); 107 if (r) 108 DRM_ERROR("error disabling interrupt (%d)\n", 109 r); 110 } 111 } 112 spin_unlock_irqrestore(&adev->irq.lock, irqflags); 113 } 114 115 /** 116 * amdgpu_irq_preinstall - drm irq preinstall callback 117 * 118 * @dev: drm dev pointer 119 * 120 * Gets the hw ready to enable irqs (all asics). 121 * This function disables all interrupt sources on the GPU. 122 */ 123 void amdgpu_irq_preinstall(struct drm_device *dev) 124 { 125 struct amdgpu_device *adev = dev->dev_private; 126 127 /* Disable *all* interrupts */ 128 amdgpu_irq_disable_all(adev); 129 /* Clear bits */ 130 amdgpu_ih_process(adev); 131 } 132 133 /** 134 * amdgpu_irq_postinstall - 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 amdgpu_irq_postinstall(struct drm_device *dev) 142 { 143 dev->max_vblank_count = 0x001fffff; 144 return 0; 145 } 146 147 /** 148 * amdgpu_irq_uninstall - 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 amdgpu_irq_uninstall(struct drm_device *dev) 155 { 156 struct amdgpu_device *adev = dev->dev_private; 157 158 if (adev == NULL) { 159 return; 160 } 161 amdgpu_irq_disable_all(adev); 162 } 163 164 /** 165 * amdgpu_irq_handler - irq handler 166 * 167 * @int irq, void *arg: args 168 * 169 * This is the irq handler for the amdgpu driver (all asics). 170 */ 171 irqreturn_t amdgpu_irq_handler(int irq, void *arg) 172 { 173 struct drm_device *dev = (struct drm_device *) arg; 174 struct amdgpu_device *adev = dev->dev_private; 175 irqreturn_t ret; 176 177 ret = amdgpu_ih_process(adev); 178 if (ret == IRQ_HANDLED) 179 pm_runtime_mark_last_busy(dev->dev); 180 return ret; 181 } 182 183 /** 184 * amdgpu_msi_ok - asic specific msi checks 185 * 186 * @adev: amdgpu device pointer 187 * 188 * Handles asic specific MSI checks to determine if 189 * MSIs should be enabled on a particular chip (all asics). 190 * Returns true if MSIs should be enabled, false if MSIs 191 * should not be enabled. 192 */ 193 static bool amdgpu_msi_ok(struct amdgpu_device *adev) 194 { 195 /* force MSI on */ 196 if (amdgpu_msi == 1) 197 return true; 198 else if (amdgpu_msi == 0) 199 return false; 200 201 return true; 202 } 203 204 /** 205 * amdgpu_irq_init - init driver interrupt info 206 * 207 * @adev: amdgpu device pointer 208 * 209 * Sets up the work irq handlers, vblank init, MSIs, etc. (all asics). 210 * Returns 0 for success, error for failure. 211 */ 212 int amdgpu_irq_init(struct amdgpu_device *adev) 213 { 214 int r = 0; 215 216 spin_lock_init(&adev->irq.lock); 217 r = drm_vblank_init(adev->ddev, adev->mode_info.num_crtc); 218 if (r) { 219 return r; 220 } 221 /* enable msi */ 222 adev->irq.msi_enabled = false; 223 224 if (amdgpu_msi_ok(adev)) { 225 int ret = pci_enable_msi(adev->pdev); 226 if (!ret) { 227 adev->irq.msi_enabled = true; 228 dev_info(adev->dev, "amdgpu: using MSI.\n"); 229 } 230 } 231 232 INIT_WORK(&adev->hotplug_work, amdgpu_hotplug_work_func); 233 INIT_WORK(&adev->reset_work, amdgpu_irq_reset_work_func); 234 235 adev->irq.installed = true; 236 r = drm_irq_install(adev->ddev, adev->ddev->pdev->irq); 237 if (r) { 238 adev->irq.installed = false; 239 flush_work(&adev->hotplug_work); 240 return r; 241 } 242 243 DRM_INFO("amdgpu: irq initialized.\n"); 244 return 0; 245 } 246 247 /** 248 * amdgpu_irq_fini - tear down driver interrupt info 249 * 250 * @adev: amdgpu device pointer 251 * 252 * Tears down the work irq handlers, vblank handlers, MSIs, etc. (all asics). 253 */ 254 void amdgpu_irq_fini(struct amdgpu_device *adev) 255 { 256 unsigned i; 257 258 drm_vblank_cleanup(adev->ddev); 259 if (adev->irq.installed) { 260 drm_irq_uninstall(adev->ddev); 261 adev->irq.installed = false; 262 if (adev->irq.msi_enabled) 263 pci_disable_msi(adev->pdev); 264 flush_work(&adev->hotplug_work); 265 } 266 267 for (i = 0; i < AMDGPU_MAX_IRQ_SRC_ID; ++i) { 268 struct amdgpu_irq_src *src = adev->irq.sources[i]; 269 270 if (!src) 271 continue; 272 273 kfree(src->enabled_types); 274 src->enabled_types = NULL; 275 } 276 } 277 278 /** 279 * amdgpu_irq_add_id - register irq source 280 * 281 * @adev: amdgpu device pointer 282 * @src_id: source id for this source 283 * @source: irq source 284 * 285 */ 286 int amdgpu_irq_add_id(struct amdgpu_device *adev, unsigned src_id, 287 struct amdgpu_irq_src *source) 288 { 289 if (src_id >= AMDGPU_MAX_IRQ_SRC_ID) 290 return -EINVAL; 291 292 if (adev->irq.sources[src_id] != NULL) 293 return -EINVAL; 294 295 if (!source->funcs) 296 return -EINVAL; 297 298 if (source->num_types && !source->enabled_types) { 299 atomic_t *types; 300 301 types = kcalloc(source->num_types, sizeof(atomic_t), 302 GFP_KERNEL); 303 if (!types) 304 return -ENOMEM; 305 306 source->enabled_types = types; 307 } 308 309 adev->irq.sources[src_id] = source; 310 return 0; 311 } 312 313 /** 314 * amdgpu_irq_dispatch - dispatch irq to IP blocks 315 * 316 * @adev: amdgpu device pointer 317 * @entry: interrupt vector 318 * 319 * Dispatches the irq to the different IP blocks 320 */ 321 void amdgpu_irq_dispatch(struct amdgpu_device *adev, 322 struct amdgpu_iv_entry *entry) 323 { 324 unsigned src_id = entry->src_id; 325 struct amdgpu_irq_src *src; 326 int r; 327 328 if (src_id >= AMDGPU_MAX_IRQ_SRC_ID) { 329 DRM_DEBUG("Invalid src_id in IV: %d\n", src_id); 330 return; 331 } 332 333 src = adev->irq.sources[src_id]; 334 if (!src) { 335 DRM_DEBUG("Unhandled interrupt src_id: %d\n", src_id); 336 return; 337 } 338 339 r = src->funcs->process(adev, src, entry); 340 if (r) 341 DRM_ERROR("error processing interrupt (%d)\n", r); 342 } 343 344 /** 345 * amdgpu_irq_update - update hw interrupt state 346 * 347 * @adev: amdgpu device pointer 348 * @src: interrupt src you want to enable 349 * @type: type of interrupt you want to update 350 * 351 * Updates the interrupt state for a specific src (all asics). 352 */ 353 int amdgpu_irq_update(struct amdgpu_device *adev, 354 struct amdgpu_irq_src *src, unsigned type) 355 { 356 unsigned long irqflags; 357 enum amdgpu_interrupt_state state; 358 int r; 359 360 spin_lock_irqsave(&adev->irq.lock, irqflags); 361 362 /* we need to determine after taking the lock, otherwise 363 we might disable just enabled interrupts again */ 364 if (amdgpu_irq_enabled(adev, src, type)) 365 state = AMDGPU_IRQ_STATE_ENABLE; 366 else 367 state = AMDGPU_IRQ_STATE_DISABLE; 368 369 r = src->funcs->set(adev, src, type, state); 370 spin_unlock_irqrestore(&adev->irq.lock, irqflags); 371 return r; 372 } 373 374 /** 375 * amdgpu_irq_get - enable interrupt 376 * 377 * @adev: amdgpu device pointer 378 * @src: interrupt src you want to enable 379 * @type: type of interrupt you want to enable 380 * 381 * Enables the interrupt type for a specific src (all asics). 382 */ 383 int amdgpu_irq_get(struct amdgpu_device *adev, struct amdgpu_irq_src *src, 384 unsigned type) 385 { 386 if (!adev->ddev->irq_enabled) 387 return -ENOENT; 388 389 if (type >= src->num_types) 390 return -EINVAL; 391 392 if (!src->enabled_types || !src->funcs->set) 393 return -EINVAL; 394 395 if (atomic_inc_return(&src->enabled_types[type]) == 1) 396 return amdgpu_irq_update(adev, src, type); 397 398 return 0; 399 } 400 401 bool amdgpu_irq_get_delayed(struct amdgpu_device *adev, 402 struct amdgpu_irq_src *src, 403 unsigned type) 404 { 405 if ((type >= src->num_types) || !src->enabled_types) 406 return false; 407 return atomic_inc_return(&src->enabled_types[type]) == 1; 408 } 409 410 /** 411 * amdgpu_irq_put - disable interrupt 412 * 413 * @adev: amdgpu device pointer 414 * @src: interrupt src you want to disable 415 * @type: type of interrupt you want to disable 416 * 417 * Disables the interrupt type for a specific src (all asics). 418 */ 419 int amdgpu_irq_put(struct amdgpu_device *adev, struct amdgpu_irq_src *src, 420 unsigned type) 421 { 422 if (!adev->ddev->irq_enabled) 423 return -ENOENT; 424 425 if (type >= src->num_types) 426 return -EINVAL; 427 428 if (!src->enabled_types || !src->funcs->set) 429 return -EINVAL; 430 431 if (atomic_dec_and_test(&src->enabled_types[type])) 432 return amdgpu_irq_update(adev, src, type); 433 434 return 0; 435 } 436 437 /** 438 * amdgpu_irq_enabled - test if irq is enabled or not 439 * 440 * @adev: amdgpu device pointer 441 * @idx: interrupt src you want to test 442 * 443 * Tests if the given interrupt source is enabled or not 444 */ 445 bool amdgpu_irq_enabled(struct amdgpu_device *adev, struct amdgpu_irq_src *src, 446 unsigned type) 447 { 448 if (!adev->ddev->irq_enabled) 449 return false; 450 451 if (type >= src->num_types) 452 return false; 453 454 if (!src->enabled_types || !src->funcs->set) 455 return false; 456 457 return !!atomic_read(&src->enabled_types[type]); 458 } 459