1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2021 Intel Corporation
4  */
5 
6 #include <linux/string_helpers.h>
7 
8 #include "intel_guc_rc.h"
9 #include "gt/intel_gt.h"
10 #include "i915_drv.h"
11 
12 static bool __guc_rc_supported(struct intel_guc *guc)
13 {
14 	/* GuC RC is unavailable for pre-Gen12 */
15 	return guc->submission_supported &&
16 		GRAPHICS_VER(guc_to_gt(guc)->i915) >= 12;
17 }
18 
19 static bool __guc_rc_selected(struct intel_guc *guc)
20 {
21 	if (!intel_guc_rc_is_supported(guc))
22 		return false;
23 
24 	return guc->submission_selected;
25 }
26 
27 void intel_guc_rc_init_early(struct intel_guc *guc)
28 {
29 	guc->rc_supported = __guc_rc_supported(guc);
30 	guc->rc_selected = __guc_rc_selected(guc);
31 }
32 
33 static int guc_action_control_gucrc(struct intel_guc *guc, bool enable)
34 {
35 	u32 rc_mode = enable ? INTEL_GUCRC_FIRMWARE_CONTROL :
36 				INTEL_GUCRC_HOST_CONTROL;
37 	u32 action[] = {
38 		INTEL_GUC_ACTION_SETUP_PC_GUCRC,
39 		rc_mode
40 	};
41 	int ret;
42 
43 	ret = intel_guc_send(guc, action, ARRAY_SIZE(action));
44 	ret = ret > 0 ? -EPROTO : ret;
45 
46 	return ret;
47 }
48 
49 static int __guc_rc_control(struct intel_guc *guc, bool enable)
50 {
51 	struct intel_gt *gt = guc_to_gt(guc);
52 	int ret;
53 
54 	if (!intel_uc_uses_guc_rc(&gt->uc))
55 		return -EOPNOTSUPP;
56 
57 	if (!intel_guc_is_ready(guc))
58 		return -EINVAL;
59 
60 	ret = guc_action_control_gucrc(guc, enable);
61 	if (ret) {
62 		i915_probe_error(guc_to_gt(guc)->i915, "Failed to %s GuC RC (%pe)\n",
63 				 str_enable_disable(enable), ERR_PTR(ret));
64 		return ret;
65 	}
66 
67 	drm_info(&gt->i915->drm, "GuC RC: %s\n",
68 		 str_enabled_disabled(enable));
69 
70 	return 0;
71 }
72 
73 int intel_guc_rc_enable(struct intel_guc *guc)
74 {
75 	return __guc_rc_control(guc, true);
76 }
77 
78 int intel_guc_rc_disable(struct intel_guc *guc)
79 {
80 	return __guc_rc_control(guc, false);
81 }
82