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