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 v6.14-rc1 316 lines 5.9 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_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 off 41 * 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 load 74 * @uc: The UC object 75 * 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 hwconfig 130 * @uc: The UC object 131 * 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 every 176 * 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 removal 293 * @uc: the UC object 294 * 295 * This function should only act on objects/structures that must be cleaned 296 * before the driver removal callback is complete and therefore can't be 297 * 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 wedged 306 * @uc: the UC object 307 * 308 * Wedge the UC which stops all submission, saves desired debug state, and 309 * 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}