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 /* Mask of the discovery table offset */
22edae1f06SKan Liang #define UNCORE_DISCOVERY_MASK			0xf
23edae1f06SKan Liang /* Global discovery table size */
24edae1f06SKan Liang #define UNCORE_DISCOVERY_GLOBAL_MAP_SIZE	0x20
25edae1f06SKan Liang 
2642839ef4SKan Liang #define UNCORE_DISCOVERY_PCI_DOMAIN(data)	((data >> 28) & 0x7)
2742839ef4SKan Liang #define UNCORE_DISCOVERY_PCI_BUS(data)		((data >> 20) & 0xff)
2842839ef4SKan Liang #define UNCORE_DISCOVERY_PCI_DEVFN(data)	((data >> 12) & 0xff)
2942839ef4SKan Liang #define UNCORE_DISCOVERY_PCI_BOX_CTRL(data)	(data & 0xfff)
3042839ef4SKan Liang 
3142839ef4SKan Liang 
32edae1f06SKan Liang #define uncore_discovery_invalid_unit(unit)			\
33edae1f06SKan Liang 	(!unit.table1 || !unit.ctl || !unit.table3 ||	\
34edae1f06SKan Liang 	 unit.table1 == -1ULL || unit.ctl == -1ULL ||	\
35edae1f06SKan Liang 	 unit.table3 == -1ULL)
36edae1f06SKan Liang 
37d6c75413SKan Liang #define GENERIC_PMON_CTL_EV_SEL_MASK	0x000000ff
38d6c75413SKan Liang #define GENERIC_PMON_CTL_UMASK_MASK	0x0000ff00
39d6c75413SKan Liang #define GENERIC_PMON_CTL_EDGE_DET	(1 << 18)
40d6c75413SKan Liang #define GENERIC_PMON_CTL_INVERT		(1 << 23)
41d6c75413SKan Liang #define GENERIC_PMON_CTL_TRESH_MASK	0xff000000
42d6c75413SKan Liang #define GENERIC_PMON_RAW_EVENT_MASK	(GENERIC_PMON_CTL_EV_SEL_MASK | \
43d6c75413SKan Liang 					 GENERIC_PMON_CTL_UMASK_MASK | \
44d6c75413SKan Liang 					 GENERIC_PMON_CTL_EDGE_DET | \
45d6c75413SKan Liang 					 GENERIC_PMON_CTL_INVERT | \
46d6c75413SKan Liang 					 GENERIC_PMON_CTL_TRESH_MASK)
47d6c75413SKan Liang 
48d6c75413SKan Liang #define GENERIC_PMON_BOX_CTL_FRZ	(1 << 0)
49d6c75413SKan Liang #define GENERIC_PMON_BOX_CTL_RST_CTRL	(1 << 8)
50d6c75413SKan Liang #define GENERIC_PMON_BOX_CTL_RST_CTRS	(1 << 9)
51d6c75413SKan Liang #define GENERIC_PMON_BOX_CTL_INT	(GENERIC_PMON_BOX_CTL_RST_CTRL | \
52d6c75413SKan Liang 					 GENERIC_PMON_BOX_CTL_RST_CTRS)
53d6c75413SKan Liang 
54edae1f06SKan Liang enum uncore_access_type {
55edae1f06SKan Liang 	UNCORE_ACCESS_MSR	= 0,
56edae1f06SKan Liang 	UNCORE_ACCESS_MMIO,
57edae1f06SKan Liang 	UNCORE_ACCESS_PCI,
58edae1f06SKan Liang 
59edae1f06SKan Liang 	UNCORE_ACCESS_MAX,
60edae1f06SKan Liang };
61edae1f06SKan Liang 
62edae1f06SKan Liang struct uncore_global_discovery {
63edae1f06SKan Liang 	union {
64edae1f06SKan Liang 		u64	table1;
65edae1f06SKan Liang 		struct {
66edae1f06SKan Liang 			u64	type : 8,
67edae1f06SKan Liang 				stride : 8,
68edae1f06SKan Liang 				max_units : 10,
69edae1f06SKan Liang 				__reserved_1 : 36,
70edae1f06SKan Liang 				access_type : 2;
71edae1f06SKan Liang 		};
72edae1f06SKan Liang 	};
73edae1f06SKan Liang 
74edae1f06SKan Liang 	u64	ctl;		/* Global Control Address */
75edae1f06SKan Liang 
76edae1f06SKan Liang 	union {
77edae1f06SKan Liang 		u64	table3;
78edae1f06SKan Liang 		struct {
79edae1f06SKan Liang 			u64	status_offset : 8,
80edae1f06SKan Liang 				num_status : 16,
81edae1f06SKan Liang 				__reserved_2 : 40;
82edae1f06SKan Liang 		};
83edae1f06SKan Liang 	};
84edae1f06SKan Liang };
85edae1f06SKan Liang 
86edae1f06SKan Liang struct uncore_unit_discovery {
87edae1f06SKan Liang 	union {
88edae1f06SKan Liang 		u64	table1;
89edae1f06SKan Liang 		struct {
90edae1f06SKan Liang 			u64	num_regs : 8,
91edae1f06SKan Liang 				ctl_offset : 8,
92edae1f06SKan Liang 				bit_width : 8,
93edae1f06SKan Liang 				ctr_offset : 8,
94edae1f06SKan Liang 				status_offset : 8,
95edae1f06SKan Liang 				__reserved_1 : 22,
96edae1f06SKan Liang 				access_type : 2;
97edae1f06SKan Liang 			};
98edae1f06SKan Liang 		};
99edae1f06SKan Liang 
100edae1f06SKan Liang 	u64	ctl;		/* Unit Control Address */
101edae1f06SKan Liang 
102edae1f06SKan Liang 	union {
103edae1f06SKan Liang 		u64	table3;
104edae1f06SKan Liang 		struct {
105edae1f06SKan Liang 			u64	box_type : 16,
106edae1f06SKan Liang 				box_id : 16,
107edae1f06SKan Liang 				__reserved_2 : 32;
108edae1f06SKan Liang 		};
109edae1f06SKan Liang 	};
110edae1f06SKan Liang };
111edae1f06SKan Liang 
112edae1f06SKan Liang struct intel_uncore_discovery_type {
113edae1f06SKan Liang 	struct rb_node	node;
114edae1f06SKan Liang 	enum uncore_access_type	access_type;
115edae1f06SKan Liang 	u64		box_ctrl;	/* Unit ctrl addr of the first box */
116edae1f06SKan Liang 	u64		*box_ctrl_die;	/* Unit ctrl addr of the first box of each die */
117edae1f06SKan Liang 	u16		type;		/* Type ID of the uncore block */
118edae1f06SKan Liang 	u8		num_counters;
119edae1f06SKan Liang 	u8		counter_width;
120edae1f06SKan Liang 	u8		ctl_offset;	/* Counter Control 0 offset */
121edae1f06SKan Liang 	u8		ctr_offset;	/* Counter 0 offset */
122edae1f06SKan Liang 	u16		num_boxes;	/* number of boxes for the uncore block */
123edae1f06SKan Liang 	unsigned int	*ids;		/* Box IDs */
124edae1f06SKan Liang 	unsigned int	*box_offset;	/* Box offset */
125edae1f06SKan Liang };
126edae1f06SKan Liang 
127edae1f06SKan Liang bool intel_uncore_has_discovery_tables(void);
128edae1f06SKan Liang void intel_uncore_clear_discovery_tables(void);
129d6c75413SKan Liang void intel_uncore_generic_uncore_cpu_init(void);
13042839ef4SKan Liang int intel_uncore_generic_uncore_pci_init(void);
131c4c55e36SKan Liang void intel_uncore_generic_uncore_mmio_init(void);
132c54c53d9SKan Liang 
133949b1138SKan Liang void intel_generic_uncore_msr_init_box(struct intel_uncore_box *box);
134949b1138SKan Liang void intel_generic_uncore_msr_disable_box(struct intel_uncore_box *box);
135949b1138SKan Liang void intel_generic_uncore_msr_enable_box(struct intel_uncore_box *box);
136949b1138SKan Liang 
13785f2e30fSKan Liang void intel_generic_uncore_mmio_init_box(struct intel_uncore_box *box);
13885f2e30fSKan Liang void intel_generic_uncore_mmio_disable_box(struct intel_uncore_box *box);
13985f2e30fSKan Liang void intel_generic_uncore_mmio_enable_box(struct intel_uncore_box *box);
14085f2e30fSKan Liang void intel_generic_uncore_mmio_disable_event(struct intel_uncore_box *box,
14185f2e30fSKan Liang 					     struct perf_event *event);
14285f2e30fSKan Liang 
143*f57191edSKan Liang void intel_generic_uncore_pci_init_box(struct intel_uncore_box *box);
144*f57191edSKan Liang void intel_generic_uncore_pci_disable_box(struct intel_uncore_box *box);
145*f57191edSKan Liang void intel_generic_uncore_pci_enable_box(struct intel_uncore_box *box);
146*f57191edSKan Liang void intel_generic_uncore_pci_disable_event(struct intel_uncore_box *box,
147*f57191edSKan Liang 					    struct perf_event *event);
148*f57191edSKan Liang u64 intel_generic_uncore_pci_read_counter(struct intel_uncore_box *box,
149*f57191edSKan Liang 					  struct perf_event *event);
150*f57191edSKan Liang 
151c54c53d9SKan Liang struct intel_uncore_type **
152c54c53d9SKan Liang intel_uncore_generic_init_uncores(enum uncore_access_type type_id);
153