cregit-Linux how code gets into the kernel

Release 4.17 drivers/gpu/drm/i915/i915_irq.c

/* i915_irq.c -- IRQ support for the I915 -*- linux-c -*-
 */
/*
 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */


#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/sysrq.h>
#include <linux/slab.h>
#include <linux/circ_buf.h>
#include <drm/drmP.h>
#include <drm/i915_drm.h>
#include "i915_drv.h"
#include "i915_trace.h"
#include "intel_drv.h"

/**
 * DOC: interrupt handling
 *
 * These functions provide the basic support for enabling and disabling the
 * interrupt handling support. There's a lot more functionality in i915_irq.c
 * and related files, but that will be described in separate chapters.
 */


static const u32 hpd_ilk[HPD_NUM_PINS] = {
	[HPD_PORT_A] = DE_DP_A_HOTPLUG,
};


static const u32 hpd_ivb[HPD_NUM_PINS] = {
	[HPD_PORT_A] = DE_DP_A_HOTPLUG_IVB,
};


static const u32 hpd_bdw[HPD_NUM_PINS] = {
	[HPD_PORT_A] = GEN8_PORT_DP_A_HOTPLUG,
};


static const u32 hpd_ibx[HPD_NUM_PINS] = {
	[HPD_CRT] = SDE_CRT_HOTPLUG,
	[HPD_SDVO_B] = SDE_SDVOB_HOTPLUG,
	[HPD_PORT_B] = SDE_PORTB_HOTPLUG,
	[HPD_PORT_C] = SDE_PORTC_HOTPLUG,
	[HPD_PORT_D] = SDE_PORTD_HOTPLUG
};


static const u32 hpd_cpt[HPD_NUM_PINS] = {
	[HPD_CRT] = SDE_CRT_HOTPLUG_CPT,
	[HPD_SDVO_B] = SDE_SDVOB_HOTPLUG_CPT,
	[HPD_PORT_B] = SDE_PORTB_HOTPLUG_CPT,
	[HPD_PORT_C] = SDE_PORTC_HOTPLUG_CPT,
	[HPD_PORT_D] = SDE_PORTD_HOTPLUG_CPT
};


static const u32 hpd_spt[HPD_NUM_PINS] = {
	[HPD_PORT_A] = SDE_PORTA_HOTPLUG_SPT,
	[HPD_PORT_B] = SDE_PORTB_HOTPLUG_CPT,
	[HPD_PORT_C] = SDE_PORTC_HOTPLUG_CPT,
	[HPD_PORT_D] = SDE_PORTD_HOTPLUG_CPT,
	[HPD_PORT_E] = SDE_PORTE_HOTPLUG_SPT
};


