1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2022 Intel Corporation 4 */ 5 6 #include "xe_device.h" 7 #include "xe_huc.h" 8 #include "xe_gt.h" 9 #include "xe_guc.h" 10 #include "xe_guc_pc.h" 11 #include "xe_guc_submit.h" 12 #include "xe_uc.h" 13 #include "xe_uc_fw.h" 14 #include "xe_wopcm.h" 15 16 static struct xe_gt * 17 uc_to_gt(struct xe_uc *uc) 18 { 19 return container_of(uc, struct xe_gt, uc); 20 } 21 22 static struct xe_device * 23 uc_to_xe(struct xe_uc *uc) 24 { 25 return gt_to_xe(uc_to_gt(uc)); 26 } 27 28 /* Should be called once at driver load only */ 29 int xe_uc_init(struct xe_uc *uc) 30 { 31 int ret; 32 33 /* GuC submission not enabled, nothing to do */ 34 if (!xe_device_guc_submission_enabled(uc_to_xe(uc))) 35 return 0; 36 37 ret = xe_guc_init(&uc->guc); 38 if (ret) 39 goto err; 40 41 ret = xe_huc_init(&uc->huc); 42 if (ret) 43 goto err; 44 45 ret = xe_wopcm_init(&uc->wopcm); 46 if (ret) 47 goto err; 48 49 ret = xe_guc_submit_init(&uc->guc); 50 if (ret) 51 goto err; 52 53 return 0; 54 55 err: 56 /* If any uC firmwares not found, fall back to execlists */ 57 xe_device_guc_submission_disable(uc_to_xe(uc)); 58 59 return ret; 60 } 61 62 /** 63 * xe_uc_init_post_hwconfig - init Uc post hwconfig load 64 * @uc: The UC object 65 * 66 * Return: 0 on success, negative error code on error. 67 */ 68 int xe_uc_init_post_hwconfig(struct xe_uc *uc) 69 { 70 /* GuC submission not enabled, nothing to do */ 71 if (!xe_device_guc_submission_enabled(uc_to_xe(uc))) 72 return 0; 73 74 return xe_guc_init_post_hwconfig(&uc->guc); 75 } 76 77 static int uc_reset(struct xe_uc *uc) 78 { 79 struct xe_device *xe = uc_to_xe(uc); 80 int ret; 81 82 ret = xe_guc_reset(&uc->guc); 83 if (ret) { 84 drm_err(&xe->drm, "Failed to reset GuC, ret = %d\n", ret); 85 return ret; 86 } 87 88 return 0; 89 } 90 91 static int uc_sanitize(struct xe_uc *uc) 92 { 93 xe_huc_sanitize(&uc->huc); 94 xe_guc_sanitize(&uc->guc); 95 96 return uc_reset(uc); 97 } 98 99 /** 100 * xe_uc_init_hwconfig - minimally init Uc, read and parse hwconfig 101 * @uc: The UC object 102 * 103 * Return: 0 on success, negative error code on error. 104 */ 105 int xe_uc_init_hwconfig(struct xe_uc *uc) 106 { 107 int ret; 108 109 /* GuC submission not enabled, nothing to do */ 110 if (!xe_device_guc_submission_enabled(uc_to_xe(uc))) 111 return 0; 112 113 ret = xe_guc_min_load_for_hwconfig(&uc->guc); 114 if (ret) 115 return ret; 116 117 return 0; 118 } 119 120 /* 121 * Should be called during driver load, after every GT reset, and after every 122 * suspend to reload / auth the firmwares. 123 */ 124 int xe_uc_init_hw(struct xe_uc *uc) 125 { 126 int ret; 127 128 /* GuC submission not enabled, nothing to do */ 129 if (!xe_device_guc_submission_enabled(uc_to_xe(uc))) 130 return 0; 131 132 ret = uc_sanitize(uc); 133 if (ret) 134 return ret; 135 136 ret = xe_huc_upload(&uc->huc); 137 if (ret) 138 return ret; 139 140 ret = xe_guc_upload(&uc->guc); 141 if (ret) 142 return ret; 143 144 ret = xe_guc_enable_communication(&uc->guc); 145 if (ret) 146 return ret; 147 148 ret = xe_gt_record_default_lrcs(uc_to_gt(uc)); 149 if (ret) 150 return ret; 151 152 ret = xe_guc_post_load_init(&uc->guc); 153 if (ret) 154 return ret; 155 156 ret = xe_guc_pc_start(&uc->guc.pc); 157 if (ret) 158 return ret; 159 160 /* We don't fail the driver load if HuC fails to auth, but let's warn */ 161 ret = xe_huc_auth(&uc->huc); 162 XE_WARN_ON(ret); 163 164 return 0; 165 } 166 167 int xe_uc_reset_prepare(struct xe_uc *uc) 168 { 169 /* GuC submission not enabled, nothing to do */ 170 if (!xe_device_guc_submission_enabled(uc_to_xe(uc))) 171 return 0; 172 173 return xe_guc_reset_prepare(&uc->guc); 174 } 175 176 void xe_uc_stop_prepare(struct xe_uc *uc) 177 { 178 xe_guc_stop_prepare(&uc->guc); 179 } 180 181 int xe_uc_stop(struct xe_uc *uc) 182 { 183 /* GuC submission not enabled, nothing to do */ 184 if (!xe_device_guc_submission_enabled(uc_to_xe(uc))) 185 return 0; 186 187 return xe_guc_stop(&uc->guc); 188 } 189 190 int xe_uc_start(struct xe_uc *uc) 191 { 192 /* GuC submission not enabled, nothing to do */ 193 if (!xe_device_guc_submission_enabled(uc_to_xe(uc))) 194 return 0; 195 196 return xe_guc_start(&uc->guc); 197 } 198 199 static void uc_reset_wait(struct xe_uc *uc) 200 { 201 int ret; 202 203 again: 204 xe_guc_reset_wait(&uc->guc); 205 206 ret = xe_uc_reset_prepare(uc); 207 if (ret) 208 goto again; 209 } 210 211 int xe_uc_suspend(struct xe_uc *uc) 212 { 213 int ret; 214 215 /* GuC submission not enabled, nothing to do */ 216 if (!xe_device_guc_submission_enabled(uc_to_xe(uc))) 217 return 0; 218 219 uc_reset_wait(uc); 220 221 ret = xe_uc_stop(uc); 222 if (ret) 223 return ret; 224 225 return xe_guc_suspend(&uc->guc); 226 } 227