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 struct intel_gt *gt = guc_to_gt(guc);
15
16 /*
17 * Wa_14017073508: mtl
18 * Do not enable gucrc to avoid additional interrupts which
19 * may disrupt pcode wa.
20 */
21 if (IS_MTL_GRAPHICS_STEP(gt->i915, P, STEP_A0, STEP_B0) &&
22 gt->type == GT_MEDIA)
23 return false;
24
25 /* GuC RC is unavailable for pre-Gen12 */
26 return guc->submission_supported &&
27 GRAPHICS_VER(gt->i915) >= 12;
28 }
29
__guc_rc_selected(struct intel_guc * guc)30 static bool __guc_rc_selected(struct intel_guc *guc)
31 {
32 if (!intel_guc_rc_is_supported(guc))
33 return false;
34
35 return guc->submission_selected;
36 }
37
intel_guc_rc_init_early(struct intel_guc * guc)38 void intel_guc_rc_init_early(struct intel_guc *guc)
39 {
40 guc->rc_supported = __guc_rc_supported(guc);
41 guc->rc_selected = __guc_rc_selected(guc);
42 }
43
guc_action_control_gucrc(struct intel_guc * guc,bool enable)44 static int guc_action_control_gucrc(struct intel_guc *guc, bool enable)
45 {
46 u32 rc_mode = enable ? INTEL_GUCRC_FIRMWARE_CONTROL :
47 INTEL_GUCRC_HOST_CONTROL;
48 u32 action[] = {
49 INTEL_GUC_ACTION_SETUP_PC_GUCRC,
50 rc_mode
51 };
52 int ret;
53
54 ret = intel_guc_send(guc, action, ARRAY_SIZE(action));
55 ret = ret > 0 ? -EPROTO : ret;
56
57 return ret;
58 }
59
__guc_rc_control(struct intel_guc * guc,bool enable)60 static int __guc_rc_control(struct intel_guc *guc, bool enable)
61 {
62 struct intel_gt *gt = guc_to_gt(guc);
63 int ret;
64
65 if (!intel_uc_uses_guc_rc(>->uc))
66 return -EOPNOTSUPP;
67
68 if (!intel_guc_is_ready(guc))
69 return -EINVAL;
70
71 ret = guc_action_control_gucrc(guc, enable);
72 if (ret) {
73 i915_probe_error(guc_to_gt(guc)->i915, "Failed to %s GuC RC (%pe)\n",
74 str_enable_disable(enable), ERR_PTR(ret));
75 return ret;
76 }
77
78 drm_info(>->i915->drm, "GuC RC: %s\n",
79 str_enabled_disabled(enable));
80
81 return 0;
82 }
83
intel_guc_rc_enable(struct intel_guc * guc)84 int intel_guc_rc_enable(struct intel_guc *guc)
85 {
86 return __guc_rc_control(guc, true);
87 }
88
intel_guc_rc_disable(struct intel_guc * guc)89 int intel_guc_rc_disable(struct intel_guc *guc)
90 {
91 return __guc_rc_control(guc, false);
92 }
93