@@ -427,6 +427,18 @@ static void host2guc_slpc_query_task_state(struct intel_slpc *slpc)
host2guc_slpc(slpc, &data, 4);
}
+static void host2guc_slpc_shutdown(struct intel_slpc *slpc)
+{
+ struct slpc_event_input data = {0};
+ u32 shared_data_gtt_offset = guc_ggtt_offset(slpc->vma);
+
+ data.header.value = SLPC_EVENT(SLPC_EVENT_SHUTDOWN, 2);
+ data.args[0] = shared_data_gtt_offset;
+ data.args[1] = 0;
+
+ host2guc_slpc(slpc, &data, 4);
+}
+
void intel_slpc_query_task_state(struct intel_slpc *slpc)
{
if (slpc->active)
@@ -598,6 +610,21 @@ void intel_slpc_tdr_reset(struct intel_slpc *slpc)
slpc->tdr_reset = false;
}
+static bool intel_slpc_disabled(struct intel_slpc *slpc)
+{
+ struct slpc_shared_data data;
+
+ intel_slpc_read_shared_data(slpc, &data);
+ return (data.global_state == SLPC_GLOBAL_STATE_NOT_RUNNING);
+}
+
void intel_slpc_disable(struct intel_slpc *slpc)
{
+ host2guc_slpc_shutdown(slpc);
+
+ /* Ensure SLPC is not running prior to releasing Shared data */
+ if (wait_for_us(intel_slpc_disabled(slpc), 20))
+ WARN_ONCE(true, "SLPC shutdown failed\n");
+
+ slpc->active = false;
}