static const u32 hpd_mask_i915[HPD_NUM_PINS] = {
	[HPD_CRT] = CRT_HOTPLUG_INT_EN,
	[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_EN,
	[HPD_SDVO_C] = SDVOC_HOTPLUG_INT_EN,
	[HPD_PORT_B] = PORTB_HOTPLUG_INT_EN,
	[HPD_PORT_C] = PORTC_HOTPLUG_INT_EN,
	[HPD_PORT_D] = PORTD_HOTPLUG_INT_EN
};


static const u32 hpd_status_g4x[HPD_NUM_PINS] = {
	[HPD_CRT] = CRT_HOTPLUG_INT_STATUS,
	[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_G4X,
	[HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_G4X,
	[HPD_PORT_B] = PORTB_HOTPLUG_INT_STATUS,
	[HPD_PORT_C] = PORTC_HOTPLUG_INT_STATUS,
	[HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS
};


static const u32 hpd_status_i915[HPD_NUM_PINS] = {
	[HPD_CRT] = CRT_HOTPLUG_INT_STATUS,
	[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_I915,
	[HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_I915,
	[HPD_PORT_B] = PORTB_HOTPLUG_INT_STATUS,
	[HPD_PORT_C] = PORTC_HOTPLUG_INT_STATUS,
	[HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS
};

/* BXT hpd list */

static const u32 hpd_bxt[HPD_NUM_PINS] = {
	[HPD_PORT_A] = BXT_DE_PORT_HP_DDIA,
	[HPD_PORT_B] = BXT_DE_PORT_HP_DDIB,
	[HPD_PORT_C] = BXT_DE_PORT_HP_DDIC
};

/* IIR can theoretically queue up two events. Be paranoid. */

#define GEN8_IRQ_RESET_NDX(type, which) do { \
        I915_WRITE(GEN8_##type##_IMR(which), 0xffffffff); \
        POSTING_READ(GEN8_##type##_IMR(which)); \
        I915_WRITE(GEN8_##type##_IER(which), 0); \
        I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \
        POSTING_READ(GEN8_##type##_IIR(which)); \
        I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \
        POSTING_READ(GEN8_##type##_IIR(which)); \
} while (0)


#define GEN3_IRQ_RESET(type) do { \
        I915_WRITE(type##IMR, 0xffffffff); \
        POSTING_READ(type##IMR); \
        I915_WRITE(type##IER, 0); \
        I915_WRITE(type##IIR, 0xffffffff); \
        POSTING_READ(type##IIR); \
        I915_WRITE(type##IIR, 0xffffffff); \
        POSTING_READ(type##IIR); \
} while (0)


#define GEN2_IRQ_RESET(type) do { \
        I915_WRITE16(type##IMR, 0xffff); \
        POSTING_READ16(type##IMR); \
        I915_WRITE16(type##IER, 0); \
        I915_WRITE16(type##IIR, 0xffff); \
        POSTING_READ16(type##IIR); \
        I915_WRITE16(type##IIR, 0xffff); \
        POSTING_READ16(type##IIR); \
} while (0)

/*
 * We should clear IMR at preinstall/uninstall, and just check at postinstall.
 */

static void gen3_assert_iir_is_zero(struct drm_i915_private *dev_priv, i915_reg_t reg) { u32 val = I915_READ(reg); if (val == 0) return; WARN(1, "Interrupt register 0x%x is not zero: 0x%08x\n", i915_mmio_reg_offset(reg), val); I915_WRITE(reg, 0xffffffff); POSTING_READ(reg); I915_WRITE(reg, 0xffffffff); POSTING_READ(reg); }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä6495.52%375.00%
Paulo Zanoni34.48%125.00%
Total67100.00%4100.00%


static void gen2_assert_iir_is_zero(struct drm_i915_private *dev_priv, i915_reg_t reg) { u16 val = I915_READ16(reg); if (val == 0) return; WARN(1, "Interrupt register 0x%x is not zero: 0x%08x\n", i915_mmio_reg_offset(reg), val); I915_WRITE16(reg, 0xffff); POSTING_READ16(reg); I915_WRITE16(reg, 0xffff); POSTING_READ16(reg); }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä67100.00%1100.00%
Total67100.00%1100.00%

#define GEN8_IRQ_INIT_NDX(type, which, imr_val, ier_val) do { \ gen3_assert_iir_is_zero(dev_priv, GEN8_##type##_IIR(which)); \ I915_WRITE(GEN8_##type##_IER(which), (ier_val)); \ I915_WRITE(GEN8_##type##_IMR(which), (imr_val)); \ POSTING_READ(GEN8_##type##_IMR(which)); \ } while (0) #define GEN3_IRQ_INIT(type, imr_val, ier_val) do { \ gen3_assert_iir_is_zero(dev_priv, type##IIR); \ I915_WRITE(type##IER, (ier_val)); \ I915_WRITE(type##IMR, (imr_val)); \ POSTING_READ(type##IMR); \ } while (0) #define GEN2_IRQ_INIT(type, imr_val, ier_val) do { \ gen2_assert_iir_is_zero(dev_priv, type##IIR); \ I915_WRITE16(type##IER, (ier_val)); \ I915_WRITE16(type##IMR, (imr_val)); \ POSTING_READ16(type##IMR); \ } while (0) static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir); static void gen9_guc_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir); /* For display hotplug interrupt */
static inline void i915_hotplug_interrupt_update_locked(struct drm_i915_private *dev_priv, uint32_t mask, uint32_t bits) { uint32_t val; lockdep_assert_held(&dev_priv->irq_lock); WARN_ON(bits & ~mask); val = I915_READ(PORT_HOTPLUG_EN); val &= ~mask; val |= bits; I915_WRITE(PORT_HOTPLUG_EN, val); }

Contributors

PersonTokensPropCommitsCommitProp
Egbert Eich5998.33%150.00%
Chris Wilson11.67%150.00%
Total60100.00%2100.00%

/** * i915_hotplug_interrupt_update - update hotplug interrupt enable * @dev_priv: driver private * @mask: bits to update * @bits: bits to enable * NOTE: the HPD enable bits are modified both inside and outside * of an interrupt context. To avoid that read-modify-write cycles * interfer, these bits are protected by a spinlock. Since this * function is usually not called from a context where the lock is * held already, this function acquires the lock itself. A non-locking * version is also available. */
void i915_hotplug_interrupt_update(struct drm_i915_private *dev_priv, uint32_t mask, uint32_t bits) { spin_lock_irq(&dev_priv->irq_lock); i915_hotplug_interrupt_update_locked(dev_priv, mask, bits); spin_unlock_irq(&dev_priv->irq_lock); }

Contributors

PersonTokensPropCommitsCommitProp
Egbert Eich41100.00%1100.00%
Total41100.00%1100.00%

/** * ilk_update_display_irq - update DEIMR * @dev_priv: driver private * @interrupt_mask: mask of interrupt bits to update * @enabled_irq_mask: mask of interrupt bits to enable */
void ilk_update_display_irq(struct drm_i915_private *dev_priv, uint32_t interrupt_mask, uint32_t enabled_irq_mask) { uint32_t new_val; lockdep_assert_held(&dev_priv->irq_lock); WARN_ON(enabled_irq_mask & ~interrupt_mask); if (WARN_ON(!intel_irqs_enabled(dev_priv))) return; new_val = dev_priv->irq_mask; new_val &= ~interrupt_mask; new_val |= (~enabled_irq_mask & interrupt_mask); if (new_val != dev_priv->irq_mask) { dev_priv->irq_mask = new_val; I915_WRITE(DEIMR, dev_priv->irq_mask); POSTING_READ(DEIMR); } }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä4041.24%110.00%
Zhenyu Wang3334.02%110.00%
Daniel Vetter77.22%110.00%
Paulo Zanoni66.19%220.00%
Chris Wilson55.15%330.00%
Jesse Barnes44.12%110.00%
Jani Nikula22.06%110.00%
Total97100.00%10100.00%

/** * ilk_update_gt_irq - update GTIMR * @dev_priv: driver private * @interrupt_mask: mask of interrupt bits to update * @enabled_irq_mask: mask of interrupt bits to enable */
static void ilk_update_gt_irq(struct drm_i915_private *dev_priv, uint32_t interrupt_mask, uint32_t enabled_irq_mask) { lockdep_assert_held(&dev_priv->irq_lock); WARN_ON(enabled_irq_mask & ~interrupt_mask); if (WARN_ON(!intel_irqs_enabled(dev_priv))) return; dev_priv->gt_irq_mask &= ~interrupt_mask; dev_priv->gt_irq_mask |= (~enabled_irq_mask & interrupt_mask); I915_WRITE(GTIMR, dev_priv->gt_irq_mask); }

Contributors

PersonTokensPropCommitsCommitProp
Paulo Zanoni5981.94%350.00%
Daniel Vetter811.11%116.67%
Jesse Barnes45.56%116.67%
Chris Wilson11.39%116.67%
Total72100.00%6100.00%


void gen5_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask) { ilk_update_gt_irq(dev_priv, mask, mask); POSTING_READ_FW(GTIMR); }

Contributors

PersonTokensPropCommitsCommitProp
Paulo Zanoni2177.78%133.33%
Chris Wilson518.52%133.33%
Daniel Vetter13.70%133.33%
Total27100.00%3100.00%


void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask) { ilk_update_gt_irq(dev_priv, mask, 0); }

Contributors

PersonTokensPropCommitsCommitProp
Paulo Zanoni2195.45%150.00%
Daniel Vetter14.55%150.00%
Total22100.00%2100.00%


static i915_reg_t gen6_pm_iir(struct drm_i915_private *dev_priv) { return INTEL_GEN(dev_priv) >= 8 ? GEN8_GT_IIR(2) : GEN6_PMIIR; }

Contributors

PersonTokensPropCommitsCommitProp
Imre Deak2492.31%133.33%
Ville Syrjälä13.85%133.33%
Dhinakaran Pandiyan13.85%133.33%
Total26100.00%3100.00%


static i915_reg_t gen6_pm_imr(struct drm_i915_private *dev_priv) { return INTEL_GEN(dev_priv) >= 8 ? GEN8_GT_IMR(2) : GEN6_PMIMR; }

Contributors

PersonTokensPropCommitsCommitProp
Paulo Zanoni1350.00%233.33%
Imre Deak934.62%116.67%
Jesse Barnes27.69%116.67%
Dhinakaran Pandiyan13.85%116.67%
Ville Syrjälä13.85%116.67%
Total26100.00%6100.00%


static i915_reg_t gen6_pm_ier(struct drm_i915_private *dev_priv) { return INTEL_GEN(dev_priv) >= 8 ? GEN8_GT_IER(2) : GEN6_PMIER; }

Contributors

PersonTokensPropCommitsCommitProp
Imre Deak2492.31%133.33%
Dhinakaran Pandiyan13.85%133.33%
Ville Syrjälä13.85%133.33%
Total26100.00%3100.00%

/** * snb_update_pm_irq - update GEN6_PMIMR * @dev_priv: driver private * @interrupt_mask: mask of interrupt bits to update * @enabled_irq_mask: mask of interrupt bits to enable */
static void snb_update_pm_irq(struct drm_i915_private *dev_priv, uint32_t interrupt_mask, uint32_t enabled_irq_mask) { uint32_t new_val; WARN_ON(enabled_irq_mask & ~interrupt_mask); lockdep_assert_held(&dev_priv->irq_lock); new_val = dev_priv->pm_imr; new_val &= ~interrupt_mask; new_val |= (~enabled_irq_mask & interrupt_mask); if (new_val != dev_priv->pm_imr) { dev_priv->pm_imr = new_val; I915_WRITE(gen6_pm_imr(dev_priv), dev_priv->pm_imr); POSTING_READ(gen6_pm_imr(dev_priv)); } }

Contributors

PersonTokensPropCommitsCommitProp
Ben Widawsky7480.43%120.00%
Daniel Vetter88.70%120.00%
Imre Deak55.43%120.00%
Akash Goel44.35%120.00%
Chris Wilson11.09%120.00%
Total92100.00%5100.00%


void gen6_unmask_pm_irq(struct drm_i915_private *dev_priv, u32 mask) { if (WARN_ON(!intel_irqs_enabled(dev_priv))) return; snb_update_pm_irq(dev_priv, mask, mask); }

Contributors

PersonTokensPropCommitsCommitProp
Ben Widawsky1955.88%125.00%
Imre Deak1338.24%250.00%
Akash Goel25.88%125.00%
Total34100.00%4100.00%


static void __gen6_mask_pm_irq(struct drm_i915_private *dev_priv, u32 mask) { snb_update_pm_irq(dev_priv, mask, 0); }

Contributors

PersonTokensPropCommitsCommitProp
Ben Widawsky1982.61%125.00%
Akash Goel28.70%125.00%
Imre Deak28.70%250.00%
Total23100.00%4100.00%


void gen6_mask_pm_irq(struct drm_i915_private *dev_priv, u32 mask) { if (WARN_ON(!intel_irqs_enabled(dev_priv))) return; __gen6_mask_pm_irq(dev_priv, mask); }

Contributors

PersonTokensPropCommitsCommitProp
Imre Deak2990.62%150.00%
Akash Goel39.38%150.00%
Total32100.00%2100.00%


static void gen6_reset_pm_iir(struct drm_i915_private *dev_priv, u32 reset_mask) { i915_reg_t reg = gen6_pm_iir(dev_priv); lockdep_assert_held(&dev_priv->irq_lock); I915_WRITE(reg, reset_mask); I915_WRITE(reg, reset_mask); POSTING_READ(reg); }

Contributors

PersonTokensPropCommitsCommitProp
Imre Deak2448.98%116.67%
Akash Goel2040.82%116.67%
Chris Wilson36.12%233.33%
Oscar Mateo12.04%116.67%
Ville Syrjälä12.04%116.67%
Total49100.00%6100.00%


static void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, u32 enable_mask) { lockdep_assert_held(&dev_priv->irq_lock); dev_priv->pm_ier |= enable_mask; I915_WRITE(gen6_pm_ier(dev_priv), dev_priv->pm_ier); gen6_unmask_pm_irq(dev_priv, enable_mask); /* unmask_pm_irq provides an implicit barrier (POSTING_READ) */ }

Contributors

PersonTokensPropCommitsCommitProp
Akash Goel3470.83%125.00%
Imre Deak1225.00%125.00%
Chris Wilson12.08%125.00%
Oscar Mateo12.08%125.00%
Total48100.00%4100.00%


static void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, u32 disable_mask) { lockdep_assert_held(&dev_priv->irq_lock); dev_priv->pm_ier &= ~disable_mask; __gen6_mask_pm_irq(dev_priv, disable_mask); I915_WRITE(gen6_pm_ier(dev_priv), dev_priv->pm_ier); /* though a barrier is missing here, but don't really need a one */ }

Contributors

PersonTokensPropCommitsCommitProp
Akash Goel4795.92%133.33%
Chris Wilson12.04%133.33%
Oscar Mateo12.04%133.33%
Total49100.00%3100.00%


void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv) { spin_lock_irq(&dev_priv->irq_lock); gen6_reset_pm_iir(dev_priv, dev_priv->pm_rps_events); dev_priv->gt_pm.rps.pm_iir = 0; spin_unlock_irq(&dev_priv->irq_lock); }

Contributors

PersonTokensPropCommitsCommitProp
Akash Goel2453.33%125.00%
Imre Deak1942.22%250.00%
Sagar Arun Kamble24.44%125.00%
Total45100.00%4100.00%


void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv) { struct intel_rps *rps = &dev_priv->gt_pm.rps; if (READ_ONCE(rps->interrupts_enabled)) return; if (WARN_ON_ONCE(IS_GEN11(dev_priv))) return; spin_lock_irq(&dev_priv->irq_lock); WARN_ON_ONCE(rps->pm_iir); WARN_ON_ONCE(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events); rps->interrupts_enabled = true; gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); spin_unlock_irq(&dev_priv->irq_lock); }

Contributors

PersonTokensPropCommitsCommitProp
Imre Deak5759.38%337.50%
Sagar Arun Kamble1515.62%112.50%
Chris Wilson1111.46%225.00%
Mika Kuoppala1111.46%112.50%
Tvrtko A. Ursulin22.08%112.50%
Total96100.00%8100.00%


void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv) { struct intel_rps *rps = &dev_priv->gt_pm.rps; if (!READ_ONCE(rps->interrupts_enabled)) return; if (WARN_ON_ONCE(IS_GEN11(dev_priv))) return; spin_lock_irq(&dev_priv->irq_lock); rps->interrupts_enabled = false; I915_WRITE(GEN6_PMINTRMSK, gen6_sanitize_rps_pm_mask(dev_priv, ~0u)); gen6_disable_pm_irq(dev_priv, dev_priv->pm_rps_events); spin_unlock_irq(&dev_priv->irq_lock); synchronize_irq(dev_priv->drm.irq); /* Now that we will not be generating any more work, flush any * outstanding tasks. As we are called on the RPS idle path, * we will reset the GPU to minimum frequencies, so the current * state of the worker can be discarded. */ cancel_work_sync(&rps->work); gen6_reset_rps_interrupts(dev_priv); }

Contributors

PersonTokensPropCommitsCommitProp
Imre Deak5448.65%430.77%
Chris Wilson2421.62%323.08%
Sagar Arun Kamble1513.51%17.69%
Mika Kuoppala119.91%17.69%
Tvrtko A. Ursulin43.60%17.69%
Dave Gordon10.90%17.69%
Oscar Mateo10.90%17.69%
Akash Goel10.90%17.69%
Total111100.00%13100.00%


void gen9_reset_guc_interrupts(struct drm_i915_private *dev_priv) { assert_rpm_wakelock_held(dev_priv); spin_lock_irq(&dev_priv->irq_lock); gen6_reset_pm_iir(dev_priv, dev_priv->pm_guc_events); spin_unlock_irq(&dev_priv->irq_lock); }

Contributors

PersonTokensPropCommitsCommitProp
Sagar Arun Kamble40100.00%2100.00%
Total40100.00%2100.00%


void gen9_enable_guc_interrupts(struct drm_i915_private *dev_priv) { assert_rpm_wakelock_held(dev_priv); spin_lock_irq(&dev_priv->irq_lock); if (!dev_priv->guc.interrupts_enabled) { WARN_ON_ONCE(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_guc_events); dev_priv->guc.interrupts_enabled = true; gen6_enable_pm_irq(dev_priv, dev_priv->pm_guc_events); } spin_unlock_irq(&dev_priv->irq_lock); }

Contributors

PersonTokensPropCommitsCommitProp
Sagar Arun Kamble74100.00%2100.00%
Total74100.00%2100.00%


void gen9_disable_guc_interrupts(struct drm_i915_private *dev_priv) { assert_rpm_wakelock_held(dev_priv); spin_lock_irq(&dev_priv->irq_lock); dev_priv->guc.interrupts_enabled = false; gen6_disable_pm_irq(dev_priv, dev_priv->pm_guc_events); spin_unlock_irq(&dev_priv->irq_lock); synchronize_irq(dev_priv->drm.irq); gen9_reset_guc_interrupts(dev_priv); }

Contributors

PersonTokensPropCommitsCommitProp
Sagar Arun Kamble62100.00%2100.00%
Total62100.00%2100.00%

/** * bdw_update_port_irq - update DE port interrupt * @dev_priv: driver private * @interrupt_mask: mask of interrupt bits to update * @enabled_irq_mask: mask of interrupt bits to enable */
static void bdw_update_port_irq(struct drm_i915_private *dev_priv, uint32_t interrupt_mask, uint32_t enabled_irq_mask) { uint32_t new_val; uint32_t old_val; lockdep_assert_held(&dev_priv->irq_lock); WARN_ON(enabled_irq_mask & ~interrupt_mask); if (WARN_ON(!intel_irqs_enabled(dev_priv))) return; old_val = I915_READ(GEN8_DE_PORT_IMR); new_val = old_val; new_val &= ~interrupt_mask; new_val |= (~enabled_irq_mask & interrupt_mask); if (new_val != old_val) { I915_WRITE(GEN8_DE_PORT_IMR, new_val); POSTING_READ(GEN8_DE_PORT_IMR); } }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä9598.96%150.00%
Chris Wilson11.04%150.00%
Total96100.00%2100.00%

/** * bdw_update_pipe_irq - update DE pipe interrupt * @dev_priv: driver private * @pipe: pipe whose interrupt to update * @interrupt_mask: mask of interrupt bits to update * @enabled_irq_mask: mask of interrupt bits to enable */
void bdw_update_pipe_irq(struct drm_i915_private *dev_priv, enum pipe pipe, uint32_t interrupt_mask, uint32_t enabled_irq_mask) { uint32_t new_val; lockdep_assert_held(&dev_priv->irq_lock); WARN_ON(enabled_irq_mask & ~interrupt_mask); if (WARN_ON(!intel_irqs_enabled(dev_priv))) return; new_val = dev_priv->de_irq_mask[pipe]; new_val &= ~interrupt_mask; new_val |= (~enabled_irq_mask & interrupt_mask); if (new_val != dev_priv->de_irq_mask[pipe]) { dev_priv->de_irq_mask[pipe] = new_val; I915_WRITE(GEN8_DE_PIPE_IMR(pipe), dev_priv->de_irq_mask[pipe]); POSTING_READ(GEN8_DE_PIPE_IMR(pipe)); } }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä11899.16%150.00%
Chris Wilson10.84%150.00%
Total119100.00%2100.00%

/** * ibx_display_interrupt_update - update SDEIMR * @dev_priv: driver private * @interrupt_mask: mask of interrupt bits to update * @enabled_irq_mask: mask of interrupt bits to enable */
void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, uint32_t interrupt_mask, uint32_t enabled_irq_mask) { uint32_t sdeimr = I915_READ(SDEIMR); sdeimr &= ~interrupt_mask; sdeimr |= (~enabled_irq_mask & interrupt_mask); WARN_ON(enabled_irq_mask & ~interrupt_mask); lockdep_assert_held(&dev_priv->irq_lock); if (WARN_ON(!intel_irqs_enabled(dev_priv))) return; I915_WRITE(SDEIMR, sdeimr); POSTING_READ(SDEIMR); }

Contributors

PersonTokensPropCommitsCommitProp
Daniel Vetter4658.97%342.86%
Ville Syrjälä3139.74%342.86%
Chris Wilson11.28%114.29%
Total78100.00%7100.00%


u32 i915_pipestat_enable_mask(struct drm_i915_private *dev_priv, enum pipe pipe) { u32 status_mask = dev_priv->pipestat_irq_mask[pipe]; u32 enable_mask = status_mask << 16; lockdep_assert_held(&dev_priv->irq_lock); if (INTEL_GEN(dev_priv) < 5) goto out; /* * On pipe A we don't support the PSR interrupt yet, * on pipe B and C the same bit MBZ. */ if (WARN_ON_ONCE(status_mask & PIPE_A_PSR_STATUS_VLV)) return 0; /* * On pipe B and C we don't support the PSR interrupt yet, on pipe * A the same bit is for perf counters which we don't use either. */ if (WARN_ON_ONCE(status_mask & PIPE_B_PSR_STATUS_VLV)) return 0; enable_mask &= ~(PIPE_FIFO_UNDERRUN_STATUS | SPRITE0_FLIP_DONE_INT_EN_VLV | SPRITE1_FLIP_DONE_INT_EN_VLV); if (status_mask & SPRITE0_FLIP_DONE_INT_STATUS_VLV) enable_mask |= SPRITE0_FLIP_DONE_INT_EN_VLV; if (status_mask & SPRITE1_FLIP_DONE_INT_STATUS_VLV) enable_mask |= SPRITE1_FLIP_DONE_INT_EN_VLV; out: WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK || status_mask & ~PIPESTAT_INT_STATUS_MASK, "pipe %c: enable_mask=0x%x, status_mask=0x%x\n", pipe_name(pipe), enable_mask, status_mask); return enable_mask; }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä9670.07%330.00%
Imre Deak1510.95%220.00%
Daniel Vetter1410.22%330.00%
Keith Packard118.03%110.00%
Chris Wilson10.73%110.00%
Total137100.00%10100.00%


void i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, u32 status_mask) { i915_reg_t reg = PIPESTAT(pipe); u32 enable_mask; WARN_ONCE(status_mask & ~PIPESTAT_INT_STATUS_MASK, "pipe %c: status_mask=0x%x\n", pipe_name(pipe), status_mask); lockdep_assert_held(&dev_priv->irq_lock); WARN_ON(!intel_irqs_enabled(dev_priv)); if ((dev_priv->pipestat_irq_mask[pipe] & status_mask) == status_mask) return; dev_priv->pipestat_irq_mask[pipe] |= status_mask; enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); I915_WRITE(reg, enable_mask | status_mask); POSTING_READ(reg); }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä5247.27%433.33%
Keith Packard2220.00%18.33%
Daniel Vetter1816.36%325.00%
Imre Deak1715.45%325.00%
Chris Wilson10.91%18.33%
Total110100.00%12100.00%


void i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, u32 status_mask) { i915_reg_t reg = PIPESTAT(pipe); u32 enable_mask; WARN_ONCE(status_mask & ~PIPESTAT_INT_STATUS_MASK, "pipe %c: status_mask=0x%x\n", pipe_name(pipe), status_mask); lockdep_assert_held(&dev_priv->irq_lock); WARN_ON(!intel_irqs_enabled(dev_priv)); if ((dev_priv->pipestat_irq_mask[pipe] & status_mask) == 0) return; dev_priv->pipestat_irq_mask[pipe] &= ~status_mask; enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); I915_WRITE(reg, enable_mask | status_mask); POSTING_READ(reg); }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä6054.05%120.00%
Imre Deak4742.34%240.00%
Chris Wilson21.80%120.00%
Wayne Boyer21.80%120.00%
Total111100.00%5100.00%

/** * i915_enable_asle_pipestat - enable ASLE pipestat for OpRegion * @dev_priv: i915 device private */
static void i915_enable_asle_pipestat(struct drm_i915_private *dev_priv) { if (!dev_priv->opregion.asle || !IS_MOBILE(dev_priv)) return; spin_lock_irq(&dev_priv->irq_lock); i915_enable_pipestat(dev_priv, PIPE_B, PIPE_LEGACY_BLC_EVENT_STATUS); if (INTEL_GEN(dev_priv) >= 4) i915_enable_pipestat(dev_priv, PIPE_A, PIPE_LEGACY_BLC_EVENT_STATUS); spin_unlock_irq(&dev_priv->irq_lock); }

Contributors

PersonTokensPropCommitsCommitProp
Yakui Zhao2535.71%220.00%
Jani Nikula1825.71%220.00%
Chris Wilson1622.86%220.00%
Tvrtko A. Ursulin57.14%110.00%
Daniel Vetter45.71%220.00%
Imre Deak22.86%110.00%
Total70100.00%10100.00%

/* * This timing diagram depicts the video signal in and * around the vertical blanking period. * * Assumptions about the fictitious mode used in this example: * vblank_start >= 3 * vsync_start = vblank_start + 1 * vsync_end = vblank_start + 2 * vtotal = vblank_start + 3 * * start of vblank: * latch double buffered registers * increment frame counter (ctg+) * generate start of vblank interrupt (gen4+) * | * | frame start: * | generate frame start interrupt (aka. vblank interrupt) (gmch) * | may be shifted forward 1-3 extra lines via PIPECONF * | | * | | start of vsync: * | | generate vsync interrupt * | | | * ___xxxx___ ___xxxx___ ___xxxx___ ___xxxx___ ___xxxx___ ___xxxx * . \hs/ . \hs/ \hs/ \hs/ . \hs/ * ----va---> <-----------------vb--------------------> <--------va------------- * | | <----vs-----> | * -vbs-----> <---vbs+1---> <---vbs+2---> <-----0-----> <-----1-----> <-----2--- (scanline counter gen2) * -vbs-2---> <---vbs-1---> <---vbs-----> <---vbs+1---> <---vbs+2---> <-----0--- (scanline counter gen3+) * -vbs-2---> <---vbs-2---> <---vbs-1---> <---vbs-----> <---vbs+1---> <---vbs+2- (scanline counter hsw+ hdmi) * | | | * last visible pixel first visible pixel * | increment frame counter (gen3/4) * pixel counter = vblank_start * htotal pixel counter = 0 (gen3/4) * * x = horizontal active * _ = horizontal blanking * hs = horizontal sync * va = vertical active * vb = vertical blanking * vs = vertical sync * vbs = vblank_start (number) * * Summary: * - most events happen at the start of horizontal sync * - frame start happens at the start of horizontal blank, 1-4 lines * (depending on PIPECONF settings) after the start of vblank * - gen3/4 pixel and frame counter are synchronized with the start * of horizontal active on the first line of vertical active */ /* Called from drm generic code, passed a 'crtc', which * we use as a pipe index */
static u32 i915_get_vblank_counter(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = to_i915(dev); i915_reg_t high_frame, low_frame; u32 high1, high2, low, pixel, vbl_start, hsync_start, htotal; const struct drm_display_mode *mode = &dev->vblank[pipe].hwmode; unsigned long irqflags; htotal = mode->crtc_htotal; hsync_start = mode->crtc_hsync_start; vbl_start = mode->crtc_vblank_start; if (mode->flags & DRM_MODE_FLAG_INTERLACE) vbl_start = DIV_ROUND_UP(vbl_start, 2); /* Convert to pixel count */ vbl_start *= htotal; /* Start of vblank event occurs at start of hsync */ vbl_start -= htotal - hsync_start; high_frame = PIPEFRAME(pipe); low_frame = PIPEFRAMEPIXEL(pipe); spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); /* * High & low register fields aren't synchronized, so make sure * we get a low value that's stable across two reads of the high * register. */ do { high1 = I915_READ_FW(high_frame) & PIPE_FRAME_HIGH_MASK; low = I915_READ_FW(low_frame); high2 = I915_READ_FW(high_frame) & PIPE_FRAME_HIGH_MASK; } while (high1 != high2); spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); high1 >>= PIPE_FRAME_HIGH_SHIFT; pixel = low & PIPE_PIXEL_MASK; low >>= PIPE_FRAME_LOW_SHIFT; /* * The frame counter increments at beginning of active. * Cook up a vblank counter by also checking the pixel * counter against vblank start. */ return (((high1 << 8) | low) + (pixel >= vbl_start)) & 0xffffff; }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä11652.25%525.00%
Eric Anholt4118.47%15.00%
Chris Wilson209.01%210.00%
Jesse Barnes156.76%315.00%
Dave Airlie125.41%210.00%
Michel Dänzer83.60%210.00%
Daniel Vetter52.25%15.00%
Jani Nikula20.90%15.00%
Maarten Lankhorst10.45%15.00%
Thierry Reding10.45%15.00%
Ander Conselvan de Oliveira10.45%15.00%
Total222100.00%20100.00%


static u32 g4x_get_vblank_counter(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = to_i915(dev); return I915_READ(PIPE_FRMCOUNT_G4X(pipe)); }

Contributors

PersonTokensPropCommitsCommitProp
Jesse Barnes2367.65%337.50%
Ville Syrjälä514.71%225.00%
Chris Wilson38.82%112.50%
Jani Nikula25.88%112.50%
Thierry Reding12.94%112.50%
Total34100.00%8100.00%

/* * On certain encoders on certain platforms, pipe * scanline register will not work to get the scanline, * since the timings are driven from the PORT or issues * with scanline register updates. * This function will use Framestamp and current * timestamp registers to calculate the scanline. */
static u32 __intel_get_crtc_scanline_from_timestamp(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct drm_vblank_crtc *vblank = &crtc->base.dev->vblank[drm_crtc_index(&crtc->base)]; const struct drm_display_mode *mode = &vblank->hwmode; u32 vblank_start = mode->crtc_vblank_start; u32 vtotal = mode->crtc_vtotal; u32 htotal = mode->crtc_htotal; u32 clock = mode->crtc_clock; u32 scanline, scan_prev_time, scan_curr_time, scan_post_time; /* * To avoid the race condition where we might cross into the * next vblank just between the PIPE_FRMTMSTMP and TIMESTAMP_CTR * reads. We make sure we read PIPE_FRMTMSTMP and TIMESTAMP_CTR * during the same frame. */ do { /* * This field provides read back of the display * pipe frame time stamp. The time stamp value * is sampled at every start of vertical blank. */ scan_prev_time = I915_READ_FW(PIPE_FRMTMSTMP(crtc->pipe)); /* * The TIMESTAMP_CTR register has the current * time stamp value. */ scan_curr_time = I915_READ_FW(IVB_TIMESTAMP_CTR); scan_post_time = I915_READ_FW(PIPE_FRMTMSTMP(crtc->pipe)); } while (scan_post_time != scan_prev_time); scanline = div_u64(mul_u32_u32(scan_curr_time - scan_prev_time, clock), 1000 * htotal); scanline = min(scanline, vtotal - 1); scanline = (scanline + vblank_start) % vtotal; return scanline; }

Contributors

PersonTokensPropCommitsCommitProp
Uma Shankar182100.00%1100.00%
Total182100.00%1100.00%

/* I915_READ_FW, only for fast reads of display block, no need for forcewake etc. */
static int __intel_get_crtc_scanline(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); const struct drm_display_mode *mode; struct drm_vblank_crtc *vblank; enum pipe pipe = crtc->pipe; int position, vtotal; if (!crtc->active) return -1; vblank = &crtc->base.dev->vblank[drm_crtc_index(&crtc->base)]; mode = &vblank->hwmode; if (mode->private_flags & I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP) return __intel_get_crtc_scanline_from_timestamp(crtc); vtotal = mode->crtc_vtotal; if (mode->flags & DRM_MODE_FLAG_INTERLACE) vtotal /= 2; if (IS_GEN2(dev_priv)) position = I915_READ_FW(PIPEDSL(pipe)) & DSL_LINEMASK_GEN2; else position = I915_READ_FW(PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; /* * On HSW, the DSL reg (0x70000) appears to return 0 if we * read it just before the start of vblank. So try it again * so we don't accidentally end up spanning a vblank frame * increment, causing the pipe_update_end() code to squak at us. * * The nature of this problem means we can't simply check the ISR * bit and return the vblank start value; nor can we use the scanline * debug register in the transcoder as it appears to have the same * problem. We may need to extend this to include other platforms, * but so far testing only shows the problem on HSW. */ if (HAS_DDI(dev_priv) && !position) { int i, temp; for (i = 0; i < 100; i++) { udelay(1); temp = I915_READ_FW(PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; if (temp != position) { position = temp; break; } } } /* * See update_scanline_offset() for the details on the * scanline_offset adjustment. */ return (position + crtc->scanline_offset) % vtotal; }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä12151.93%545.45%
Jesse Barnes6025.75%19.09%
Daniel Vetter3213.73%19.09%
Uma Shankar146.01%19.09%
Chris Wilson31.29%19.09%
Tvrtko A. Ursulin20.86%19.09%
Maarten Lankhorst10.43%19.09%
Total233100.00%11100.00%


static bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, bool in_vblank_irq, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode) { struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = intel_get_crtc_for_pipe(dev_priv, pipe); int position; int vbl_start, vbl_end, hsync_start, htotal, vtotal; unsigned long irqflags; if (WARN_ON(!mode->crtc_clock)) { DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled " "pipe %c\n", pipe_name(pipe)); return false; } htotal = mode->crtc_htotal; hsync_start = mode->crtc_hsync_start; vtotal = mode->crtc_vtotal; vbl_start = mode->crtc_vblank_start; vbl_end = mode->crtc_vblank_end; if (mode->flags & DRM_MODE_FLAG_INTERLACE) { vbl_start = DIV_ROUND_UP(vbl_start, 2); vbl_end /= 2; vtotal /= 2; } /* * Lock uncore.lock, as we will do multiple timing critical raw * register reads, potentially with preemption disabled, so the * following code must not block on uncore.lock. */ spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ /* Get optional system timestamp before query. */ if (stime) *stime = ktime_get(); if (IS_GEN2(dev_priv) || IS_G4X(dev_priv) || INTEL_GEN(dev_priv) >= 5) { /* No obvious pixelcount register. Only query vertical * scanout position from Display scan line register. */ position = __intel_get_crtc_scanline(intel_crtc); } else { /* Have access to pixelcount since start of frame. * We can split this into vertical and horizontal * scanout position. */ position = (I915_READ_FW(PIPEFRAMEPIXEL(pipe)) & PIPE_PIXEL_MASK) >> PIPE_PIXEL_SHIFT; /* convert to pixel counts */ vbl_start *= htotal; vbl_end *= htotal; vtotal *= htotal; /* * In interlaced modes, the pixel counter counts all pixels, * so one field will have htotal more pixels. In order to avoid * the reported position from jumping backwards when the pixel * counter is beyond the length of the shorter field, just * clamp the position the length of the shorter field. This * matches how the scanline counter based position works since * the scanline counter doesn't count the two half lines. */ if (position >= vtotal) position = vtotal - 1; /* * Start of vblank interrupt is triggered at start of hsync, * just prior to the first active line of vblank. However we * consider lines to start at the leading edge of horizontal * active. So, should we get here before we've crossed into * the horizontal active of the first line in vblank, we would * not set the DRM_SCANOUTPOS_INVBL flag. In order to fix that, * always add htotal-hsync_start to the current pixel position. */ position = (position + htotal - hsync_start) % vtotal; } /* Get optional system timestamp after query. */ if (etime) *etime = ktime_get(); /* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */ spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); /* * While in vblank, position will be negative * counting up towards 0 at vbl_end. And outside * vblank, position will be positive counting * up since vbl_end. */ if (position >= vbl_start) position -= vbl_end; else position += vtotal - vbl_end; if (IS_GEN2(dev_priv) || IS_G4X(dev_priv) || INTEL_GEN(dev_priv) >= 5) { *vpos = position; *hpos = 0; } else { *vpos = position / htotal; *hpos = position - (*vpos * htotal); } return true; }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä18750.00%1359.09%
Mario Kleiner16042.78%29.09%
Tvrtko A. Ursulin82.14%14.55%
Maarten Lankhorst51.34%14.55%
Jesse Barnes51.34%29.09%
Daniel Vetter51.34%14.55%
Chris Wilson30.80%14.55%
Thierry Reding10.27%14.55%
Total374100.00%22100.00%


int intel_get_crtc_scanline(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); unsigned long irqflags; int position; spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); position = __intel_get_crtc_scanline(crtc); spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); return position; }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä6295.38%150.00%
Chris Wilson34.62%150.00%
Total65100.00%2100.00%


static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv) { u32 busy_up, busy_down, max_avg, min_avg; u8 new_delay; spin_lock(&mchdev_lock); I915_WRITE16(MEMINTRSTS, I915_READ(MEMINTRSTS)); new_delay = dev_priv->ips.cur_delay; I915_WRITE16(MEMINTRSTS, MEMINT_EVAL_CHG); busy_up = I915_READ(RCPREVBSYTUPAVG); busy_down = I915_READ(RCPREVBSYTDNAVG); max_avg = I915_READ(RCBMAXAVG); min_avg = I915_READ(RCBMINAVG); /* Handle RCS change request from hw */ if (busy_up > max_avg) { if (dev_priv->ips.cur_delay != dev_priv->ips.max_delay) new_delay = dev_priv->ips.cur_delay - 1; if (new_delay < dev_priv->ips.max_delay) new_delay = dev_priv->ips.max_delay; } else if (busy_down < min_avg) { if (dev_priv->ips.cur_delay != dev_priv->ips.min_delay) new_delay = dev_priv->ips.cur_delay + 1; if (new_delay > dev_priv->ips.min_delay) new_delay = dev_priv->ips.min_delay; } if (ironlake_set_drps(dev_priv, new_delay)) dev_priv->ips.cur_delay = new_delay; spin_unlock(&mchdev_lock); return; }

Contributors

PersonTokensPropCommitsCommitProp
Jani Nikula14770.67%350.00%
Dave Airlie4220.19%116.67%
Egbert Eich167.69%116.67%
Tvrtko A. Ursulin31.44%116.67%
Total208100.00%6100.00%


static void notify_ring(struct intel_engine_cs *engine) { struct i915_request *rq = NULL; struct intel_wait *wait; if (!engine->breadcrumbs.irq_armed) return; atomic_inc(&engine->irq_count); set_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted); spin_lock(&engine->breadcrumbs.irq_lock); wait = engine->breadcrumbs.irq_wait; if (wait) { bool wakeup = engine->irq_seqno_barrier; /* We use a callback from the dma-fence to submit * requests after waiting on our own requests. To * ensure minimum delay in queuing the next request to * hardware, signal the fence now rather than wait for * the signaler to be woken up. We still wake up the * waiter in order to handle the irq-seqno coherency * issues (we may receive the interrupt before the * seqno is written, see __i915_request_irq_complete()) * and to handle coalescing of multiple seqno updates * and many waiters. */ if (i915_seqno_passed(intel_engine_get_seqno(engine), wait->seqno)) { struct i915_request *waiter = wait->request; wakeup = true; if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &waiter->fence.flags) && intel_wait_check_request(wait, waiter)) rq = i915_request_get(waiter); } if (wakeup) wake_up_process(wait->tsk); } else { if (engine->breadcrumbs.irq_armed) __intel_engine_disarm_breadcrumbs(engine); } spin_unlock(&engine->breadcrumbs.irq_lock); if (rq) { dma_fence_signal(&rq->fence); GEM_BUG_ON(!i915_request_completed(rq)); i915_request_put(rq); } trace_intel_engine_notify(engine, wait); }

Contributors

PersonTokensPropCommitsCommitProp
Chris Wilson18486.38%1477.78%
Jani Nikula104.69%15.56%
Dave Airlie104.69%15.56%
Tvrtko A. Ursulin94.23%211.11%
Total213100.00%18100.00%


static void vlv_c0_read(struct drm_i915_private *dev_priv, struct intel_rps_ei *ei) { ei->ktime = ktime_get_raw(); ei->render_c0 = I915_READ(VLV_RENDER_C0_COUNT); ei->media_c0 = I915_READ(VLV_MEDIA_C0_COUNT); }

Contributors

PersonTokensPropCommitsCommitProp
Jani Nikula3278.05%240.00%
Jesse Barnes512.20%120.00%
Mika Kuoppala37.32%120.00%
Keith Packard12.44%120.00%
Total41100.00%5100.00%


void gen6_rps_reset_ei(struct drm_i915_private *dev_priv) { memset(&dev_priv->gt_pm.rps.ei, 0, sizeof(dev_priv->gt_pm.rps.ei)); }

Contributors

PersonTokensPropCommitsCommitProp
Jani Nikula1542.86%120.00%
Chris Wilson1028.57%120.00%
Egbert Eich617.14%240.00%
Sagar Arun Kamble411.43%120.00%
Total35100.00%5100.00%


static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir) { struct intel_rps *rps = &dev_priv->gt_pm.rps; const struct intel_rps_ei *prev = &rps->ei; struct intel_rps_ei now; u32 events = 0; if ((pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) == 0) return 0; vlv_c0_read(dev_priv, &now); if (prev->ktime) { u64 time, c0; u32 render, media; time = ktime_us_delta(now.ktime, prev->ktime); time *= dev_priv->czclk_freq; /* Workload can be split between render + media, * e.g. SwapBuffers being blitted in X after being rendered in * mesa. To account for this we need to combine both engines * into our activity counter. */ render = now.render_c0 - prev->render_c0; media = now.media_c0 - prev->media_c0; c0 = max(render, media); c0 *= 1000 * 100 << 8; /* to usecs and scale to threshold% */ if (c0 > time * rps->up_threshold) events = GEN6_PM_RP_UP_THRESHOLD; else if (c0 < time * rps->down_threshold) events = GEN6_PM_RP_DOWN_THRESHOLD; } rps->ei = now; return events; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Wilson8245.30%218.18%
Jani Nikula6033.15%218.18%
Sagar Arun Kamble168.84%19.09%
Mika Kuoppala137.18%218.18%
Keith Packard52.76%327.27%
Egbert Eich52.76%19.09%
Total181100.00%11100.00%


static void gen6_pm_rps_work(struct work_struct *work) { struct drm_i915_private *dev_priv = container_of(work, struct drm_i915_private, gt_pm.rps.work); struct intel_rps *rps = &dev_priv->gt_pm.rps; bool client_boost = false; int new_delay, adj, min, max; u32 pm_iir = 0; spin_lock_irq(&dev_priv->irq_lock); if (rps->interrupts_enabled) { pm_iir = fetch_and_zero(&rps->pm_iir); client_boost = atomic_read(&rps->num_waiters); } spin_unlock_irq(&dev_priv->irq_lock); /* Make sure we didn't queue anything we're not going to process. */ WARN_ON(pm_iir & ~dev_priv->pm_rps_events); if ((pm_iir & dev_priv->pm_rps_events) == 0 && !client_boost) goto out; mutex_lock(&dev_priv->pcu_lock); pm_iir |= vlv_wa_c0_ei(dev_priv, pm_iir); adj = rps->last_adj; new_delay = rps->cur_freq; min = rps->min_freq_softlimit; max = rps->max_freq_softlimit; if (client_boost) max = rps->max_freq; if (client_boost && new_delay < rps->boost_freq) { new_delay = rps->boost_freq; adj = 0; } else if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) { if (adj > 0) adj *= 2; else /* CHV needs even encode values */ adj = IS_CHERRYVIEW(dev_priv) ? 2 : 1; if (new_delay >= rps->max_freq_softlimit) adj = 0; } else if (client_boost) { adj = 0; } else if (pm_iir & GEN6_PM_RP_DOWN_TIMEOUT) { if (rps->cur_freq > rps->efficient_freq) new_delay = rps->efficient_freq; else if (rps->cur_freq > rps->min_freq_softlimit) new_delay = rps->min_freq_softlimit; adj = 0; } else if (pm_iir & GEN6_PM_RP_DOWN_THRESHOLD) { if (adj < 0) adj *= 2; else /* CHV needs even encode values */ adj = IS_CHERRYVIEW(dev_priv) ? -2 : -1; if (new_delay <= rps->min_freq_softlimit) adj = 0; } else { /* unknown event */ adj = 0; } rps->last_adj = adj; /* sysfs frequency interfaces may have snuck in while servicing the * interrupt */ new_delay += adj; new_delay = clamp_t(int, new_delay, min, max); if (intel_set_rps(dev_priv, new_delay)) { DRM_DEBUG_DRIVER("Failed to set new GPU frequency\n"); rps->last_adj = 0; } mutex_unlock(&dev_priv->pcu_lock); out: /* Make sure not to corrupt PMIMR state used by ringbuffer on GEN6 */ spin_lock_irq(&dev_priv->irq_lock); if (rps->interrupts_enabled) gen6_unmask_pm_irq(dev_priv, dev_priv->pm_rps_events); spin_unlock_irq(&dev_priv->irq_lock); }

Contributors

PersonTokensPropCommitsCommitProp
Jani Nikula22850.67%211.76%
Chris Wilson9821.78%847.06%
Sagar Arun Kamble5913.11%317.65%
Jesse Barnes4710.44%211.76%
Deepak S122.67%15.88%
Daniel Vetter61.33%15.88%
Total450100.00%17100.00%

/** * ivybridge_parity_work - Workqueue called when a parity error interrupt * occurred. * @work: workqueue struct * * Doesn't actually do anything except notify userspace. As a consequence of * this event, userspace should try to remap the bad rows since statistically * it is likely the same row is more likely to go bad again. */
static void ivybridge_parity_work(struct work_struct *work) { struct drm_i915_private *dev_priv = container_of(work, typeof(*dev_priv), l3_parity.error_work); u32 error_status, row, bank, subbank; char *parity_event[6]; uint32_t misccpctl; uint8_t slice = 0; /* We must turn off DOP level clock gating to access the L3 registers. * In order to prevent a get/put style interface, acquire struct mutex * any time we access those registers. */ mutex_lock(&dev_priv->drm.struct_mutex); /* If we've screwed up tracking, just let the interrupt fire again */ if (WARN_ON(!dev_priv->l3_parity.which_slice)) goto out; misccpctl = I915_READ(GEN7_MISCCPCTL); I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE); POSTING_READ(GEN7_MISCCPCTL); while ((slice = ffs(dev_priv->l3_parity.which_slice)) != 0) { i915_reg_t reg; slice--; if (WARN_ON_ONCE(slice >= NUM_L3_SLICES(dev_priv))) break; dev_priv->l3_parity.which_slice &= ~(1<<slice); reg = GEN7_L3CDERRST1(slice); error_status = I915_READ(reg); row = GEN7_PARITY_ERROR_ROW(error_status); bank = GEN7_PARITY_ERROR_BANK(error_status); subbank = GEN7_PARITY_ERROR_SUBBANK(error_status); I915_WRITE(reg, GEN7_PARITY_ERROR_VALID | GEN7_L3CDERRST1_ENABLE); POSTING_READ(reg); parity_event[0] = I915_L3_PARITY_UEVENT "=1"; parity_event[1] = kasprintf(GFP_KERNEL, "ROW=%d", row); parity_event[2] = kasprintf(GFP_KERNEL, "BANK=%d", bank); parity_event[3] = kasprintf(GFP_KERNEL, "SUBBANK=%d", subbank); parity_event[4] = kasprintf(GFP_KERNEL, "SLICE=%d", slice); parity_event[5] = NULL; kobject_uevent_env(&dev_priv->drm.primary->kdev->kobj, KOBJ_CHANGE, parity_event); DRM_DEBUG("Parity error: Slice = %d, Row = %d, Bank = %d, Sub bank = %d.\n", slice, row, bank, subbank); kfree(parity_event[4]); kfree(parity_event[3]); kfree(parity_event[2]); kfree(parity_event[1]); } I915_WRITE(GEN7_MISCCPCTL, misccpctl); out: WARN_ON(dev_priv->l3_parity.which_slice); spin_lock_irq(&dev_priv->irq_lock); gen5_enable_gt_irq(dev_priv, GT_PARITY_ERROR(dev_priv)); spin_unlock_irq(&dev_priv->irq_lock); mutex_unlock(&dev_priv->drm.struct_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
Ben Widawsky25865.82%323.08%
Jani Nikula8722.19%215.38%
Daniel Vetter225.61%215.38%
Paulo Zanoni112.81%215.38%
Chris Wilson61.53%17.69%
Joonas Lahtinen51.28%17.69%
Ville Syrjälä30.77%215.38%
Total392100.00%13100.00%


static void ivybridge_parity_error_irq_handler(struct drm_i915_private *dev_priv, u32 iir) { if (!HAS_L3_DPF(dev_priv)) return; spin_lock(&dev_priv->irq_lock); gen5_disable_gt_irq(dev_priv, GT_PARITY_ERROR(dev_priv)); spin_unlock(&dev_priv->irq_lock); iir &= GT_PARITY_ERROR(dev_priv); if (iir & GT_RENDER_L3_PARITY_ERROR_INTERRUPT_S1) dev_priv->l3_parity.which_slice |= 1 << 1; if (iir & GT_RENDER_L3_PARITY_ERROR_INTERRUPT) dev_priv->l3_parity.which_slice |= 1 << 0; queue_work(dev_priv->wq, &dev_priv->l3_parity.error_work); }

Contributors

PersonTokensPropCommitsCommitProp
Jani Nikula6159.80%111.11%
Egbert Eich1211.76%222.22%
Ben Widawsky98.82%111.11%
Oscar Mateo54.90%111.11%
Ville Syrjälä54.90%111.11%
Chris Wilson43.92%111.11%
Thomas Daniel43.92%111.11%
Daniel Vetter21.96%111.11%
Total102100.00%9100.00%


static void ilk_gt_irq_handler(struct drm_i915_private *dev_priv, u32 gt_iir) { if (gt_iir & GT_RENDER_USER_INTERRUPT) notify_ring(dev_priv->engine[RCS]); if (gt_iir & ILK_BSD_USER_INTERRUPT) notify_ring(dev_priv->engine[VCS]); }

Contributors

PersonTokensPropCommitsCommitProp
Jani Nikula2043.48%114.29%
Egbert Eich1021.74%228.57%
Thomas Daniel510.87%114.29%
Ben Widawsky510.87%114.29%
Chris Wilson48.70%114.29%
Tvrtko A. Ursulin24.35%114.29%
Total46100.00%7100.00%


static void snb_gt_irq_handler(struct drm_i915_private *dev_priv, u32 gt_iir) { if (gt_iir & GT_RENDER_USER_INTERRUPT) notify_ring(dev_priv->engine[RCS]); if (gt_iir & GT_BSD_USER_INTERRUPT) notify_ring(dev_priv->engine[VCS]); if (gt_iir & GT_BLT_USER_INTERRUPT) notify_ring(dev_priv->engine[BCS]); if (gt_iir & (GT_BLT_CS_ERROR_INTERRUPT | GT_BSD_CS_ERROR_INTERRUPT | GT_RENDER_CS_MASTER_ERROR_INTERRUPT)) DRM_DEBUG("Command parser error, gt_iir 0x%08x\n", gt_iir); if (gt_iir & GT_PARITY_ERROR(dev_priv)) ivybridge_parity_error_irq_handler(dev_priv, gt_iir); }

Contributors

PersonTokensPropCommitsCommitProp
Jani Nikula4344.33%110.00%
Thomas Daniel1414.43%110.00%
Ben Widawsky1010.31%110.00%
Yakui Zhao88.25%110.00%
Chris Wilson88.25%110.00%
Egbert Eich55.15%220.00%
Oscar Mateo44.12%110.00%
Tvrtko A. Ursulin33.09%110.00%
Ville Syrjälä22.06%110.00%
Total97100.00%10100.00%


static void gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir, int test_shift) { struct intel_engine_execlists * const execlists = &engine->execlists; bool tasklet = false; if (iir & (GT_CONTEXT_SWITCH_INTERRUPT << test_shift)) { if (READ_ONCE(engine->execlists.active)) { __set_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); tasklet = true; } } if (iir & (GT_RENDER_USER_INTERRUPT << test_shift)) { notify_ring(engine); tasklet |= USES_GUC_SUBMISSION(engine->i915); } if (tasklet) tasklet_hi_schedule(&execlists->tasklet); }

