cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

radeon_irq_kms.c (16958B)


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