/** * radeon_disable_vblank_kms - disable vblank interrupt * * @dev: drm dev pointer * @crtc: crtc to disable vblank interrupt for * * Disable the interrupt on the requested crtc (all asics). */ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) { struct radeon_device *rdev = dev->dev_private; unsigned long irqflags; if (crtc < 0 || crtc >= rdev->num_crtc) { DRM_ERROR("Invalid crtc %d\n", crtc); return; } spin_lock_irqsave(&rdev->irq.lock, irqflags); rdev->irq.crtc_vblank_int[crtc] = false; radeon_irq_set(rdev); spin_unlock_irqrestore(&rdev->irq.lock, irqflags); }
void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc) { unsigned long irqflags; if (crtc < 0 || crtc >= rdev->num_crtc) return; spin_lock_irqsave(&rdev->irq.pflip_lock[crtc], irqflags); BUG_ON(rdev->ddev->irq_enabled && rdev->irq.pflip_refcount[crtc] <= 0); if (rdev->ddev->irq_enabled && (--rdev->irq.pflip_refcount[crtc] == 0)) { rdev->irq.pflip[crtc] = false; radeon_irq_set(rdev); } spin_unlock_irqrestore(&rdev->irq.pflip_lock[crtc], irqflags); }
void radeon_driver_irq_uninstall_kms(struct drm_device *dev) { struct radeon_device *rdev = dev->dev_private; unsigned i; if (rdev == NULL) { return; } /* Disable *all* interrupts */ rdev->irq.sw_int = false; for (i = 0; i < 2; i++) { rdev->irq.crtc_vblank_int[i] = false; } radeon_irq_set(rdev); }
/** * radeon_irq_kms_pflip_irq_put - disable pageflip interrupt * * @rdev: radeon device pointer * @crtc: crtc whose interrupt you want to disable * * Disables the pageflip interrupt for a specific crtc (all asics). * For pageflips we use the vblank interrupt source. */ void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc) { unsigned long irqflags; if (crtc < 0 || crtc >= rdev->num_crtc) return; if (!rdev->ddev->irq_enabled) return; if (atomic_dec_and_test(&rdev->irq.pflip[crtc])) { spin_lock_irqsave(&rdev->irq.lock, irqflags); radeon_irq_set(rdev); spin_unlock_irqrestore(&rdev->irq.lock, irqflags); } }
/** * radeon_irq_kms_pflip_irq_put - disable pageflip interrupt * * @rdev: radeon device pointer * @crtc: crtc whose interrupt you want to disable * * Disables the pageflip interrupt for a specific crtc (all asics). * For pageflips we use the vblank interrupt source. */ void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc) { unsigned long irqflags; if (crtc < 0 || crtc >= rdev->num_crtc) return; if (!rdev->ddev->irq_enabled) return; if (atomic_dec_and_test(&rdev->irq.pflip[crtc])) { DRM_SPINLOCK_IRQSAVE(&rdev->irq.lock, irqflags); radeon_irq_set(rdev); DRM_SPINUNLOCK_IRQRESTORE(&rdev->irq.lock, irqflags); } }
/** * radeon_enable_vblank_kms - enable vblank interrupt * * @dev: drm dev pointer * @crtc: crtc to enable vblank interrupt for * * Enable the interrupt on the requested crtc (all asics). * Returns 0 on success, -EINVAL on failure. */ int radeon_enable_vblank_kms(struct drm_device *dev, int crtc) { struct radeon_device *rdev = dev->dev_private; int r; if (crtc < 0 || crtc >= rdev->num_crtc) { DRM_ERROR("Invalid crtc %d\n", crtc); return -EINVAL; } mtx_lock(&rdev->irq.lock); rdev->irq.crtc_vblank_int[crtc] = true; r = radeon_irq_set(rdev); mtx_unlock(&rdev->irq.lock); return r; }
/** * radeon_enable_vblank_kms - enable vblank interrupt * * @dev: drm dev pointer * @crtc: crtc to enable vblank interrupt for * * Enable the interrupt on the requested crtc (all asics). * Returns 0 on success, -EINVAL on failure. */ int radeon_enable_vblank_kms(struct drm_device *dev, int crtc) { struct radeon_device *rdev = dev->dev_private; int r; if (crtc < 0 || crtc >= rdev->num_crtc) { DRM_ERROR("Invalid crtc %d\n", crtc); return -EINVAL; } lockmgr(&rdev->irq.lock, LK_EXCLUSIVE); rdev->irq.crtc_vblank_int[crtc] = true; r = radeon_irq_set(rdev); lockmgr(&rdev->irq.lock, LK_RELEASE); return r; }
void radeon_driver_irq_preinstall_kms(struct drm_device *dev) { struct radeon_device *rdev = dev->dev_private; unsigned i; INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); /* Disable *all* interrupts */ rdev->irq.sw_int = false; for (i = 0; i < 2; i++) { rdev->irq.crtc_vblank_int[i] = false; } radeon_irq_set(rdev); /* Clear bits */ radeon_irq_process(rdev); }
void radeon_driver_irq_preinstall_kms(struct drm_device *dev) { struct radeon_device *rdev = dev->dev_private; unsigned i; /* Disable *all* interrupts */ rdev->irq.sw_int = false; rdev->irq.gui_idle = false; for (i = 0; i < rdev->num_crtc; i++) rdev->irq.crtc_vblank_int[i] = false; for (i = 0; i < 6; i++) { rdev->irq.hpd[i] = false; rdev->irq.pflip[i] = false; } radeon_irq_set(rdev); /* Clear bits */ radeon_irq_process(rdev); }
void radeon_driver_irq_uninstall_kms(struct drm_device *dev) { struct radeon_device *rdev = dev->dev_private; unsigned i; if (rdev == NULL) { return; } /* Disable *all* interrupts */ rdev->irq.sw_int = false; rdev->irq.gui_idle = false; for (i = 0; i < RADEON_MAX_HPD_PINS; i++) rdev->irq.hpd[i] = false; for (i = 0; i < RADEON_MAX_CRTCS; i++) { rdev->irq.crtc_vblank_int[i] = false; rdev->irq.pflip[i] = false; } radeon_irq_set(rdev); }
/** * radeon_fence_check_lockup - check for hardware lockup * * @work: delayed work item * * Checks for fence activity and if there is none probe * the hardware if a lockup occured. */ static void radeon_fence_check_lockup(struct work_struct *work) { struct radeon_fence_driver *fence_drv; struct radeon_device *rdev; int ring; fence_drv = container_of(work, struct radeon_fence_driver, lockup_work.work); rdev = fence_drv->rdev; ring = fence_drv - &rdev->fence_drv[0]; // if (!down_read_trylock(&rdev->exclusive_lock)) { // /* just reschedule the check if a reset is going on */ // radeon_fence_schedule_check(rdev, ring); // return; // } if (fence_drv->delayed_irq && rdev->ddev->irq_enabled) { unsigned long irqflags; fence_drv->delayed_irq = false; spin_lock_irqsave(&rdev->irq.lock, irqflags); radeon_irq_set(rdev); spin_unlock_irqrestore(&rdev->irq.lock, irqflags); } if (radeon_fence_activity(rdev, ring)) wake_up_all(&rdev->fence_queue); else if (radeon_ring_is_lockup(rdev, ring, &rdev->ring[ring])) { /* good news we believe it's a lockup */ dev_warn(rdev->dev, "GPU lockup (current fence id " "0x%016llx last fence id 0x%016llx on ring %d)\n", (uint64_t)atomic64_read(&fence_drv->last_seq), fence_drv->sync_seq[ring], ring); /* remember that we need an reset */ rdev->needs_reset = true; wake_up_all(&rdev->fence_queue); } // up_read(&rdev->exclusive_lock); }
void radeon_driver_irq_preinstall_kms(struct drm_device *dev) { struct radeon_device *rdev = dev->dev_private; unsigned i; /* Disable *all* interrupts */ for (i = 0; i < RADEON_NUM_RINGS; i++) rdev->irq.sw_int[i] = false; rdev->irq.gui_idle = false; for (i = 0; i < RADEON_MAX_HPD_PINS; i++) rdev->irq.hpd[i] = false; for (i = 0; i < RADEON_MAX_CRTCS; i++) { rdev->irq.crtc_vblank_int[i] = false; rdev->irq.pflip[i] = false; } radeon_irq_set(rdev); /* Clear bits */ radeon_irq_process(rdev); }
/** * radeon_driver_irq_preinstall_kms - drm irq preinstall callback * * @dev: drm dev pointer * * Gets the hw ready to enable irqs (all asics). * This function disables all interrupt sources on the GPU. */ void radeon_driver_irq_preinstall_kms(struct drm_device *dev) { struct radeon_device *rdev = dev->dev_private; unsigned i; lockmgr(&rdev->irq.lock, LK_EXCLUSIVE); /* Disable *all* interrupts */ for (i = 0; i < RADEON_NUM_RINGS; i++) atomic_set(&rdev->irq.ring_int[i], 0); for (i = 0; i < RADEON_MAX_HPD_PINS; i++) rdev->irq.hpd[i] = false; for (i = 0; i < RADEON_MAX_CRTCS; i++) { rdev->irq.crtc_vblank_int[i] = false; atomic_set(&rdev->irq.pflip[i], 0); rdev->irq.afmt[i] = false; } radeon_irq_set(rdev); lockmgr(&rdev->irq.lock, LK_RELEASE); /* Clear bits */ radeon_irq_process(rdev); }
/** * radeon_driver_irq_preinstall_kms - drm irq preinstall callback * * @dev: drm dev pointer * * Gets the hw ready to enable irqs (all asics). * This function disables all interrupt sources on the GPU. */ void radeon_driver_irq_preinstall_kms(struct drm_device *dev) { struct radeon_device *rdev = dev->dev_private; unsigned long irqflags; unsigned i; DRM_SPINLOCK_IRQSAVE(&rdev->irq.lock, irqflags); /* Disable *all* interrupts */ for (i = 0; i < RADEON_NUM_RINGS; i++) atomic_set(&rdev->irq.ring_int[i], 0); for (i = 0; i < RADEON_MAX_HPD_PINS; i++) rdev->irq.hpd[i] = false; for (i = 0; i < RADEON_MAX_CRTCS; i++) { rdev->irq.crtc_vblank_int[i] = false; atomic_set(&rdev->irq.pflip[i], 0); rdev->irq.afmt[i] = false; } radeon_irq_set(rdev); DRM_SPINUNLOCK_IRQRESTORE(&rdev->irq.lock, irqflags); /* Clear bits */ radeon_irq_process(rdev); }
/** * radeon_driver_irq_uninstall_kms - drm irq uninstall callback * * @dev: drm dev pointer * * This function disables all interrupt sources on the GPU (all asics). */ void radeon_driver_irq_uninstall_kms(struct drm_device *dev) { struct radeon_device *rdev = dev->dev_private; unsigned i; if (rdev == NULL) { return; } mtx_enter(&rdev->irq.lock); /* Disable *all* interrupts */ for (i = 0; i < RADEON_NUM_RINGS; i++) atomic_set(&rdev->irq.ring_int[i], 0); for (i = 0; i < RADEON_MAX_HPD_PINS; i++) rdev->irq.hpd[i] = false; for (i = 0; i < RADEON_MAX_CRTCS; i++) { rdev->irq.crtc_vblank_int[i] = false; atomic_set(&rdev->irq.pflip[i], 0); rdev->irq.afmt[i] = false; } radeon_irq_set(rdev); mtx_leave(&rdev->irq.lock); }
/** * radeon_driver_irq_preinstall_kms - drm irq preinstall callback * * @dev: drm dev pointer * * Gets the hw ready to enable irqs (all asics). * This function disables all interrupt sources on the GPU. */ void radeon_driver_irq_preinstall_kms(struct drm_device *dev) { struct radeon_device *rdev = dev->dev_private; unsigned long irqflags; unsigned i; spin_lock_irqsave(&rdev->irq.lock, irqflags); /* Disable *all* interrupts */ for (i = 0; i < RADEON_NUM_RINGS; i++) atomic_set(&rdev->irq.ring_int[i], 0); rdev->irq.dpm_thermal = false; for (i = 0; i < RADEON_MAX_HPD_PINS; i++) rdev->irq.hpd[i] = false; for (i = 0; i < RADEON_MAX_CRTCS; i++) { rdev->irq.crtc_vblank_int[i] = false; atomic_set(&rdev->irq.pflip[i], 0); rdev->irq.afmt[i] = false; } radeon_irq_set(rdev); spin_unlock_irqrestore(&rdev->irq.lock, irqflags); /* Clear bits */ radeon_irq_process(rdev); }