Commit 0d053475 authored by Matt Roper's avatar Matt Roper Committed by Rodrigo Vivi
Browse files

drm/xe/wa: Apply tile workarounds at probe/resume



Although the vast majority of workarounds the driver needs to implement
are either GT-based or display-based, there are occasionally workarounds
that reside outside those parts of the hardware (i.e., in they target
registers in the sgunit/soc); we can consider these to be "tile"
workarounds since there will be instance of these registers per tile.
The registers in question should only lose their values during a
function-level reset, so they only need to be applied during probe and
resume; the registers will not be affected by GT/engine resets.

Tile workarounds are rare (there's only one, 22010954014, that's
relevant to Xe at the moment) so it's probably not worth updating the
xe_rtp design to handle tile-level workarounds yet, although we may want
to consider that in the future if/when more of these show up on future
platforms.

Reviewed-by: default avatarLucas De Marchi <lucas.demarchi@intel.com>
Acked-by: default avatarJani Nikula <jani.nikula@intel.com>
Link: https://lore.kernel.org/r/20230913231411.291933-13-matthew.d.roper@intel.com


Signed-off-by: default avatarMatt Roper <matthew.d.roper@intel.com>
Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
parent 7764222d
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -69,6 +69,9 @@
#define GU_CNTL					XE_REG(0x101010)
#define   LMEM_INIT				REG_BIT(7)

#define XEHP_CLOCK_GATE_DIS			XE_REG(0x101014)
#define   SGSI_SIDECLK_DIS			REG_BIT(17)

#define GGC					XE_REG(0x108040)
#define   GMS_MASK				REG_GENMASK(15, 8)
#define   GGMS_MASK				REG_GENMASK(7, 6)
+5 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include "xe_guc.h"
#include "xe_irq.h"
#include "xe_pcode.h"
#include "xe_wa.h"

/**
 * DOC: Xe Power Management
@@ -79,10 +80,14 @@ int xe_pm_suspend(struct xe_device *xe)
 */
int xe_pm_resume(struct xe_device *xe)
{
	struct xe_tile *tile;
	struct xe_gt *gt;
	u8 id;
	int err;

	for_each_tile(tile, xe, id)
		xe_wa_apply_tile_workarounds(tile);

	for_each_gt(gt, xe, id) {
		err = xe_pcode_init(gt);
		if (err)
+3 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include "xe_tile.h"
#include "xe_tile_sysfs.h"
#include "xe_ttm_vram_mgr.h"
#include "xe_wa.h"

/**
 * DOC: Multi-tile Design
@@ -143,6 +144,8 @@ int xe_tile_init_noalloc(struct xe_tile *tile)
	if (IS_ERR(tile->mem.kernel_bb_pool))
		err = PTR_ERR(tile->mem.kernel_bb_pool);

	xe_wa_apply_tile_workarounds(tile);

	xe_tile_sysfs_init(tile);

err_mem_access:
+20 −0
Original line number Diff line number Diff line
@@ -753,3 +753,23 @@ void xe_wa_dump(struct xe_gt *gt, struct drm_printer *p)
		if (oob_was[idx].name)
			drm_printf_indent(p, 1, "%s\n", oob_was[idx].name);
}

/*
 * Apply tile (non-GT, non-display) workarounds.  Think very carefully before
 * adding anything to this function; most workarounds should be implemented
 * elsewhere.  The programming here is primarily for sgunit/soc workarounds,
 * which are relatively rare.  Since the registers these workarounds target are
 * outside the GT, they should only need to be applied once at device
 * probe/resume; they will not lose their values on any kind of GT or engine
 * reset.
 *
 * TODO:  We may want to move this over to xe_rtp in the future once we have
 * enough workarounds to justify the work.
 */
void xe_wa_apply_tile_workarounds(struct xe_tile *tile)
{
	struct xe_gt *mmio = tile->primary_gt;

	if (XE_WA(mmio, 22010954014))
		xe_mmio_rmw32(mmio, XEHP_CLOCK_GATE_DIS, 0, SGSI_SIDECLK_DIS);
}
+2 −0
Original line number Diff line number Diff line
@@ -9,12 +9,14 @@
struct drm_printer;
struct xe_gt;
struct xe_hw_engine;
struct xe_tile;

int xe_wa_init(struct xe_gt *gt);
void xe_wa_process_oob(struct xe_gt *gt);
void xe_wa_process_gt(struct xe_gt *gt);
void xe_wa_process_engine(struct xe_hw_engine *hwe);
void xe_wa_process_lrc(struct xe_hw_engine *hwe);
void xe_wa_apply_tile_workarounds(struct xe_tile *tile);

void xe_reg_whitelist_process_engine(struct xe_hw_engine *hwe);
void xe_wa_dump(struct xe_gt *gt, struct drm_printer *p);
Loading