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 | |