Contributors

PersonTokensPropCommitsCommitProp
Chris Wilson4742.73%440.00%
Nick Hoath4036.36%110.00%
Mika Kuoppala1210.91%110.00%
Michal Wajdeczko65.45%110.00%
Tvrtko A. Ursulin43.64%220.00%
Sagar Arun Kamble10.91%110.00%
Total110100.00%10100.00%


static void gen8_gt_irq_ack(struct drm_i915_private *i915, u32 master_ctl, u32 gt_iir[4]) { void __iomem * const regs = i915->regs; #define GEN8_GT_IRQS (GEN8_GT_RCS_IRQ | \ GEN8_GT_BCS_IRQ | \ GEN8_GT_VCS1_IRQ | \ GEN8_GT_VCS2_IRQ | \ GEN8_GT_VECS_IRQ | \ GEN8_GT_PM_IRQ | \ GEN8_GT_GUC_IRQ) if (master_ctl & (GEN8_GT_RCS_IRQ | GEN8_GT_BCS_IRQ)) { gt_iir[0] = raw_reg_read(regs, GEN8_GT_IIR(0)); if (likely(gt_iir[0])) raw_reg_write(regs, GEN8_GT_IIR(0), gt_iir[0]); } if (master_ctl & (GEN8_GT_VCS1_IRQ | GEN8_GT_VCS2_IRQ)) { gt_iir[1] = raw_reg_read(regs, GEN8_GT_IIR(1)); if (likely(gt_iir[1])) raw_reg_write(regs, GEN8_GT_IIR(1), gt_iir[1]); } if (master_ctl & (GEN8_GT_PM_IRQ | GEN8_GT_GUC_IRQ)) { gt_iir[2] = raw_reg_read(regs, GEN8_GT_IIR(2)); if (likely(gt_iir[2] & (i915->pm_rps_events | i915->pm_guc_events))) raw_reg_write(regs, GEN8_GT_IIR(2), gt_iir[2] & (i915->pm_rps_events | i915->pm_guc_events)); } if (master_ctl & GEN8_GT_VECS_IRQ) { gt_iir[3] = raw_reg_read(regs, GEN8_GT_IIR(3)); if (likely(gt_iir[3])) raw_reg_write(regs, GEN8_GT_IIR(3), gt_iir[3]); } }

Contributors

PersonTokensPropCommitsCommitProp
Jani Nikula9135.27%330.00%
Chris Wilson8834.11%330.00%
Ville Syrjälä5722.09%110.00%
Ben Widawsky197.36%220.00%
Egbert Eich31.16%110.00%
Total258100.00%10100.00%


static void gen8_gt_irq_handler(struct drm_i915_private *i915, u32 master_ctl, u32 gt_iir[4]) { if (master_ctl & (GEN8_GT_RCS_IRQ | GEN8_GT_BCS_IRQ)) { gen8_cs_irq_handler(i915->engine[RCS], gt_iir[0], GEN8_RCS_IRQ_SHIFT); gen8_cs_irq_handler(i915->engine[BCS], gt_iir[0], GEN8_BCS_IRQ_SHIFT); } if (master_ctl & (GEN8_GT_VCS1_IRQ | GEN8_GT_VCS2_IRQ)) { gen8_cs_irq_handler(i915->engine[VCS], gt_iir[1], GEN8_VCS1_IRQ_SHIFT); gen8_cs_irq_handler(i915->engine[VCS2], gt_iir[1], GEN8_VCS2_IRQ_SHIFT); } if (master_ctl & GEN8_GT_VECS_IRQ) { gen8_cs_irq_handler(i915->engine[VECS], gt_iir[3], GEN8_VECS_IRQ_SHIFT); } if (master_ctl & (GEN8_GT_PM_IRQ | GEN8_GT_GUC_IRQ)) { gen6_rps_irq_handler(i915, gt_iir[2]); gen9_guc_irq_handler(i915, gt_iir[2]); } }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä11869.82%125.00%
Chris Wilson4224.85%250.00%
Sagar Arun Kamble95.33%125.00%
Total169100.00%4100.00%


static bool bxt_port_hotplug_long_detect(enum port port, u32 val) { switch (port) { case PORT_A: return val & PORTA_HOTPLUG_LONG_DETECT; case PORT_B: return val & PORTB_HOTPLUG_LONG_DETECT; case PORT_C: return val & PORTC_HOTPLUG_LONG_DETECT; default: return false; } }

Contributors

PersonTokensPropCommitsCommitProp
Imre Deak4697.87%150.00%
Ville Syrjälä12.13%150.00%
Total47100.00%2100.00%


static bool spt_port_hotplug2_long_detect(enum port port, u32 val) { switch (port) { case PORT_E: return val & PORTE_HOTPLUG_LONG_DETECT; default: return false; } }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä31100.00%1100.00%
Total31100.00%1100.00%


static bool spt_port_hotplug_long_detect(enum port port, u32 val) { switch (port) { case PORT_A: return val & PORTA_HOTPLUG_LONG_DETECT; case PORT_B: return val & PORTB_HOTPLUG_LONG_DETECT; case PORT_C: return val & PORTC_HOTPLUG_LONG_DETECT; case PORT_D: return val & PORTD_HOTPLUG_LONG_DETECT; default: return false; } }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä55100.00%1100.00%
Total55100.00%1100.00%


static bool ilk_port_hotplug_long_detect(enum port port, u32 val) { switch (port) { case PORT_A: return val & DIGITAL_PORTA_HOTPLUG_LONG_DETECT; default: return false; } }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä31100.00%1100.00%
Total31100.00%1100.00%


static bool pch_port_hotplug_long_detect(enum port port, u32 val) { switch (port) { case PORT_B: return val & PORTB_HOTPLUG_LONG_DETECT; case PORT_C: return val & PORTC_HOTPLUG_LONG_DETECT; case PORT_D: return val & PORTD_HOTPLUG_LONG_DETECT; default: return false; } }

Contributors

PersonTokensPropCommitsCommitProp
Dave Airlie2961.70%150.00%
Jani Nikula1838.30%150.00%
Total47100.00%2100.00%


static bool i9xx_port_hotplug_long_detect(enum port port, u32 val) { switch (port) { case PORT_B: return val & PORTB_HOTPLUG_INT_LONG_PULSE; case PORT_C: return val & PORTC_HOTPLUG_INT_LONG_PULSE; case PORT_D: return val & PORTD_HOTPLUG_INT_LONG_PULSE; default: return false; } }

Contributors

PersonTokensPropCommitsCommitProp
Dave Airlie2859.57%133.33%
Jani Nikula1940.43%266.67%
Total47100.00%3100.00%

/* * Get a bit mask of pins that have triggered, and which ones may be long. * This can be called multiple times with the same masks to accumulate * hotplug detection results from several registers. * * Note that the caller is expected to zero out the masks initially. */
static void intel_get_hpd_pins(struct drm_i915_private *dev_priv, u32 *pin_mask, u32 *long_mask, u32 hotplug_trigger, u32 dig_hotplug_reg, const u32 hpd[HPD_NUM_PINS], bool long_pulse_detect(enum port port, u32 val)) { enum port port; int i; for_each_hpd_pin(i) { if ((hpd[i] & hotplug_trigger) == 0) continue; *pin_mask |= BIT(i); port = intel_hpd_pin_to_port(dev_priv, i); if (port == PORT_NONE) continue; if (long_pulse_detect(port, dig_hotplug_reg)) *long_mask |= BIT(i); } DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x, dig 0x%08x, pins 0x%08x\n", hotplug_trigger, dig_hotplug_reg, *pin_mask); }

Contributors

PersonTokensPropCommitsCommitProp
Jani Nikula7157.72%318.75%
Rodrigo Vivi1512.20%212.50%
Imre Deak1411.38%212.50%
Egbert Eich75.69%212.50%
Shuang He54.07%16.25%
Damien Lespiau54.07%318.75%
Dave Airlie43.25%16.25%
Daniel Vetter21.63%212.50%
Total123100.00%16100.00%


static void gmbus_irq_handler(struct drm_i915_private *dev_priv) { wake_up_all(&dev_priv->gmbus_wait_queue); }

Contributors

PersonTokensPropCommitsCommitProp
Daniel Vetter1578.95%360.00%
Tvrtko A. Ursulin210.53%120.00%
Damien Lespiau210.53%120.00%
Total19100.00%5100.00%


static void dp_aux_irq_handler(struct drm_i915_private *dev_priv) { wake_up_all(&dev_priv->gmbus_wait_queue); }

Contributors

PersonTokensPropCommitsCommitProp
Daniel Vetter1578.95%360.00%
Damien Lespiau210.53%120.00%
Tvrtko A. Ursulin210.53%120.00%
Total19100.00%5100.00%

#if defined(CONFIG_DEBUG_FS)
static void display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, enum pipe pipe, uint32_t crc0, uint32_t crc1, uint32_t crc2, uint32_t crc3, uint32_t crc4) { struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe]; struct intel_pipe_crc_entry *entry; struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe); struct drm_driver *driver = dev_priv->drm.driver; uint32_t crcs[5]; int head, tail; spin_lock(&pipe_crc->lock); if (pipe_crc->source) { if (!pipe_crc->entries) { spin_unlock(&pipe_crc->lock); DRM_DEBUG_KMS("spurious interrupt\n"); return; } head = pipe_crc->head; tail = pipe_crc->tail; if (CIRC_SPACE(head, tail, INTEL_PIPE_CRC_ENTRIES_NR) < 1) { spin_unlock(&pipe_crc->lock); DRM_ERROR("CRC buffer overflowing\n"); return; } entry = &pipe_crc->entries[head]; entry->frame = driver->get_vblank_counter(&dev_priv->drm, pipe); entry->crc[0] = crc0; entry->crc[1] = crc1; entry->crc[2] = crc2; entry->crc[3] = crc3; entry->crc[4] = crc4; head = (head + 1) & (INTEL_PIPE_CRC_ENTRIES_NR - 1); pipe_crc->head = head; spin_unlock(&pipe_crc->lock); wake_up_interruptible(&pipe_crc->wq); } else { /* * For some not yet identified reason, the first CRC is * bonkers. So let's just wait for the next vblank and read * out the buggy result. * * On GEN8+ sometimes the second CRC is bonkers as well, so * don't trust that one either. */ if (pipe_crc->skipped == 0 || (INTEL_GEN(dev_priv) >= 8 && pipe_crc->skipped == 1)) { pipe_crc->skipped++; spin_unlock(&pipe_crc->lock); return; } spin_unlock(&pipe_crc->lock); crcs[0] = crc0; crcs[1] = crc1; crcs[2] = crc2; crcs[3] = crc3; crcs[4] = crc4; drm_crtc_add_crc_entry(&crtc->base, true, drm_crtc_accurate_vblank_count(&crtc->base), crcs); } }

Contributors

PersonTokensPropCommitsCommitProp
Tomeu Vizoso13836.80%28.33%
Damien Lespiau6216.53%520.83%
Shuang He6016.00%14.17%
Daniel Vetter5815.47%937.50%
Ben Widawsky266.93%28.33%
Jesse Barnes215.60%28.33%
Tvrtko A. Ursulin41.07%14.17%
Rodrigo Vivi41.07%14.17%
Chris Wilson20.53%14.17%
Total375100.00%24100.00%

#else
static inline void display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, enum pipe pipe, uint32_t crc0, uint32_t crc1, uint32_t crc2, uint32_t crc3, uint32_t crc4) {}

Contributors

PersonTokensPropCommitsCommitProp
Daniel Vetter2893.33%150.00%
Tvrtko A. Ursulin26.67%150.00%
Total30100.00%2100.00%

#endif
static void hsw_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, enum pipe pipe) { display_pipe_crc_irq_handler(dev_priv, pipe, I915_READ(PIPE_CRC_RES_1_IVB(pipe)), 0, 0, 0, 0); }

Contributors

PersonTokensPropCommitsCommitProp
Daniel Vetter2052.63%225.00%
Jesse Barnes1128.95%337.50%
Egbert Eich410.53%225.00%
Tvrtko A. Ursulin37.89%112.50%
Total38100.00%8100.00%


static void ivb_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, enum pipe pipe) { display_pipe_crc_irq_handler(dev_priv, pipe, I915_READ(PIPE_CRC_RES_1_IVB(pipe)), I915_READ(PIPE_CRC_RES_2_IVB(pipe)), I915_READ(PIPE_CRC_RES_3_IVB(pipe)), I915_READ(PIPE_CRC_RES_4_IVB(pipe)), I915_READ(PIPE_CRC_RES_5_IVB(pipe))); }

Contributors

PersonTokensPropCommitsCommitProp
Daniel Vetter3658.06%650.00%
Jesse Barnes2235.48%433.33%
Tvrtko A. Ursulin34.84%18.33%
Egbert Eich11.61%18.33%
Total62100.00%12100.00%


