-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
drm/i915: Extract GT powermanagement interrupt handling
i915_irq.c is large. It serves as the central dispatch and handler for all of our device interrupts. Pull out the GT pm interrupt handling (leaving the central dispatch) so that we can encapsulate the logic a little better. Based on a patch by Chris Wilson. Signed-off-by: Andi Shyti <andi.shyti@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Link: https://patchwork.freedesktop.org/patch/msgid/20190811142801.2460-1-chris@chris-wilson.co.uk
- Loading branch information
Andi Shyti
authored and
Chris Wilson
committed
Aug 12, 2019
1 parent
4ecd20c
commit d762043
Showing
8 changed files
with
191 additions
and
174 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/* | ||
* SPDX-License-Identifier: MIT | ||
* | ||
* Copyright © 2019 Intel Corporation | ||
*/ | ||
|
||
#include "i915_drv.h" | ||
#include "i915_reg.h" | ||
#include "intel_gt.h" | ||
#include "intel_gt_pm_irq.h" | ||
|
||
static void write_pm_imr(struct intel_gt *gt) | ||
{ | ||
struct drm_i915_private *i915 = gt->i915; | ||
struct intel_uncore *uncore = gt->uncore; | ||
u32 mask = gt->pm_imr; | ||
i915_reg_t reg; | ||
|
||
if (INTEL_GEN(i915) >= 11) { | ||
reg = GEN11_GPM_WGBOXPERF_INTR_MASK; | ||
mask <<= 16; /* pm is in upper half */ | ||
} else if (INTEL_GEN(i915) >= 8) { | ||
reg = GEN8_GT_IMR(2); | ||
} else { | ||
reg = GEN6_PMIMR; | ||
} | ||
|
||
intel_uncore_write(uncore, reg, mask); | ||
} | ||
|
||
static void gen6_gt_pm_update_irq(struct intel_gt *gt, | ||
u32 interrupt_mask, | ||
u32 enabled_irq_mask) | ||
{ | ||
u32 new_val; | ||
|
||
WARN_ON(enabled_irq_mask & ~interrupt_mask); | ||
|
||
lockdep_assert_held(>->irq_lock); | ||
|
||
new_val = gt->pm_imr; | ||
new_val &= ~interrupt_mask; | ||
new_val |= ~enabled_irq_mask & interrupt_mask; | ||
|
||
if (new_val != gt->pm_imr) { | ||
gt->pm_imr = new_val; | ||
write_pm_imr(gt); | ||
} | ||
} | ||
|
||
void gen6_gt_pm_unmask_irq(struct intel_gt *gt, u32 mask) | ||
{ | ||
gen6_gt_pm_update_irq(gt, mask, mask); | ||
} | ||
|
||
void gen6_gt_pm_mask_irq(struct intel_gt *gt, u32 mask) | ||
{ | ||
gen6_gt_pm_update_irq(gt, mask, 0); | ||
} | ||
|
||
void gen6_gt_pm_reset_iir(struct intel_gt *gt, u32 reset_mask) | ||
{ | ||
struct intel_uncore *uncore = gt->uncore; | ||
i915_reg_t reg = INTEL_GEN(gt->i915) >= 8 ? GEN8_GT_IIR(2) : GEN6_PMIIR; | ||
|
||
lockdep_assert_held(>->irq_lock); | ||
|
||
intel_uncore_write(uncore, reg, reset_mask); | ||
intel_uncore_write(uncore, reg, reset_mask); | ||
intel_uncore_posting_read(uncore, reg); | ||
} | ||
|
||
static void write_pm_ier(struct intel_gt *gt) | ||
{ | ||
struct drm_i915_private *i915 = gt->i915; | ||
struct intel_uncore *uncore = gt->uncore; | ||
u32 mask = gt->pm_ier; | ||
i915_reg_t reg; | ||
|
||
if (INTEL_GEN(i915) >= 11) { | ||
reg = GEN11_GPM_WGBOXPERF_INTR_ENABLE; | ||
mask <<= 16; /* pm is in upper half */ | ||
} else if (INTEL_GEN(i915) >= 8) { | ||
reg = GEN8_GT_IER(2); | ||
} else { | ||
reg = GEN6_PMIER; | ||
} | ||
|
||
intel_uncore_write(uncore, reg, mask); | ||
} | ||
|
||
void gen6_gt_pm_enable_irq(struct intel_gt *gt, u32 enable_mask) | ||
{ | ||
lockdep_assert_held(>->irq_lock); | ||
|
||
gt->pm_ier |= enable_mask; | ||
write_pm_ier(gt); | ||
gen6_gt_pm_unmask_irq(gt, enable_mask); | ||
} | ||
|
||
void gen6_gt_pm_disable_irq(struct intel_gt *gt, u32 disable_mask) | ||
{ | ||
lockdep_assert_held(>->irq_lock); | ||
|
||
gt->pm_ier &= ~disable_mask; | ||
gen6_gt_pm_mask_irq(gt, disable_mask); | ||
write_pm_ier(gt); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* | ||
* SPDX-License-Identifier: MIT | ||
* | ||
* Copyright © 2019 Intel Corporation | ||
*/ | ||
|
||
#ifndef INTEL_GT_PM_IRQ_H | ||
#define INTEL_GT_PM_IRQ_H | ||
|
||
#include <linux/types.h> | ||
|
||
struct intel_gt; | ||
|
||
void gen6_gt_pm_unmask_irq(struct intel_gt *gt, u32 mask); | ||
void gen6_gt_pm_mask_irq(struct intel_gt *gt, u32 mask); | ||
|
||
void gen6_gt_pm_enable_irq(struct intel_gt *gt, u32 enable_mask); | ||
void gen6_gt_pm_disable_irq(struct intel_gt *gt, u32 disable_mask); | ||
|
||
void gen6_gt_pm_reset_iir(struct intel_gt *gt, u32 reset_mask); | ||
|
||
#endif /* INTEL_GT_PM_IRQ_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.