[Intel-xe] [PATCH v2 4/7] drm/xe/xe2: Program PAT tables
Balasubramani Vivekanandan
balasubramani.vivekanandan at intel.com
Fri Oct 6 07:35:24 UTC 2023
On 03.10.2023 05:52, Lucas De Marchi wrote:
> From: Matt Roper <matthew.d.roper at intel.com>
>
> The PAT tables become significantly more complicated on Xe2 platforms.
> They now control L3, L4, and coherency settings, as well as additional
> characteristics such as compression.
>
> Aside from the main PAT table, there's an additional register that
> also needs to be programmed with PAT settings for PCI Address
> Translation Services.
>
> Bspec: 71582
> Cc: Balasubramani Vivekanandan <balasubramani.vivekanandan at intel.com>
> Signed-off-by: Matt Roper <matthew.d.roper at intel.com>
> Signed-off-by: Lucas De Marchi <lucas.demarchi at intel.com>
Reviewed-by: Balasubramani Vivekanandan <balasubramani.vivekanandan at intel.com>
Regards,
Bala
> ---
> drivers/gpu/drm/xe/xe_pat.c | 92 ++++++++++++++++++++++++++++++++++++-
> 1 file changed, 91 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_pat.c b/drivers/gpu/drm/xe/xe_pat.c
> index 4668ca3932c5..296763594370 100644
> --- a/drivers/gpu/drm/xe/xe_pat.c
> +++ b/drivers/gpu/drm/xe/xe_pat.c
> @@ -10,10 +10,18 @@
> #include "xe_gt_mcr.h"
> #include "xe_mmio.h"
>
> +#define _PAT_ATS 0x47fc
> #define _PAT_INDEX(index) _PICK_EVEN_2RANGES(index, 8, \
> 0x4800, 0x4804, \
> 0x4848, 0x484c)
>
> +#define XE2_NO_PROMOTE REG_BIT(10)
> +#define XE2_COMP_EN REG_BIT(9)
> +#define XE2_L3_CLOS REG_GENMASK(7, 6)
> +#define XE2_L3_POLICY REG_GENMASK(5, 4)
> +#define XE2_L4_POLICY REG_GENMASK(3, 2)
> +#define XE2_COH_MODE REG_GENMASK(1, 0)
> +
> #define XELPG_L4_POLICY_MASK REG_GENMASK(3, 2)
> #define XELPG_PAT_3_UC REG_FIELD_PREP(XELPG_L4_POLICY_MASK, 3)
> #define XELPG_PAT_1_WT REG_FIELD_PREP(XELPG_L4_POLICY_MASK, 1)
> @@ -67,6 +75,64 @@ static const u32 xelpg_pat_table[] = {
> [4] = XELPG_PAT_0_WB | XELPG_3_COH_2W,
> };
>
> +/*
> + * The Xe2 table is getting large/complicated so it's easier to review if
> + * provided in a form that exactly matches the bspec's formatting. The meaning
> + * of the fields here are:
> + * - no_promote: 0=promotable, 1=no promote
> + * - comp_en: 0=disable, 1=enable
> + * - l3clos: L3 class of service (0-3)
> + * - l3_policy: 0=WB, 1=XD ("WB - Transient Display"), 3=UC
> + * - l4_policy: 0=WB, 1=WT, 3=UC
> + * - coh_mode: 0=no snoop, 2=1-way coherent, 3=2-way coherent
> + *
> + * Reserved entries should be programmed with the maximum caching, minimum
> + * coherency (which matches an all-0's encoding), so we can just omit them
> + * in the table.
> + */
> +#define XE2_PAT(no_promote, comp_en, l3clos, l3_policy, l4_policy, coh_mode) \
> + (no_promote ? XE2_NO_PROMOTE : 0) | \
> + (comp_en ? XE2_COMP_EN : 0) | \
> + REG_FIELD_PREP(XE2_L3_CLOS, l3clos) | \
> + REG_FIELD_PREP(XE2_L3_POLICY, l3_policy) | \
> + REG_FIELD_PREP(XE2_L4_POLICY, l4_policy) | \
> + REG_FIELD_PREP(XE2_COH_MODE, coh_mode)
> +
> +static const u32 xe2_pat_table[] = {
> + [ 0] = XE2_PAT( 0, 0, 0, 0, 3, 0 ),
> + [ 1] = XE2_PAT( 0, 0, 0, 0, 3, 2 ),
> + [ 2] = XE2_PAT( 0, 0, 0, 0, 3, 3 ),
> + [ 3] = XE2_PAT( 0, 0, 0, 3, 3, 0 ),
> + [ 4] = XE2_PAT( 0, 0, 0, 3, 0, 2 ),
> + [ 5] = XE2_PAT( 0, 0, 0, 3, 3, 2 ),
> + [ 6] = XE2_PAT( 1, 0, 0, 1, 3, 0 ),
> + [ 7] = XE2_PAT( 0, 0, 0, 3, 0, 3 ),
> + [ 8] = XE2_PAT( 0, 0, 0, 3, 0, 0 ),
> + [ 9] = XE2_PAT( 0, 1, 0, 0, 3, 0 ),
> + [10] = XE2_PAT( 0, 1, 0, 3, 0, 0 ),
> + [11] = XE2_PAT( 1, 1, 0, 1, 3, 0 ),
> + [12] = XE2_PAT( 0, 1, 0, 3, 3, 0 ),
> + [13] = XE2_PAT( 0, 0, 0, 0, 0, 0 ),
> + [14] = XE2_PAT( 0, 1, 0, 0, 0, 0 ),
> + [15] = XE2_PAT( 1, 1, 0, 1, 1, 0 ),
> + /* 16..19 are reserved; leave set to all 0's */
> + [20] = XE2_PAT( 0, 0, 1, 0, 3, 0 ),
> + [21] = XE2_PAT( 0, 1, 1, 0, 3, 0 ),
> + [22] = XE2_PAT( 0, 0, 1, 0, 3, 2 ),
> + [23] = XE2_PAT( 0, 0, 1, 0, 3, 3 ),
> + [24] = XE2_PAT( 0, 0, 2, 0, 3, 0 ),
> + [25] = XE2_PAT( 0, 1, 2, 0, 3, 0 ),
> + [26] = XE2_PAT( 0, 0, 2, 0, 3, 2 ),
> + [27] = XE2_PAT( 0, 0, 2, 0, 3, 3 ),
> + [28] = XE2_PAT( 0, 0, 3, 0, 3, 0 ),
> + [29] = XE2_PAT( 0, 1, 3, 0, 3, 0 ),
> + [30] = XE2_PAT( 0, 0, 3, 0, 3, 2 ),
> + [31] = XE2_PAT( 0, 0, 3, 0, 3, 3 ),
> +};
> +
> +/* Special PAT values programmed outside the main table */
> +#define XE2_PAT_ATS XE2_PAT( 0, 0, 0, 0, 3, 3 )
> +
> static void program_pat(struct xe_gt *gt, const u32 table[], int n_entries)
> {
> for (int i = 0; i < n_entries; i++) {
> @@ -102,9 +168,33 @@ static const struct xe_pat_ops xelpg_pat_ops = {
> .program_media = program_pat_mcr,
> };
>
> +static void xe2lpg_program_pat(struct xe_gt *gt, const u32 table[], int n_entries)
> +{
> + program_pat_mcr(gt, table, n_entries);
> + xe_gt_mcr_multicast_write(gt, XE_REG_MCR(_PAT_ATS), XE2_PAT_ATS);
> +}
> +
> +static void xe2lpm_program_pat(struct xe_gt *gt, const u32 table[], int n_entries)
> +{
> + program_pat(gt, table, n_entries);
> + xe_mmio_write32(gt, XE_REG(_PAT_ATS), XE2_PAT_ATS);
> +}
> +
> +static const struct xe_pat_ops xe2_pat_ops = {
> + .program_graphics = xe2lpg_program_pat,
> + .program_media = xe2lpm_program_pat,
> +};
> +
> void xe_pat_init_early(struct xe_device *xe)
> {
> - if (xe->info.platform == XE_METEORLAKE) {
> + if (GRAPHICS_VER(xe) == 20) {
> + xe->pat.ops = &xe2_pat_ops;
> + xe->pat.table = xe2_pat_table;
> + xe->pat.n_entries = ARRAY_SIZE(xe2_pat_table);
> + xe->pat.idx[XE_CACHE_NONE] = 3;
> + xe->pat.idx[XE_CACHE_WT] = 15;
> + xe->pat.idx[XE_CACHE_WB] = 2;
> + } else if (xe->info.platform == XE_METEORLAKE) {
> xe->pat.ops = &xelpg_pat_ops;
> xe->pat.table = xelpg_pat_table;
> xe->pat.n_entries = ARRAY_SIZE(xelpg_pat_table);
> --
> 2.40.1
>
More information about the Intel-xe
mailing list