1/* SPDX-License-Identifier: GPL-2.0-only */
2
3/* Store the full address of the global discovery table */
4#define UNCORE_DISCOVERY_MSR 0x201e
5
6/* Generic device ID of a discovery table device */
7#define UNCORE_DISCOVERY_TABLE_DEVICE 0x09a7
8/* Capability ID for a discovery table device */
9#define UNCORE_EXT_CAP_ID_DISCOVERY 0x23
10/* First DVSEC offset */
11#define UNCORE_DISCOVERY_DVSEC_OFFSET 0x8
12/* Mask of the supported discovery entry type */
13#define UNCORE_DISCOVERY_DVSEC_ID_MASK 0xffff
14/* PMON discovery entry type ID */
15#define UNCORE_DISCOVERY_DVSEC_ID_PMON 0x1
16/* Second DVSEC offset */
17#define UNCORE_DISCOVERY_DVSEC2_OFFSET 0xc
18/* Mask of the discovery table BAR offset */
19#define UNCORE_DISCOVERY_DVSEC2_BIR_MASK 0x7
20/* Discovery table BAR base offset */
21#define UNCORE_DISCOVERY_BIR_BASE 0x10
22/* Discovery table BAR step */
23#define UNCORE_DISCOVERY_BIR_STEP 0x4
24/* Global discovery table size */
25#define UNCORE_DISCOVERY_GLOBAL_MAP_SIZE 0x20
26
27#define UNCORE_DISCOVERY_PCI_DOMAIN_OFFSET 28
28#define UNCORE_DISCOVERY_PCI_DOMAIN(data) \
29 ((data >> UNCORE_DISCOVERY_PCI_DOMAIN_OFFSET) & 0x7)
30#define UNCORE_DISCOVERY_PCI_BUS_OFFSET 20
31#define UNCORE_DISCOVERY_PCI_BUS(data) \
32 ((data >> UNCORE_DISCOVERY_PCI_BUS_OFFSET) & 0xff)
33#define UNCORE_DISCOVERY_PCI_DEVFN_OFFSET 12
34#define UNCORE_DISCOVERY_PCI_DEVFN(data) \
35 ((data >> UNCORE_DISCOVERY_PCI_DEVFN_OFFSET) & 0xff)
36#define UNCORE_DISCOVERY_PCI_BOX_CTRL(data) (data & 0xfff)
37
38
39#define uncore_discovery_invalid_unit(unit) \
40 (!unit.table1 || !unit.ctl || \
41 unit.table1 == -1ULL || unit.ctl == -1ULL || \
42 unit.table3 == -1ULL)
43
44#define GENERIC_PMON_CTL_EV_SEL_MASK 0x000000ff
45#define GENERIC_PMON_CTL_UMASK_MASK 0x0000ff00
46#define GENERIC_PMON_CTL_EDGE_DET (1 << 18)
47#define GENERIC_PMON_CTL_INVERT (1 << 23)
48#define GENERIC_PMON_CTL_TRESH_MASK 0xff000000
49#define GENERIC_PMON_RAW_EVENT_MASK (GENERIC_PMON_CTL_EV_SEL_MASK | \
50 GENERIC_PMON_CTL_UMASK_MASK | \
51 GENERIC_PMON_CTL_EDGE_DET | \
52 GENERIC_PMON_CTL_INVERT | \
53 GENERIC_PMON_CTL_TRESH_MASK)
54
55#define GENERIC_PMON_BOX_CTL_FRZ (1 << 0)
56#define GENERIC_PMON_BOX_CTL_RST_CTRL (1 << 8)
57#define GENERIC_PMON_BOX_CTL_RST_CTRS (1 << 9)
58#define GENERIC_PMON_BOX_CTL_INT (GENERIC_PMON_BOX_CTL_RST_CTRL | \
59 GENERIC_PMON_BOX_CTL_RST_CTRS)
60
61enum uncore_access_type {
62 UNCORE_ACCESS_MSR = 0,
63 UNCORE_ACCESS_MMIO,
64 UNCORE_ACCESS_PCI,
65
66 UNCORE_ACCESS_MAX,
67};
68
69struct uncore_global_discovery {
70 union {
71 u64 table1;
72 struct {
73 u64 type : 8,
74 stride : 8,
75 max_units : 10,
76 __reserved_1 : 36,
77 access_type : 2;
78 };
79 };
80
81 u64 ctl; /* Global Control Address */
82
83 union {
84 u64 table3;
85 struct {
86 u64 status_offset : 8,
87 num_status : 16,
88 __reserved_2 : 40;
89 };
90 };
91};
92
93struct uncore_unit_discovery {
94 union {
95 u64 table1;
96 struct {
97 u64 num_regs : 8,
98 ctl_offset : 8,
99 bit_width : 8,
100 ctr_offset : 8,
101 status_offset : 8,
102 __reserved_1 : 22,
103 access_type : 2;
104 };
105 };
106
107 u64 ctl; /* Unit Control Address */
108
109 union {
110 u64 table3;
111 struct {
112 u64 box_type : 16,
113 box_id : 16,
114 __reserved_2 : 32;
115 };
116 };
117};
118
119struct intel_uncore_discovery_unit {
120 struct rb_node node;
121 unsigned int pmu_idx; /* The idx of the corresponding PMU */
122 unsigned int id; /* Unit ID */
123 unsigned int die; /* Die ID */
124 u64 addr; /* Unit Control Address */
125};
126
127struct intel_uncore_discovery_type {
128 struct rb_node node;
129 enum uncore_access_type access_type;
130 struct rb_root units; /* Unit ctrl addr for all units */
131 u16 type; /* Type ID of the uncore block */
132 u8 num_counters;
133 u8 counter_width;
134 u8 ctl_offset; /* Counter Control 0 offset */
135 u8 ctr_offset; /* Counter 0 offset */
136 u16 num_units; /* number of units */
137};
138
139bool intel_uncore_has_discovery_tables(int *ignore);
140void intel_uncore_clear_discovery_tables(void);
141void intel_uncore_generic_uncore_cpu_init(void);
142int intel_uncore_generic_uncore_pci_init(void);
143void intel_uncore_generic_uncore_mmio_init(void);
144
145void intel_generic_uncore_msr_init_box(struct intel_uncore_box *box);
146void intel_generic_uncore_msr_disable_box(struct intel_uncore_box *box);
147void intel_generic_uncore_msr_enable_box(struct intel_uncore_box *box);
148
149void intel_generic_uncore_mmio_init_box(struct intel_uncore_box *box);
150void intel_generic_uncore_mmio_disable_box(struct intel_uncore_box *box);
151void intel_generic_uncore_mmio_enable_box(struct intel_uncore_box *box);
152void intel_generic_uncore_mmio_disable_event(struct intel_uncore_box *box,
153 struct perf_event *event);
154void intel_generic_uncore_mmio_enable_event(struct intel_uncore_box *box,
155 struct perf_event *event);
156
157void intel_generic_uncore_pci_init_box(struct intel_uncore_box *box);
158void intel_generic_uncore_pci_disable_box(struct intel_uncore_box *box);
159void intel_generic_uncore_pci_enable_box(struct intel_uncore_box *box);
160void intel_generic_uncore_pci_disable_event(struct intel_uncore_box *box,
161 struct perf_event *event);
162u64 intel_generic_uncore_pci_read_counter(struct intel_uncore_box *box,
163 struct perf_event *event);
164
165struct intel_uncore_type **
166intel_uncore_generic_init_uncores(enum uncore_access_type type_id, int num_extra);
167
168int intel_uncore_find_discovery_unit_id(struct rb_root *units, int die,
169 unsigned int pmu_idx);
170bool intel_generic_uncore_assign_hw_event(struct perf_event *event,
171 struct intel_uncore_box *box);
172void uncore_find_add_unit(struct intel_uncore_discovery_unit *node,
173 struct rb_root *root, u16 *num_units);
174struct intel_uncore_type **
175uncore_get_uncores(enum uncore_access_type type_id, int num_extra,
176 struct intel_uncore_type **extra, int max_num_types,
177 struct intel_uncore_type **uncores);
178