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, 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(>->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, 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, 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(>->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 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, mask); 91 } 92 93 void gen6_gt_pm_enable_irq(struct intel_gt *gt, u32 enable_mask) 94 { 95 lockdep_assert_held(>->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 102 void gen6_gt_pm_disable_irq(struct intel_gt *gt, u32 disable_mask) 103 { 104 lockdep_assert_held(>->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