Skip to content

Commit a187f13

Browse files
committed
drm/i915/guc: handle interrupts from media GuC
The render and media GuCs share the same interrupt enable register, so we can no longer disable interrupts when we disable communication for one of the GuCs as this would impact the other GuC. Instead, we keep the interrupts always enabled in HW and use a variable in the GuC structure to determine if we want to service the received interrupts or not. v2: use MTL_ prefix for reg definition (Matt) Signed-off-by: Daniele Ceraolo Spurio <[email protected]> Cc: Matt Roper <[email protected]> Cc: John Harrison <[email protected]> Cc: Alan Previn <[email protected]> Reviewed-by: Matt Roper <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent b910f71 commit a187f13

File tree

5 files changed

+45
-20
lines changed

5 files changed

+45
-20
lines changed

drivers/gpu/drm/i915/gt/intel_gt_irq.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717

1818
static void guc_irq_handler(struct intel_guc *guc, u16 iir)
1919
{
20+
if (unlikely(!guc->interrupts.enabled))
21+
return;
22+
2023
if (iir & GUC_INTR_GUC2HOST)
2124
intel_guc_to_host_event_handler(guc);
2225
}
@@ -251,6 +254,7 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
251254
{
252255
struct intel_uncore *uncore = gt->uncore;
253256
u32 irqs = GT_RENDER_USER_INTERRUPT;
257+
u32 guc_mask = intel_uc_wants_guc(&gt->uc) ? GUC_INTR_GUC2HOST : 0;
254258
u32 gsc_mask = 0;
255259
u32 dmask;
256260
u32 smask;
@@ -305,6 +309,19 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
305309
if (gsc_mask)
306310
intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_MASK, ~gsc_mask);
307311

312+
if (guc_mask) {
313+
/* the enable bit is common for both GTs but the masks are separate */
314+
u32 mask = gt->type == GT_MEDIA ?
315+
REG_FIELD_PREP(ENGINE0_MASK, guc_mask) :
316+
REG_FIELD_PREP(ENGINE1_MASK, guc_mask);
317+
318+
intel_uncore_write(uncore, GEN11_GUC_SG_INTR_ENABLE,
319+
REG_FIELD_PREP(ENGINE1_MASK, guc_mask));
320+
321+
/* we might not be the first GT to write this reg */
322+
intel_uncore_rmw(uncore, MTL_GUC_MGUC_INTR_MASK, mask, 0);
323+
}
324+
308325
/*
309326
* RPS interrupts will get enabled/disabled on demand when RPS itself
310327
* is enabled/disabled.
@@ -313,10 +330,6 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
313330
gt->pm_imr = ~gt->pm_ier;
314331
intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_ENABLE, 0);
315332
intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_MASK, ~0);
316-
317-
/* Same thing for GuC interrupts */
318-
intel_uncore_write(uncore, GEN11_GUC_SG_INTR_ENABLE, 0);
319-
intel_uncore_write(uncore, GEN11_GUC_SG_INTR_MASK, ~0);
320333
}
321334

322335
void gen5_gt_irq_handler(struct intel_gt *gt, u32 gt_iir)

drivers/gpu/drm/i915/gt/intel_gt_regs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,6 +1554,7 @@
15541554
#define GEN11_CSME (31)
15551555
#define GEN11_GUNIT (28)
15561556
#define GEN11_GUC (25)
1557+
#define MTL_MGUC (24)
15571558
#define GEN11_WDPERF (20)
15581559
#define GEN11_KCR (19)
15591560
#define GEN11_GTPM (16)
@@ -1608,6 +1609,7 @@
16081609
#define GEN11_VECS0_VECS1_INTR_MASK _MMIO(0x1900d0)
16091610
#define GEN12_VECS2_VECS3_INTR_MASK _MMIO(0x1900d4)
16101611
#define GEN11_GUC_SG_INTR_MASK _MMIO(0x1900e8)
1612+
#define MTL_GUC_MGUC_INTR_MASK _MMIO(0x1900e8) /* MTL+ */
16111613
#define GEN11_GPM_WGBOXPERF_INTR_MASK _MMIO(0x1900ec)
16121614
#define GEN11_CRYPTO_RSVD_INTR_MASK _MMIO(0x1900f0)
16131615
#define GEN11_GUNIT_CSME_INTR_MASK _MMIO(0x1900f4)

drivers/gpu/drm/i915/gt/uc/intel_guc.c

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,16 @@ static void gen9_enable_guc_interrupts(struct intel_guc *guc)
9898
gt->pm_guc_events);
9999
gen6_gt_pm_enable_irq(gt, gt->pm_guc_events);
100100
spin_unlock_irq(gt->irq_lock);
101+
102+
guc->interrupts.enabled = true;
101103
}
102104

