Skip to content

Commit 1ebf7aa

Browse files
committed
drm/i915/gt: Prefer soft-rc6 over RPS DOWN_TIMEOUT
The RPS DOWN_TIMEOUT interrupt is signaled after a period of rc6, and upon receipt of that interrupt we reprogram the GPU clocks down to the next idle notch [to help convserve power during rc6]. However, on execlists, we benefit from soft-rc6 immediately parking the GPU and setting idle frequencies upon idling [within a jiffie], and here the interrupt prevents us from restarting from our last frequency. In the process, we can simply opt for a static pm_events mask and rely on the enable/disable interrupts to flush the worker on parking. This will reduce the amount of oscillation observed during steady workloads with microsleeps, as each time the rc6 timeout occurs we immediately follow with a waitboost for a dropped frame. Signed-off-by: Chris Wilson <[email protected]> Reviewed-by: Andi Shyti <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 7db8736 commit 1ebf7aa

File tree

1 file changed

+18
-23
lines changed

1 file changed

+18
-23
lines changed

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

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ static u32 rps_pm_mask(struct intel_rps *rps, u8 val)
5757
if (val < rps->max_freq_softlimit)
5858
mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_UP_THRESHOLD;
5959

60-
mask &= READ_ONCE(rps->pm_events);
60+
mask &= rps->pm_events;
6161

6262
return rps_pm_sanitize_mask(rps, ~mask);
6363
}
@@ -70,19 +70,9 @@ static void rps_reset_ei(struct intel_rps *rps)
7070
static void rps_enable_interrupts(struct intel_rps *rps)
7171
{
7272
struct intel_gt *gt = rps_to_gt(rps);
73-
u32 events;
7473

7574
rps_reset_ei(rps);
7675

77-
if (IS_VALLEYVIEW(gt->i915))
78-
/* WaGsvRC0ResidencyMethod:vlv */
79-
events = GEN6_PM_RP_UP_EI_EXPIRED;
80-
else
81-
events = (GEN6_PM_RP_UP_THRESHOLD |
82-
GEN6_PM_RP_DOWN_THRESHOLD |
83-
GEN6_PM_RP_DOWN_TIMEOUT);
84-
WRITE_ONCE(rps->pm_events, events);
85-
8676
spin_lock_irq(&gt->irq_lock);
8777
gen6_gt_pm_enable_irq(gt, rps->pm_events);
8878
spin_unlock_irq(&gt->irq_lock);
@@ -120,8 +110,6 @@ static void rps_disable_interrupts(struct intel_rps *rps)
120110
{
121111
struct intel_gt *gt = rps_to_gt(rps);
122112

123-
WRITE_ONCE(rps->pm_events, 0);
124-
125113
intel_uncore_write(gt->uncore,
126114
GEN6_PMINTRMSK, rps_pm_sanitize_mask(rps, ~0u));
127115

@@ -919,12 +907,10 @@ static bool gen9_rps_enable(struct intel_rps *rps)
919907
intel_uncore_write_fw(uncore, GEN6_RC_VIDEO_FREQ,
920908
GEN9_FREQUENCY(rps->rp1_freq));
921909

922-
/* 1 second timeout */
923-
intel_uncore_write_fw(uncore, GEN6_RP_DOWN_TIMEOUT,
924-
GT_INTERVAL_FROM_US(i915, 1000000));
925-
926910
intel_uncore_write_fw(uncore, GEN6_RP_IDLE_HYSTERSIS, 0xa);
927911

912+
rps->pm_events = GEN6_PM_RP_UP_THRESHOLD | GEN6_PM_RP_DOWN_THRESHOLD;
913+
928914
return rps_reset(rps);
929915
}
930916

@@ -935,12 +921,10 @@ static bool gen8_rps_enable(struct intel_rps *rps)
935921
intel_uncore_write_fw(uncore, GEN6_RC_VIDEO_FREQ,
936922
HSW_FREQUENCY(rps->rp1_freq));
937923

938-
/* NB: Docs say 1s, and 1000000 - which aren't equivalent */
939-
intel_uncore_write_fw(uncore, GEN6_RP_DOWN_TIMEOUT,
940-
100000000 / 128); /* 1 second timeout */
941-
942924
intel_uncore_write_fw(uncore, GEN6_RP_IDLE_HYSTERSIS, 10);
943925

926+
rps->pm_events = GEN6_PM_RP_UP_THRESHOLD | GEN6_PM_RP_DOWN_THRESHOLD;
927+
944928
return rps_reset(rps);
945929
}
946930

@@ -952,6 +936,10 @@ static bool gen6_rps_enable(struct intel_rps *rps)
952936
intel_uncore_write_fw(uncore, GEN6_RP_DOWN_TIMEOUT, 50000);
953937
intel_uncore_write_fw(uncore, GEN6_RP_IDLE_HYSTERSIS, 10);
954938

939+
rps->pm_events = (GEN6_PM_RP_UP_THRESHOLD |
940+
GEN6_PM_RP_DOWN_THRESHOLD |
941+
GEN6_PM_RP_DOWN_TIMEOUT);
942+
955943
return rps_reset(rps);
956944
}
957945

@@ -1037,6 +1025,10 @@ static bool chv_rps_enable(struct intel_rps *rps)
10371025
GEN6_RP_UP_BUSY_AVG |
10381026
GEN6_RP_DOWN_IDLE_AVG);
10391027

1028+
rps->pm_events = (GEN6_PM_RP_UP_THRESHOLD |
1029+
GEN6_PM_RP_DOWN_THRESHOLD |
1030+
GEN6_PM_RP_DOWN_TIMEOUT);
1031+
10401032
/* Setting Fixed Bias */
10411033
vlv_punit_get(i915);
10421034

@@ -1135,6 +1127,9 @@ static bool vlv_rps_enable(struct intel_rps *rps)
11351127
GEN6_RP_UP_BUSY_AVG |
11361128
GEN6_RP_DOWN_IDLE_CONT);
11371129

1130+
/* WaGsvRC0ResidencyMethod:vlv */
1131+
rps->pm_events = GEN6_PM_RP_UP_EI_EXPIRED;
1132+
11381133
vlv_punit_get(i915);
11391134

11401135
/* Setting Fixed Bias */
@@ -1469,7 +1464,7 @@ static void rps_work(struct work_struct *work)
14691464
u32 pm_iir = 0;
14701465

14711466
spin_lock_irq(&gt->irq_lock);
1472-
pm_iir = fetch_and_zero(&rps->pm_iir) & READ_ONCE(rps->pm_events);
1467+
pm_iir = fetch_and_zero(&rps->pm_iir) & rps->pm_events;
14731468
client_boost = atomic_read(&rps->num_waiters);
14741469
spin_unlock_irq(&gt->irq_lock);
14751470

@@ -1572,7 +1567,7 @@ void gen6_rps_irq_handler(struct intel_rps *rps, u32 pm_iir)
15721567
struct intel_gt *gt = rps_to_gt(rps);
15731568
u32 events;
15741569

1575-
events = pm_iir & READ_ONCE(rps->pm_events);
1570+
events = pm_iir & rps->pm_events;
15761571
if (events) {
15771572
spin_lock(&gt->irq_lock);
15781573

0 commit comments

Comments
 (0)