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 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 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 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 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 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 84 int intel_guc_rc_enable(struct intel_guc *guc) 85 { 86 return __guc_rc_control(guc, true); 87 } 88 89 int intel_guc_rc_disable(struct intel_guc *guc) 90 { 91 return __guc_rc_control(guc, false); 92 } 93