Skip to content

Commit 0cfab4c

Browse files
seanzhuarodrigovivi
authored andcommitted
drm/i915/pxp: Enable PXP power management
During the power event S3+ sleep/resume, hardware will lose all the encryption keys for every hardware session, even though the session state might still be marked as alive after resume. Therefore, we should consider the session as dead on suspend and invalidate all the objects. The session will be automatically restarted on the first protected submission on resume. v2: runtime suspend also invalidates the keys v3: fix return codes, simplify rpm ops (Chris), use the new worker func v4: invalidate the objects on suspend, don't re-create the arb sesson on resume (delayed to first submission). v5: move irq changes back to irq patch (Rodrigo) v6: drop invalidation in runtime suspend (Rodrigo) Signed-off-by: Huang, Sean Z <sean.z.huang@intel.com> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20210924191452.1539378-13-alan.previn.teres.alexis@intel.com
1 parent 32271ec commit 0cfab4c

File tree

8 files changed

+126
-11
lines changed

8 files changed

+126
-11
lines changed

drivers/gpu/drm/i915/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ i915-$(CONFIG_DRM_I915_PXP) += \
283283
pxp/intel_pxp.o \
284284
pxp/intel_pxp_cmd.o \
285285
pxp/intel_pxp_irq.o \
286+
pxp/intel_pxp_pm.o \
286287
pxp/intel_pxp_session.o \
287288
pxp/intel_pxp_tee.o
288289

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "intel_rc6.h"
1919
#include "intel_rps.h"
2020
#include "intel_wakeref.h"
21+
#include "pxp/intel_pxp_pm.h"
2122

2223
#define I915_GT_SUSPEND_IDLE_TIMEOUT (HZ / 2)
2324

@@ -264,6 +265,8 @@ int intel_gt_resume(struct intel_gt *gt)
264265

265266
intel_uc_resume(&gt->uc);
266267

268+
intel_pxp_resume(&gt->pxp);
269+
267270
user_forcewake(gt, false);
268271

269272
out_fw:
@@ -297,6 +300,8 @@ void intel_gt_suspend_prepare(struct intel_gt *gt)
297300
{
298301
user_forcewake(gt, true);
299302
wait_for_suspend(gt);
303+
304+
intel_pxp_suspend(&gt->pxp, false);
300305
}
301306

302307
static suspend_state_t pm_suspend_target(void)
@@ -348,18 +353,27 @@ void intel_gt_suspend_late(struct intel_gt *gt)
348353

349354
void intel_gt_runtime_suspend(struct intel_gt *gt)
350355
{
356+
intel_pxp_suspend(&gt->pxp, true);
351357
intel_uc_runtime_suspend(&gt->uc);
352358

353359
GT_TRACE(gt, "\n");
354360
}
355361

356362
int intel_gt_runtime_resume(struct intel_gt *gt)
357363
{
364+
int ret;
365+
358366
GT_TRACE(gt, "\n");
359367
intel_gt_init_swizzling(gt);
360368
intel_ggtt_restore_fences(gt->ggtt);
361369

362-
return intel_uc_runtime_resume(&gt->uc);
370+
ret = intel_uc_runtime_resume(&gt->uc);
371+
if (ret)
372+
return ret;
373+
374+
intel_pxp_resume(&gt->pxp);
375+
376+
return 0;
363377
}
364378

365379
static ktime_t __intel_gt_get_awake_time(const struct intel_gt *gt)

drivers/gpu/drm/i915/i915_drv.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@
6767
#include "gt/intel_gt_pm.h"
6868
#include "gt/intel_rc6.h"
6969

70+
#include "pxp/intel_pxp_pm.h"
71+
7072
#include "i915_debugfs.h"
7173
#include "i915_drv.h"
7274
#include "i915_ioc32.h"

drivers/gpu/drm/i915/pxp/intel_pxp_irq.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "gt/intel_gt_types.h"
1111
#include "i915_irq.h"
1212
#include "i915_reg.h"
13+
#include "intel_runtime_pm.h"
1314

