| 1 | // SPDX-License-Identifier: MIT | 
|---|
| 2 | /* | 
|---|
| 3 | * Copyright © 2019 Intel Corporation | 
|---|
| 4 | */ | 
|---|
| 5 |  | 
|---|
| 6 | #include "i915_drv.h" | 
|---|
| 7 | #include "i915_reg.h" | 
|---|
| 8 | #include "intel_gt.h" | 
|---|
| 9 | #include "intel_gt_irq.h" | 
|---|
| 10 | #include "intel_gt_pm_irq.h" | 
|---|
| 11 | #include "intel_gt_regs.h" | 
|---|
| 12 |  | 
|---|
| 13 | static 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 (GRAPHICS_VER(i915) >= 11) { | 
|---|
| 21 | reg = GEN11_GPM_WGBOXPERF_INTR_MASK; | 
|---|
| 22 | mask <<= 16; /* pm is in upper half */ | 
|---|
| 23 | } else if (GRAPHICS_VER(i915) >= 8) { | 
|---|
| 24 | reg = GEN8_GT_IMR(2); | 
|---|
| 25 | } else { | 
|---|
| 26 | reg = GEN6_PMIMR; | 
|---|
| 27 | } | 
|---|
| 28 |  | 
|---|
| 29 | intel_uncore_write(uncore, reg, val: mask); | 
|---|
| 30 | } | 
|---|
| 31 |  | 
|---|
| 32 | static 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 |  | 
|---|
| 52 | void gen6_gt_pm_unmask_irq(struct intel_gt *gt, u32 mask) | 
|---|
| 53 | { | 
|---|
| 54 | gen6_gt_pm_update_irq(gt, interrupt_mask: mask, enabled_irq_mask: mask); | 
|---|
| 55 | } | 
|---|
| 56 |  | 
|---|
| 57 | void gen6_gt_pm_mask_irq(struct intel_gt *gt, u32 mask) | 
|---|
| 58 | { | 
|---|
| 59 | gen6_gt_pm_update_irq(gt, interrupt_mask: mask, enabled_irq_mask: 0); | 
|---|
| 60 | } | 
|---|
| 61 |  | 
|---|
| 62 | void 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 = GRAPHICS_VER(gt->i915) >= 8 ? GEN8_GT_IIR(2) : GEN6_PMIIR; | 
|---|
| 66 |  | 
|---|
| 67 | lockdep_assert_held(gt->irq_lock); | 
|---|
| 68 |  | 
|---|
| 69 | intel_uncore_write(uncore, reg, val: reset_mask); | 
|---|
| 70 | intel_uncore_write(uncore, reg, val: reset_mask); | 
|---|
| 71 | intel_uncore_posting_read(uncore, reg); | 
|---|
| 72 | } | 
|---|
| 73 |  | 
|---|
| 74 | static 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 (GRAPHICS_VER(i915) >= 11) { | 
|---|
| 82 | reg = GEN11_GPM_WGBOXPERF_INTR_ENABLE; | 
|---|
| 83 | mask <<= 16; /* pm is in upper half */ | 
|---|
| 84 | } else if (GRAPHICS_VER(i915) >= 8) { | 
|---|
| 85 | reg = GEN8_GT_IER(2); | 
|---|
| 86 | } else { | 
|---|
| 87 | reg = GEN6_PMIER; | 
|---|
| 88 | } | 
|---|
| 89 |  | 
|---|
| 90 | intel_uncore_write(uncore, reg, val: mask); | 
|---|
| 91 | } | 
|---|
| 92 |  | 
|---|
| 93 | void 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, mask: enable_mask); | 
|---|
| 100 | } | 
|---|
| 101 |  | 
|---|
| 102 | void 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, mask: disable_mask); | 
|---|
| 108 | write_pm_ier(gt); | 
|---|
| 109 | } | 
|---|
| 110 |  | 
|---|