Skip to content

Commit 661a695

Browse files
msatwoodLucas De Marchi
authored andcommitted
drm/xe: Add infrastructure for Device OOB workarounds
Some workarounds need to be able to be applied ahead of any GT initialization for example 15015404425. This patch creates XE_DEVICE_WA macro, in the same vein as XE_WA. This macro can be used ahead of GT initialization, and can be tracked in sysfs. This should alleviate some of the complexities that exist in i915. v2: name change SoC to Device, address style issues v5: split into separate patch from RTP changes, put oob within a struct, move the initiation of oob workarounds into xe_device_probe_early(), clean up the comments around XE_WA. Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> Signed-off-by: Matt Atwood <matthew.s.atwood@intel.com> Link: https://lore.kernel.org/r/20250709221605.172516-5-matthew.s.atwood@intel.com Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
1 parent e7201d9 commit 661a695

5 files changed

Lines changed: 108 additions & 2 deletions

File tree

drivers/gpu/drm/xe/xe_debugfs.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "xe_pxp_debugfs.h"
2222
#include "xe_sriov.h"
2323
#include "xe_step.h"
24+
#include "xe_wa.h"
2425

2526
#ifdef CONFIG_DRM_XE_DEBUG
2627
#include "xe_bo_evict.h"
@@ -82,9 +83,28 @@ static int sriov_info(struct seq_file *m, void *data)
8283
return 0;
8384
}
8485

86+
static int workarounds(struct xe_device *xe, struct drm_printer *p)
87+
{
88+
xe_pm_runtime_get(xe);
89+
xe_wa_device_dump(xe, p);
90+
xe_pm_runtime_put(xe);
91+
92+
return 0;
93+
}
94+
95+
static int workaround_info(struct seq_file *m, void *data)
96+
{
97+
struct xe_device *xe = node_to_xe(m->private);
98+
struct drm_printer p = drm_seq_file_printer(m);
99+
100+
workarounds(xe, &p);
101+
return 0;
102+
}
103+
85104
static const struct drm_info_list debugfs_list[] = {
86105
{"info", info, 0},
87106
{ .name = "sriov_info", .show = sriov_info, },
107+
{ .name = "workarounds", .show = workaround_info, },
88108
};
89109

90110
static int forcewake_open(struct inode *inode, struct file *file)

