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 "intel_guc_print.h"
10 #include "gt/intel_gt.h"
11 #include "i915_drv.h"
12
__guc_rc_supported(struct intel_guc * guc)13 static bool __guc_rc_supported(struct intel_guc *guc)
14 {
15 /* GuC RC is unavailable for pre-Gen12 */
16 return guc->submission_supported &&
17 GRAPHICS_VER(guc_to_i915(guc)) >= 12;
18 }
19
__guc_rc_selected(struct intel_guc * guc)20 static bool __guc_rc_selected(struct intel_guc *guc)
21 {
22 if (!intel_guc_rc_is_supported(guc))
23 return false;
24
25 return guc->submission_selected;
26 }
27
intel_guc_rc_init_early(struct intel_guc * guc)28 void intel_guc_rc_init_early(struct intel_guc *guc)
29 {
30 guc->rc_supported = __guc_rc_supported(guc);
31 guc->rc_selected = __guc_rc_selected(guc);
32 }
33
guc_action_control_gucrc(struct intel_guc * guc,bool enable)34 static int guc_action_control_gucrc(struct intel_guc *guc, bool enable)
35 {
36 u32 rc_mode = enable ? INTEL_GUCRC_FIRMWARE_CONTROL :
37 INTEL_GUCRC_HOST_CONTROL;
38 u32 action[] = {
39 INTEL_GUC_ACTION_SETUP_PC_GUCRC,
40 rc_mode
41 };
42 int ret;
43
44 ret = intel_guc_send(guc, action, ARRAY_SIZE(action));
45 ret = ret > 0 ? -EPROTO : ret;
46
47 return ret;
48 }
49
__guc_rc_control(struct intel_guc * guc,bool enable)50 static int __guc_rc_control(struct intel_guc *guc, bool enable)
51 {
52 struct intel_gt *gt = guc_to_gt(guc);
53 int ret;
54
55 if (!intel_uc_uses_guc_rc(>->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 guc_probe_error(guc, "Failed to %s RC (%pe)\n",
64 str_enable_disable(enable), ERR_PTR(ret));
65 return ret;
66 }
67
68 guc_info(guc, "RC %s\n", str_enabled_disabled(enable));
69
70 return 0;
71 }
72
intel_guc_rc_enable(struct intel_guc * guc)73 int intel_guc_rc_enable(struct intel_guc *guc)
74 {
75 return __guc_rc_control(guc, true);
76 }
77
intel_guc_rc_disable(struct intel_guc * guc)78 int intel_guc_rc_disable(struct intel_guc *guc)
79 {
80 return __guc_rc_control(guc, false);
81 }
82