static void i9xx_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, enum pipe pipe) { uint32_t res1, res2; if (INTEL_GEN(dev_priv) >= 3) res1 = I915_READ(PIPE_CRC_RES_RES1_I915(pipe)); else res1 = 0; if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv)) res2 = I915_READ(PIPE_CRC_RES_RES2_G4X(pipe)); else res2 = 0; display_pipe_crc_irq_handler(dev_priv, pipe, I915_READ(PIPE_CRC_RES_RED(pipe)), I915_READ(PIPE_CRC_RES_GREEN(pipe)), I915_READ(PIPE_CRC_RES_BLUE(pipe)), res1, res2); }

Contributors

PersonTokensPropCommitsCommitProp
Daniel Vetter5954.63%640.00%
Paulo Zanoni2119.44%16.67%
Jesse Barnes1110.19%213.33%
Tvrtko A. Ursulin87.41%16.67%
Ville Syrjälä43.70%16.67%
Eric Anholt21.85%16.67%
Michel Dänzer10.93%16.67%
Zou Nan hai10.93%16.67%
Chris Wilson10.93%16.67%
Total108100.00%15100.00%

/* The RPS events need forcewake, so we add them to a work queue and mask their * IMR bits until the work is done. Other interrupts can be processed without * the work queue. */
static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) { struct intel_rps *rps = &dev_priv->gt_pm.rps; if (pm_iir & dev_priv->pm_rps_events) { spin_lock(&dev_priv->irq_lock); gen6_mask_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events); if (rps->interrupts_enabled) { rps->pm_iir |= pm_iir & dev_priv->pm_rps_events; schedule_work(&rps->work); } spin_unlock(&dev_priv->irq_lock); } if (INTEL_GEN(dev_priv) >= 8) return; if (HAS_VEBOX(dev_priv)) { if (pm_iir & PM_VEBOX_USER_INTERRUPT) notify_ring(dev_priv->engine[VECS]); if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT) DRM_DEBUG("Command parser error, pm_iir 0x%08x\n", pm_iir); } }

Contributors

PersonTokensPropCommitsCommitProp
Ben Widawsky4230.66%210.53%
Paulo Zanoni3122.63%315.79%
Imre Deak2921.17%210.53%
Sagar Arun Kamble1510.95%15.26%
Daniel Vetter85.84%526.32%
Deepak S64.38%15.26%
Mika Kuoppala21.46%15.26%
Tvrtko A. Ursulin10.73%15.26%
Chris Wilson10.73%15.26%
Akash Goel10.73%15.26%
Dhinakaran Pandiyan10.73%15.26%
Total137100.00%19100.00%


static void gen9_guc_irq_handler(struct drm_i915_private *dev_priv, u32 gt_iir) { if (gt_iir & GEN9_GUC_TO_HOST_INT_EVENT) { /* Sample the log buffer flush related bits & clear them out now * itself from the message identity register to minimize the * probability of losing a flush interrupt, when there are back * to back flush interrupts. * There can be a new flush interrupt, for different log buffer * type (like for ISR), whilst Host is handling one (for DPC). * Since same bit is used in message register for ISR & DPC, it * could happen that GuC sets the bit for 2nd interrupt but Host * clears out the bit on handling the 1st interrupt. */ u32 msg, flush; msg = I915_READ(SOFT_SCRATCH(15)); flush = msg & (INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED | INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER); if (flush) { /* Clear the message bits that are handled */ I915_WRITE(SOFT_SCRATCH(15), msg & ~flush); /* Handle flush interrupt in bottom half */ queue_work(dev_priv->guc.log.runtime.flush_wq, &dev_priv->guc.log.runtime.flush_work); dev_priv->guc.log.flush_interrupt_count++; } else { /* Not clearing of unhandled event bits won't result in * re-triggering of the interrupt. */ } } }

Contributors

PersonTokensPropCommitsCommitProp
Sagar Arun Kamble9185.85%240.00%
Akash Goel98.49%120.00%
Oscar Mateo43.77%120.00%
Arkadiusz Hiler21.89%120.00%
Total106100.00%5100.00%


static void i9xx_pipestat_irq_reset(struct drm_i915_private *dev_priv) { enum pipe pipe; for_each_pipe(dev_priv, pipe) { I915_WRITE(PIPESTAT(pipe), PIPESTAT_INT_STATUS_MASK | PIPE_FIFO_UNDERRUN_STATUS); dev_priv->pipestat_irq_mask[pipe] = 0; } }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä44100.00%1100.00%
Total44100.00%1100.00%


static void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv, u32 iir, u32 pipe_stats[I915_MAX_PIPES]) { int pipe; spin_lock(&dev_priv->irq_lock); if (!dev_priv->display_irqs_enabled) { spin_unlock(&dev_priv->irq_lock); return; } for_each_pipe(dev_priv, pipe) { i915_reg_t reg; u32 status_mask, enable_mask, iir_bit = 0; /* * PIPESTAT bits get signalled even when the interrupt is * disabled with the mask bits, and some of the status bits do * not generate interrupts at all (like the underrun bit). Hence * we need to be careful that we only handle what we want to * handle. */ /* fifo underruns are filterered in the underrun handler. */ status_mask = PIPE_FIFO_UNDERRUN_STATUS; switch (pipe) { case PIPE_A: iir_bit = I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; break; case PIPE_B: iir_bit = I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; break; case PIPE_C: iir_bit = I915_DISPLAY_PIPE_C_EVENT_INTERRUPT; break; } if (iir & iir_bit) status_mask |= dev_priv->pipestat_irq_mask[pipe]; if (!status_mask) continue; reg = PIPESTAT(pipe); pipe_stats[pipe] = I915_READ(reg) & status_mask; enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); /* * Clear the PIPE*STAT regs before the IIR */ if (pipe_stats[pipe]) I915_WRITE(reg, enable_mask | pipe_stats[pipe]); } spin_unlock(&dev_priv->irq_lock); }

Contributors

PersonTokensPropCommitsCommitProp
Daniel Vetter5429.67%420.00%
Ville Syrjälä5329.12%630.00%
Imre Deak3217.58%315.00%
Jesse Barnes2614.29%315.00%
Paulo Zanoni94.95%15.00%
Shuang He42.20%15.00%
Tvrtko A. Ursulin21.10%15.00%
Damien Lespiau21.10%15.00%
Total182100.00%20100.00%


static void i8xx_pipestat_irq_handler(struct drm_i915_private *dev_priv, u16 iir, u32 pipe_stats[I915_MAX_PIPES]) { enum pipe pipe; for_each_pipe(dev_priv, pipe) { if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS) drm_handle_vblank(&dev_priv->drm, pipe); if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) i9xx_pipe_crc_irq_handler(dev_priv, pipe); if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); } }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä83100.00%1100.00%
Total83100.00%1100.00%


static void i915_pipestat_irq_handler(struct drm_i915_private *dev_priv, u32 iir, u32 pipe_stats[I915_MAX_PIPES]) { bool blc_event = false; enum pipe pipe; for_each_pipe(dev_priv, pipe) { if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS) drm_handle_vblank(&dev_priv->drm, pipe); if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) blc_event = true; if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) i9xx_pipe_crc_irq_handler(dev_priv, pipe); if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); } if (blc_event || (iir & I915_ASLE_INTERRUPT)) intel_opregion_asle_intr(dev_priv); }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä116100.00%1100.00%
Total116100.00%1100.00%


static void i965_pipestat_irq_handler(struct drm_i915_private *dev_priv, u32 iir, u32 pipe_stats[I915_MAX_PIPES]) { bool blc_event = false; enum pipe pipe; for_each_pipe(dev_priv, pipe) { if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS) drm_handle_vblank(&dev_priv->drm, pipe); if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) blc_event = true; if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) i9xx_pipe_crc_irq_handler(dev_priv, pipe); if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); } if (blc_event || (iir & I915_ASLE_INTERRUPT)) intel_opregion_asle_intr(dev_priv); if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS) gmbus_irq_handler(dev_priv); }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä130100.00%1100.00%
Total130100.00%1100.00%


static void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv, u32 pipe_stats[I915_MAX_PIPES]) { enum pipe pipe; for_each_pipe(dev_priv, pipe) { if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS) drm_handle_vblank(&dev_priv->drm, pipe); if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) i9xx_pipe_crc_irq_handler(dev_priv, pipe); if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); } if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS) gmbus_irq_handler(dev_priv); }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä3234.04%213.33%
Jesse Barnes1920.21%320.00%
Daniel Vetter1819.15%533.33%
Imre Deak1414.89%16.67%
Tvrtko A. Ursulin55.32%16.67%
Paulo Zanoni44.26%213.33%
Damien Lespiau22.13%16.67%
Total94100.00%15100.00%


static u32 i9xx_hpd_irq_ack(struct drm_i915_private *dev_priv) { u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); if (hotplug_status) I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); return hotplug_status; }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä1751.52%240.00%
Oscar Mateo927.27%120.00%
Imre Deak618.18%120.00%
Jani Nikula13.03%120.00%
Total33100.00%5100.00%


static void i9xx_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 hotplug_status) { u32 pin_mask = 0, long_mask = 0; if (IS_G4X(dev_priv) || IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_G4X; if (hotplug_trigger) { intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, hotplug_trigger, hotplug_trigger, hpd_status_g4x, i9xx_port_hotplug_long_detect); intel_hpd_irq_handler(dev_priv, pin_mask, long_mask); } if (hotplug_status & DP_AUX_CHANNEL_MASK_INT_STATUS_G4X) dp_aux_irq_handler(dev_priv); } else { u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_I915; if (hotplug_trigger) { intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, hotplug_trigger, hotplug_trigger, hpd_status_i915, i9xx_port_hotplug_long_detect); intel_hpd_irq_handler(dev_priv, pin_mask, long_mask); } } }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä7151.45%538.46%
Jani Nikula3626.09%215.38%
Imre Deak107.25%17.69%
Tvrtko A. Ursulin85.80%17.69%
Rodrigo Vivi42.90%17.69%
Wayne Boyer42.90%17.69%
Oscar Mateo32.17%17.69%
Dave Airlie21.45%17.69%
Total138100.00%13100.00%


static irqreturn_t valleyview_irq_handler(int irq, void *arg) { struct drm_device *dev = arg; struct drm_i915_private *dev_priv = to_i915(dev); irqreturn_t ret = IRQ_NONE; if (!intel_irqs_enabled(dev_priv)) return IRQ_NONE; /* IRQs are synced during runtime_suspend, we don't require a wakeref */ disable_rpm_wakeref_asserts(dev_priv); do { u32 iir, gt_iir, pm_iir; u32 pipe_stats[I915_MAX_PIPES] = {}; u32 hotplug_status = 0; u32 ier = 0; gt_iir = I915_READ(GTIIR); pm_iir = I915_READ(GEN6_PMIIR); iir = I915_READ(VLV_IIR); if (gt_iir == 0 && pm_iir == 0 && iir == 0) break; ret = IRQ_HANDLED; /* * Theory on interrupt generation, based on empirical evidence: * * x = ((VLV_IIR & VLV_IER) || * (((GT_IIR & GT_IER) || (GEN6_PMIIR & GEN6_PMIER)) && * (VLV_MASTER_IER & MASTER_INTERRUPT_ENABLE))); * * A CPU interrupt will only be raised when 'x' has a 0->1 edge. * Hence we clear MASTER_INTERRUPT_ENABLE and VLV_IER to * guarantee the CPU interrupt will be raised again even if we * don't end up clearing all the VLV_IIR, GT_IIR, GEN6_PMIIR * bits this time around. */ I915_WRITE(VLV_MASTER_IER, 0); ier = I915_READ(VLV_IER); I915_WRITE(VLV_IER, 0); if (gt_iir) I915_WRITE(GTIIR, gt_iir); if (pm_iir) I915_WRITE(GEN6_PMIIR, pm_iir); if (iir & I915_DISPLAY_PORT_INTERRUPT) hotplug_status = i9xx_hpd_irq_ack(dev_priv); /* Call regardless, as some status bits might not be * signalled in iir */ i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); if (iir & (I915_LPE_PIPE_A_INTERRUPT | I915_LPE_PIPE_B_INTERRUPT)) intel_lpe_audio_irq_handler(dev_priv); /* * VLV_IIR is single buffered, and reflects the level * from PIPESTAT/PORT_HOTPLUG_STAT, hence clear it last. */ if (iir) I915_WRITE(VLV_IIR, iir); I915_WRITE(VLV_IER, ier); I915_WRITE(VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE); POSTING_READ(VLV_MASTER_IER); if (gt_iir) snb_gt_irq_handler(dev_priv, gt_iir); if (pm_iir) gen6_rps_irq_handler(dev_priv, pm_iir); if (hotplug_status) i9xx_hpd_irq_handler(dev_priv, hotplug_status); valleyview_pipestat_irq_handler(dev_priv, pipe_stats); } while (0); enable_rpm_wakeref_asserts(dev_priv); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä15955.59%945.00%
Imre Deak8027.97%315.00%
Jerome Anand155.24%15.00%
Oscar Mateo144.90%15.00%
Jesse Barnes93.15%210.00%
Tvrtko A. Ursulin31.05%15.00%
Chris Wilson31.05%15.00%
Jani Nikula20.70%15.00%
Paulo Zanoni10.35%15.00%
Total286100.00%20100.00%


static irqreturn_t cherryview_irq_handler(int irq, void *arg) { struct drm_device *dev = arg; struct drm_i915_private *dev_priv = to_i915(dev); irqreturn_t ret = IRQ_NONE; if (!intel_irqs_enabled(dev_priv)) return IRQ_NONE; /* IRQs are synced during runtime_suspend, we don't require a wakeref */ disable_rpm_wakeref_asserts(dev_priv); do { u32 master_ctl, iir; u32 pipe_stats[I915_MAX_PIPES] = {}; u32 hotplug_status = 0; u32 gt_iir[4]; u32 ier = 0; master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL; iir = I915_READ(VLV_IIR); if (master_ctl == 0 && iir == 0) break; ret = IRQ_HANDLED; /* * Theory on interrupt generation, based on empirical evidence: * * x = ((VLV_IIR & VLV_IER) || * ((GEN8_MASTER_IRQ & ~GEN8_MASTER_IRQ_CONTROL) && * (GEN8_MASTER_IRQ & GEN8_MASTER_IRQ_CONTROL))); * * A CPU interrupt will only be raised when 'x' has a 0->1 edge. * Hence we clear GEN8_MASTER_IRQ_CONTROL and VLV_IER to * guarantee the CPU interrupt will be raised again even if we * don't end up clearing all the VLV_IIR and GEN8_MASTER_IRQ_CONTROL * bits this time around. */ I915_WRITE(GEN8_MASTER_IRQ, 0); ier = I915_READ(VLV_IER); I915_WRITE(VLV_IER, 0); gen8_gt_irq_ack(dev_priv, master_ctl, gt_iir); if (iir & I915_DISPLAY_PORT_INTERRUPT) hotplug_status = i9xx_hpd_irq_ack(dev_priv); /* Call regardless, as some status bits might not be * signalled in iir */ i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); if (iir & (I915_LPE_PIPE_A_INTERRUPT | I915_LPE_PIPE_B_INTERRUPT | I915_LPE_PIPE_C_INTERRUPT)) intel_lpe_audio_irq_handler(dev_priv); /* * VLV_IIR is single buffered, and reflects the level * from PIPESTAT/PORT_HOTPLUG_STAT, hence clear it last. */ if (iir) I915_WRITE(VLV_IIR, iir); I915_WRITE(VLV_IER, ier); I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); POSTING_READ(GEN8_MASTER_IRQ); gen8_gt_irq_handler(dev_priv, master_ctl, gt_iir); if (hotplug_status) i9xx_hpd_irq_handler(dev_priv, hotplug_status); valleyview_pipestat_irq_handler(dev_priv, pipe_stats); } while (0); enable_rpm_wakeref_asserts(dev_priv); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä18973.26%1157.89%
Imre Deak228.53%210.53%
Chris Wilson176.59%315.79%
Jerome Anand176.59%15.26%
Oscar Mateo103.88%15.26%
Tvrtko A. Ursulin31.16%15.26%
Total258100.00%19100.00%


static void ibx_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 hotplug_trigger, const u32 hpd[HPD_NUM_PINS]) { u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0; /* * Somehow the PCH doesn't seem to really ack the interrupt to the CPU * unless we touch the hotplug register, even if hotplug_trigger is * zero. Not acking leads to "The master control interrupt lied (SDE)!" * errors. */ dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); if (!hotplug_trigger) { u32 mask = PORTA_HOTPLUG_STATUS_MASK | PORTD_HOTPLUG_STATUS_MASK | PORTC_HOTPLUG_STATUS_MASK | PORTB_HOTPLUG_STATUS_MASK; dig_hotplug_reg &= ~mask; } I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); if (!hotplug_trigger) return; intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, hotplug_trigger, dig_hotplug_reg, hpd, pch_port_hotplug_long_detect); intel_hpd_irq_handler(dev_priv, pin_mask, long_mask); }

Contributors

PersonTokensPropCommitsCommitProp
Jani Nikula4745.19%218.18%
Dave Airlie1817.31%19.09%
Ville Syrjälä1413.46%218.18%
Adam Jackson98.65%19.09%
Egbert Eich65.77%19.09%
Tvrtko A. Ursulin32.88%19.09%
Imre Deak32.88%19.09%
Rodrigo Vivi21.92%19.09%
Sonika Jindal21.92%19.09%
Total104100.00%11100.00%


static void ibx_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) { int pipe; u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK; ibx_hpd_irq_handler(dev_priv, hotplug_trigger, hpd_ibx); if (pch_iir & SDE_AUDIO_POWER_MASK) { int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK) >> SDE_AUDIO_POWER_SHIFT); DRM_DEBUG_DRIVER("PCH audio power change on port %d\n", port_name(port)); } if (pch_iir & SDE_AUX_MASK) dp_aux_irq_handler(dev_priv); if (pch_iir & SDE_GMBUS) gmbus_irq_handler(dev_priv); if (pch_iir & SDE_AUDIO_HDCP_MASK) DRM_DEBUG_DRIVER("PCH HDCP audio interrupt\n"); if (pch_iir & SDE_AUDIO_TRANS_MASK) DRM_DEBUG_DRIVER("PCH transcoder audio interrupt\n"); if (pch_iir & SDE_POISON) DRM_ERROR("PCH poison interrupt\n"); if (pch_iir & SDE_FDI_MASK) for_each_pipe(dev_priv, pipe) DRM_DEBUG_DRIVER(" pipe %c FDI IIR: 0x%08x\n", pipe_name(pipe), I915_READ(FDI_RX_IIR(pipe))); if (pch_iir & (SDE_TRANSB_CRC_DONE | SDE_TRANSA_CRC_DONE)) DRM_DEBUG_DRIVER("PCH transcoder CRC done interrupt\n"); if (pch_iir & (SDE_TRANSB_CRC_ERR | SDE_TRANSA_CRC_ERR)) DRM_DEBUG_DRIVER("PCH transcoder CRC error interrupt\n"); if (pch_iir & SDE_TRANSA_FIFO_UNDER) intel_pch_fifo_underrun_irq_handler(dev_priv, PIPE_A); if (pch_iir & SDE_TRANSB_FIFO_UNDER) intel_pch_fifo_underrun_irq_handler(dev_priv, PIPE_B); }

Contributors

PersonTokensPropCommitsCommitProp
Adam Jackson7033.98%16.67%
Paulo Zanoni6632.04%213.33%
Ville Syrjälä4521.84%213.33%
Daniel Vetter125.83%640.00%
Tvrtko A. Ursulin52.43%16.67%
Jesse Barnes41.94%16.67%
Matthias Kaehlcke20.97%16.67%
Damien Lespiau20.97%16.67%
Total206100.00%15100.00%


static void ivb_err_int_handler(struct drm_i915_private *dev_priv) { u32 err_int = I915_READ(GEN7_ERR_INT); enum pipe pipe; if (err_int & ERR_INT_POISON) DRM_ERROR("Poison interrupt\n"); for_each_pipe(dev_priv, pipe) { if (err_int & ERR_INT_FIFO_UNDERRUN(pipe)) intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); if (err_int & ERR_INT_PIPE_CRC_DONE(pipe)) { if (IS_IVYBRIDGE(dev_priv)) ivb_pipe_crc_irq_handler(dev_priv, pipe); else hsw_pipe_crc_irq_handler(dev_priv, pipe); } } I915_WRITE(GEN7_ERR_INT, err_int); }

Contributors

PersonTokensPropCommitsCommitProp
Paulo Zanoni6465.31%327.27%
Daniel Vetter2727.55%654.55%
Tvrtko A. Ursulin55.10%19.09%
Damien Lespiau22.04%19.09%
Total98100.00%11100.00%


static void cpt_serr_int_handler(struct drm_i915_private *dev_priv) { u32 serr_int = I915_READ(SERR_INT); enum pipe pipe; if (serr_int & SERR_INT_POISON) DRM_ERROR("PCH poison interrupt\n"); for_each_pipe(dev_priv, pipe) if (serr_int & SERR_INT_TRANS_FIFO_UNDERRUN(pipe)) intel_pch_fifo_underrun_irq_handler(dev_priv, pipe); I915_WRITE(SERR_INT, serr_int); }

Contributors

PersonTokensPropCommitsCommitProp
Paulo Zanoni4876.19%337.50%
Mika Kahola1015.87%112.50%
Daniel Vetter34.76%337.50%
Tvrtko A. Ursulin23.17%112.50%
Total63100.00%8100.00%


static void cpt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) { int pipe; u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT; ibx_hpd_irq_handler(dev_priv, hotplug_trigger, hpd_cpt); if (pch_iir & SDE_AUDIO_POWER_MASK_CPT) { int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK_CPT) >> SDE_AUDIO_POWER_SHIFT_CPT); DRM_DEBUG_DRIVER("PCH audio power change on port %c\n", port_name(port)); } if (pch_iir & SDE_AUX_MASK_CPT) dp_aux_irq_handler(dev_priv); if (pch_iir & SDE_GMBUS_CPT) gmbus_irq_handler(dev_priv); if (pch_iir & SDE_AUDIO_CP_REQ_CPT) DRM_DEBUG_DRIVER("Audio CP request interrupt\n"); if (pch_iir & SDE_AUDIO_CP_CHG_CPT) DRM_DEBUG_DRIVER("Audio CP change interrupt\n"); if (pch_iir & SDE_FDI_MASK_CPT) for_each_pipe(dev_priv, pipe) DRM_DEBUG_DRIVER(" pipe %c FDI IIR: 0x%08x\n", pipe_name(pipe), I915_READ(FDI_RX_IIR(pipe))); if (pch_iir & SDE_ERROR_CPT) cpt_serr_int_handler(dev_priv); }

Contributors

PersonTokensPropCommitsCommitProp
Adam Jackson6845.33%14.76%
Paulo Zanoni1812.00%419.05%
Ville Syrjälä1610.67%314.29%
Daniel Vetter85.33%419.05%
Zhenyu Wang74.67%14.76%
Egbert Eich64.00%14.76%
Zou Nan hai64.00%14.76%
Tvrtko A. Ursulin64.00%14.76%
Ben Widawsky53.33%14.76%
Jesse Barnes53.33%14.76%
Jani Nikula21.33%14.76%
Damien Lespiau21.33%14.76%
Dave Airlie10.67%14.76%
Total150100.00%21100.00%


