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