Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 337 lines 6.2 kB view raw
1// SPDX-License-Identifier: MIT 2/* 3 * Copyright © 2022 Intel Corporation 4 */ 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_gt.h" 12#include "xe_gt_printk.h" 13#include "xe_gt_sriov_vf.h" 14#include "xe_guc.h" 15#include "xe_guc_pc.h" 16#include "xe_guc_rc.h" 17#include "xe_guc_engine_activity.h" 18#include "xe_huc.h" 19#include "xe_sriov.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_noalloc(struct xe_uc *uc) 36{ 37 int ret; 38 39 ret = xe_guc_init_noalloc(&uc->guc); 40 if (ret) 41 goto err; 42 43 /* HuC and GSC have no early dependencies and will be initialized during xe_uc_init(). */ 44 return 0; 45 46err: 47 xe_gt_err(uc_to_gt(uc), "Failed to early initialize uC (%pe)\n", ERR_PTR(ret)); 48 return ret; 49} 50 51int xe_uc_init(struct xe_uc *uc) 52{ 53 int ret; 54 55 /* 56 * We call the GuC/HuC/GSC init functions even if GuC submission is off 57 * to correctly move our tracking of the FW state to "disabled". 58 */ 59 ret = xe_guc_init(&uc->guc); 60 if (ret) 61 goto err; 62 63 ret = xe_huc_init(&uc->huc); 64 if (ret) 65 goto err; 66 67 ret = xe_gsc_init(&uc->gsc); 68 if (ret) 69 goto err; 70 71 if (!xe_device_uc_enabled(uc_to_xe(uc))) 72 return 0; 73 74 if (!IS_SRIOV_VF(uc_to_xe(uc))) { 75 ret = xe_wopcm_init(&uc->wopcm); 76 if (ret) 77 goto err; 78 } 79 80 ret = xe_guc_min_load_for_hwconfig(&uc->guc); 81 if (ret) 82 goto err; 83 84 return 0; 85err: 86 xe_gt_err(uc_to_gt(uc), "Failed to initialize uC (%pe)\n", ERR_PTR(ret)); 87 return ret; 88} 89 90/** 91 * xe_uc_init_post_hwconfig - init Uc post hwconfig load 92 * @uc: The UC object 93 * 94 * Return: 0 on success, negative error code on error. 95 */ 96int xe_uc_init_post_hwconfig(struct xe_uc *uc) 97{ 98 int err; 99 100 /* GuC submission not enabled, nothing to do */ 101 if (!xe_device_uc_enabled(uc_to_xe(uc))) 102 return 0; 103 104 err = xe_uc_sanitize_reset(uc); 105 if (err) 106 return err; 107 108 err = xe_guc_init_post_hwconfig(&uc->guc); 109 if (err) 110 return err; 111 112 err = xe_huc_init_post_hwconfig(&uc->huc); 113 if (err) 114 return err; 115 116 return xe_gsc_init_post_hwconfig(&uc->gsc); 117} 118 119static int uc_reset(struct xe_uc *uc) 120{ 121 struct xe_device *xe = uc_to_xe(uc); 122 int ret; 123 124 ret = xe_guc_reset(&uc->guc); 125 if (ret) { 126 drm_err(&xe->drm, "Failed to reset GuC, ret = %d\n", ret); 127 return ret; 128 } 129 130 return 0; 131} 132 133static void xe_uc_sanitize(struct xe_uc *uc) 134{ 135 xe_huc_sanitize(&uc->huc); 136 xe_guc_sanitize(&uc->guc); 137} 138 139int xe_uc_sanitize_reset(struct xe_uc *uc) 140{ 141 xe_uc_sanitize(uc); 142 143 return uc_reset(uc); 144} 145 146static int vf_uc_load_hw(struct xe_uc *uc) 147{ 148 int err; 149 150 err = xe_uc_sanitize_reset(uc); 151 if (err) 152 return err; 153 154 err = xe_guc_enable_communication(&uc->guc); 155 if (err) 156 return err; 157 158 err = xe_gt_sriov_vf_connect(uc_to_gt(uc)); 159 if (err) 160 return err; 161 162 uc->guc.submission_state.enabled = true; 163 164 err = xe_guc_opt_in_features_enable(&uc->guc); 165 if (err) 166 return err; 167 168 err = xe_gt_record_default_lrcs(uc_to_gt(uc)); 169 if (err) 170 return err; 171 172 return 0; 173} 174 175/* 176 * Should be called during driver load, after every GT reset, and after every 177 * suspend to reload / auth the firmwares. 178 */ 179int xe_uc_load_hw(struct xe_uc *uc) 180{ 181 int ret; 182 183 /* GuC submission not enabled, nothing to do */ 184 if (!xe_device_uc_enabled(uc_to_xe(uc))) 185 return 0; 186 187 if (IS_SRIOV_VF(uc_to_xe(uc))) 188 return vf_uc_load_hw(uc); 189 190 ret = xe_huc_upload(&uc->huc); 191 if (ret) 192 return ret; 193 194 ret = xe_guc_upload(&uc->guc); 195 if (ret) 196 return ret; 197 198 ret = xe_guc_enable_communication(&uc->guc); 199 if (ret) 200 return ret; 201 202 ret = xe_gt_record_default_lrcs(uc_to_gt(uc)); 203 if (ret) 204 return ret; 205 206 ret = xe_guc_post_load_init(&uc->guc); 207 if (ret) 208 return ret; 209 210 ret = xe_guc_pc_start(&uc->guc.pc); 211 if (ret) 212 return ret; 213 214 ret = xe_guc_rc_enable(&uc->guc); 215 if (ret) 216 return ret; 217 218 xe_guc_engine_activity_enable_stats(&uc->guc); 219 220 /* We don't fail the driver load if HuC fails to auth */ 221 ret = xe_huc_auth(&uc->huc, XE_HUC_AUTH_VIA_GUC); 222 if (ret) 223 xe_gt_err(uc_to_gt(uc), 224 "HuC authentication failed (%pe), continuing with no HuC\n", 225 ERR_PTR(ret)); 226 227 /* GSC load is async */ 228 xe_gsc_load_start(&uc->gsc); 229 230 return 0; 231} 232 233int xe_uc_reset_prepare(struct xe_uc *uc) 234{ 235 /* GuC submission not enabled, nothing to do */ 236 if (!xe_device_uc_enabled(uc_to_xe(uc))) 237 return 0; 238 239 return xe_guc_reset_prepare(&uc->guc); 240} 241 242void xe_uc_stop_prepare(struct xe_uc *uc) 243{ 244 xe_gsc_stop_prepare(&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 278void xe_uc_suspend_prepare(struct xe_uc *uc) 279{ 280 xe_gsc_wait_for_worker_completion(&uc->gsc); 281 xe_guc_stop_prepare(&uc->guc); 282} 283 284int xe_uc_suspend(struct xe_uc *uc) 285{ 286 /* GuC submission not enabled, nothing to do */ 287 if (!xe_device_uc_enabled(uc_to_xe(uc))) 288 return 0; 289 290 uc_reset_wait(uc); 291 292 xe_uc_stop(uc); 293 294 return xe_guc_suspend(&uc->guc); 295} 296 297/** 298 * xe_uc_runtime_suspend() - UC runtime suspend 299 * @uc: the UC object 300 * 301 * Runtime suspend all UCs. 302 */ 303void xe_uc_runtime_suspend(struct xe_uc *uc) 304{ 305 if (!xe_device_uc_enabled(uc_to_xe(uc))) 306 return; 307 308 xe_guc_runtime_suspend(&uc->guc); 309} 310 311/** 312 * xe_uc_runtime_resume() - UC runtime resume 313 * @uc: the UC object 314 * 315 * Runtime resume all UCs. 316 */ 317void xe_uc_runtime_resume(struct xe_uc *uc) 318{ 319 if (!xe_device_uc_enabled(uc_to_xe(uc))) 320 return; 321 322 xe_guc_runtime_resume(&uc->guc); 323} 324 325/** 326 * xe_uc_declare_wedged() - Declare UC wedged 327 * @uc: the UC object 328 * 329 * Wedge the UC which stops all submission, saves desired debug state, and 330 * cleans up anything which could timeout. 331 */ 332void xe_uc_declare_wedged(struct xe_uc *uc) 333{ 334 xe_gt_assert(uc_to_gt(uc), uc_to_xe(uc)->wedged.mode); 335 336 xe_guc_declare_wedged(&uc->guc); 337}