static void spt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) { u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_SPT & ~SDE_PORTE_HOTPLUG_SPT; u32 hotplug2_trigger = pch_iir & SDE_PORTE_HOTPLUG_SPT; u32 pin_mask = 0, long_mask = 0; if (hotplug_trigger) { u32 dig_hotplug_reg; dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, hotplug_trigger, dig_hotplug_reg, hpd_spt, spt_port_hotplug_long_detect); } if (hotplug2_trigger) { u32 dig_hotplug_reg; dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG2); I915_WRITE(PCH_PORT_HOTPLUG2, dig_hotplug_reg); intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, hotplug2_trigger, dig_hotplug_reg, hpd_spt, spt_port_hotplug2_long_detect); } if (pin_mask) intel_hpd_irq_handler(dev_priv, pin_mask, long_mask); if (pch_iir & SDE_GMBUS_CPT) gmbus_irq_handler(dev_priv); }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä14094.59%250.00%
Tvrtko A. Ursulin42.70%125.00%
Rodrigo Vivi42.70%125.00%
Total148100.00%4100.00%


static void ilk_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 hotplug_trigger, const u32 hpd[HPD_NUM_PINS]) { u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0; dig_hotplug_reg = I915_READ(DIGITAL_PORT_HOTPLUG_CNTRL); I915_WRITE(DIGITAL_PORT_HOTPLUG_CNTRL, dig_hotplug_reg); intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, hotplug_trigger, dig_hotplug_reg, hpd, ilk_port_hotplug_long_detect); intel_hpd_irq_handler(dev_priv, pin_mask, long_mask); }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä6081.08%240.00%
Paulo Zanoni912.16%120.00%
Tvrtko A. Ursulin34.05%120.00%
Rodrigo Vivi22.70%120.00%
Total74100.00%5100.00%


static void ilk_display_irq_handler(struct drm_i915_private *dev_priv, u32 de_iir) { enum pipe pipe; u32 hotplug_trigger = de_iir & DE_DP_A_HOTPLUG; if (hotplug_trigger) ilk_hpd_irq_handler(dev_priv, hotplug_trigger, hpd_ilk); if (de_iir & DE_AUX_CHANNEL_A) dp_aux_irq_handler(dev_priv); if (de_iir & DE_GSE) intel_opregion_asle_intr(dev_priv); if (de_iir & DE_POISON) DRM_ERROR("Poison interrupt\n"); for_each_pipe(dev_priv, pipe) { if (de_iir & DE_PIPE_VBLANK(pipe)) drm_handle_vblank(&dev_priv->drm, pipe); if (de_iir & DE_PIPE_FIFO_UNDERRUN(pipe)) intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); if (de_iir & DE_PIPE_CRC_DONE(pipe)) i9xx_pipe_crc_irq_handler(dev_priv, pipe); } /* check event from PCH */ if (de_iir & DE_PCH_EVENT) { u32 pch_iir = I915_READ(SDEIIR); if (HAS_PCH_CPT(dev_priv)) cpt_irq_handler(dev_priv, pch_iir); else ibx_irq_handler(dev_priv, pch_iir); /* should clear PCH hotplug event before clear CPU irq */ I915_WRITE(SDEIIR, pch_iir); } if (IS_GEN5(dev_priv) && de_iir & DE_PCU_EVENT) ironlake_rps_change_irq_handler(dev_priv); }

Contributors

PersonTokensPropCommitsCommitProp
Paulo Zanoni7337.82%312.50%
Ville Syrjälä3417.62%14.17%
Daniel Vetter3216.58%729.17%
Chris Wilson136.74%28.33%
Tvrtko A. Ursulin115.70%14.17%
Zou Nan hai105.18%312.50%
Ben Widawsky105.18%28.33%
Li Peng31.55%14.17%
Yakui Zhao31.55%14.17%
Damien Lespiau21.04%14.17%
Jesse Barnes10.52%14.17%
Zhenyu Wang10.52%14.17%
Total193100.00%24100.00%


static void ivb_display_irq_handler(struct drm_i915_private *dev_priv, u32 de_iir) { enum pipe pipe; u32 hotplug_trigger = de_iir & DE_DP_A_HOTPLUG_IVB; if (hotplug_trigger) ilk_hpd_irq_handler(dev_priv, hotplug_trigger, hpd_ivb); if (de_iir & DE_ERR_INT_IVB) ivb_err_int_handler(dev_priv); if (de_iir & DE_AUX_CHANNEL_A_IVB) dp_aux_irq_handler(dev_priv); if (de_iir & DE_GSE_IVB) intel_opregion_asle_intr(dev_priv); for_each_pipe(dev_priv, pipe) { if (de_iir & (DE_PIPE_VBLANK_IVB(pipe))) drm_handle_vblank(&dev_priv->drm, pipe); } /* check event from PCH */ if (!HAS_PCH_NOP(dev_priv) && (de_iir & DE_PCH_EVENT_IVB)) { u32 pch_iir = I915_READ(SDEIIR); cpt_irq_handler(dev_priv, pch_iir); /* clear PCH hotplug event before clear CPU irq */ I915_WRITE(SDEIIR, pch_iir); } }

Contributors

PersonTokensPropCommitsCommitProp
Paulo Zanoni7251.43%19.09%
Daniel Vetter3424.29%545.45%
Ville Syrjälä1913.57%218.18%
Tvrtko A. Ursulin96.43%19.09%
Damien Lespiau64.29%218.18%
Total140100.00%11100.00%

/* * To handle irqs with the minimum potential races with fresh interrupts, we: * 1 - Disable Master Interrupt Control. * 2 - Find the source(s) of the interrupt. * 3 - Clear the Interrupt Identity bits (IIR). * 4 - Process the interrupt(s) that had bits set in the IIRs. * 5 - Re-enable Master Interrupt Control. */
static irqreturn_t ironlake_irq_handler(int irq, void *arg) { struct drm_device *dev = arg; struct drm_i915_private *dev_priv = to_i915(dev); u32 de_iir, gt_iir, de_ier, sde_ier = 0; irqreturn_t ret = IRQ_NONE; if (!intel_irqs_enabled(dev_priv)) return IRQ_NONE; /* IRQs are synced during runtime_suspend, we don't require a wakeref */ disable_rpm_wakeref_asserts(dev_priv); /* disable master interrupt before clearing iir */ de_ier = I915_READ(DEIER); I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); POSTING_READ(DEIER); /* Disable south interrupts. We'll only write to SDEIIR once, so further * interrupts will will be stored on its back queue, and then we'll be * able to process them after we restore SDEIER (as soon as we restore * it, we'll get an interrupt if SDEIIR still has something to process * due to its back queue). */ if (!HAS_PCH_NOP(dev_priv)) { sde_ier = I915_READ(SDEIER); I915_WRITE(SDEIER, 0); POSTING_READ(SDEIER); } /* Find, clear, then process each source of interrupt */ gt_iir = I915_READ(GTIIR); if (gt_iir) { I915_WRITE(GTIIR, gt_iir); ret = IRQ_HANDLED; if (INTEL_GEN(dev_priv) >= 6) snb_gt_irq_handler(dev_priv, gt_iir); else ilk_gt_irq_handler(dev_priv, gt_iir); } de_iir = I915_READ(DEIIR); if (de_iir) { I915_WRITE(DEIIR, de_iir); ret = IRQ_HANDLED; if (INTEL_GEN(dev_priv) >= 7) ivb_display_irq_handler(dev_priv, de_iir); else ilk_display_irq_handler(dev_priv, de_iir); } if (INTEL_GEN(dev_priv) >= 6) { u32 pm_iir = I915_READ(GEN6_PMIIR); if (pm_iir) { I915_WRITE(GEN6_PMIIR, pm_iir); ret = IRQ_HANDLED; gen6_rps_irq_handler(dev_priv, pm_iir); } } I915_WRITE(DEIER, de_ier); POSTING_READ(DEIER); if (!HAS_PCH_NOP(dev_priv)) { I915_WRITE(SDEIER, sde_ier); POSTING_READ(SDEIER); } /* IRQs are synced during runtime_suspend, we don't require a wakeref */ enable_rpm_wakeref_asserts(dev_priv); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Jesse Barnes5418.06%411.11%
Paulo Zanoni4414.72%513.89%
Chris Wilson3612.04%616.67%
Oscar Mateo3010.03%12.78%
Daniel Vetter248.03%513.89%
Imre Deak237.69%25.56%
Zou Nan hai237.69%25.56%
Simon Farnsworth227.36%12.78%
Ben Widawsky175.69%411.11%
Zhenyu Wang113.68%25.56%
Tvrtko A. Ursulin103.34%12.78%
Yakui Zhao20.67%12.78%
Jani Nikula20.67%12.78%
Li Peng10.33%12.78%
Total299100.00%36100.00%


static void bxt_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 hotplug_trigger, const u32 hpd[HPD_NUM_PINS]) { u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0; dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, hotplug_trigger, dig_hotplug_reg, hpd, bxt_port_hotplug_long_detect); intel_hpd_irq_handler(dev_priv, pin_mask, long_mask); }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä2229.73%428.57%
Jani Nikula2027.03%214.29%
Shashank Sharma2027.03%17.14%
Jesse Barnes45.41%321.43%
Tvrtko A. Ursulin34.05%17.14%
Imre Deak34.05%214.29%
Rodrigo Vivi22.70%17.14%
Total74100.00%14100.00%


static irqreturn_t gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) { irqreturn_t ret = IRQ_NONE; u32 iir; enum pipe pipe; if (master_ctl & GEN8_DE_MISC_IRQ) { iir = I915_READ(GEN8_DE_MISC_IIR); if (iir) { I915_WRITE(GEN8_DE_MISC_IIR, iir); ret = IRQ_HANDLED; if (iir & GEN8_DE_MISC_GSE) intel_opregion_asle_intr(dev_priv); else DRM_ERROR("Unexpected DE Misc interrupt\n"); } else DRM_ERROR("The master control interrupt lied (DE MISC)!\n"); } if (master_ctl & GEN8_DE_PORT_IRQ) { iir = I915_READ(GEN8_DE_PORT_IIR); if (iir) { u32 tmp_mask; bool found = false; I915_WRITE(GEN8_DE_PORT_IIR, iir); ret = IRQ_HANDLED; tmp_mask = GEN8_AUX_CHANNEL_A; if (INTEL_GEN(dev_priv) >= 9) tmp_mask |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C | GEN9_AUX_CHANNEL_D; if (IS_CNL_WITH_PORT_F(dev_priv)) tmp_mask |= CNL_AUX_CHANNEL_F; if (iir & tmp_mask) { dp_aux_irq_handler(dev_priv); found = true; } if (IS_GEN9_LP(dev_priv)) { tmp_mask = iir & BXT_DE_PORT_HOTPLUG_MASK; if (tmp_mask) { bxt_hpd_irq_handler(dev_priv, tmp_mask, hpd_bxt); found = true; } } else if (IS_BROADWELL(dev_priv)) { tmp_mask = iir & GEN8_PORT_DP_A_HOTPLUG; if (tmp_mask) { ilk_hpd_irq_handler(dev_priv, tmp_mask, hpd_bdw); found = true; } } if (IS_GEN9_LP(dev_priv) && (iir & BXT_DE_PORT_GMBUS)) { gmbus_irq_handler(dev_priv); found = true; } if (!found) DRM_ERROR("Unexpected DE Port interrupt\n"); } else DRM_ERROR("The master control interrupt lied (DE PORT)!\n"); } for_each_pipe(dev_priv, pipe) { u32 fault_errors; if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe))) continue; iir = I915_READ(GEN8_DE_PIPE_IIR(pipe)); if (!iir) { DRM_ERROR("The master control interrupt lied (DE PIPE)!\n"); continue; } ret = IRQ_HANDLED; I915_WRITE(GEN8_DE_PIPE_IIR(pipe), iir); if (iir & GEN8_PIPE_VBLANK) drm_handle_vblank(&dev_priv->drm, pipe); if (iir & GEN8_PIPE_CDCLK_CRC_DONE) hsw_pipe_crc_irq_handler(dev_priv, pipe); if (iir & GEN8_PIPE_FIFO_UNDERRUN) intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); fault_errors = iir; if (INTEL_GEN(dev_priv) >= 9) fault_errors &= GEN9_DE_PIPE_IRQ_FAULT_ERRORS; else fault_errors &= GEN8_DE_PIPE_IRQ_FAULT_ERRORS; if (fault_errors) DRM_ERROR("Fault errors on pipe %c: 0x%08x\n", pipe_name(pipe), fault_errors); } if (HAS_PCH_SPLIT(dev_priv) && !HAS_PCH_NOP(dev_priv) && master_ctl & GEN8_DE_PCH_IRQ) { /* * FIXME(BDW): Assume for now that the new interrupt handling * scheme also closed the SDE interrupt handling race we've seen * on older pch-split platforms. But this needs testing. */ iir = I915_READ(SDEIIR); if (iir) { I915_WRITE(SDEIIR, iir); ret = IRQ_HANDLED; if (HAS_PCH_SPT(dev_priv) || HAS_PCH_KBP(dev_priv) || HAS_PCH_CNP(dev_priv)) spt_irq_handler(dev_priv, iir); else cpt_irq_handler(dev_priv, iir); } else { /* * Like on previous PCH there seems to be something * fishy going on with forwarding PCH interrupts. */ DRM_DEBUG_DRIVER("The master control interrupt lied (SDE)!\n"); } } return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Tvrtko A. Ursulin12825.20%47.69%
Jesse Barnes6913.58%713.46%
Daniel Vetter6412.60%1121.15%
Oscar Mateo5210.24%11.92%
Shashank Sharma5210.24%35.77%
Ville Syrjälä377.28%35.77%
Ben Widawsky295.71%23.85%
Rodrigo Vivi244.72%47.69%
Damien Lespiau152.95%23.85%
Chris Wilson61.18%35.77%
Simon Farnsworth61.18%11.92%
Keith Packard40.79%11.92%
Jani Nikula40.79%11.92%
Michel Dänzer40.79%23.85%
Eric Anholt30.59%11.92%
Dave Airlie20.39%11.92%
Ander Conselvan de Oliveira20.39%11.92%
Ben Gamari20.39%11.92%
Dhinakaran Pandiyan20.39%11.92%
Kristian Högsberg20.39%11.92%
Zou Nan hai10.20%11.92%
Total508100.00%52100.00%


static irqreturn_t gen8_irq_handler(int irq, void *arg) { struct drm_i915_private *dev_priv = to_i915(arg); u32 master_ctl; u32 gt_iir[4]; if (!intel_irqs_enabled(dev_priv)) return IRQ_NONE; master_ctl = I915_READ_FW(GEN8_MASTER_IRQ); master_ctl &= ~GEN8_MASTER_IRQ_CONTROL; if (!master_ctl) return IRQ_NONE; I915_WRITE_FW(GEN8_MASTER_IRQ, 0); /* Find, clear, then process each source of interrupt */ gen8_gt_irq_ack(dev_priv, master_ctl, gt_iir); /* IRQs are synced during runtime_suspend, we don't require a wakeref */ if (master_ctl & ~GEN8_GT_IRQS) { disable_rpm_wakeref_asserts(dev_priv); gen8_de_irq_handler(dev_priv, master_ctl); enable_rpm_wakeref_asserts(dev_priv); } I915_WRITE_FW(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); gen8_gt_irq_handler(dev_priv, master_ctl, gt_iir); return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
Tvrtko A. Ursulin7357.94%110.00%
Chris Wilson2620.63%330.00%
Ville Syrjälä1310.32%110.00%
Jesse Barnes53.97%110.00%
Imre Deak43.17%110.00%
Ben Widawsky32.38%110.00%
Eric Anholt21.59%220.00%
Total126100.00%10100.00%

struct wedge_me { struct delayed_work work; struct drm_i915_private *i915; const char *name; };
static void wedge_me(struct work_struct *work) { struct wedge_me *w = container_of(work, typeof(*w), work.work); dev_err(w->i915->drm.dev, "%s timed out, cancelling all in-flight rendering.\n", w->name); i915_gem_set_wedged(w->i915); }

Contributors

PersonTokensPropCommitsCommitProp
Chris Wilson55100.00%1100.00%
Total55100.00%1100.00%


static void __init_wedge(struct wedge_me *w, struct drm_i915_private *i915, long timeout, const char *name) { w->i915 = i915; w->name = name; INIT_DELAYED_WORK_ONSTACK(&w->work, wedge_me); schedule_delayed_work(&w->work, timeout); }

Contributors

PersonTokensPropCommitsCommitProp
Chris Wilson56100.00%1100.00%
Total56100.00%1100.00%


static void __fini_wedge(struct wedge_me *w) { cancel_delayed_work_sync(&w->work); destroy_delayed_work_on_stack(&w->work); w->i915 = NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Wilson33100.00%1100.00%
Total33100.00%1100.00%

#define i915_wedge_on_timeout(W, DEV, TIMEOUT) \ for (__init_wedge((W), (DEV), (TIMEOUT), __func__); \ (W)->i915; \ __fini_wedge((W)))
static __always_inline void gen11_cs_irq_handler(struct intel_engine_cs * const engine, const u32 iir) { gen8_cs_irq_handler(engine, iir, 0); }

Contributors

PersonTokensPropCommitsCommitProp
Mika Kuoppala26100.00%1100.00%
Total26100.00%1100.00%


static void gen11_gt_engine_irq_handler(struct drm_i915_private * const i915, const unsigned int bank, const unsigned int engine_n, const u16 iir) { struct intel_engine_cs ** const engine = i915->engine; switch (bank) { case 0: switch (engine_n) { case GEN11_RCS0: return gen11_cs_irq_handler(engine[RCS], iir); case GEN11_BCS: return gen11_cs_irq_handler(engine[BCS], iir); } case 1: switch (engine_n) { case GEN11_VCS(0): return gen11_cs_irq_handler(engine[_VCS(0)], iir); case GEN11_VCS(1): return gen11_cs_irq_handler(engine[_VCS(1)], iir); case GEN11_VCS(2): return gen11_cs_irq_handler(engine[_VCS(2)], iir); case GEN11_VCS(3): return gen11_cs_irq_handler(engine[_VCS(3)], iir); case GEN11_VECS(0): return gen11_cs_irq_handler(engine[_VECS(0)], iir); case GEN11_VECS(1): return gen11_cs_irq_handler(engine[_VECS(1)], iir); } } }

Contributors

PersonTokensPropCommitsCommitProp
Mika Kuoppala17483.25%15.88%
Chris Wilson125.74%635.29%
Eric Anholt83.83%211.76%
Keith Packard52.39%211.76%
Jesse Barnes31.44%211.76%
Zou Nan hai31.44%15.88%
Ville Syrjälä20.96%15.88%
Daniel Vetter10.48%15.88%
Dave Airlie10.48%15.88%
Total209100.00%17100.00%


static u32 gen11_gt_engine_intr(struct drm_i915_private * const i915, const unsigned int bank, const unsigned int bit) { void __iomem * const regs = i915->regs; u32 timeout_ts; u32 ident; raw_reg_write(regs, GEN11_IIR_REG_SELECTOR(bank), BIT(bit)); /* * NB: Specs do not specify how long to spin wait, * so we do ~100us as an educated guess. */ timeout_ts = (local_clock() >> 10) + 100; do { ident = raw_reg_read(regs, GEN11_INTR_IDENTITY_REG(bank)); } while (!(ident & GEN11_INTR_DATA_VALID) && !time_after32(local_clock() >> 10, timeout_ts)); if (unlikely(!(ident & GEN11_INTR_DATA_VALID))) { DRM_ERROR("INTR_IDENTITY_REG%u:%u 0x%08x not valid!\n", bank, bit, ident); return 0; } raw_reg_write(regs, GEN11_INTR_IDENTITY_REG(bank), GEN11_INTR_DATA_VALID); return ident & GEN11_INTR_ENGINE_MASK; }

Contributors

PersonTokensPropCommitsCommitProp
Mika Kuoppala146100.00%1100.00%
Total146100.00%1100.00%


static void gen11_gt_irq_handler(struct drm_i915_private * const i915, const u32 master_ctl) { void __iomem * const regs = i915->regs; unsigned int bank; for (bank = 0; bank < 2; bank++) { unsigned long intr_dw; unsigned int bit; if (!(master_ctl & GEN11_GT_DW_IRQ(bank))) continue; intr_dw = raw_reg_read(regs, GEN11_GT_INTR_DW(bank)); if (unlikely(!intr_dw)) { DRM_ERROR("GT_INTR_DW%u blank!\n", bank); continue; } for_each_set_bit(bit, &intr_dw, 32) { const u16 iir = gen11_gt_engine_intr(i915, bank, bit); if (unlikely(!iir)) continue; gen11_gt_engine_irq_handler(i915, bank, bit, iir); } /* Clear must be after shared has been served for engine */ raw_reg_write(regs, GEN11_GT_INTR_DW(bank), intr_dw); } }

Contributors

PersonTokensPropCommitsCommitProp
Mika Kuoppala152100.00%1100.00%
Total152100.00%1100.00%


static irqreturn_t gen11_irq_handler(int irq, void *arg) { struct drm_i915_private * const i915 = to_i915(arg); void __iomem * const regs = i915->regs; u32 master_ctl; if (!intel_irqs_enabled(i915)) return IRQ_NONE; master_ctl = raw_reg_read(regs, GEN11_GFX_MSTR_IRQ); master_ctl &= ~GEN11_MASTER_IRQ; if (!master_ctl) return IRQ_NONE; /* Disable interrupts. */ raw_reg_write(regs, GEN11_GFX_MSTR_IRQ, 0); /* Find, clear, then process each source of interrupt. */ gen11_gt_irq_handler(i915, master_ctl); /* IRQs are synced during runtime_suspend, we don't require a wakeref */ if (master_ctl & GEN11_DISPLAY_IRQ) { const u32 disp_ctl = raw_reg_read(regs, GEN11_DISPLAY_INT_CTL); disable_rpm_wakeref_asserts(i915); /* * GEN11_DISPLAY_INT_CTL has same format as GEN8_MASTER_IRQ * for the display related bits. */ gen8_de_irq_handler(i915, disp_ctl); enable_rpm_wakeref_asserts(i915); } /* Acknowledge and enable interrupts. */ raw_reg_write(regs, GEN11_GFX_MSTR_IRQ, GEN11_MASTER_IRQ | master_ctl); return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
Mika Kuoppala141100.00%1100.00%
Total141100.00%1100.00%

/** * i915_reset_device - do process context error handling work * @dev_priv: i915 device private * * Fire an error uevent so userspace can see that a hang or error * was detected. */
static void i915_reset_device(struct drm_i915_private *dev_priv) { struct kobject *kobj = &dev_priv->drm.primary->kdev->kobj; char *error_event[] = { I915_ERROR_UEVENT "=1", NULL }; char *reset_event[] = { I915_RESET_UEVENT "=1", NULL }; char *reset_done_event[] = { I915_ERROR_UEVENT "=0", NULL }; struct wedge_me w; kobject_uevent_env(kobj, KOBJ_CHANGE, error_event); DRM_DEBUG_DRIVER("resetting chip\n"); kobject_uevent_env(kobj, KOBJ_CHANGE, reset_event); /* Use a watchdog to ensure that our reset completes */ i915_wedge_on_timeout(&w, dev_priv, 5*HZ) { intel_prepare_reset(dev_priv); /* Signal that locked waiters should reset the GPU */ set_bit(I915_RESET_HANDOFF, &dev_priv->gpu_error.flags); wake_up_all(&dev_priv->gpu_error.wait_queue); /* Wait for anyone holding the lock to wakeup, without * blocking indefinitely on struct_mutex. */ do { if (mutex_trylock(&dev_priv->drm.struct_mutex)) { i915_reset(dev_priv, 0); mutex_unlock(&dev_priv->drm.struct_mutex); } } while (wait_on_bit_timeout(&dev_priv->gpu_error.flags, I915_RESET_HANDOFF, TASK_UNINTERRUPTIBLE, 1)); intel_finish_reset(dev_priv); } if (!test_bit(I915_WEDGED, &dev_priv->gpu_error.flags)) kobject_uevent_env(kobj, KOBJ_CHANGE, reset_done_event); }

Contributors

PersonTokensPropCommitsCommitProp
Mika Kuoppala14969.95%16.25%
Chris Wilson4621.60%637.50%
Jesse Barnes62.82%16.25%
Eric Anholt31.41%16.25%
Dave Airlie20.94%212.50%
Keith Packard20.94%16.25%
Ben Widawsky20.94%16.25%
Ville Syrjälä10.47%16.25%
Kristian Högsberg10.47%16.25%
Michel Dänzer10.47%16.25%
Total213100.00%16100.00%


static void i915_clear_error_registers(struct drm_i915_private *dev_priv) { u32 eir; if (!IS_GEN2(dev_priv)) I915_WRITE(PGTBL_ER, I915_READ(PGTBL_ER)); if (INTEL_GEN(dev_priv) < 4) I915_WRITE(IPEIR, I915_READ(IPEIR)); else I915_WRITE(IPEIR_I965, I915_READ(IPEIR_I965)); I915_WRITE(EIR, I915_READ(EIR)); eir = I915_READ(EIR); if (eir) { /* * some errors might have become stuck, * mask them. */ DRM_DEBUG_DRIVER("EIR stuck: 0x%08x, masking\n", eir); I915_WRITE(EMR, I915_READ(EMR) | eir); I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); } }

Contributors

PersonTokensPropCommitsCommitProp
Jesse Barnes8878.57%218.18%
Chris Wilson1311.61%327.27%
Eric Anholt43.57%19.09%
Keith Packard32.68%19.09%
Kristian Högsberg10.89%19.09%
Michel Dänzer10.89%19.09%
Daniel Vetter10.89%19.09%
Dave Airlie10.89%19.09%
Total112100.00%11100.00%

/** * i915_handle_error - handle a gpu error * @dev_priv: i915 device private * @engine_mask: mask representing engines that are hung * @fmt: Error message format string * * Do some basic checking of register state at error time and * dump it to the syslog. Also call i915_capture_error_state() to make * sure we get a record and make it available in debugfs. Fire a uevent * so userspace knows something bad happened (should trigger collection * of a ring dump etc.). */
void i915_handle_error(struct drm_i915_private *dev_priv, u32 engine_mask, const char *fmt, ...) { struct intel_engine_cs *engine; unsigned int tmp; va_list args; char error_msg[80]; va_start(args, fmt); vscnprintf(error_msg, sizeof(error_msg), fmt, args); va_end(args); /* * In most cases it's guaranteed that we get here with an RPM * reference held, for example because there is a pending GPU * request that won't finish until the reset is done. This * isn't the case at least when we get here by doing a * simulated reset via debugfs, so get an RPM reference. */ intel_runtime_pm_get(dev_priv); i915_capture_error_state(dev_priv, engine_mask, error_msg); i915_clear_error_registers(dev_priv); /* * Try engine reset when available. We fall back to full reset if * single reset fails. */ if (intel_has_reset_engine(dev_priv)) { for_each_engine_masked(engine, dev_priv, engine_mask, tmp) { BUILD_BUG_ON(I915_RESET_MODESET >= I915_RESET_ENGINE); if (test_and_set_bit(I915_RESET_ENGINE + engine->id, &dev_priv->gpu_error.flags)) continue; if (i915_reset_engine(engine, 0) == 0) engine_mask &= ~intel_engine_flag(engine); clear_bit(I915_RESET_ENGINE + engine->id, &dev_priv->gpu_error.flags); wake_up_bit(&dev_priv->gpu_error.flags, I915_RESET_ENGINE + engine->id); } } if (!engine_mask) goto out; /* Full reset needs the mutex, stop any other user trying to do so. */ if (test_and_set_bit(I915_RESET_BACKOFF, &dev_priv->gpu_error.flags)) { wait_event(dev_priv->gpu_error.reset_queue, !test_bit(I915_RESET_BACKOFF, &dev_priv->gpu_error.flags)); goto out; } /* Prevent any other reset-engine attempt. */ for_each_engine(engine, dev_priv, tmp) { while (test_and_set_bit(I915_RESET_ENGINE + engine->id, &dev_priv->gpu_error.flags)) wait_on_bit(&dev_priv->gpu_error.flags, I915_RESET_ENGINE + engine->id, TASK_UNINTERRUPTIBLE); } i915_reset_device(dev_priv); for_each_engine(engine, dev_priv, tmp) { clear_bit(I915_RESET_ENGINE + engine->id, &dev_priv->gpu_error.flags); } clear_bit(I915_RESET_BACKOFF, &dev_priv->gpu_error.flags); wake_up_all(&dev_priv->gpu_error.reset_queue); out: intel_runtime_pm_put(dev_priv); }

Contributors

PersonTokensPropCommitsCommitProp
Michel Thierry17952.65%15.88%
Chris Wilson9929.12%952.94%
Mika Kuoppala4513.24%15.88%
Jesse Barnes102.94%211.76%
Arun Siluvery41.18%15.88%
Daniel Vetter20.59%211.76%
Paulo Zanoni10.29%15.88%
Total340100.00%17100.00%

/* Called from drm generic code, passed 'crtc' which * we use as a pipe index */
static int i8xx_enable_vblank(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = to_i915(dev); unsigned long irqflags; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); i915_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_STATUS); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Wilson3862.30%555.56%
Jesse Barnes1931.15%111.11%
Jani Nikula23.28%111.11%
Imre Deak11.64%111.11%
Thierry Reding11.64%111.11%
Total61100.00%9100.00%


static int i965_enable_vblank(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = to_i915(dev); unsigned long irqflags; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); i915_enable_pipestat(dev_priv, pipe, PIPE_START_VBLANK_INTERRUPT_STATUS); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Wilson3455.74%660.00%
Jesse Barnes2236.07%110.00%
Jani Nikula23.28%110.00%
Mika Kuoppala23.28%110.00%
Thierry Reding11.64%110.00%
Total61100.00%10100.00%


static int ironlake_enable_vblank(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = to_i915(dev); unsigned long irqflags; uint32_t bit = INTEL_GEN(dev_priv) >= 7 ? DE_PIPE_VBLANK_IVB(pipe) : DE_PIPE_VBLANK(pipe); spin_lock_irqsave(&dev_priv->irq_lock, irqflags); ilk_enable_display_irq(dev_priv, bit); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); /* Even though there is no DMC, frame counter can get stuck when * PSR is active as no frames are generated. */ if (HAS_PSR(dev_priv)) drm_vblank_restore(dev, pipe); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Wilson3537.23%535.71%
Jesse Barnes3132.98%214.29%
Dhinakaran Pandiyan1515.96%17.14%
Mika Kuoppala88.51%214.29%
Jani Nikula22.13%17.14%
Thierry Reding11.06%17.14%
Damien Lespiau11.06%17.14%
Tvrtko A. Ursulin11.06%17.14%
Total94100.00%14100.00%


static int gen8_enable_vblank(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = to_i915(dev); unsigned long irqflags; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); /* Even if there is no DMC, frame counter can get stuck when * PSR is active as no frames are generated, so check only for PSR. */ if (HAS_PSR(dev_priv)) drm_vblank_restore(dev, pipe); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Ben Widawsky3140.79%17.69%
Chris Wilson2026.32%538.46%
Dhinakaran Pandiyan1519.74%17.69%
Ville Syrjälä45.26%17.69%
Daniel Vetter33.95%215.38%
Mika Kuoppala22.63%215.38%
Thierry Reding11.32%17.69%
Total76100.00%13100.00%

/* Called from drm generic code, passed 'crtc' which * we use as a pipe index */
static void i8xx_disable_vblank(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = to_i915(dev); unsigned long irqflags; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); i915_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_STATUS); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); }