103105
static void gen9_disable_guc_interrupts(struct intel_guc *guc)
104106
{
105107
struct intel_gt *gt = guc_to_gt(guc);
106108

107109
assert_rpm_wakelock_held(&gt->i915->runtime_pm);
110+
guc->interrupts.enabled = false;
108111

109112
spin_lock_irq(gt->irq_lock);
110113

@@ -116,39 +119,39 @@ static void gen9_disable_guc_interrupts(struct intel_guc *guc)
116119
gen9_reset_guc_interrupts(guc);
117120
}
118121

122+
static bool __gen11_reset_guc_interrupts(struct intel_gt *gt)
123+
{
124+
u32 irq = gt->type == GT_MEDIA ? MTL_MGUC : GEN11_GUC;
125+
126+
lockdep_assert_held(gt->irq_lock);
127+
return gen11_gt_reset_one_iir(gt, 0, irq);
128+
}
129+
119130
static void gen11_reset_guc_interrupts(struct intel_guc *guc)
120131
{
121132
struct intel_gt *gt = guc_to_gt(guc);
122133

123134
spin_lock_irq(gt->irq_lock);
124-
gen11_gt_reset_one_iir(gt, 0, GEN11_GUC);
135+
__gen11_reset_guc_interrupts(gt);
125136
spin_unlock_irq(gt->irq_lock);
126137
}
127138

128139
static void gen11_enable_guc_interrupts(struct intel_guc *guc)
129140
{
130141
struct intel_gt *gt = guc_to_gt(guc);
131-
u32 events = REG_FIELD_PREP(ENGINE1_MASK, GUC_INTR_GUC2HOST);
132142

133143
spin_lock_irq(gt->irq_lock);
134-
WARN_ON_ONCE(gen11_gt_reset_one_iir(gt, 0, GEN11_GUC));
135-
intel_uncore_write(gt->uncore,
136-
GEN11_GUC_SG_INTR_ENABLE, events);
137-
intel_uncore_write(gt->uncore,
138-
GEN11_GUC_SG_INTR_MASK, ~events);
144+
__gen11_reset_guc_interrupts(gt);
139145
spin_unlock_irq(gt->irq_lock);
146+
147+
guc->interrupts.enabled = true;
140148
}
141149

142150
static void gen11_disable_guc_interrupts(struct intel_guc *guc)
143151
{
144152
struct intel_gt *gt = guc_to_gt(guc);
145153

146-
spin_lock_irq(gt->irq_lock);
147-
148-
intel_uncore_write(gt->uncore, GEN11_GUC_SG_INTR_MASK, ~0);
149-
intel_uncore_write(gt->uncore, GEN11_GUC_SG_INTR_ENABLE, 0);
150-
151-
spin_unlock_irq(gt->irq_lock);
154+
guc->interrupts.enabled = false;
152155
intel_synchronize_irq(gt->i915);
153156

154157
gen11_reset_guc_interrupts(guc);

drivers/gpu/drm/i915/gt/uc/intel_guc.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ struct intel_guc {
7878

7979
/** @interrupts: pointers to GuC interrupt-managing functions. */
8080
struct {
81+
bool enabled;
8182
void (*reset)(struct intel_guc *guc);
8283
void (*enable)(struct intel_guc *guc);
8384
void (*disable)(struct intel_guc *guc);
@@ -330,9 +331,11 @@ static inline int intel_guc_send_busy_loop(struct intel_guc *guc,
330331
return err;
331332
}
332333

334+
/* Only call this from the interrupt handler code */
333335
static inline void intel_guc_to_host_event_handler(struct intel_guc *guc)
334336
{
335-
intel_guc_ct_event_handler(&guc->ct);
337+
if (guc->interrupts.enabled)
338+
intel_guc_ct_event_handler(&guc->ct);
336339
}
337340

338341
/* GuC addresses above GUC_GGTT_TOP also don't map through the GTT */

drivers/gpu/drm/i915/gt/uc/intel_uc.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -636,8 +636,10 @@ void intel_uc_runtime_suspend(struct intel_uc *uc)
636636
{
637637
struct intel_guc *guc = &uc->guc;
638638

639-
if (!intel_guc_is_ready(guc))
639+
if (!intel_guc_is_ready(guc)) {
640+
guc->interrupts.enabled = false;
640641
return;
642+
}
641643

642644
/*
643645
* Wait for any outstanding CTB before tearing down communication /w the
@@ -657,8 +659,10 @@ void intel_uc_suspend(struct intel_uc *uc)
657659
intel_wakeref_t wakeref;
658660
int err;
659661

660-
if (!intel_guc_is_ready(guc))
662+
if (!intel_guc_is_ready(guc)) {
663+
guc->interrupts.enabled = false;
661664
return;
665+
}
662666

663667
with_intel_runtime_pm(&uc_to_gt(uc)->i915->runtime_pm, wakeref) {
664668
err = intel_guc_suspend(guc);

0 commit comments

Comments
 (0)