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