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
__guc_rc_supported(struct intel_guc * guc)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
__guc_rc_selected(struct intel_guc * guc)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
intel_guc_rc_init_early(struct intel_guc * guc)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
guc_action_control_gucrc(struct intel_guc * guc,bool enable)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
__guc_rc_control(struct intel_guc * guc,bool enable)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(>->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(>->i915->drm, "GuC RC: %s\n",
68 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