linux/drivers/gpu/drm/i915/gt/intel_gt_pm_irq.c
<<
>>
Prefs
   1/*
   2 * SPDX-License-Identifier: MIT
   3 *
   4 * Copyright © 2019 Intel Corporation
   5 */
   6
   7#include "i915_drv.h"
   8#include "i915_reg.h"
   9#include "intel_gt.h"
  10#include "intel_gt_irq.h"
  11#include "intel_gt_pm_irq.h"
  12
  13static void write_pm_imr(struct intel_gt *gt)
  14{
  15        struct drm_i915_private *i915 = gt->i915;
  16        struct intel_uncore *uncore = gt->uncore;
  17        u32 mask = gt->pm_imr;
  18        i915_reg_t reg;
  19
  20        if (INTEL_GEN(i915) >= 11) {
  21                reg = GEN11_GPM_WGBOXPERF_INTR_MASK;
  22                mask <<= 16; /* pm is in upper half */
  23        } else if (INTEL_GEN(i915) >= 8) {
  24                reg = GEN8_GT_IMR(2);
  25        } else {
  26                reg = GEN6_PMIMR;
  27        }
  28
  29        intel_uncore_write(uncore, reg, mask);
  30}
  31
  32static void gen6_gt_pm_update_irq(struct intel_gt *gt,
  33                                  u32 interrupt_mask,
  34                                  u32 enabled_irq_mask)
  35{
  36        u32 new_val;
  37
  38        WARN_ON(enabled_irq_mask & ~interrupt_mask);
  39
  40        lockdep_assert_held(&gt->irq_lock);
  41
  42        new_val = gt->pm_imr;
  43        new_val &= ~interrupt_mask;
  44        new_val |= ~enabled_irq_mask & interrupt_mask;
  45
  46        if (new_val != gt->pm_imr) {
  47                gt->pm_imr = new_val;
  48                write_pm_imr(gt);
  49        }
  50}
  51
  52void gen6_gt_pm_unmask_irq(struct intel_gt *gt, u32 mask)
  53{
  54        gen6_gt_pm_update_irq(gt, mask, mask);
  55}
  56
  57void gen6_gt_pm_mask_irq(struct intel_gt *gt, u32 mask)
  58{
  59        gen6_gt_pm_update_irq(gt, mask, 0);
  60}
  61
  62void gen6_gt_pm_reset_iir(struct intel_gt *gt, u32 reset_mask)
  63{
  64        struct intel_uncore *uncore = gt->uncore;
  65        i915_reg_t reg = INTEL_GEN(gt->i915) >= 8 ? GEN8_GT_IIR(2) : GEN6_PMIIR;
  66
  67        lockdep_assert_held(&gt->irq_lock);
  68
  69        intel_uncore_write(uncore, reg, reset_mask);
  70        intel_uncore_write(uncore, reg, reset_mask);
  71        intel_uncore_posting_read(uncore, reg);
  72}
  73
  74static void write_pm_ier(struct intel_gt *gt)
  75{
  76        struct drm_i915_private *i915 = gt->i915;
  77        struct intel_uncore *uncore = gt->uncore;
  78        u32 mask = gt->pm_ier;
  79        i915_reg_t reg;
  80
  81        if (INTEL_GEN(i915) >= 11) {
  82                reg = GEN11_GPM_WGBOXPERF_INTR_ENABLE;
  83                mask <<= 16; /* pm is in upper half */
  84        } else if (INTEL_GEN(i915) >= 8) {
  85                reg = GEN8_GT_IER(2);
  86        } else {
  87                reg = GEN6_PMIER;
  88        }
  89
  90        intel_uncore_write(uncore, reg, mask);
  91}
  92
  93void gen6_gt_pm_enable_irq(struct intel_gt *gt, u32 enable_mask)
  94{
  95        lockdep_assert_held(&gt->irq_lock);
  96
  97        gt->pm_ier |= enable_mask;
  98        write_pm_ier(gt);
  99        gen6_gt_pm_unmask_irq(gt, enable_mask);
 100}
 101
 102void gen6_gt_pm_disable_irq(struct intel_gt *gt, u32 disable_mask)
 103{
 104        lockdep_assert_held(&gt->irq_lock);
 105
 106        gt->pm_ier &= ~disable_mask;
 107        gen6_gt_pm_mask_irq(gt, disable_mask);
 108        write_pm_ier(gt);
 109}
 110