1edae1f06SKan Liang /* SPDX-License-Identifier: GPL-2.0-only */
2edae1f06SKan Liang 
3edae1f06SKan Liang /* Generic device ID of a discovery table device */
4edae1f06SKan Liang #define UNCORE_DISCOVERY_TABLE_DEVICE		0x09a7
5edae1f06SKan Liang /* Capability ID for a discovery table device */
6edae1f06SKan Liang #define UNCORE_EXT_CAP_ID_DISCOVERY		0x23
7edae1f06SKan Liang /* First DVSEC offset */
8edae1f06SKan Liang #define UNCORE_DISCOVERY_DVSEC_OFFSET		0x8
9edae1f06SKan Liang /* Mask of the supported discovery entry type */
10edae1f06SKan Liang #define UNCORE_DISCOVERY_DVSEC_ID_MASK		0xffff
11edae1f06SKan Liang /* PMON discovery entry type ID */
12edae1f06SKan Liang #define UNCORE_DISCOVERY_DVSEC_ID_PMON		0x1
13edae1f06SKan Liang /* Second DVSEC offset */
14edae1f06SKan Liang #define UNCORE_DISCOVERY_DVSEC2_OFFSET		0xc
15edae1f06SKan Liang /* Mask of the discovery table BAR offset */
16edae1f06SKan Liang #define UNCORE_DISCOVERY_DVSEC2_BIR_MASK	0x7
17edae1f06SKan Liang /* Discovery table BAR base offset */
18edae1f06SKan Liang #define UNCORE_DISCOVERY_BIR_BASE		0x10
19edae1f06SKan Liang /* Discovery table BAR step */
20edae1f06SKan Liang #define UNCORE_DISCOVERY_BIR_STEP		0x4
21edae1f06SKan Liang /* Global discovery table size */
22edae1f06SKan Liang #define UNCORE_DISCOVERY_GLOBAL_MAP_SIZE	0x20
23edae1f06SKan Liang 
24*65248a9aSKan Liang #define UNCORE_DISCOVERY_PCI_DOMAIN_OFFSET	28
25*65248a9aSKan Liang #define UNCORE_DISCOVERY_PCI_DOMAIN(data)			\
26*65248a9aSKan Liang 		((data >> UNCORE_DISCOVERY_PCI_DOMAIN_OFFSET) & 0x7)
27*65248a9aSKan Liang #define UNCORE_DISCOVERY_PCI_BUS_OFFSET		20
28*65248a9aSKan Liang #define UNCORE_DISCOVERY_PCI_BUS(data)				\
29*65248a9aSKan Liang 		((data >> UNCORE_DISCOVERY_PCI_BUS_OFFSET) & 0xff)
30*65248a9aSKan Liang #define UNCORE_DISCOVERY_PCI_DEVFN_OFFSET	12
31*65248a9aSKan Liang #define UNCORE_DISCOVERY_PCI_DEVFN(data)			\
32*65248a9aSKan Liang 		((data >> UNCORE_DISCOVERY_PCI_DEVFN_OFFSET) & 0xff)
3342839ef4SKan Liang #define UNCORE_DISCOVERY_PCI_BOX_CTRL(data)	(data & 0xfff)
3442839ef4SKan Liang 
3542839ef4SKan Liang 
36edae1f06SKan Liang #define uncore_discovery_invalid_unit(unit)			\
37e2bb9fabSKan Liang 	(!unit.table1 || !unit.ctl || \
38edae1f06SKan Liang 	 unit.table1 == -1ULL || unit.ctl == -1ULL ||	\
39edae1f06SKan Liang 	 unit.table3 == -1ULL)
40edae1f06SKan Liang 
41d6c75413SKan Liang #define GENERIC_PMON_CTL_EV_SEL_MASK	0x000000ff
42d6c75413SKan Liang #define GENERIC_PMON_CTL_UMASK_MASK	0x0000ff00
43d6c75413SKan Liang #define GENERIC_PMON_CTL_EDGE_DET	(1 << 18)
44d6c75413SKan Liang #define GENERIC_PMON_CTL_INVERT		(1 << 23)
45d6c75413SKan Liang #define GENERIC_PMON_CTL_TRESH_MASK	0xff000000
46d6c75413SKan Liang #define GENERIC_PMON_RAW_EVENT_MASK	(GENERIC_PMON_CTL_EV_SEL_MASK | \
47d6c75413SKan Liang 					 GENERIC_PMON_CTL_UMASK_MASK | \
48d6c75413SKan Liang 					 GENERIC_PMON_CTL_EDGE_DET | \
49d6c75413SKan Liang 					 GENERIC_PMON_CTL_INVERT | \
50d6c75413SKan Liang 					 GENERIC_PMON_CTL_TRESH_MASK)
51d6c75413SKan Liang 
52d6c75413SKan Liang #define GENERIC_PMON_BOX_CTL_FRZ	(1 << 0)
53d6c75413SKan Liang #define GENERIC_PMON_BOX_CTL_RST_CTRL	(1 << 8)
54d6c75413SKan Liang #define GENERIC_PMON_BOX_CTL_RST_CTRS	(1 << 9)
55d6c75413SKan Liang #define GENERIC_PMON_BOX_CTL_INT	(GENERIC_PMON_BOX_CTL_RST_CTRL | \
56d6c75413SKan Liang 					 GENERIC_PMON_BOX_CTL_RST_CTRS)
57d6c75413SKan Liang 
58edae1f06SKan Liang enum uncore_access_type {
59edae1f06SKan Liang 	UNCORE_ACCESS_MSR	= 0,
60edae1f06SKan Liang 	UNCORE_ACCESS_MMIO,
61edae1f06SKan Liang 	UNCORE_ACCESS_PCI,
62edae1f06SKan Liang 
63edae1f06SKan Liang 	UNCORE_ACCESS_MAX,
64edae1f06SKan Liang };
65edae1f06SKan Liang 
66edae1f06SKan Liang struct uncore_global_discovery {
67edae1f06SKan Liang 	union {
68edae1f06SKan Liang 		u64	table1;
69edae1f06SKan Liang 		struct {
70edae1f06SKan Liang 			u64	type : 8,
71edae1f06SKan Liang 				stride : 8,
72edae1f06SKan Liang 				max_units : 10,
73edae1f06SKan Liang 				__reserved_1 : 36,
74edae1f06SKan Liang 				access_type : 2;
75edae1f06SKan Liang 		};
76edae1f06SKan Liang 	};
77edae1f06SKan Liang 
78edae1f06SKan Liang 	u64	ctl;		/* Global Control Address */
79edae1f06SKan Liang 
80edae1f06SKan Liang 	union {
81edae1f06SKan Liang 		u64	table3;
82edae1f06SKan Liang 		struct {
83edae1f06SKan Liang 			u64	status_offset : 8,
84edae1f06SKan Liang 				num_status : 16,
85edae1f06SKan Liang 				__reserved_2 : 40;
86edae1f06SKan Liang 		};
87edae1f06SKan Liang 	};
88edae1f06SKan Liang };
89edae1f06SKan Liang 
90edae1f06SKan Liang struct uncore_unit_discovery {
91edae1f06SKan Liang 	union {
92edae1f06SKan Liang 		u64	table1;
93edae1f06SKan Liang 		struct {
94edae1f06SKan Liang 			u64	num_regs : 8,
95edae1f06SKan Liang 				ctl_offset : 8,
96edae1f06SKan Liang 				bit_width : 8,
97edae1f06SKan Liang 				ctr_offset : 8,
98edae1f06SKan Liang 				status_offset : 8,
99edae1f06SKan Liang 				__reserved_1 : 22,
100edae1f06SKan Liang 				access_type : 2;
101edae1f06SKan Liang 			};
102edae1f06SKan Liang 		};
103edae1f06SKan Liang 
104edae1f06SKan Liang 	u64	ctl;		/* Unit Control Address */
105edae1f06SKan Liang 
106edae1f06SKan Liang 	union {
107edae1f06SKan Liang 		u64	table3;
108edae1f06SKan Liang 		struct {
109edae1f06SKan Liang 			u64	box_type : 16,
110edae1f06SKan Liang 				box_id : 16,
111edae1f06SKan Liang 				__reserved_2 : 32;
112edae1f06SKan Liang 		};
113edae1f06SKan Liang 	};
114edae1f06SKan Liang };
115edae1f06SKan Liang 
116edae1f06SKan Liang struct intel_uncore_discovery_type {
117edae1f06SKan Liang 	struct rb_node	node;
118edae1f06SKan Liang 	enum uncore_access_type	access_type;
119edae1f06SKan Liang 	u64		box_ctrl;	/* Unit ctrl addr of the first box */
120edae1f06SKan Liang 	u64		*box_ctrl_die;	/* Unit ctrl addr of the first box of each die */
121edae1f06SKan Liang 	u16		type;		/* Type ID of the uncore block */
122edae1f06SKan Liang 	u8		num_counters;
123edae1f06SKan Liang 	u8		counter_width;
124edae1f06SKan Liang 	u8		ctl_offset;	/* Counter Control 0 offset */
125edae1f06SKan Liang 	u8		ctr_offset;	/* Counter 0 offset */
126edae1f06SKan Liang 	u16		num_boxes;	/* number of boxes for the uncore block */
127edae1f06SKan Liang 	unsigned int	*ids;		/* Box IDs */
128edae1f06SKan Liang 	unsigned int	*box_offset;	/* Box offset */
129edae1f06SKan Liang };
130edae1f06SKan Liang 
131bd9514a4SKan Liang bool intel_uncore_has_discovery_tables(int *ignore);
132edae1f06SKan Liang void intel_uncore_clear_discovery_tables(void);
133d6c75413SKan Liang void intel_uncore_generic_uncore_cpu_init(void);
13442839ef4SKan Liang int intel_uncore_generic_uncore_pci_init(void);
135c4c55e36SKan Liang void intel_uncore_generic_uncore_mmio_init(void);
136c54c53d9SKan Liang 
137949b1138SKan Liang void intel_generic_uncore_msr_init_box(struct intel_uncore_box *box);
138949b1138SKan Liang void intel_generic_uncore_msr_disable_box(struct intel_uncore_box *box);
139949b1138SKan Liang void intel_generic_uncore_msr_enable_box(struct intel_uncore_box *box);
140949b1138SKan Liang 
14185f2e30fSKan Liang void intel_generic_uncore_mmio_init_box(struct intel_uncore_box *box);
14285f2e30fSKan Liang void intel_generic_uncore_mmio_disable_box(struct intel_uncore_box *box);
14385f2e30fSKan Liang void intel_generic_uncore_mmio_enable_box(struct intel_uncore_box *box);
14485f2e30fSKan Liang void intel_generic_uncore_mmio_disable_event(struct intel_uncore_box *box,
14585f2e30fSKan Liang 					     struct perf_event *event);
1465a4487f9SKan Liang void intel_generic_uncore_mmio_enable_event(struct intel_uncore_box *box,
1475a4487f9SKan Liang 					    struct perf_event *event);
14885f2e30fSKan Liang 
149f57191edSKan Liang void intel_generic_uncore_pci_init_box(struct intel_uncore_box *box);
150f57191edSKan Liang void intel_generic_uncore_pci_disable_box(struct intel_uncore_box *box);
151f57191edSKan Liang void intel_generic_uncore_pci_enable_box(struct intel_uncore_box *box);
152f57191edSKan Liang void intel_generic_uncore_pci_disable_event(struct intel_uncore_box *box,
153f57191edSKan Liang 					    struct perf_event *event);
154f57191edSKan Liang u64 intel_generic_uncore_pci_read_counter(struct intel_uncore_box *box,
155f57191edSKan Liang 					  struct perf_event *event);
156f57191edSKan Liang 
157c54c53d9SKan Liang struct intel_uncore_type **
1580378c93aSKan Liang intel_uncore_generic_init_uncores(enum uncore_access_type type_id, int num_extra);
159