drivers/gpu/drm/xe/xe_device.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,9 @@ int xe_device_probe_early(struct xe_device *xe)
700700
{
701701
int err;
702702

703+
xe_wa_device_init(xe);
704+
xe_wa_process_device_oob(xe);
705+
703706
err = xe_mmio_probe_early(xe);
704707
if (err)
705708
return err;

drivers/gpu/drm/xe/xe_device_types.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,18 @@ struct xe_device {
363363
u8 skip_pcode:1;
364364
} info;
365365

366+
struct {
367+
/** @wa_active.oob: bitmap with active OOB workarounds */
368+
unsigned long *oob;
369+
370+
/**
371+
* @wa_active.oob_initialized: Mark oob as initialized to help detecting misuse
372+
* of XE_DEVICE_WA() - it can only be called on initialization after
373+
* Device OOB WAs have been processed.
374+
*/
375+
bool oob_initialized;
376+
} wa_active;
377+
366378
/** @survivability: survivability information for device */
367379
struct xe_survivability survivability;
368380

drivers/gpu/drm/xe/xe_wa.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/compiler_types.h>
1111
#include <linux/fault-inject.h>
1212

13+
#include <generated/xe_device_wa_oob.h>
1314
#include <generated/xe_wa_oob.h>
1415

1516
#include "regs/xe_engine_regs.h"
@@ -876,8 +877,33 @@ static __maybe_unused const struct xe_rtp_entry oob_was[] = {
876877

877878
static_assert(ARRAY_SIZE(oob_was) - 1 == _XE_WA_OOB_COUNT);
878879

880+
static __maybe_unused const struct xe_rtp_entry device_oob_was[] = {
881+
#include <generated/xe_device_wa_oob.c>
882+
{}
883+
};
884+
885+
static_assert(ARRAY_SIZE(device_oob_was) - 1 == _XE_DEVICE_WA_OOB_COUNT);
886+
879887
__diag_pop();
880888

889+
/**
890+
* xe_wa_process_device_oob - process OOB workaround table
891+
* @xe: device instance to process workarounds for
892+
*
893+
* process OOB workaround table for this device, marking in @xe the
894+
* workarounds that are active.
895+
*/
896+
897+
void xe_wa_process_device_oob(struct xe_device *xe)
898+
{
899+
struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(xe);
900+
901+
xe_rtp_process_ctx_enable_active_tracking(&ctx, xe->wa_active.oob, ARRAY_SIZE(device_oob_was));
902+
903+
xe->wa_active.oob_initialized = true;
904+
xe_rtp_process(&ctx, device_oob_was);
905+
}
906+
881907
/**
882908
* xe_wa_process_oob - process OOB workaround table
883909
* @gt: GT instance to process workarounds for
@@ -946,6 +972,28 @@ void xe_wa_process_lrc(struct xe_hw_engine *hwe)
946972
xe_rtp_process_to_sr(&ctx, lrc_was, ARRAY_SIZE(lrc_was), &hwe->reg_lrc);
947973
}
948974

975+
/**
976+
* xe_wa_device_init - initialize device with workaround oob bookkeeping
977+
* @xe: Xe device instance to initialize
978+
*
979+
* Returns 0 for success, negative with error code otherwise
980+
*/
981+
int xe_wa_device_init(struct xe_device *xe)
982+
{
983+
unsigned long *p;
984+
985+
p = drmm_kzalloc(&xe->drm,
986+
sizeof(*p) * BITS_TO_LONGS(ARRAY_SIZE(device_oob_was)),
987+
GFP_KERNEL);
988+
989+
if (!p)
990+
return -ENOMEM;
991+
992+
xe->wa_active.oob = p;
993+
994+
return 0;
995+
}
996+
949997
/**
950998
* xe_wa_init - initialize gt with workaround bookkeeping
951999
* @gt: GT instance to initialize
@@ -980,6 +1028,16 @@ int xe_wa_init(struct xe_gt *gt)
9801028
}
9811029
ALLOW_ERROR_INJECTION(xe_wa_init, ERRNO); /* See xe_pci_probe() */
9821030

1031+
void xe_wa_device_dump(struct xe_device *xe, struct drm_printer *p)
1032+
{
1033+
size_t idx;
1034+
1035+
drm_printf(p, "Device OOB Workarounds\n");
1036+
for_each_set_bit(idx, xe->wa_active.oob, ARRAY_SIZE(device_oob_was))
1037+
if (device_oob_was[idx].name)
1038+
drm_printf_indent(p, 1, "%s\n", device_oob_was[idx].name);
1039+
}
1040+
9831041
void xe_wa_dump(struct xe_gt *gt, struct drm_printer *p)
9841042
{
9851043
size_t idx;

drivers/gpu/drm/xe/xe_wa.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,19 @@ struct xe_gt;
1313
struct xe_hw_engine;
1414
struct xe_tile;
1515

16+
int xe_wa_device_init(struct xe_device *xe);
1617
int xe_wa_init(struct xe_gt *gt);
18+
void xe_wa_process_device_oob(struct xe_device *xe);
1719
void xe_wa_process_oob(struct xe_gt *gt);
1820
void xe_wa_process_gt(struct xe_gt *gt);
1921
void xe_wa_process_engine(struct xe_hw_engine *hwe);
2022
void xe_wa_process_lrc(struct xe_hw_engine *hwe);
2123
void xe_wa_apply_tile_workarounds(struct xe_tile *tile);
24+
void xe_wa_device_dump(struct xe_device *xe, struct drm_printer *p);
2225
void xe_wa_dump(struct xe_gt *gt, struct drm_printer *p);
2326

2427
/**
25-
* XE_WA - Out-of-band workarounds, that don't fit the lifecycle any
26-
* other more specific type
28+
* XE_WA - Out-of-band workarounds, to be queried and called as needed.
2729
* @gt__: gt instance
2830
* @id__: XE_OOB_<id__>, as generated by build system in generated/xe_wa_oob.h
2931
*/
@@ -32,4 +34,15 @@ void xe_wa_dump(struct xe_gt *gt, struct drm_printer *p);
3234
test_bit(XE_WA_OOB_ ## id__, (gt__)->wa_active.oob); \
3335
})
3436

37+
/**
38+
* XE_DEVICE_WA - Out-of-band Device workarounds, to be queried and called
39+
* as needed.
40+
* @xe__: xe_device
41+
* @id__: XE_DEVICE_WA_OOB_<id__>, as generated by build system in generated/xe_device_wa_oob.h
42+
*/
43+
#define XE_DEVICE_WA(xe__, id__) ({ \
44+
xe_assert(xe__, (xe__)->wa_active.oob_initialized); \
45+
test_bit(XE_DEVICE_WA_OOB_ ## id__, (xe__)->wa_active.oob); \
46+
})
47+
3548
#endif

0 commit comments

Comments
 (0)