Contributors

PersonTokensPropCommitsCommitProp
Jesse Barnes3458.62%17.69%
Chris Wilson1322.41%538.46%
Mika Kuoppala610.34%323.08%
Jani Nikula23.45%17.69%
Damien Lespiau11.72%17.69%
Imre Deak11.72%17.69%
Thierry Reding11.72%17.69%
Total58100.00%13100.00%


static void i965_disable_vblank(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = to_i915(dev); unsigned long irqflags; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); i915_disable_pipestat(dev_priv, pipe, PIPE_START_VBLANK_INTERRUPT_STATUS); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); }

Contributors

PersonTokensPropCommitsCommitProp
Jesse Barnes3255.17%111.11%
Chris Wilson1627.59%444.44%
Daniel Vetter58.62%111.11%
Mika Kuoppala23.45%111.11%
Jani Nikula23.45%111.11%
Thierry Reding11.72%111.11%
Total58100.00%9100.00%


static void ironlake_disable_vblank(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = to_i915(dev); unsigned long irqflags; uint32_t bit = INTEL_GEN(dev_priv) >= 7 ? DE_PIPE_VBLANK_IVB(pipe) : DE_PIPE_VBLANK(pipe); spin_lock_irqsave(&dev_priv->irq_lock, irqflags); ilk_disable_display_irq(dev_priv, bit); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); }

Contributors

PersonTokensPropCommitsCommitProp
Jesse Barnes4356.58%220.00%
Chris Wilson2836.84%440.00%
Jani Nikula22.63%110.00%
Tvrtko A. Ursulin11.32%110.00%
Mika Kuoppala11.32%110.00%
Thierry Reding11.32%110.00%
Total76100.00%10100.00%


static void gen8_disable_vblank(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = to_i915(dev); unsigned long irqflags; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); }

Contributors

PersonTokensPropCommitsCommitProp
Ben Widawsky4272.41%110.00%
Chris Wilson610.34%330.00%
Ville Syrjälä46.90%110.00%
Jesse Barnes23.45%110.00%
Mika Kuoppala23.45%220.00%
Daniel Vetter11.72%110.00%
Thierry Reding11.72%110.00%
Total58100.00%10100.00%


static void ibx_irq_reset(struct drm_i915_private *dev_priv) { if (HAS_PCH_NOP(dev_priv)) return; GEN3_IRQ_RESET(SDE); if (HAS_PCH_CPT(dev_priv) || HAS_PCH_LPT(dev_priv)) I915_WRITE(SERR_INT, 0xffffffff); }

Contributors

PersonTokensPropCommitsCommitProp
Paulo Zanoni3479.07%450.00%
Tvrtko A. Ursulin511.63%225.00%
Mika Kuoppala36.98%112.50%
Ville Syrjälä12.33%112.50%
Total43100.00%8100.00%

/* * SDEIER is also touched by the interrupt handler to work around missed PCH * interrupts. Hence we can't update it after the interrupt handler is enabled - * instead we unconditionally enable all PCH interrupt sources here, but then * only unmask them as needed with SDEIMR. * * This function needs to be called before interrupts are enabled. */
static void ibx_irq_pre_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); if (HAS_PCH_NOP(dev_priv)) return; WARN_ON(I915_READ(SDEIER) != 0); I915_WRITE(SDEIER, 0xffffffff); POSTING_READ(SDEIER); }

Contributors

PersonTokensPropCommitsCommitProp
Daniel Vetter3262.75%114.29%
Paulo Zanoni1325.49%228.57%
Chris Wilson35.88%114.29%
Mika Kuoppala11.96%114.29%
Jesse Barnes11.96%114.29%
Tvrtko A. Ursulin11.96%114.29%
Total51100.00%7100.00%


static void gen5_gt_irq_reset(struct drm_i915_private *dev_priv) { GEN3_IRQ_RESET(GT); if (INTEL_GEN(dev_priv) >= 6) GEN3_IRQ_RESET(GEN6_PM); }

Contributors

PersonTokensPropCommitsCommitProp
Jesse Barnes826.67%19.09%
Daniel Vetter516.67%19.09%
Mika Kuoppala516.67%218.18%
Tvrtko A. Ursulin413.33%19.09%
Paulo Zanoni310.00%218.18%
Chris Wilson26.67%218.18%
Ville Syrjälä26.67%19.09%
Jani Nikula13.33%19.09%
Total30100.00%11100.00%


static void vlv_display_irq_reset(struct drm_i915_private *dev_priv) { if (IS_CHERRYVIEW(dev_priv)) I915_WRITE(DPINVGTT, DPINVGTT_STATUS_MASK_CHV); else I915_WRITE(DPINVGTT, DPINVGTT_STATUS_MASK); i915_hotplug_interrupt_update_locked(dev_priv, 0xffffffff, 0); I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); i9xx_pipestat_irq_reset(dev_priv); GEN3_IRQ_RESET(VLV_); dev_priv->irq_mask = ~0u; }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä4869.57%430.77%
Chris Wilson811.59%430.77%
Jesse Barnes57.25%17.69%
Mika Kuoppala34.35%17.69%
Paulo Zanoni22.90%17.69%
Ben Widawsky22.90%17.69%
Jani Nikula11.45%17.69%
Total69100.00%13100.00%


static void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) { u32 pipestat_mask; u32 enable_mask; enum pipe pipe; pipestat_mask = PIPE_CRC_DONE_INTERRUPT_STATUS; i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); for_each_pipe(dev_priv, pipe) i915_enable_pipestat(dev_priv, pipe, pipestat_mask); enable_mask = I915_DISPLAY_PORT_INTERRUPT | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | I915_LPE_PIPE_A_INTERRUPT | I915_LPE_PIPE_B_INTERRUPT; if (IS_CHERRYVIEW(dev_priv)) enable_mask |= I915_DISPLAY_PIPE_C_EVENT_INTERRUPT | I915_LPE_PIPE_C_INTERRUPT; WARN_ON(dev_priv->irq_mask != ~0u); dev_priv->irq_mask = ~enable_mask; GEN3_IRQ_INIT(VLV_, dev_priv->irq_mask, enable_mask); }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä10199.02%787.50%
Chris Wilson10.98%112.50%
Total102100.00%8100.00%

/* drm_dma.h hooks */
static void ironlake_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); if (IS_GEN5(dev_priv)) I915_WRITE(HWSTAM, 0xffffffff); GEN3_IRQ_RESET(DE); if (IS_GEN7(dev_priv)) I915_WRITE(GEN7_ERR_INT, 0xffffffff); gen5_gt_irq_reset(dev_priv); ibx_irq_reset(dev_priv); }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä5890.62%562.50%
Tvrtko A. Ursulin34.69%225.00%
Chris Wilson34.69%112.50%
Total64100.00%8100.00%


static void valleyview_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); I915_WRITE(VLV_MASTER_IER, 0); POSTING_READ(VLV_MASTER_IER); gen5_gt_irq_reset(dev_priv); spin_lock_irq(&dev_priv->irq_lock); if (dev_priv->display_irqs_enabled) vlv_display_irq_reset(dev_priv); spin_unlock_irq(&dev_priv->irq_lock); }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä4061.54%640.00%
Ben Gamari913.85%16.67%
Mika Kuoppala69.23%213.33%
Chris Wilson34.62%16.67%
Jani Nikula23.08%16.67%
Jesse Barnes23.08%16.67%
Paulo Zanoni23.08%213.33%
Tvrtko A. Ursulin11.54%16.67%
Total65100.00%15100.00%


static void gen8_gt_irq_reset(struct drm_i915_private *dev_priv) { GEN8_IRQ_RESET_NDX(GT, 0); GEN8_IRQ_RESET_NDX(GT, 1); GEN8_IRQ_RESET_NDX(GT, 2); GEN8_IRQ_RESET_NDX(GT, 3); }

Contributors

PersonTokensPropCommitsCommitProp
Mika Kuoppala2256.41%150.00%
Daniel Vetter1743.59%150.00%
Total39100.00%2100.00%


static void gen8_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); int pipe; I915_WRITE(GEN8_MASTER_IRQ, 0); POSTING_READ(GEN8_MASTER_IRQ); gen8_gt_irq_reset(dev_priv); for_each_pipe(dev_priv, pipe) if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) GEN8_IRQ_RESET_NDX(DE_PIPE, pipe); GEN3_IRQ_RESET(GEN8_DE_PORT_); GEN3_IRQ_RESET(GEN8_DE_MISC_); GEN3_IRQ_RESET(GEN8_PCU_); if (HAS_PCH_SPLIT(dev_priv)) ibx_irq_reset(dev_priv); }

Contributors

PersonTokensPropCommitsCommitProp
Mika Kuoppala93100.00%1100.00%
Total93100.00%1100.00%


static void gen11_gt_irq_reset(struct drm_i915_private *dev_priv) { /* Disable RCS, BCS, VCS and VECS class engines. */ I915_WRITE(GEN11_RENDER_COPY_INTR_ENABLE, 0); I915_WRITE(GEN11_VCS_VECS_INTR_ENABLE, 0); /* Restore masks irqs on RCS, BCS, VCS and VECS engines. */ I915_WRITE(GEN11_RCS0_RSVD_INTR_MASK, ~0); I915_WRITE(GEN11_BCS_RSVD_INTR_MASK, ~0); I915_WRITE(GEN11_VCS0_VCS1_INTR_MASK, ~0); I915_WRITE(GEN11_VCS2_VCS3_INTR_MASK, ~0); I915_WRITE(GEN11_VECS0_VECS1_INTR_MASK, ~0); }

Contributors

PersonTokensPropCommitsCommitProp
Mika Kuoppala5480.60%150.00%
Daniel Vetter1319.40%150.00%
Total67100.00%2100.00%


static void gen11_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int pipe; I915_WRITE(GEN11_GFX_MSTR_IRQ, 0); POSTING_READ(GEN11_GFX_MSTR_IRQ); gen11_gt_irq_reset(dev_priv); I915_WRITE(GEN11_DISPLAY_INT_CTL, 0); for_each_pipe(dev_priv, pipe) if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) GEN8_IRQ_RESET_NDX(DE_PIPE, pipe); GEN3_IRQ_RESET(GEN8_DE_PORT_); GEN3_IRQ_RESET(GEN8_DE_MISC_); GEN3_IRQ_RESET(GEN8_PCU_); }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä5967.82%228.57%
Mika Kuoppala1314.94%114.29%
Paulo Zanoni1112.64%114.29%
Daniel Vetter22.30%228.57%
Damien Lespiau22.30%114.29%
Total87100.00%7100.00%


void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, u8 pipe_mask) { uint32_t extra_ier = GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN; enum pipe pipe; spin_lock_irq(&dev_priv->irq_lock); if (!intel_irqs_enabled(dev_priv)) { spin_unlock_irq(&dev_priv->irq_lock); return; } for_each_pipe_masked(dev_priv, pipe, pipe_mask) GEN8_IRQ_INIT_NDX(DE_PIPE, pipe, dev_priv->de_irq_mask[pipe], ~dev_priv->de_irq_mask[pipe] | extra_ier); spin_unlock_irq(&dev_priv->irq_lock); }

Contributors

PersonTokensPropCommitsCommitProp
Paulo Zanoni5560.44%225.00%
Imre Deak2021.98%225.00%
Ville Syrjälä1112.09%112.50%
Damien Lespiau33.30%225.00%
Daniel Vetter22.20%112.50%
Total91100.00%8100.00%


void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv, u8 pipe_mask) { enum pipe pipe; spin_lock_irq(&dev_priv->irq_lock); if (!intel_irqs_enabled(dev_priv)) { spin_unlock_irq(&dev_priv->irq_lock); return; } for_each_pipe_masked(dev_priv, pipe, pipe_mask) GEN8_IRQ_RESET_NDX(DE_PIPE, pipe); spin_unlock_irq(&dev_priv->irq_lock); /* make sure we're done processing display irqs */ synchronize_irq(dev_priv->drm.irq); }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä5571.43%240.00%
Imre Deak2025.97%240.00%
Chris Wilson22.60%120.00%
Total77100.00%5100.00%


static void cherryview_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); I915_WRITE(GEN8_MASTER_IRQ, 0); POSTING_READ(GEN8_MASTER_IRQ); gen8_gt_irq_reset(dev_priv); GEN3_IRQ_RESET(GEN8_PCU_); spin_lock_irq(&dev_priv->irq_lock); if (dev_priv->display_irqs_enabled) vlv_display_irq_reset(dev_priv); spin_unlock_irq(&dev_priv->irq_lock); }

Contributors

PersonTokensPropCommitsCommitProp
Daniel Vetter2941.43%218.18%
Ville Syrjälä2840.00%654.55%
Ben Widawsky811.43%19.09%
Chris Wilson34.29%19.09%
Jesse Barnes22.86%19.09%
Total70100.00%11100.00%


static u32 intel_hpd_enabled_irqs(struct drm_i915_private *dev_priv, const u32 hpd[HPD_NUM_PINS]) { struct intel_encoder *encoder; u32 enabled_irqs = 0; for_each_intel_encoder(&dev_priv->drm, encoder) if (dev_priv->hotplug.stats[encoder->hpd_pin].state == HPD_ENABLED) enabled_irqs |= hpd[encoder->hpd_pin]; return enabled_irqs; }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä1726.98%17.69%
Egbert Eich1015.87%17.69%
Daniel Vetter1015.87%215.38%
Ben Widawsky812.70%17.69%
Jani Nikula57.94%215.38%
Mika Kuoppala57.94%17.69%
Chris Wilson34.76%215.38%
Jesse Barnes23.17%17.69%
Tvrtko A. Ursulin23.17%17.69%
Damien Lespiau11.59%17.69%
Total63100.00%13100.00%


static void ibx_hpd_detection_setup(struct drm_i915_private *dev_priv) { u32 hotplug; /* * Enable digital hotplug on the PCH, and configure the DP short pulse * duration to 2ms (which is the minimum in the Display Port spec). * The pulse duration bits are reserved on LPT+. */ hotplug = I915_READ(PCH_PORT_HOTPLUG); hotplug &= ~(PORTB_PULSE_DURATION_MASK | PORTC_PULSE_DURATION_MASK | PORTD_PULSE_DURATION_MASK); hotplug |= PORTB_HOTPLUG_ENABLE | PORTB_PULSE_DURATION_2ms; hotplug |= PORTC_HOTPLUG_ENABLE | PORTC_PULSE_DURATION_2ms; hotplug |= PORTD_HOTPLUG_ENABLE | PORTD_PULSE_DURATION_2ms; /* * When CPU and PCH are on the same package, port A * HPD must be enabled in both north and south. */ if (HAS_PCH_LPT_LP(dev_priv)) hotplug |= PORTA_HOTPLUG_ENABLE; I915_WRITE(PCH_PORT_HOTPLUG, hotplug); }

