Home | History | Annotate | Line # | Download | only in radeon
      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