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 	struct drm_device *drm = &guc_to_gt(guc)->i915->drm;
53 	int ret;
54 
55 	if (!intel_uc_uses_guc_rc(&gt->uc))
56 		return -EOPNOTSUPP;
57 
58 	if (!intel_guc_is_ready(guc))
59 		return -EINVAL;
60 
61 	ret = guc_action_control_gucrc(guc, enable);
62 	if (ret) {
63 		drm_err(drm, "Failed to %s GuC RC (%pe)\n",
64 			str_enable_disable(enable), ERR_PTR(ret));
65 		return ret;
66 	}
67 
68 	drm_info(&gt->i915->drm, "GuC RC: %s\n",
69 		 str_enabled_disabled(enable));
70 
71 	return 0;
72 }
73 
74 int intel_guc_rc_enable(struct intel_guc *guc)
75 {
76 	return __guc_rc_control(guc, true);
77 }
78 
79 int intel_guc_rc_disable(struct intel_guc *guc)
80 {
81 	return __guc_rc_control(guc, false);
82 }
83