Contributors

PersonTokensPropCommitsCommitProp
Imre Deak70100.00%1100.00%
Total70100.00%1100.00%


static void ibx_hpd_irq_setup(struct drm_i915_private *dev_priv) { u32 hotplug_irqs, enabled_irqs; if (HAS_PCH_IBX(dev_priv)) { hotplug_irqs = SDE_HOTPLUG_MASK; enabled_irqs = intel_hpd_enabled_irqs(dev_priv, hpd_ibx); } else { hotplug_irqs = SDE_HOTPLUG_MASK_CPT; enabled_irqs = intel_hpd_enabled_irqs(dev_priv, hpd_cpt); } ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs); ibx_hpd_detection_setup(dev_priv); }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä2841.18%325.00%
Xiong Zhang1217.65%18.33%
Daniel Vetter1217.65%216.67%
Tvrtko A. Ursulin68.82%18.33%
Jesse Barnes57.35%18.33%
Chris Wilson22.94%18.33%
Ben Widawsky11.47%18.33%
Egbert Eich11.47%18.33%
Imre Deak11.47%18.33%
Total68100.00%12100.00%


static void spt_hpd_detection_setup(struct drm_i915_private *dev_priv) { u32 val, hotplug; /* Display WA #1179 WaHardHangonHotPlug: cnp */ if (HAS_PCH_CNP(dev_priv)) { val = I915_READ(SOUTH_CHICKEN1); val &= ~CHASSIS_CLK_REQ_DURATION_MASK; val |= CHASSIS_CLK_REQ_DURATION(0xf); I915_WRITE(SOUTH_CHICKEN1, val); } /* Enable digital hotplug on the PCH */ hotplug = I915_READ(PCH_PORT_HOTPLUG); hotplug |= PORTA_HOTPLUG_ENABLE | PORTB_HOTPLUG_ENABLE | PORTC_HOTPLUG_ENABLE | PORTD_HOTPLUG_ENABLE; I915_WRITE(PCH_PORT_HOTPLUG, hotplug); hotplug = I915_READ(PCH_PORT_HOTPLUG2); hotplug |= PORTE_HOTPLUG_ENABLE; I915_WRITE(PCH_PORT_HOTPLUG2, hotplug); }

Contributors

PersonTokensPropCommitsCommitProp
Rodrigo Vivi3840.00%116.67%
Ville Syrjälä3132.63%233.33%
Xiong Zhang1920.00%116.67%
Imre Deak55.26%116.67%
Tvrtko A. Ursulin22.11%116.67%
Total95100.00%6100.00%


static void spt_hpd_irq_setup(struct drm_i915_private *dev_priv) { u32 hotplug_irqs, enabled_irqs; hotplug_irqs = SDE_HOTPLUG_MASK_SPT; enabled_irqs = intel_hpd_enabled_irqs(dev_priv, hpd_spt); ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs); spt_hpd_detection_setup(dev_priv); }

Contributors

PersonTokensPropCommitsCommitProp
Imre Deak43100.00%1100.00%
Total43100.00%1100.00%


static void ilk_hpd_detection_setup(struct drm_i915_private *dev_priv) { u32 hotplug; /* * Enable digital hotplug on the CPU, and configure the DP short pulse * duration to 2ms (which is the minimum in the Display Port spec) * The pulse duration bits are reserved on HSW+. */ hotplug = I915_READ(DIGITAL_PORT_HOTPLUG_CNTRL); hotplug &= ~DIGITAL_PORTA_PULSE_DURATION_MASK; hotplug |= DIGITAL_PORTA_HOTPLUG_ENABLE | DIGITAL_PORTA_PULSE_DURATION_2ms; I915_WRITE(DIGITAL_PORT_HOTPLUG_CNTRL, hotplug); }

Contributors

PersonTokensPropCommitsCommitProp
Imre Deak40100.00%1100.00%
Total40100.00%1100.00%


static void ilk_hpd_irq_setup(struct drm_i915_private *dev_priv) { u32 hotplug_irqs, enabled_irqs; if (INTEL_GEN(dev_priv) >= 8) { hotplug_irqs = GEN8_PORT_DP_A_HOTPLUG; enabled_irqs = intel_hpd_enabled_irqs(dev_priv, hpd_bdw); bdw_update_port_irq(dev_priv, hotplug_irqs, enabled_irqs); } else if (INTEL_GEN(dev_priv) >= 7) { hotplug_irqs = DE_DP_A_HOTPLUG_IVB; enabled_irqs = intel_hpd_enabled_irqs(dev_priv, hpd_ivb); ilk_update_display_irq(dev_priv, hotplug_irqs, enabled_irqs); } else { hotplug_irqs = DE_DP_A_HOTPLUG; enabled_irqs = intel_hpd_enabled_irqs(dev_priv, hpd_ilk); ilk_update_display_irq(dev_priv, hotplug_irqs, enabled_irqs); } ilk_hpd_detection_setup(dev_priv); ibx_hpd_irq_setup(dev_priv); }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä10689.83%360.00%
Tvrtko A. Ursulin108.47%120.00%
Imre Deak21.69%120.00%
Total118100.00%5100.00%


static void __bxt_hpd_detection_setup(struct drm_i915_private *dev_priv, u32 enabled_irqs) { u32 hotplug; hotplug = I915_READ(PCH_PORT_HOTPLUG); hotplug |= PORTA_HOTPLUG_ENABLE | PORTB_HOTPLUG_ENABLE | PORTC_HOTPLUG_ENABLE; DRM_DEBUG_KMS("Invert bit setting: hp_ctl:%x hp_port:%x\n", hotplug, enabled_irqs); hotplug &= ~BXT_DDI_HPD_INVERT_MASK; /* * For BXT invert bit has to be set based on AOB design * for HPD detection logic, update it based on VBT fields. */ if ((enabled_irqs & BXT_DE_PORT_HP_DDIA) && intel_bios_is_port_hpd_inverted(dev_priv, PORT_A)) hotplug |= BXT_DDIA_HPD_INVERT; if ((enabled_irqs & BXT_DE_PORT_HP_DDIB) && intel_bios_is_port_hpd_inverted(dev_priv, PORT_B)) hotplug |= BXT_DDIB_HPD_INVERT; if ((enabled_irqs & BXT_DE_PORT_HP_DDIC) && intel_bios_is_port_hpd_inverted(dev_priv, PORT_C)) hotplug |= BXT_DDIC_HPD_INVERT; I915_WRITE(PCH_PORT_HOTPLUG, hotplug); }

Contributors

PersonTokensPropCommitsCommitProp
Shubhangi Shrivastava7264.86%120.00%
Shashank Sharma2118.92%120.00%
Ville Syrjälä109.01%120.00%
Imre Deak65.41%120.00%
Tvrtko A. Ursulin21.80%120.00%
Total111100.00%5100.00%


static void bxt_hpd_detection_setup(struct drm_i915_private *dev_priv) { __bxt_hpd_detection_setup(dev_priv, BXT_DE_PORT_HOTPLUG_MASK); }

Contributors

PersonTokensPropCommitsCommitProp
Imre Deak18100.00%1100.00%
Total18100.00%1100.00%


static void bxt_hpd_irq_setup(struct drm_i915_private *dev_priv) { u32 hotplug_irqs, enabled_irqs; enabled_irqs = intel_hpd_enabled_irqs(dev_priv, hpd_bxt); hotplug_irqs = BXT_DE_PORT_HOTPLUG_MASK; bdw_update_port_irq(dev_priv, hotplug_irqs, enabled_irqs); __bxt_hpd_detection_setup(dev_priv, enabled_irqs); }

Contributors

PersonTokensPropCommitsCommitProp
Imre Deak45100.00%1100.00%
Total45100.00%1100.00%


static void ibx_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); u32 mask; if (HAS_PCH_NOP(dev_priv)) return; if (HAS_PCH_IBX(dev_priv)) mask = SDE_GMBUS | SDE_AUX_MASK | SDE_POISON; else if (HAS_PCH_CPT(dev_priv) || HAS_PCH_LPT(dev_priv)) mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT; else mask = SDE_GMBUS_CPT; gen3_assert_iir_is_zero(dev_priv, SDEIIR); I915_WRITE(SDEIMR, ~mask); if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv) || HAS_PCH_LPT(dev_priv)) ibx_hpd_detection_setup(dev_priv); else spt_hpd_detection_setup(dev_priv); }

Contributors

PersonTokensPropCommitsCommitProp
Imre Deak2824.56%29.52%
Paulo Zanoni1916.67%314.29%
Dhinakaran Pandiyan1815.79%14.76%
Ben Gamari1412.28%14.76%
Chris Wilson87.02%523.81%
Daniel Vetter76.14%29.52%
Mika Kuoppala54.39%14.76%
Jesse Barnes43.51%14.76%
Egbert Eich43.51%14.76%
Ville Syrjälä32.63%29.52%
Jani Nikula21.75%14.76%
Tvrtko A. Ursulin21.75%14.76%
Total114100.00%21100.00%


static void gen5_gt_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); u32 pm_irqs, gt_irqs; pm_irqs = gt_irqs = 0; dev_priv->gt_irq_mask = ~0; if (HAS_L3_DPF(dev_priv)) { /* L3 parity interrupt is always unmasked. */ dev_priv->gt_irq_mask = ~GT_PARITY_ERROR(dev_priv); gt_irqs |= GT_PARITY_ERROR(dev_priv); } gt_irqs |= GT_RENDER_USER_INTERRUPT; if (IS_GEN5(dev_priv)) { gt_irqs |= ILK_BSD_USER_INTERRUPT; } else { gt_irqs |= GT_BLT_USER_INTERRUPT | GT_BSD_USER_INTERRUPT; } GEN3_IRQ_INIT(GT, dev_priv->gt_irq_mask, gt_irqs); if (INTEL_GEN(dev_priv) >= 6) { /* * RPS interrupts will get enabled/disabled on demand when RPS * itself is enabled/disabled. */ if (HAS_VEBOX(dev_priv)) { pm_irqs |= PM_VEBOX_USER_INTERRUPT; dev_priv->pm_ier |= PM_VEBOX_USER_INTERRUPT; } dev_priv->pm_imr = 0xffffffff; GEN3_IRQ_INIT(GEN6_PM, dev_priv->pm_imr, pm_irqs); } }

Contributors

PersonTokensPropCommitsCommitProp
Daniel Vetter8958.94%313.64%
Akash Goel117.28%14.55%
Dave Airlie95.96%29.09%
Paulo Zanoni85.30%29.09%
Egbert Eich85.30%29.09%
Tvrtko A. Ursulin63.97%418.18%
Mika Kuoppala53.31%14.55%
Ben Widawsky53.31%29.09%
Jesse Barnes42.65%29.09%
Chris Wilson31.99%14.55%
Ville Syrjälä21.32%14.55%
Imre Deak10.66%14.55%
Total151100.00%22100.00%


static int ironlake_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); u32 display_mask, extra_mask; if (INTEL_GEN(dev_priv) >= 7) { display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB | DE_PCH_EVENT_IVB | DE_AUX_CHANNEL_A_IVB); extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB | DE_PIPEA_VBLANK_IVB | DE_ERR_INT_IVB | DE_DP_A_HOTPLUG_IVB); } else { display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | DE_AUX_CHANNEL_A | DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE | DE_POISON); extra_mask = (DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT | DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN | DE_DP_A_HOTPLUG); } dev_priv->irq_mask = ~display_mask; ibx_irq_pre_postinstall(dev); GEN3_IRQ_INIT(DE, dev_priv->irq_mask, display_mask | extra_mask); gen5_gt_irq_postinstall(dev); ilk_hpd_detection_setup(dev_priv); ibx_irq_postinstall(dev); if (IS_IRONLAKE_M(dev_priv)) { /* Enable PCU event interrupts * * spinlocking not required here for correctness since interrupt * setup is guaranteed to run in single-threaded context. But we * need it to make the assert_spin_locked happy. */ spin_lock_irq(&dev_priv->irq_lock); ilk_enable_display_irq(dev_priv, DE_PCU_EVENT); spin_unlock_irq(&dev_priv->irq_lock); } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Paulo Zanoni7140.34%620.69%
Jesse Barnes3117.61%13.45%
Daniel Vetter2413.64%827.59%
Ben Widawsky158.52%13.45%
Ville Syrjälä84.55%413.79%
Mika Kuoppala52.84%13.45%
Zhenyu Wang52.84%13.45%
Imre Deak52.84%13.45%
Tvrtko A. Ursulin31.70%26.90%
Chris Wilson31.70%13.45%
Keith Packard31.70%13.45%
Jani Nikula21.14%13.45%
Egbert Eich10.57%13.45%
Total176100.00%29100.00%


void valleyview_enable_display_irqs(struct drm_i915_private *dev_priv) { lockdep_assert_held(&dev_priv->irq_lock); if (dev_priv->display_irqs_enabled) return; dev_priv->display_irqs_enabled = true; if (intel_irqs_enabled(dev_priv)) { vlv_display_irq_reset(dev_priv); vlv_display_irq_postinstall(dev_priv); } }

Contributors

PersonTokensPropCommitsCommitProp
Imre Deak3060.00%228.57%
Ville Syrjälä816.00%228.57%
Daniel Vetter714.00%114.29%
Ben Widawsky48.00%114.29%
Chris Wilson12.00%114.29%
Total50100.00%7100.00%


void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv) { lockdep_assert_held(&dev_priv->irq_lock); if (!dev_priv->display_irqs_enabled) return; dev_priv->display_irqs_enabled = false; if (intel_irqs_enabled(dev_priv)) vlv_display_irq_reset(dev_priv); }

Contributors

PersonTokensPropCommitsCommitProp
Imre Deak3579.55%228.57%
Ben Widawsky49.09%114.29%
Daniel Vetter24.55%114.29%
Ville Syrjälä24.55%228.57%
Chris Wilson12.27%114.29%
Total44100.00%7100.00%


static int valleyview_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); gen5_gt_irq_postinstall(dev); spin_lock_irq(&dev_priv->irq_lock); if (dev_priv->display_irqs_enabled) vlv_display_irq_postinstall(dev_priv); spin_unlock_irq(&dev_priv->irq_lock); I915_WRITE(VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE); POSTING_READ(VLV_MASTER_IER); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä4972.06%450.00%
Ben Widawsky1217.65%112.50%
Daniel Vetter34.41%112.50%
Chris Wilson34.41%112.50%
Paulo Zanoni11.47%112.50%
Total68100.00%8100.00%


static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv) { /* These are interrupts we'll toggle with the ring mask register */ uint32_t gt_interrupts[] = { GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT | GT_CONTEXT_SWITCH_INTERRUPT << GEN8_RCS_IRQ_SHIFT | GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT | GT_CONTEXT_SWITCH_INTERRUPT << GEN8_BCS_IRQ_SHIFT, GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT | GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VCS1_IRQ_SHIFT | GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT | GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VCS2_IRQ_SHIFT, 0, GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT | GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VECS_IRQ_SHIFT }; if (HAS_L3_DPF(dev_priv)) gt_interrupts[0] |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT; dev_priv->pm_ier = 0x0; dev_priv->pm_imr = ~dev_priv->pm_ier; GEN8_IRQ_INIT_NDX(GT, 0, ~gt_interrupts[0], gt_interrupts[0]); GEN8_IRQ_INIT_NDX(GT, 1, ~gt_interrupts[1], gt_interrupts[1]); /* * RPS interrupts will get enabled/disabled on demand when RPS itself * is enabled/disabled. Same wil be the case for GuC interrupts. */ GEN8_IRQ_INIT_NDX(GT, 2, dev_priv->pm_imr, dev_priv->pm_ier); GEN8_IRQ_INIT_NDX(GT, 3, ~gt_interrupts[3], gt_interrupts[3]); }

Contributors

PersonTokensPropCommitsCommitProp
Ben Widawsky5735.85%222.22%
Deepak S4628.93%111.11%
Oscar Mateo2012.58%111.11%
Akash Goel159.43%111.11%
Tvrtko A. Ursulin148.81%111.11%
Daniel Vetter42.52%111.11%
Paulo Zanoni21.26%111.11%
Sagar Arun Kamble10.63%111.11%
Total159100.00%9100.00%


static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) { uint32_t de_pipe_masked = GEN8_PIPE_CDCLK_CRC_DONE; uint32_t de_pipe_enables; u32 de_port_masked = GEN8_AUX_CHANNEL_A; u32 de_port_enables; u32 de_misc_masked = GEN8_DE_MISC_GSE; enum pipe pipe; if (INTEL_GEN(dev_priv) >= 9) { de_pipe_masked |= GEN9_DE_PIPE_IRQ_FAULT_ERRORS; de_port_masked |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C | GEN9_AUX_CHANNEL_D; if (IS_GEN9_LP(dev_priv)) de_port_masked |= BXT_DE_PORT_GMBUS; } else { de_pipe_masked |= GEN8_DE_PIPE_IRQ_FAULT_ERRORS; } if (IS_CNL_WITH_PORT_F(dev_priv)) de_port_masked |= CNL_AUX_CHANNEL_F; de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN; de_port_enables = de_port_masked; if (IS_GEN9_LP(dev_priv)) de_port_enables |= BXT_DE_PORT_HOTPLUG_MASK; else if (IS_BROADWELL(dev_priv)) de_port_enables |= GEN8_PORT_DP_A_HOTPLUG; for_each_pipe(dev_priv, pipe) { dev_priv->de_irq_mask[pipe] = ~de_pipe_masked; if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) GEN8_IRQ_INIT_NDX(DE_PIPE, pipe, dev_priv->de_irq_mask[pipe], de_pipe_enables); } GEN3_IRQ_INIT(GEN8_DE_PORT_, ~de_port_masked, de_port_enables); GEN3_IRQ_INIT(GEN8_DE_MISC_, ~de_misc_masked, de_misc_masked); if (IS_GEN9_LP(dev_priv)) bxt_hpd_detection_setup(dev_priv); else if (IS_BROADWELL(dev_priv)) ilk_hpd_detection_setup(dev_priv); }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä5927.57%519.23%
Imre Deak2511.68%27.69%
Ben Widawsky2310.75%13.85%
Jesse Barnes209.35%27.69%
Damien Lespiau198.88%13.85%
Paulo Zanoni157.01%311.54%
Rodrigo Vivi136.07%27.69%
Daniel Vetter104.67%415.38%
Mika Kahola94.21%13.85%
Shashank Sharma94.21%13.85%
Mika Kuoppala52.34%13.85%
Zhenyu Wang41.87%13.85%
Ander Conselvan de Oliveira20.93%13.85%
Dhinakaran Pandiyan10.47%13.85%
Total214100.00%26100.00%


static int gen8_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); if (HAS_PCH_SPLIT(dev_priv)) ibx_irq_pre_postinstall(dev); gen8_gt_irq_postinstall(dev_priv); gen8_de_irq_postinstall(dev_priv); if (HAS_PCH_SPLIT(dev_priv)) ibx_irq_postinstall(dev); I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); POSTING_READ(GEN8_MASTER_IRQ); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä5375.71%240.00%
Shashank Sharma1217.14%120.00%
Chris Wilson34.29%120.00%
Tvrtko A. Ursulin22.86%120.00%
Total70100.00%5100.00%


static void gen11_gt_irq_postinstall(struct drm_i915_private *dev_priv) { const u32 irqs = GT_RENDER_USER_INTERRUPT | GT_CONTEXT_SWITCH_INTERRUPT; BUILD_BUG_ON(irqs & 0xffff0000); /* Enable RCS, BCS, VCS and VECS class interrupts. */ I915_WRITE(GEN11_RENDER_COPY_INTR_ENABLE, irqs << 16 | irqs); I915_WRITE(GEN11_VCS_VECS_INTR_ENABLE, irqs << 16 | irqs); /* Unmask irqs on RCS, BCS, VCS and VECS engines. */ I915_WRITE(GEN11_RCS0_RSVD_INTR_MASK, ~(irqs << 16)); I915_WRITE(GEN11_BCS_RSVD_INTR_MASK, ~(irqs << 16)); I915_WRITE(GEN11_VCS0_VCS1_INTR_MASK, ~(irqs | irqs << 16)); I915_WRITE(GEN11_VCS2_VCS3_INTR_MASK, ~(irqs | irqs << 16)); I915_WRITE(GEN11_VECS0_VECS1_INTR_MASK, ~(irqs | irqs << 16)); dev_priv->pm_imr = 0xffffffff; /* TODO */ }

Contributors

PersonTokensPropCommitsCommitProp
Mika Kuoppala123100.00%1100.00%
Total123100.00%1100.00%


static int gen11_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; gen11_gt_irq_postinstall(dev_priv); gen8_de_irq_postinstall(dev_priv); I915_WRITE(GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); I915_WRITE(GEN11_GFX_MSTR_IRQ, GEN11_MASTER_IRQ); POSTING_READ(GEN11_GFX_MSTR_IRQ); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Mika Kuoppala52100.00%1100.00%
Total52100.00%1100.00%


static int cherryview_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); gen8_gt_irq_postinstall(dev_priv); spin_lock_irq(&dev_priv->irq_lock); if (dev_priv->display_irqs_enabled) vlv_display_irq_postinstall(dev_priv); spin_unlock_irq(&dev_priv->irq_lock); I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); POSTING_READ(GEN8_MASTER_IRQ); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä4769.12%650.00%
Chris Wilson811.76%216.67%
Ben Widawsky57.35%18.33%
Jesse Barnes45.88%18.33%
Keith Packard22.94%18.33%
Daniel Vetter22.94%18.33%
Total68100.00%12100.00%


static void i8xx_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); i9xx_pipestat_irq_reset(dev_priv); I915_WRITE16(HWSTAM, 0xffff); GEN2_IRQ_RESET(); }

Contributors

PersonTokensPropCommitsCommitProp
Chris Wilson1644.44%222.22%
Ville Syrjälä1233.33%444.44%
Mika Kuoppala513.89%111.11%
Jani Nikula25.56%111.11%
Ben Widawsky12.78%111.11%
Total36100.00%9100.00%


static int i8xx_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); u16 enable_mask; I915_WRITE16(EMR, ~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH)); /* Unmask the interrupts that we always want on. */ dev_priv->irq_mask = ~(I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT); enable_mask = I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | I915_USER_INTERRUPT; GEN2_IRQ_INIT(, dev_priv->irq_mask, enable_mask); /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked check happy. */ spin_lock_irq(&dev_priv->irq_lock); i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS); i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS); spin_unlock_irq(&dev_priv->irq_lock); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Wilson4947.57%222.22%
Daniel Vetter3332.04%333.33%
Ville Syrjälä1211.65%111.11%
Mika Kuoppala54.85%111.11%
Imre Deak21.94%111.11%
Jani Nikula21.94%111.11%
Total103100.00%9100.00%


