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