From: Lucas De Marchi Date: Wed, 27 Sep 2023 19:38:56 +0000 (-0700) Subject: drm/xe: Use vfunc to initialize PAT X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=b445be5710200501bba693fe6f9c614895412b94;p=linux.git 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: Matt Roper Link: https://lore.kernel.org/r/20230927193902.2849159-6-lucas.demarchi@intel.com Signed-off-by: Lucas De Marchi Signed-off-by: Rodrigo Vivi --- diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index 67ec55810ca35..113fca462141f 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -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) { diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index aa9935ff6d84e..c4920631677bd 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -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 */ diff --git a/drivers/gpu/drm/xe/xe_pat.c b/drivers/gpu/drm/xe/xe_pat.c index 71e0e047fff3b..28f401c500d8f 100644 --- a/drivers/gpu/drm/xe/xe_pat.c +++ b/drivers/gpu/drm/xe/xe_pat.c @@ -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, +}; + +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 + */ +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) { - /* - * 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)); + 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); +} diff --git a/drivers/gpu/drm/xe/xe_pat.h b/drivers/gpu/drm/xe/xe_pat.h index 659de40081316..168e80e63809a 100644 --- a/drivers/gpu/drm/xe/xe_pat.h +++ b/drivers/gpu/drm/xe/xe_pat.h @@ -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