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