static irqreturn_t i8xx_irq_handler(int irq, void *arg) { struct drm_device *dev = arg; struct drm_i915_private *dev_priv = to_i915(dev); irqreturn_t ret = IRQ_NONE; if (!intel_irqs_enabled(dev_priv)) return IRQ_NONE; /* IRQs are synced during runtime_suspend, we don't require a wakeref */ disable_rpm_wakeref_asserts(dev_priv); do { u32 pipe_stats[I915_MAX_PIPES] = {}; u16 iir; iir = I915_READ16(IIR); if (iir == 0) break; ret = IRQ_HANDLED; /* Call regardless, as some status bits might not be * signalled in iir */ i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); I915_WRITE16(IIR, iir); if (iir & I915_USER_INTERRUPT) notify_ring(dev_priv->engine[RCS]); if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) DRM_DEBUG("Command parser error, iir 0x%08x\n", iir); i8xx_pipestat_irq_handler(dev_priv, iir, pipe_stats); } while (0); enable_rpm_wakeref_asserts(dev_priv); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä6844.74%422.22%
Chris Wilson3623.68%211.11%
Imre Deak2717.76%211.11%
Daniel Vetter106.58%527.78%
Mika Kuoppala53.29%15.56%
Zhenyu Wang21.32%15.56%
Jani Nikula21.32%15.56%
Tvrtko A. Ursulin10.66%15.56%
Damien Lespiau10.66%15.56%
Total152100.00%18100.00%


static void i915_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); if (I915_HAS_HOTPLUG(dev_priv)) { i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0); I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); } i9xx_pipestat_irq_reset(dev_priv); I915_WRITE(HWSTAM, 0xffffffff); GEN3_IRQ_RESET(); }

Contributors

PersonTokensPropCommitsCommitProp
Jesse Barnes2234.38%212.50%
Zhenyu Wang1015.62%16.25%
Ville Syrjälä812.50%531.25%
Mika Kuoppala57.81%16.25%
Keith Packard46.25%16.25%
Egbert Eich46.25%16.25%
Dave Airlie46.25%16.25%
Chris Wilson46.25%212.50%
Jani Nikula23.12%16.25%
Tvrtko A. Ursulin11.56%16.25%
Total64100.00%16100.00%


static int i915_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); u32 enable_mask; I915_WRITE(EMR, ~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH)); /* Unmask the interrupts that we always want on. */ dev_priv->irq_mask = ~(I915_ASLE_INTERRUPT | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT); enable_mask = I915_ASLE_INTERRUPT | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | I915_USER_INTERRUPT; if (I915_HAS_HOTPLUG(dev_priv)) { /* Enable in IER... */ enable_mask |= I915_DISPLAY_PORT_INTERRUPT; /* and unmask in IMR */ dev_priv->irq_mask &= ~I915_DISPLAY_PORT_INTERRUPT; } GEN3_IRQ_INIT(, dev_priv->irq_mask, enable_mask); /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked check happy. */ spin_lock_irq(&dev_priv->irq_lock); i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS); i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS); spin_unlock_irq(&dev_priv->irq_lock); i915_enable_asle_pipestat(dev_priv); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Wilson4231.34%421.05%
Daniel Vetter3727.61%421.05%
Adam Jackson1914.18%15.26%
Jesse Barnes118.21%210.53%
Dave Airlie85.97%210.53%
Ville Syrjälä75.22%210.53%
Mika Kuoppala53.73%15.26%
Imre Deak21.49%15.26%
Jani Nikula21.49%15.26%
Tvrtko A. Ursulin10.75%15.26%
Total134100.00%19100.00%


static irqreturn_t i915_irq_handler(int irq, void *arg) { struct drm_device *dev = arg; struct drm_i915_private *dev_priv = to_i915(dev); irqreturn_t ret = IRQ_NONE; if (!intel_irqs_enabled(dev_priv)) return IRQ_NONE; /* IRQs are synced during runtime_suspend, we don't require a wakeref */ disable_rpm_wakeref_asserts(dev_priv); do { u32 pipe_stats[I915_MAX_PIPES] = {}; u32 hotplug_status = 0; u32 iir; iir = I915_READ(IIR); if (iir == 0) break; ret = IRQ_HANDLED; if (I915_HAS_HOTPLUG(dev_priv) && iir & I915_DISPLAY_PORT_INTERRUPT) hotplug_status = i9xx_hpd_irq_ack(dev_priv); /* Call regardless, as some status bits might not be * signalled in iir */ i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); I915_WRITE(IIR, iir); if (iir & I915_USER_INTERRUPT) notify_ring(dev_priv->engine[RCS]); if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) DRM_DEBUG("Command parser error, iir 0x%08x\n", iir); if (hotplug_status) i9xx_hpd_irq_handler(dev_priv, hotplug_status); i915_pipestat_irq_handler(dev_priv, iir, pipe_stats); } while (0); enable_rpm_wakeref_asserts(dev_priv); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä9350.00%419.05%
Chris Wilson3418.28%419.05%
Imre Deak2211.83%29.52%
Daniel Vetter115.91%314.29%
Jesse Barnes105.38%14.76%
Mika Kuoppala84.30%29.52%
Tvrtko A. Ursulin21.08%14.76%
Keith Packard21.08%14.76%
Jani Nikula21.08%14.76%
Dave Airlie10.54%14.76%
Egbert Eich10.54%14.76%
Total186100.00%21100.00%


static void i965_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0); I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); i9xx_pipestat_irq_reset(dev_priv); I915_WRITE(HWSTAM, 0xffffffff); GEN3_IRQ_RESET(); }

Contributors

PersonTokensPropCommitsCommitProp
Chris Wilson3665.45%327.27%
Ville Syrjälä712.73%436.36%
Mika Kuoppala59.09%19.09%
Egbert Eich47.27%19.09%
Jani Nikula23.64%19.09%
Dave Airlie11.82%19.09%
Total55100.00%11100.00%


static int i965_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); u32 enable_mask; u32 error_mask; /* * Enable some error detection, note the instruction error mask * bit is reserved, so we leave it masked. */ if (IS_G4X(dev_priv)) { error_mask = ~(GM45_ERROR_PAGE_TABLE | GM45_ERROR_MEM_PRIV | GM45_ERROR_CP_PRIV | I915_ERROR_MEMORY_REFRESH); } else { error_mask = ~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH); } I915_WRITE(EMR, error_mask); /* Unmask the interrupts that we always want on. */ dev_priv->irq_mask = ~(I915_ASLE_INTERRUPT | I915_DISPLAY_PORT_INTERRUPT | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); enable_mask = I915_ASLE_INTERRUPT | I915_DISPLAY_PORT_INTERRUPT | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT | I915_USER_INTERRUPT; if (IS_G4X(dev_priv)) enable_mask |= I915_BSD_USER_INTERRUPT; GEN3_IRQ_INIT(, dev_priv->irq_mask, enable_mask); /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked check happy. */ spin_lock_irq(&dev_priv->irq_lock); i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS); i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS); spin_unlock_irq(&dev_priv->irq_lock); i915_enable_asle_pipestat(dev_priv); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä6135.26%211.11%
Chris Wilson5129.48%527.78%
Daniel Vetter4827.75%633.33%
Mika Kuoppala52.89%15.56%
Imre Deak31.73%15.56%
Jani Nikula31.73%211.11%
Tvrtko A. Ursulin21.16%15.56%
Total173100.00%18100.00%


static void i915_hpd_irq_setup(struct drm_i915_private *dev_priv) { u32 hotplug_en; lockdep_assert_held(&dev_priv->irq_lock); /* Note HDMI and DP share hotplug bits */ /* enable bits are the same for all generations */ hotplug_en = intel_hpd_enabled_irqs(dev_priv, hpd_mask_i915); /* Programming the CRT detection parameters tends to generate a spurious hotplug event about three seconds later. So just do it once. */ if (IS_G4X(dev_priv)) hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64; hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; /* Ignore TV since it's buggy */ i915_hotplug_interrupt_update_locked(dev_priv, HOTPLUG_INT_EN_MASK | CRT_HOTPLUG_VOLTAGE_COMPARE_MASK | CRT_HOTPLUG_ACTIVATION_PERIOD_64, hotplug_en); }

Contributors

PersonTokensPropCommitsCommitProp
Chris Wilson2438.10%321.43%
Daniel Vetter1320.63%214.29%
Egbert Eich1117.46%321.43%
Ville Syrjälä57.94%214.29%
Tvrtko A. Ursulin46.35%17.14%
Mika Kuoppala34.76%17.14%
Jani Nikula34.76%214.29%
Total63100.00%14100.00%


static irqreturn_t i965_irq_handler(int irq, void *arg) { struct drm_device *dev = arg; struct drm_i915_private *dev_priv = to_i915(dev); irqreturn_t ret = IRQ_NONE; if (!intel_irqs_enabled(dev_priv)) return IRQ_NONE; /* IRQs are synced during runtime_suspend, we don't require a wakeref */ disable_rpm_wakeref_asserts(dev_priv); do { u32 pipe_stats[I915_MAX_PIPES] = {}; u32 hotplug_status = 0; u32 iir; iir = I915_READ(IIR); if (iir == 0) break; ret = IRQ_HANDLED; if (iir & I915_DISPLAY_PORT_INTERRUPT) hotplug_status = i9xx_hpd_irq_ack(dev_priv); /* Call regardless, as some status bits might not be * signalled in iir */ i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); I915_WRITE(IIR, iir); if (iir & I915_USER_INTERRUPT) notify_ring(dev_priv->engine[RCS]); if (iir & I915_BSD_USER_INTERRUPT) notify_ring(dev_priv->engine[VCS]); if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) DRM_DEBUG("Command parser error, iir 0x%08x\n", iir); if (hotplug_status) i9xx_hpd_irq_handler(dev_priv, hotplug_status); i965_pipestat_irq_handler(dev_priv, iir, pipe_stats); } while (0); enable_rpm_wakeref_asserts(dev_priv); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Chris Wilson8342.13%315.79%
Ville Syrjälä6834.52%526.32%
Imre Deak2211.17%210.53%
Daniel Vetter126.09%421.05%
Mika Kuoppala73.55%210.53%
Tvrtko A. Ursulin31.52%210.53%
Jani Nikula21.02%15.26%
Total197100.00%19100.00%

/** * intel_irq_init - initializes irq support * @dev_priv: i915 device instance * * This function initializes all the irq support including work items, timers * and all the vtables. It does not setup the interrupt itself though. */
void intel_irq_init(struct drm_i915_private *dev_priv) { struct drm_device *dev = &dev_priv->drm; struct intel_rps *rps = &dev_priv->gt_pm.rps; int i; intel_hpd_init_work(dev_priv); INIT_WORK(&rps->work, gen6_pm_rps_work); INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work); for (i = 0; i < MAX_L3_SLICES; ++i) dev_priv->l3_parity.remap_info[i] = NULL; if (HAS_GUC_SCHED(dev_priv)) dev_priv->pm_guc_events = GEN9_GUC_TO_HOST_INT_EVENT; /* Let's track the enabled rps events */ if (IS_VALLEYVIEW(dev_priv)) /* WaGsvRC0ResidencyMethod:vlv */ dev_priv->pm_rps_events = GEN6_PM_RP_UP_EI_EXPIRED; else dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS; rps->pm_intrmsk_mbz = 0; /* * SNB,IVB,HSW can while VLV,CHV may hard hang on looping batchbuffer * if GEN6_PM_UP_EI_EXPIRED is masked. * * TODO: verify if this can be reproduced on VLV,CHV. */ if (INTEL_GEN(dev_priv) <= 7) rps->pm_intrmsk_mbz |= GEN6_PM_RP_UP_EI_EXPIRED; if (INTEL_GEN(dev_priv) >= 8) rps->pm_intrmsk_mbz |= GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC; if (IS_GEN2(dev_priv)) { /* Gen2 doesn't have a hardware frame counter */ dev->max_vblank_count = 0; } else if (IS_G4X(dev_priv) || INTEL_GEN(dev_priv) >= 5) { dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */ dev->driver->get_vblank_counter = g4x_get_vblank_counter; } else { dev->driver->get_vblank_counter = i915_get_vblank_counter; dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ } /* * Opt out of the vblank disable timer on everything except gen2. * Gen2 doesn't have a hardware frame counter and so depends on * vblank interrupts to produce sane vblank seuquence numbers. */ if (!IS_GEN2(dev_priv)) dev->vblank_disable_immediate = true; /* Most platforms treat the display irq block as an always-on * power domain. vlv/chv can disable it at runtime and need * special care to avoid writing any of the display block registers * outside of the power domain. We defer setting up the display irqs * in this case to the runtime pm. */ dev_priv->display_irqs_enabled = true; if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) dev_priv->display_irqs_enabled = false; dev_priv->hotplug.hpd_storm_threshold = HPD_STORM_DEFAULT_THRESHOLD; dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos; dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; if (IS_CHERRYVIEW(dev_priv)) { dev->driver->irq_handler = cherryview_irq_handler; dev->driver->irq_preinstall = cherryview_irq_reset; dev->driver->irq_postinstall = cherryview_irq_postinstall; dev->driver->irq_uninstall = cherryview_irq_reset; dev->driver->enable_vblank = i965_enable_vblank; dev->driver->disable_vblank = i965_disable_vblank; dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; } else if (IS_VALLEYVIEW(dev_priv)) { dev->driver->irq_handler = valleyview_irq_handler; dev->driver->irq_preinstall = valleyview_irq_reset; dev->driver->irq_postinstall = valleyview_irq_postinstall; dev->driver->irq_uninstall = valleyview_irq_reset; dev->driver->enable_vblank = i965_enable_vblank; dev->driver->disable_vblank = i965_disable_vblank; dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; } else if (INTEL_GEN(dev_priv) >= 11) { dev->driver->irq_handler = gen11_irq_handler; dev->driver->irq_preinstall = gen11_irq_reset; dev->driver->irq_postinstall = gen11_irq_postinstall; dev->driver->irq_uninstall = gen11_irq_reset; dev->driver->enable_vblank = gen8_enable_vblank; dev->driver->disable_vblank = gen8_disable_vblank; dev_priv->display.hpd_irq_setup = spt_hpd_irq_setup; } else if (INTEL_GEN(dev_priv) >= 8) { dev->driver->irq_handler = gen8_irq_handler; dev->driver->irq_preinstall = gen8_irq_reset; dev->driver->irq_postinstall = gen8_irq_postinstall; dev->driver->irq_uninstall = gen8_irq_reset; dev->driver->enable_vblank = gen8_enable_vblank; dev->driver->disable_vblank = gen8_disable_vblank; if (IS_GEN9_LP(dev_priv)) dev_priv->display.hpd_irq_setup = bxt_hpd_irq_setup; else if (HAS_PCH_SPT(dev_priv) || HAS_PCH_KBP(dev_priv) || HAS_PCH_CNP(dev_priv)) dev_priv->display.hpd_irq_setup = spt_hpd_irq_setup; else dev_priv->display.hpd_irq_setup = ilk_hpd_irq_setup; } else if (HAS_PCH_SPLIT(dev_priv)) { dev->driver->irq_handler = ironlake_irq_handler; dev->driver->irq_preinstall = ironlake_irq_reset; dev->driver->irq_postinstall = ironlake_irq_postinstall; dev->driver->irq_uninstall = ironlake_irq_reset; dev->driver->enable_vblank = ironlake_enable_vblank; dev->driver->disable_vblank = ironlake_disable_vblank; dev_priv->display.hpd_irq_setup = ilk_hpd_irq_setup; } else { if (IS_GEN2(dev_priv)) { dev->driver->irq_preinstall = i8xx_irq_reset; dev->driver->irq_postinstall = i8xx_irq_postinstall; dev->driver->irq_handler = i8xx_irq_handler; dev->driver->irq_uninstall = i8xx_irq_reset; dev->driver->enable_vblank = i8xx_enable_vblank; dev->driver->disable_vblank = i8xx_disable_vblank; } else if (IS_GEN3(dev_priv)) { dev->driver->irq_preinstall = i915_irq_reset; dev->driver->irq_postinstall = i915_irq_postinstall; dev->driver->irq_uninstall = i915_irq_reset; dev->driver->irq_handler = i915_irq_handler; dev->driver->enable_vblank = i8xx_enable_vblank; dev->driver->disable_vblank = i8xx_disable_vblank; } else { dev->driver->irq_preinstall = i965_irq_reset; dev->driver->irq_postinstall = i965_irq_postinstall; dev->driver->irq_uninstall = i965_irq_reset; dev->driver->irq_handler = i965_irq_handler; dev->driver->enable_vblank = i965_enable_vblank; dev->driver->disable_vblank = i965_disable_vblank; } if (I915_HAS_HOTPLUG(dev_priv)) dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; } }

Contributors

PersonTokensPropCommitsCommitProp
Jesse Barnes18221.49%23.64%
Chris Wilson17020.07%712.73%
Ville Syrjälä15518.30%1120.00%
Mika Kuoppala738.62%35.45%
Ben Widawsky617.20%11.82%
Sagar Arun Kamble586.85%47.27%
Daniel Vetter465.43%712.73%
Joonas Lahtinen273.19%11.82%
Deepak S202.36%23.64%
Shashank Sharma131.53%11.82%
Rodrigo Vivi101.18%35.45%
Stephen Chandler Paul80.94%11.82%
Tvrtko A. Ursulin70.83%47.27%
Dave Airlie50.59%11.82%
Dhinakaran Pandiyan40.47%11.82%
Damien Lespiau20.24%11.82%
Eugeni Dodonov20.24%11.82%
Egbert Eich20.24%23.64%
Ander Conselvan de Oliveira10.12%11.82%
Jani Nikula10.12%11.82%
Total847100.00%55100.00%

/** * intel_irq_fini - deinitializes IRQ support * @i915: i915 device instance * * This function deinitializes all the IRQ support. */
void intel_irq_fini(struct drm_i915_private *i915) { int i; for (i = 0; i < MAX_L3_SLICES; ++i) kfree(i915->l3_parity.remap_info[i]); }

Contributors

PersonTokensPropCommitsCommitProp
Joonas Lahtinen38100.00%1100.00%
Total38100.00%1100.00%

/** * intel_irq_install - enables the hardware interrupt * @dev_priv: i915 device instance * * This function enables the hardware interrupt handling, but leaves the hotplug * handling still disabled. It is called after intel_irq_init(). * * In the driver load and resume code we need working interrupts in a few places * but don't want to deal with the hassle of concurrent probe and hotplug * workers. Hence the split into this two-stage approach. */
int intel_irq_install(struct drm_i915_private *dev_priv) { /* * We enable some interrupt sources in our postinstall hooks, so mark * interrupts as enabled _before_ actually enabling them to avoid * special cases in our ordering checks. */ dev_priv->runtime_pm.irqs_enabled = true; return drm_irq_install(&dev_priv->drm, dev_priv->drm.pdev->irq); }

Contributors

PersonTokensPropCommitsCommitProp
Daniel Vetter3186.11%133.33%
Chris Wilson411.11%133.33%
Sagar Arun Kamble12.78%133.33%
Total36100.00%3100.00%

/** * intel_irq_uninstall - finilizes all irq handling * @dev_priv: i915 device instance * * This stops interrupt and hotplug handling and unregisters and frees all * resources acquired in the init functions. */
void intel_irq_uninstall(struct drm_i915_private *dev_priv) { drm_irq_uninstall(&dev_priv->drm); intel_hpd_cancel_work(dev_priv); dev_priv->runtime_pm.irqs_enabled = false; }

Contributors

PersonTokensPropCommitsCommitProp
Daniel Vetter2890.32%133.33%
Chris Wilson26.45%133.33%
Sagar Arun Kamble13.23%133.33%
Total31100.00%3100.00%

/** * intel_runtime_pm_disable_interrupts - runtime interrupt disabling * @dev_priv: i915 device instance * * This function is used to disable interrupts at runtime, both in the runtime * pm and the system suspend/resume code. */
void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv) { dev_priv->drm.driver->irq_uninstall(&dev_priv->drm); dev_priv->runtime_pm.irqs_enabled = false; synchronize_irq(dev_priv->drm.irq); }

Contributors

PersonTokensPropCommitsCommitProp
Paulo Zanoni2151.22%228.57%
Imre Deak717.07%114.29%
Daniel Vetter614.63%228.57%
Chris Wilson614.63%114.29%
Sagar Arun Kamble12.44%114.29%
Total41100.00%7100.00%

/** * intel_runtime_pm_enable_interrupts - runtime interrupt enabling * @dev_priv: i915 device instance * * This function is used to enable interrupts at runtime, both in the runtime * pm and the system suspend/resume code. */
void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv) { dev_priv->runtime_pm.irqs_enabled = true; dev_priv->drm.driver->irq_preinstall(&dev_priv->drm); dev_priv->drm.driver->irq_postinstall(&dev_priv->drm); }

Contributors

PersonTokensPropCommitsCommitProp
Paulo Zanoni2452.17%233.33%
Daniel Vetter1328.26%233.33%
Chris Wilson817.39%116.67%
Sagar Arun Kamble12.17%116.67%
Total46100.00%6100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Ville Syrjälä415123.19%10419.26%
Chris Wilson195010.89%8115.00%
Mika Kuoppala14358.02%112.04%
Daniel Vetter12857.18%8115.00%
Imre Deak11336.33%264.81%
Jani Nikula10896.08%152.78%
Jesse Barnes10355.78%244.44%
Paulo Zanoni9175.12%325.93%
Ben Widawsky8274.62%142.59%
Sagar Arun Kamble4792.68%101.85%
Tvrtko A. Ursulin4372.44%213.89%
Egbert Eich4252.37%101.85%
Uma Shankar1971.10%10.19%
Dave Airlie1891.06%61.11%
Michel Thierry1801.01%20.37%
Akash Goel1730.97%20.37%
Adam Jackson1660.93%20.37%
Mario Kleiner1600.89%20.37%
Oscar Mateo1560.87%71.30%
Shashank Sharma1500.84%40.74%
Tomeu Vizoso1380.77%20.37%
Damien Lespiau1370.77%132.41%
Rodrigo Vivi1180.66%91.67%
Deepak S840.47%30.56%
Shuang He750.42%10.19%
Zhenyu Wang730.41%30.56%
Shubhangi Shrivastava720.40%10.19%
Joonas Lahtinen710.40%10.19%
Xiong Zhang650.36%10.19%
Eric Anholt640.36%30.56%
Keith Packard640.36%71.30%
Dhinakaran Pandiyan590.33%30.56%
Zou Nan hai440.25%50.93%
Nick Hoath400.22%10.19%
Yakui Zhao380.21%30.56%
Jerome Anand320.18%10.19%
Simon Farnsworth280.16%10.19%
Ben Gamari250.14%10.19%
Thomas Daniel230.13%10.19%
Mika Kahola190.11%20.37%
Michel Dänzer150.08%30.56%
Thierry Reding110.06%10.19%
Stephen Chandler Paul80.04%10.19%
Sonika Jindal80.04%20.37%
Joe Perches70.04%10.19%
Maarten Lankhorst70.04%20.37%
Wayne Boyer60.03%10.19%
Michal Wajdeczko60.03%10.19%
Ander Conselvan de Oliveira60.03%20.37%
Kristian Högsberg40.02%10.19%
Arun Siluvery40.02%10.19%
Li Peng40.02%10.19%
Tejun Heo30.02%10.19%
Arkadiusz Hiler20.01%10.19%
Matthias Kaehlcke20.01%10.19%
David Howells20.01%10.19%
Eugeni Dodonov20.01%10.19%
Dave Gordon10.01%10.19%
Total17901100.00%540100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.