summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/xe/xe_pat.c
blob: b56a65779d26baa601efe21d2fdf10c9d63ceda8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// SPDX-License-Identifier: MIT
/*
 * Copyright © 2023 Intel Corporation
 */

#include "xe_pat.h"

#include "regs/xe_reg_defs.h"
#include "xe_gt.h"
#include "xe_gt_mcr.h"
#include "xe_mmio.h"

#define _PAT_INDEX(index)			_PICK_EVEN_2RANGES(index, 8, \
								   0x4800, 0x4804, \
								   0x4848, 0x484c)

#define MTL_L4_POLICY_MASK			REG_GENMASK(3, 2)
#define MTL_PAT_3_UC				REG_FIELD_PREP(MTL_L4_POLICY_MASK, 3)
#define MTL_PAT_1_WT				REG_FIELD_PREP(MTL_L4_POLICY_MASK, 1)
#define MTL_PAT_0_WB				REG_FIELD_PREP(MTL_L4_POLICY_MASK, 0)
#define MTL_INDEX_COH_MODE_MASK			REG_GENMASK(1, 0)
#define MTL_3_COH_2W				REG_FIELD_PREP(MTL_INDEX_COH_MODE_MASK, 3)
#define MTL_2_COH_1W				REG_FIELD_PREP(MTL_INDEX_COH_MODE_MASK, 2)
#define MTL_0_COH_NON				REG_FIELD_PREP(MTL_INDEX_COH_MODE_MASK, 0)

#define PVC_CLOS_LEVEL_MASK			REG_GENMASK(3, 2)
#define PVC_PAT_CLOS(x)				REG_FIELD_PREP(PVC_CLOS_LEVEL_MASK, x)

#define TGL_MEM_TYPE_MASK			REG_GENMASK(1, 0)
#define TGL_PAT_WB				REG_FIELD_PREP(TGL_MEM_TYPE_MASK, 3)
#define TGL_PAT_WT				REG_FIELD_PREP(TGL_MEM_TYPE_MASK, 2)
#define TGL_PAT_WC				REG_FIELD_PREP(TGL_MEM_TYPE_MASK, 1)
#define TGL_PAT_UC				REG_FIELD_PREP(TGL_MEM_TYPE_MASK, 0)

static const u32 tgl_pat_table[] = {
	[0] = TGL_PAT_WB,
	[1] = TGL_PAT_WC,
	[2] = TGL_PAT_WT,
	[3] = TGL_PAT_UC,
	[4] = TGL_PAT_WB,
	[5] = TGL_PAT_WB,
	[6] = TGL_PAT_WB,
	[7] = TGL_PAT_WB,
};

static const u32 pvc_pat_table[] = {
	[0] = TGL_PAT_UC,
	[1] = TGL_PAT_WC,
	[2] = TGL_PAT_WT,
	[3] = TGL_PAT_WB,
	[4] = PVC_PAT_CLOS(1) | TGL_PAT_WT,
	[5] = PVC_PAT_CLOS(1) | TGL_PAT_WB,
	[6] = PVC_PAT_CLOS(2) | TGL_PAT_WT,
	[7] = PVC_PAT_CLOS(2) | TGL_PAT_WB,
};

static const u32 mtl_pat_table[] = {
	[0] = MTL_PAT_0_WB,
	[1] = MTL_PAT_1_WT,
	[2] = MTL_PAT_3_UC,
	[3] = MTL_PAT_0_WB | MTL_2_COH_1W,
	[4] = MTL_PAT_0_WB | MTL_3_COH_2W,
};

static void program_pat(struct xe_gt *gt, const u32 table[], int n_entries)
{
	for (int i = 0; i < n_entries; i++) {
		struct xe_reg reg = XE_REG(_PAT_INDEX(i));

		xe_mmio_write32(gt, reg, table[i]);
	}
}

static void program_pat_mcr(struct xe_gt *gt, const u32 table[], int n_entries)
{
	for (int i = 0; i < n_entries; i++) {
		struct xe_reg_mcr reg_mcr = XE_REG_MCR(_PAT_INDEX(i));

		xe_gt_mcr_multicast_write(gt, reg_mcr, table[i]);
	}
}

void xe_pat_init(struct xe_gt *gt)
{
	struct xe_device *xe = gt_to_xe(gt);

	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));
	} else if (xe->info.platform == XE_PVC || xe->info.platform == XE_DG2) {
		program_pat_mcr(gt, pvc_pat_table, ARRAY_SIZE(pvc_pat_table));
	} else if (GRAPHICS_VERx100(xe) <= 1210) {
		program_pat(gt, tgl_pat_table, ARRAY_SIZE(tgl_pat_table));
	} else {
		/*
		 * Going forward we expect to need new PAT settings for most
		 * new platforms; failure to provide a new table can easily
		 * lead to subtle, hard-to-debug problems.  If none of the
		 * conditions above match the platform we're running on we'll
		 * raise an error rather than trying to silently inherit the
		 * most recent platform's behavior.
		 */
		drm_err(&xe->drm, "Missing PAT table for platform with graphics version %d.%2d!\n",
			GRAPHICS_VER(xe), GRAPHICS_VERx100(xe) % 100);
	}
}