1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2022 Intel Corporation 4 */ 5 6 #include "xe_uc.h" 7 8 #include "xe_assert.h" 9 #include "xe_device.h" 10 #include "xe_gsc.h" 11 #include "xe_gsc_proxy.h" 12 #include "xe_gt.h" 13 #include "xe_gt_printk.h" 14 #include "xe_gt_sriov_vf.h" 15 #include "xe_guc.h" 16 #include "xe_guc_pc.h" 17 #include "xe_guc_engine_activity.h" 18 #include "xe_huc.h" 19 #include "xe_sriov.h" 20 #include "xe_uc_fw.h" 21 #include "xe_wopcm.h" 22 23 static struct xe_gt * 24 uc_to_gt(struct xe_uc *uc) 25 { 26 return container_of(uc, struct xe_gt, uc); 27 } 28 29 static struct xe_device * 30 uc_to_xe(struct xe_uc *uc) 31 { 32 return gt_to_xe(uc_to_gt(uc)); 33 } 34 35 /* Should be called once at driver load only */ 36 int xe_uc_init(struct xe_uc *uc) 37 { 38 int ret; 39 40 /* 41 * We call the GuC/HuC/GSC init functions even if GuC submission is off 42 * to correctly move our tracking of the FW state to "disabled". 43 */ 44 ret = xe_guc_init(&uc->guc); 45 if (ret) 46 goto err; 47 48 ret = xe_huc_init(&uc->huc); 49 if (ret) 50 goto err; 51 52 ret = xe_gsc_init(&uc->gsc); 53 if (ret) 54 goto err; 55 56 if (!xe_device_uc_enabled(uc_to_xe(uc))) 57 return 0; 58 59 if (IS_SRIOV_VF(uc_to_xe(uc))) 60 return 0; 61 62 ret = xe_wopcm_init(&uc->wopcm); 63 if (ret) 64 goto err; 65 66 return 0; 67 68 err: 69 xe_gt_err(uc_to_gt(uc), "Failed to initialize uC (%pe)\n", ERR_PTR(ret)); 70 return ret; 71 } 72 73 /** 74 * xe_uc_init_post_hwconfig - init Uc post hwconfig load 75 * @uc: The UC object 76 * 77 * Return: 0 on success, negative error code on error. 78 */ 79 int xe_uc_init_post_hwconfig(struct xe_uc *uc) 80 { 81 int err; 82 83 /* GuC submission not enabled, nothing to do */ 84 if (!xe_device_uc_enabled(uc_to_xe(uc))) 85 return 0; 86 87 err = xe_uc_sanitize_reset(uc); 88 if (err) 89 return err; 90 91 err = xe_guc_init_post_hwconfig(&uc->guc); 92 if (err) 93 return err; 94 95 err = xe_huc_init_post_hwconfig(&uc->huc); 96 if (err) 97 return err; 98 99 return xe_gsc_init_post_hwconfig(&uc->gsc); 100 } 101 102 static int uc_reset(struct xe_uc *uc) 103 { 104 struct xe_device *xe = uc_to_xe(uc); 105 int ret; 106 107 ret = xe_guc_reset(&uc->guc); 108 if (ret) { 109 drm_err(&xe->drm, "Failed to reset GuC, ret = %d\n", ret); 110 return ret; 111 } 112 113 return 0; 114 } 115 116 static void xe_uc_sanitize(struct xe_uc *uc) 117 { 118 xe_huc_sanitize(&uc->huc); 119 xe_guc_sanitize(&uc->guc); 120 } 121 122 int xe_uc_sanitize_reset(struct xe_uc *uc) 123 { 124 xe_uc_sanitize(uc); 125 126 return uc_reset(uc); 127 } 128 129 /** 130 * xe_uc_init_hwconfig - minimally init Uc, read and parse hwconfig 131 * @uc: The UC object 132 * 133 * Return: 0 on success, negative error code on error. 134 */ 135 int xe_uc_init_hwconfig(struct xe_uc *uc) 136 { 137 int ret; 138 139 /* GuC submission not enabled, nothing to do */ 140 if (!xe_device_uc_enabled(uc_to_xe(uc))) 141 return 0; 142 143 ret = xe_guc_min_load_for_hwconfig(&uc->guc); 144 if (ret) 145 return ret; 146 147 return 0; 148 } 149 150 static int vf_uc_init_hw(struct xe_uc *uc) 151 { 152 int err; 153 154 err = xe_uc_sanitize_reset(uc); 155 if (err) 156 return err; 157 158 err = xe_guc_enable_communication(&uc->guc); 159 if (err) 160 return err; 161 162 err = xe_gt_sriov_vf_connect(uc_to_gt(uc)); 163 if (err) 164 return err; 165 166 uc->guc.submission_state.enabled = true; 167 168 err = xe_gt_record_default_lrcs(uc_to_gt(uc)); 169 if (err) 170 return err; 171 172 return 0; 173 } 174 175 /* 176 * Should be called during driver load, after every GT reset, and after every 177 * suspend to reload / auth the firmwares. 178 */ 179 int xe_uc_init_hw(struct xe_uc *uc) 180 { 181 int ret; 182 183 /* GuC submission not enabled, nothing to do */ 184 if (!xe_device_uc_enabled(uc_to_xe(uc))) 185 return 0; 186 187 if (IS_SRIOV_VF(uc_to_xe(uc))) 188 return vf_uc_init_hw(uc); 189 190 ret = xe_huc_upload(&uc->huc); 191 if (ret) 192 return ret; 193 194 ret = xe_guc_upload(&uc->guc); 195 if (ret) 196 return ret; 197 198 ret = xe_guc_enable_communication(&uc->guc); 199 if (ret) 200 return ret; 201 202 ret = xe_gt_record_default_lrcs(uc_to_gt(uc)); 203 if (ret) 204 return ret; 205 206 ret = xe_guc_post_load_init(&uc->guc); 207 if (ret) 208 return ret; 209 210 ret = xe_guc_pc_start(&uc->guc.pc); 211 if (ret) 212 return ret; 213 214 xe_guc_engine_activity_enable_stats(&uc->guc); 215 216 /* We don't fail the driver load if HuC fails to auth, but let's warn */ 217 ret = xe_huc_auth(&uc->huc, XE_HUC_AUTH_VIA_GUC); 218 xe_gt_assert(uc_to_gt(uc), !ret); 219 220 /* GSC load is async */ 221 xe_gsc_load_start(&uc->gsc); 222 223 return 0; 224 } 225 226 int xe_uc_fini_hw(struct xe_uc *uc) 227 { 228 return xe_uc_sanitize_reset(uc); 229 } 230 231 int xe_uc_reset_prepare(struct xe_uc *uc) 232 { 233 /* GuC submission not enabled, nothing to do */ 234 if (!xe_device_uc_enabled(uc_to_xe(uc))) 235 return 0; 236 237 return xe_guc_reset_prepare(&uc->guc); 238 } 239 240 void xe_uc_gucrc_disable(struct xe_uc *uc) 241 { 242 XE_WARN_ON(xe_guc_pc_gucrc_disable(&uc->guc.pc)); 243 } 244 245 void xe_uc_stop_prepare(struct xe_uc *uc) 246 { 247 xe_gsc_stop_prepare(&uc->gsc); 248 xe_guc_stop_prepare(&uc->guc); 249 } 250 251 void xe_uc_stop(struct xe_uc *uc) 252 { 253 /* GuC submission not enabled, nothing to do */ 254 if (!xe_device_uc_enabled(uc_to_xe(uc))) 255 return; 256 257 xe_guc_stop(&uc->guc); 258 } 259 260 int xe_uc_start(struct xe_uc *uc) 261 { 262 /* GuC submission not enabled, nothing to do */ 263 if (!xe_device_uc_enabled(uc_to_xe(uc))) 264 return 0; 265 266 return xe_guc_start(&uc->guc); 267 } 268 269 static void uc_reset_wait(struct xe_uc *uc) 270 { 271 int ret; 272 273 again: 274 xe_guc_reset_wait(&uc->guc); 275 276 ret = xe_uc_reset_prepare(uc); 277 if (ret) 278 goto again; 279 } 280 281 void xe_uc_suspend_prepare(struct xe_uc *uc) 282 { 283 xe_gsc_wait_for_worker_completion(&uc->gsc); 284 xe_guc_stop_prepare(&uc->guc); 285 } 286 287 int xe_uc_suspend(struct xe_uc *uc) 288 { 289 /* GuC submission not enabled, nothing to do */ 290 if (!xe_device_uc_enabled(uc_to_xe(uc))) 291 return 0; 292 293 uc_reset_wait(uc); 294 295 xe_uc_stop(uc); 296 297 return xe_guc_suspend(&uc->guc); 298 } 299 300 /** 301 * xe_uc_declare_wedged() - Declare UC wedged 302 * @uc: the UC object 303 * 304 * Wedge the UC which stops all submission, saves desired debug state, and 305 * cleans up anything which could timeout. 306 */ 307 void xe_uc_declare_wedged(struct xe_uc *uc) 308 { 309 xe_gt_assert(uc_to_gt(uc), uc_to_xe(uc)->wedged.mode); 310 311 xe_guc_declare_wedged(&uc->guc); 312 } 313