Skip to content

Commit 20fd600

Browse files
dceraoloickle
authored andcommitted
drm/i915/guc: fix GuC suspend/resume
The ENTER/EXIT_S_STATE actions queue the save/restore operation in GuC FW and then return, so waiting on the H2G is not enough to guarantee GuC is done. When all the processing is done, GuC writes 0 to scratch register 14, so we can poll on that. Note that GuC does not ensure that the value in the register is different from 0 while the action is in progress so we need to take care of that ourselves as well. v2: improve comment, return early on GuC error and improve error message (Michal) Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Michal Wajdeczko <michal.wajdeczko@intel.com> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Acked-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Link: https://patchwork.freedesktop.org/patch/msgid/20181016224648.2326-1-daniele.ceraolospurio@intel.com
1 parent 138bdac commit 20fd600

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

drivers/gpu/drm/i915/intel_guc.c

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,44 @@ int intel_guc_auth_huc(struct intel_guc *guc, u32 rsa_offset)
521521
return intel_guc_send(guc, action, ARRAY_SIZE(action));
522522
}
523523

524+
/*
525+
* The ENTER/EXIT_S_STATE actions queue the save/restore operation in GuC FW and
526+
* then return, so waiting on the H2G is not enough to guarantee GuC is done.
527+
* When all the processing is done, GuC writes INTEL_GUC_SLEEP_STATE_SUCCESS to
528+
* scratch register 14, so we can poll on that. Note that GuC does not ensure
529+
* that the value in the register is different from
530+
* INTEL_GUC_SLEEP_STATE_SUCCESS while the action is in progress so we need to
531+
* take care of that ourselves as well.
532+
*/
533+
static int guc_sleep_state_action(struct intel_guc *guc,
534+
const u32 *action, u32 len)
535+
{
536+
struct drm_i915_private *dev_priv = guc_to_i915(guc);
537+
int ret;
538+
u32 status;
539+
540+
I915_WRITE(SOFT_SCRATCH(14), INTEL_GUC_SLEEP_STATE_INVALID_MASK);
541+
542+
ret = intel_guc_send(guc, action, len);
543+
if (ret)
544+
return ret;
545+
546+
ret = __intel_wait_for_register(dev_priv, SOFT_SCRATCH(14),
547+
INTEL_GUC_SLEEP_STATE_INVALID_MASK,
548+
0, 0, 10, &status);
549+
if (ret)
550+
return ret;
551+
552+
if (status != INTEL_GUC_SLEEP_STATE_SUCCESS) {
553+
DRM_ERROR("GuC failed to change sleep state. "
554+
"action=0x%x, err=%u\n",
555+
action[0], status);
556+
return -EIO;
557+
}
558+
559+
return 0;
560+
}
561+
524562
/**
525563
* intel_guc_suspend() - notify GuC entering suspend state
526564
* @guc: the guc
@@ -533,7 +571,7 @@ int intel_guc_suspend(struct intel_guc *guc)
533571
intel_guc_ggtt_offset(guc, guc->shared_data)
534572
};
535573

536-
return intel_guc_send(guc, data, ARRAY_SIZE(data));
574+
return guc_sleep_state_action(guc, data, ARRAY_SIZE(data));
537575
}
538576

539577
/**
@@ -571,7 +609,7 @@ int intel_guc_resume(struct intel_guc *guc)
571609
intel_guc_ggtt_offset(guc, guc->shared_data)
572610
};
573611

574-
return intel_guc_send(guc, data, ARRAY_SIZE(data));
612+
return guc_sleep_state_action(guc, data, ARRAY_SIZE(data));
575613
}
576614

577615
/**

drivers/gpu/drm/i915/intel_guc_fwif.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,13 @@ enum intel_guc_report_status {
687687
INTEL_GUC_REPORT_STATUS_COMPLETE = 0x4,
688688
};
689689

690+
enum intel_guc_sleep_state_status {
691+
INTEL_GUC_SLEEP_STATE_SUCCESS = 0x0,
692+
INTEL_GUC_SLEEP_STATE_PREEMPT_TO_IDLE_FAILED = 0x1,
693+
INTEL_GUC_SLEEP_STATE_ENGINE_RESET_FAILED = 0x2
694+
#define INTEL_GUC_SLEEP_STATE_INVALID_MASK 0x80000000
695+
};
696+
690697
#define GUC_LOG_CONTROL_LOGGING_ENABLED (1 << 0)
691698
#define GUC_LOG_CONTROL_VERBOSITY_SHIFT 4
692699
#define GUC_LOG_CONTROL_VERBOSITY_MASK (0xF << GUC_LOG_CONTROL_VERBOSITY_SHIFT)

0 commit comments

Comments
 (0)