1415
/**
1516
* intel_pxp_irq_handler - Handles PXP interrupts.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// SPDX-License-Identifier: MIT
2+
/*
3+
* Copyright(c) 2020 Intel Corporation.
4+
*/
5+
6+
#include "intel_pxp.h"
7+
#include "intel_pxp_irq.h"
8+
#include "intel_pxp_pm.h"
9+
#include "intel_pxp_session.h"
10+
11+
void intel_pxp_suspend(struct intel_pxp *pxp, bool runtime)
12+
{
13+
if (!intel_pxp_is_enabled(pxp))
14+
return;
15+
16+
pxp->arb_is_valid = false;
17+
18+
/*
19+
* Contexts using protected objects keep a runtime PM reference, so we
20+
* can only runtime suspend when all of them have been either closed
21+
* or banned. Therefore, there is no need to invalidate in that
22+
* scenario.
23+
*/
24+
if (!runtime)
25+
intel_pxp_invalidate(pxp);
26+
27+
intel_pxp_fini_hw(pxp);
28+
29+
pxp->hw_state_invalidated = false;
30+
}
31+
32+
void intel_pxp_resume(struct intel_pxp *pxp)
33+
{
34+
if (!intel_pxp_is_enabled(pxp))
35+
return;
36+
37+
/*
38+
* The PXP component gets automatically unbound when we go into S3 and
39+
* re-bound after we come out, so in that scenario we can defer the
40+
* hw init to the bind call.
41+
*/
42+
if (!pxp->pxp_component)
43+
return;
44+
45+
intel_pxp_init_hw(pxp);
46+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/* SPDX-License-Identifier: MIT */
2+
/*
3+
* Copyright(c) 2020, Intel Corporation. All rights reserved.
4+
*/
5+
6+
#ifndef __INTEL_PXP_PM_H__
7+
#define __INTEL_PXP_PM_H__
8+
9+
#include "intel_pxp_types.h"
10+
11+
#ifdef CONFIG_DRM_I915_PXP
12+
void intel_pxp_suspend(struct intel_pxp *pxp, bool runtime);
13+
void intel_pxp_resume(struct intel_pxp *pxp);
14+
#else
15+
static inline void intel_pxp_suspend(struct intel_pxp *pxp, bool runtime)
16+
{
17+
}
18+
19+
static inline void intel_pxp_resume(struct intel_pxp *pxp)
20+
{
21+
}
22+
#endif
23+
24+
#endif /* __INTEL_PXP_PM_H__ */

drivers/gpu/drm/i915/pxp/intel_pxp_session.c

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,36 @@
2121

2222
static bool intel_pxp_session_is_in_play(struct intel_pxp *pxp, u32 id)
2323
{
24-
struct intel_gt *gt = pxp_to_gt(pxp);
24+
struct intel_uncore *uncore = pxp_to_gt(pxp)->uncore;
2525
intel_wakeref_t wakeref;
2626
u32 sip = 0;
2727

28-
with_intel_runtime_pm(gt->uncore->rpm, wakeref)
29-
sip = intel_uncore_read(gt->uncore, GEN12_KCR_SIP);
28+
/* if we're suspended the session is considered off */
29+
with_intel_runtime_pm_if_in_use(uncore->rpm, wakeref)
30+
sip = intel_uncore_read(uncore, GEN12_KCR_SIP);
3031

3132
return sip & BIT(id);
3233
}
3334

3435
static int pxp_wait_for_session_state(struct intel_pxp *pxp, u32 id, bool in_play)
3536
{
36-
struct intel_gt *gt = pxp_to_gt(pxp);
37+
struct intel_uncore *uncore = pxp_to_gt(pxp)->uncore;
3738
intel_wakeref_t wakeref;
3839
u32 mask = BIT(id);
3940
int ret;
4041

41-
with_intel_runtime_pm(gt->uncore->rpm, wakeref)
42-
ret = intel_wait_for_register(gt->uncore,
43-
GEN12_KCR_SIP,
44-
mask,
45-
in_play ? mask : 0,
46-
100);
42+
/* if we're suspended the session is considered off */
43+
wakeref = intel_runtime_pm_get_if_in_use(uncore->rpm);
44+
if (!wakeref)
45+
return in_play ? -ENODEV : 0;
46+
47+
ret = intel_wait_for_register(uncore,
48+
GEN12_KCR_SIP,
49+
mask,
50+
in_play ? mask : 0,
51+
100);
52+
53+
intel_runtime_pm_put(uncore->rpm, wakeref);
4754

4855
return ret;
4956
}
@@ -135,6 +142,7 @@ void intel_pxp_session_work(struct work_struct *work)
135142
{
136143
struct intel_pxp *pxp = container_of(work, typeof(*pxp), session_work);
137144
struct intel_gt *gt = pxp_to_gt(pxp);
145+
intel_wakeref_t wakeref;
138146
u32 events = 0;
139147

140148
spin_lock_irq(&gt->irq_lock);
@@ -147,11 +155,21 @@ void intel_pxp_session_work(struct work_struct *work)
147155
if (events & PXP_INVAL_REQUIRED)
148156
intel_pxp_invalidate(pxp);
149157

158+
/*
159+
* If we're processing an event while suspending then don't bother,
160+
* we're going to re-init everything on resume anyway.
161+
*/
162+
wakeref = intel_runtime_pm_get_if_in_use(gt->uncore->rpm);
163+
if (!wakeref)
164+
return;
165+
150166
if (events & PXP_TERMINATION_REQUEST) {
151167
events &= ~PXP_TERMINATION_COMPLETE;
152168
pxp_terminate(pxp);
153169
}
154170

155171
if (events & PXP_TERMINATION_COMPLETE)
156172
pxp_terminate_complete(pxp);
173+
174+
intel_runtime_pm_put(gt->uncore->rpm, wakeref);
157175
}

drivers/gpu/drm/i915/pxp/intel_pxp_tee.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,25 @@ static int intel_pxp_tee_io_message(struct intel_pxp *pxp,
7878
static int i915_pxp_tee_component_bind(struct device *i915_kdev,
7979
struct device *tee_kdev, void *data)
8080
{
81+
struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
8182
struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
83+
intel_wakeref_t wakeref;
8284

8385
mutex_lock(&pxp->tee_mutex);
8486
pxp->pxp_component = data;
8587
pxp->pxp_component->tee_dev = tee_kdev;
8688
mutex_unlock(&pxp->tee_mutex);
8789

90+
/* if we are suspended, the HW will be re-initialized on resume */
91+
wakeref = intel_runtime_pm_get_if_in_use(&i915->runtime_pm);
92+
if (!wakeref)
93+
return 0;
94+
8895
/* the component is required to fully start the PXP HW */
8996
intel_pxp_init_hw(pxp);
9097

98+
intel_runtime_pm_put(&i915->runtime_pm, wakeref);
99+
91100
return 0;
92101
}
93102

0 commit comments

Comments
 (0)