|
32 | 32 | #include "xe_guc_ct.h" |
33 | 33 | #include "xe_guc_exec_queue_types.h" |
34 | 34 | #include "xe_guc_id_mgr.h" |
| 35 | +#include "xe_guc_klv_helpers.h" |
35 | 36 | #include "xe_guc_submit_types.h" |
36 | 37 | #include "xe_hw_engine.h" |
37 | 38 | #include "xe_hw_fence.h" |
@@ -316,6 +317,71 @@ int xe_guc_submit_init(struct xe_guc *guc, unsigned int num_ids) |
316 | 317 | return drmm_add_action_or_reset(&xe->drm, guc_submit_fini, guc); |
317 | 318 | } |
318 | 319 |
|
| 320 | +/* |
| 321 | + * Given that we want to guarantee enough RCS throughput to avoid missing |
| 322 | + * frames, we set the yield policy to 20% of each 80ms interval. |
| 323 | + */ |
| 324 | +#define RC_YIELD_DURATION 80 /* in ms */ |
| 325 | +#define RC_YIELD_RATIO 20 /* in percent */ |
| 326 | +static u32 *emit_render_compute_yield_klv(u32 *emit) |
| 327 | +{ |
| 328 | + *emit++ = PREP_GUC_KLV_TAG(SCHEDULING_POLICIES_RENDER_COMPUTE_YIELD); |
| 329 | + *emit++ = RC_YIELD_DURATION; |
| 330 | + *emit++ = RC_YIELD_RATIO; |
| 331 | + |
| 332 | + return emit; |
| 333 | +} |
| 334 | + |
| 335 | +#define SCHEDULING_POLICY_MAX_DWORDS 16 |
| 336 | +static int guc_init_global_schedule_policy(struct xe_guc *guc) |
| 337 | +{ |
| 338 | + u32 data[SCHEDULING_POLICY_MAX_DWORDS]; |
| 339 | + u32 *emit = data; |
| 340 | + u32 count = 0; |
| 341 | + int ret; |
| 342 | + |
| 343 | + if (GUC_SUBMIT_VER(guc) < MAKE_GUC_VER(1, 1, 0)) |
| 344 | + return 0; |
| 345 | + |
| 346 | + *emit++ = XE_GUC_ACTION_UPDATE_SCHEDULING_POLICIES_KLV; |
| 347 | + |
| 348 | + if (CCS_MASK(guc_to_gt(guc))) |
| 349 | + emit = emit_render_compute_yield_klv(emit); |
| 350 | + |
| 351 | + count = emit - data; |
| 352 | + if (count > 1) { |
| 353 | + xe_assert(guc_to_xe(guc), count <= SCHEDULING_POLICY_MAX_DWORDS); |
| 354 | + |
| 355 | + ret = xe_guc_ct_send_block(&guc->ct, data, count); |
| 356 | + if (ret < 0) { |
| 357 | + xe_gt_err(guc_to_gt(guc), |
| 358 | + "failed to enable GuC sheduling policies: %pe\n", |
| 359 | + ERR_PTR(ret)); |
| 360 | + return ret; |
| 361 | + } |
| 362 | + } |
| 363 | + |
| 364 | + return 0; |
| 365 | +} |
| 366 | + |
| 367 | +int xe_guc_submit_enable(struct xe_guc *guc) |
| 368 | +{ |
| 369 | + int ret; |
| 370 | + |
| 371 | + ret = guc_init_global_schedule_policy(guc); |
| 372 | + if (ret) |
| 373 | + return ret; |
| 374 | + |
| 375 | + guc->submission_state.enabled = true; |
| 376 | + |
| 377 | + return 0; |
| 378 | +} |
| 379 | + |
| 380 | +void xe_guc_submit_disable(struct xe_guc *guc) |
| 381 | +{ |
| 382 | + guc->submission_state.enabled = false; |
| 383 | +} |
| 384 | + |
319 | 385 | static void __release_guc_id(struct xe_guc *guc, struct xe_exec_queue *q, u32 xa_count) |
320 | 386 | { |
321 | 387 | int i; |
|
0 commit comments