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