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