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