Commit b445be57 authored by Lucas De Marchi's avatar Lucas De Marchi Committed by Rodrigo Vivi

drm/xe: Use vfunc to initialize PAT

Split the PAT initialization between SW-only and HW. The _early() only
sets up the ops and data structure that are used later to program the
tables. This allows the PAT to be easily extended to other platforms.
Reviewed-by: default avatarMatt Roper <matthew.d.roper@intel.com>
Link: https://lore.kernel.org/r/20230927193902.2849159-6-lucas.demarchi@intel.comSigned-off-by: default avatarLucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
parent 23c8495e
......@@ -25,6 +25,7 @@
#include "xe_irq.h"
#include "xe_mmio.h"
#include "xe_module.h"
#include "xe_pat.h"
#include "xe_pcode.h"
#include "xe_pm.h"
#include "xe_query.h"
......@@ -268,6 +269,8 @@ int xe_device_probe(struct xe_device *xe)
int err;
u8 id;
xe_pat_init_early(xe);
xe->info.mem_region_mask = 1;
for_each_tile(tile, xe, id) {
......
......@@ -19,6 +19,7 @@
#include "xe_step_types.h"
struct xe_ggtt;
struct xe_pat_ops;
#define XE_BO_INVALID_OFFSET LONG_MAX
......@@ -310,6 +311,18 @@ struct xe_device {
atomic_t ref;
} mem_access;
/**
* @pat: Encapsulate PAT related stuff
*/
struct {
/** Internal operations to abstract platforms */
const struct xe_pat_ops *ops;
/** PAT table to program in the HW */
const u32 *table;
/** Number of PAT entries */
int n_entries;
} pat;
/** @d3cold: Encapsulate d3cold related stuff */
struct {
/** capable: Indicates if root port is d3cold capable */
......
......@@ -32,6 +32,11 @@
#define TGL_PAT_WC REG_FIELD_PREP(TGL_MEM_TYPE_MASK, 1)
#define TGL_PAT_UC REG_FIELD_PREP(TGL_MEM_TYPE_MASK, 0)
struct xe_pat_ops {
void (*program_graphics)(struct xe_gt *gt, const u32 table[], int n_entries);
void (*program_media)(struct xe_gt *gt, const u32 table[], int n_entries);
};
static const u32 tgl_pat_table[] = {
[0] = TGL_PAT_WB,
[1] = TGL_PAT_WC,
......@@ -80,24 +85,37 @@ static void program_pat_mcr(struct xe_gt *gt, const u32 table[], int n_entries)
}
}
void xe_pat_init(struct xe_gt *gt)
{
struct xe_device *xe = gt_to_xe(gt);
static const struct xe_pat_ops tgl_pat_ops = {
.program_graphics = program_pat,
};
if (xe->info.platform == XE_METEORLAKE) {
/*
* SAMedia register offsets are adjusted by the write methods
* and they target registers that are not MCR, while for normal
* GT they are MCR
static const struct xe_pat_ops dg2_pat_ops = {
.program_graphics = program_pat_mcr,
};
/*
* SAMedia register offsets are adjusted by the write methods and they target
* registers that are not MCR, while for normal GT they are MCR
*/
if (xe_gt_is_media_type(gt))
program_pat(gt, mtl_pat_table, ARRAY_SIZE(mtl_pat_table));
else
program_pat_mcr(gt, mtl_pat_table, ARRAY_SIZE(mtl_pat_table));
static const struct xe_pat_ops mtl_pat_ops = {
.program_graphics = program_pat,
.program_media = program_pat_mcr,
};
void xe_pat_init_early(struct xe_device *xe)
{
if (xe->info.platform == XE_METEORLAKE) {
xe->pat.ops = &mtl_pat_ops;
xe->pat.table = mtl_pat_table;
xe->pat.n_entries = ARRAY_SIZE(mtl_pat_table);
} else if (xe->info.platform == XE_PVC || xe->info.platform == XE_DG2) {
program_pat_mcr(gt, pvc_pat_table, ARRAY_SIZE(pvc_pat_table));
xe->pat.ops = &dg2_pat_ops;
xe->pat.table = pvc_pat_table;
xe->pat.n_entries = ARRAY_SIZE(pvc_pat_table);
} else if (GRAPHICS_VERx100(xe) <= 1210) {
program_pat(gt, tgl_pat_table, ARRAY_SIZE(tgl_pat_table));
xe->pat.ops = &tgl_pat_ops;
xe->pat.table = tgl_pat_table;
xe->pat.n_entries = ARRAY_SIZE(tgl_pat_table);
} else {
/*
* Going forward we expect to need new PAT settings for most
......@@ -111,3 +129,16 @@ void xe_pat_init(struct xe_gt *gt)
GRAPHICS_VER(xe), GRAPHICS_VERx100(xe) % 100);
}
}
void xe_pat_init(struct xe_gt *gt)
{
struct xe_device *xe = gt_to_xe(gt);
if (!xe->pat.ops)
return;
if (xe_gt_is_media_type(gt))
xe->pat.ops->program_media(gt, xe->pat.table, xe->pat.n_entries);
else
xe->pat.ops->program_graphics(gt, xe->pat.table, xe->pat.n_entries);
}
......@@ -7,7 +7,18 @@
#define _XE_PAT_H_
struct xe_gt;
struct xe_device;
/**
* xe_pat_init_early - SW initialization, setting up data based on device
* @xe: xe device
*/
void xe_pat_init_early(struct xe_device *xe);
/**
* xe_pat_init - Program HW PAT table
* @gt: GT structure
*/
void xe_pat_init(struct xe_gt *gt);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment