|
8 | 8 | #include <linux/nospec.h> |
9 | 9 |
|
10 | 10 | #include <drm/drm_managed.h> |
| 11 | +#include <drm/drm_print.h> |
11 | 12 | #include <uapi/drm/xe_drm.h> |
| 13 | +#include <generated/xe_wa_oob.h> |
12 | 14 |
|
13 | 15 | #include "regs/xe_engine_regs.h" |
14 | 16 | #include "regs/xe_gt_regs.h" |
|
21 | 23 | #include "xe_gsc.h" |
22 | 24 | #include "xe_gt.h" |
23 | 25 | #include "xe_gt_ccs_mode.h" |
| 26 | +#include "xe_gt_clock.h" |
24 | 27 | #include "xe_gt_printk.h" |
25 | 28 | #include "xe_gt_mcr.h" |
26 | 29 | #include "xe_gt_topology.h" |
@@ -564,6 +567,33 @@ static void hw_engine_init_early(struct xe_gt *gt, struct xe_hw_engine *hwe, |
564 | 567 | xe_reg_whitelist_process_engine(hwe); |
565 | 568 | } |
566 | 569 |
|
| 570 | +static void adjust_idledly(struct xe_hw_engine *hwe) |
| 571 | +{ |
| 572 | + struct xe_gt *gt = hwe->gt; |
| 573 | + u32 idledly, maxcnt; |
| 574 | + u32 idledly_units_ps = 8 * gt->info.timestamp_base; |
| 575 | + u32 maxcnt_units_ns = 640; |
| 576 | + bool inhibit_switch = 0; |
| 577 | + |
| 578 | + if (!IS_SRIOV_VF(gt_to_xe(hwe->gt)) && XE_WA(gt, 16023105232)) { |
| 579 | + idledly = xe_mmio_read32(>->mmio, RING_IDLEDLY(hwe->mmio_base)); |
| 580 | + maxcnt = xe_mmio_read32(>->mmio, RING_PWRCTX_MAXCNT(hwe->mmio_base)); |
| 581 | + |
| 582 | + inhibit_switch = idledly & INHIBIT_SWITCH_UNTIL_PREEMPTED; |
| 583 | + idledly = REG_FIELD_GET(IDLE_DELAY, idledly); |
| 584 | + idledly = DIV_ROUND_CLOSEST(idledly * idledly_units_ps, 1000); |
| 585 | + maxcnt = REG_FIELD_GET(IDLE_WAIT_TIME, maxcnt); |
| 586 | + maxcnt *= maxcnt_units_ns; |
| 587 | + |
| 588 | + if (xe_gt_WARN_ON(gt, idledly >= maxcnt || inhibit_switch)) { |
| 589 | + idledly = DIV_ROUND_CLOSEST(((maxcnt - 1) * maxcnt_units_ns), |
| 590 | + idledly_units_ps); |
| 591 | + idledly = DIV_ROUND_CLOSEST(idledly, 1000); |
| 592 | + xe_mmio_write32(>->mmio, RING_IDLEDLY(hwe->mmio_base), idledly); |
| 593 | + } |
| 594 | + } |
| 595 | +} |
| 596 | + |
567 | 597 | static int hw_engine_init(struct xe_gt *gt, struct xe_hw_engine *hwe, |
568 | 598 | enum xe_hw_engine_id id) |
569 | 599 | { |
@@ -604,6 +634,9 @@ static int hw_engine_init(struct xe_gt *gt, struct xe_hw_engine *hwe, |
604 | 634 | if (xe->info.has_usm && hwe->class == XE_ENGINE_CLASS_COPY) |
605 | 635 | gt->usm.reserved_bcs_instance = hwe->instance; |
606 | 636 |
|
| 637 | + /* Ensure IDLEDLY is lower than MAXCNT */ |
| 638 | + adjust_idledly(hwe); |
| 639 | + |
607 | 640 | return devm_add_action_or_reset(xe->drm.dev, hw_engine_fini, hwe); |
608 | 641 |
|
609 | 642 | err_hwsp: |
|
0 commit comments