1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2ed367e6cSBorislav Petkov /* SandyBridge-EP/IvyTown uncore support */
3ed367e6cSBorislav Petkov #include "uncore.h"
4c54c53d9SKan Liang #include "uncore_discovery.h"
5ed367e6cSBorislav Petkov 
668ce4a0dSKan Liang /* SNB-EP pci bus to socket mapping */
768ce4a0dSKan Liang #define SNBEP_CPUNODEID			0x40
868ce4a0dSKan Liang #define SNBEP_GIDNIDMAP			0x54
968ce4a0dSKan Liang 
10ed367e6cSBorislav Petkov /* SNB-EP Box level control */
11ed367e6cSBorislav Petkov #define SNBEP_PMON_BOX_CTL_RST_CTRL	(1 << 0)
12ed367e6cSBorislav Petkov #define SNBEP_PMON_BOX_CTL_RST_CTRS	(1 << 1)
13ed367e6cSBorislav Petkov #define SNBEP_PMON_BOX_CTL_FRZ		(1 << 8)
14ed367e6cSBorislav Petkov #define SNBEP_PMON_BOX_CTL_FRZ_EN	(1 << 16)
15ed367e6cSBorislav Petkov #define SNBEP_PMON_BOX_CTL_INT		(SNBEP_PMON_BOX_CTL_RST_CTRL | \
16ed367e6cSBorislav Petkov 					 SNBEP_PMON_BOX_CTL_RST_CTRS | \
17ed367e6cSBorislav Petkov 					 SNBEP_PMON_BOX_CTL_FRZ_EN)
18ed367e6cSBorislav Petkov /* SNB-EP event control */
19ed367e6cSBorislav Petkov #define SNBEP_PMON_CTL_EV_SEL_MASK	0x000000ff
20ed367e6cSBorislav Petkov #define SNBEP_PMON_CTL_UMASK_MASK	0x0000ff00
21ed367e6cSBorislav Petkov #define SNBEP_PMON_CTL_RST		(1 << 17)
22ed367e6cSBorislav Petkov #define SNBEP_PMON_CTL_EDGE_DET		(1 << 18)
23ed367e6cSBorislav Petkov #define SNBEP_PMON_CTL_EV_SEL_EXT	(1 << 21)
24ed367e6cSBorislav Petkov #define SNBEP_PMON_CTL_EN		(1 << 22)
25ed367e6cSBorislav Petkov #define SNBEP_PMON_CTL_INVERT		(1 << 23)
26ed367e6cSBorislav Petkov #define SNBEP_PMON_CTL_TRESH_MASK	0xff000000
27ed367e6cSBorislav Petkov #define SNBEP_PMON_RAW_EVENT_MASK	(SNBEP_PMON_CTL_EV_SEL_MASK | \
28ed367e6cSBorislav Petkov 					 SNBEP_PMON_CTL_UMASK_MASK | \
29ed367e6cSBorislav Petkov 					 SNBEP_PMON_CTL_EDGE_DET | \
30ed367e6cSBorislav Petkov 					 SNBEP_PMON_CTL_INVERT | \
31ed367e6cSBorislav Petkov 					 SNBEP_PMON_CTL_TRESH_MASK)
32ed367e6cSBorislav Petkov 
33ed367e6cSBorislav Petkov /* SNB-EP Ubox event control */
34ed367e6cSBorislav Petkov #define SNBEP_U_MSR_PMON_CTL_TRESH_MASK		0x1f000000
35ed367e6cSBorislav Petkov #define SNBEP_U_MSR_PMON_RAW_EVENT_MASK		\
36ed367e6cSBorislav Petkov 				(SNBEP_PMON_CTL_EV_SEL_MASK | \
37ed367e6cSBorislav Petkov 				 SNBEP_PMON_CTL_UMASK_MASK | \
38ed367e6cSBorislav Petkov 				 SNBEP_PMON_CTL_EDGE_DET | \
39ed367e6cSBorislav Petkov 				 SNBEP_PMON_CTL_INVERT | \
40ed367e6cSBorislav Petkov 				 SNBEP_U_MSR_PMON_CTL_TRESH_MASK)
41ed367e6cSBorislav Petkov 
42ed367e6cSBorislav Petkov #define SNBEP_CBO_PMON_CTL_TID_EN		(1 << 19)
43ed367e6cSBorislav Petkov #define SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK	(SNBEP_PMON_RAW_EVENT_MASK | \
44ed367e6cSBorislav Petkov 						 SNBEP_CBO_PMON_CTL_TID_EN)
45ed367e6cSBorislav Petkov 
46ed367e6cSBorislav Petkov /* SNB-EP PCU event control */
47ed367e6cSBorislav Petkov #define SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK	0x0000c000
48ed367e6cSBorislav Petkov #define SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK	0x1f000000
49ed367e6cSBorislav Petkov #define SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT	(1 << 30)
50ed367e6cSBorislav Petkov #define SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET	(1 << 31)
51ed367e6cSBorislav Petkov #define SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK	\
52ed367e6cSBorislav Petkov 				(SNBEP_PMON_CTL_EV_SEL_MASK | \
53ed367e6cSBorislav Petkov 				 SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \
54ed367e6cSBorislav Petkov 				 SNBEP_PMON_CTL_EDGE_DET | \
55ed367e6cSBorislav Petkov 				 SNBEP_PMON_CTL_INVERT | \
56ed367e6cSBorislav Petkov 				 SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \
57ed367e6cSBorislav Petkov 				 SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \
58ed367e6cSBorislav Petkov 				 SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET)
59ed367e6cSBorislav Petkov 
60ed367e6cSBorislav Petkov #define SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK	\
61ed367e6cSBorislav Petkov 				(SNBEP_PMON_RAW_EVENT_MASK | \
62ed367e6cSBorislav Petkov 				 SNBEP_PMON_CTL_EV_SEL_EXT)
63ed367e6cSBorislav Petkov 
64ed367e6cSBorislav Petkov /* SNB-EP pci control register */
65ed367e6cSBorislav Petkov #define SNBEP_PCI_PMON_BOX_CTL			0xf4
66ed367e6cSBorislav Petkov #define SNBEP_PCI_PMON_CTL0			0xd8
67ed367e6cSBorislav Petkov /* SNB-EP pci counter register */
68ed367e6cSBorislav Petkov #define SNBEP_PCI_PMON_CTR0			0xa0
69ed367e6cSBorislav Petkov 
70ed367e6cSBorislav Petkov /* SNB-EP home agent register */
71ed367e6cSBorislav Petkov #define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH0	0x40
72ed367e6cSBorislav Petkov #define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH1	0x44
73ed367e6cSBorislav Petkov #define SNBEP_HA_PCI_PMON_BOX_OPCODEMATCH	0x48
74ed367e6cSBorislav Petkov /* SNB-EP memory controller register */
75ed367e6cSBorislav Petkov #define SNBEP_MC_CHy_PCI_PMON_FIXED_CTL		0xf0
76ed367e6cSBorislav Petkov #define SNBEP_MC_CHy_PCI_PMON_FIXED_CTR		0xd0
77ed367e6cSBorislav Petkov /* SNB-EP QPI register */
78ed367e6cSBorislav Petkov #define SNBEP_Q_Py_PCI_PMON_PKT_MATCH0		0x228
79ed367e6cSBorislav Petkov #define SNBEP_Q_Py_PCI_PMON_PKT_MATCH1		0x22c
80ed367e6cSBorislav Petkov #define SNBEP_Q_Py_PCI_PMON_PKT_MASK0		0x238
81ed367e6cSBorislav Petkov #define SNBEP_Q_Py_PCI_PMON_PKT_MASK1		0x23c
82ed367e6cSBorislav Petkov 
83ed367e6cSBorislav Petkov /* SNB-EP Ubox register */
84ed367e6cSBorislav Petkov #define SNBEP_U_MSR_PMON_CTR0			0xc16
85ed367e6cSBorislav Petkov #define SNBEP_U_MSR_PMON_CTL0			0xc10
86ed367e6cSBorislav Petkov 
87ed367e6cSBorislav Petkov #define SNBEP_U_MSR_PMON_UCLK_FIXED_CTL		0xc08
88ed367e6cSBorislav Petkov #define SNBEP_U_MSR_PMON_UCLK_FIXED_CTR		0xc09
89ed367e6cSBorislav Petkov 
90ed367e6cSBorislav Petkov /* SNB-EP Cbo register */
91ed367e6cSBorislav Petkov #define SNBEP_C0_MSR_PMON_CTR0			0xd16
92ed367e6cSBorislav Petkov #define SNBEP_C0_MSR_PMON_CTL0			0xd10
93ed367e6cSBorislav Petkov #define SNBEP_C0_MSR_PMON_BOX_CTL		0xd04
94ed367e6cSBorislav Petkov #define SNBEP_C0_MSR_PMON_BOX_FILTER		0xd14
95ed367e6cSBorislav Petkov #define SNBEP_CBO_MSR_OFFSET			0x20
96ed367e6cSBorislav Petkov 
97ed367e6cSBorislav Petkov #define SNBEP_CB0_MSR_PMON_BOX_FILTER_TID	0x1f
98ed367e6cSBorislav Petkov #define SNBEP_CB0_MSR_PMON_BOX_FILTER_NID	0x3fc00
99ed367e6cSBorislav Petkov #define SNBEP_CB0_MSR_PMON_BOX_FILTER_STATE	0x7c0000
100ed367e6cSBorislav Petkov #define SNBEP_CB0_MSR_PMON_BOX_FILTER_OPC	0xff800000
101ed367e6cSBorislav Petkov 
102ed367e6cSBorislav Petkov #define SNBEP_CBO_EVENT_EXTRA_REG(e, m, i) {	\
103ed367e6cSBorislav Petkov 	.event = (e),				\
104ed367e6cSBorislav Petkov 	.msr = SNBEP_C0_MSR_PMON_BOX_FILTER,	\
105ed367e6cSBorislav Petkov 	.config_mask = (m),			\
106ed367e6cSBorislav Petkov 	.idx = (i)				\
107ed367e6cSBorislav Petkov }
108ed367e6cSBorislav Petkov 
109ed367e6cSBorislav Petkov /* SNB-EP PCU register */
110ed367e6cSBorislav Petkov #define SNBEP_PCU_MSR_PMON_CTR0			0xc36
111ed367e6cSBorislav Petkov #define SNBEP_PCU_MSR_PMON_CTL0			0xc30
112ed367e6cSBorislav Petkov #define SNBEP_PCU_MSR_PMON_BOX_CTL		0xc24
113ed367e6cSBorislav Petkov #define SNBEP_PCU_MSR_PMON_BOX_FILTER		0xc34
114ed367e6cSBorislav Petkov #define SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK	0xffffffff
115ed367e6cSBorislav Petkov #define SNBEP_PCU_MSR_CORE_C3_CTR		0x3fc
116ed367e6cSBorislav Petkov #define SNBEP_PCU_MSR_CORE_C6_CTR		0x3fd
117ed367e6cSBorislav Petkov 
118ed367e6cSBorislav Petkov /* IVBEP event control */
119ed367e6cSBorislav Petkov #define IVBEP_PMON_BOX_CTL_INT		(SNBEP_PMON_BOX_CTL_RST_CTRL | \
120ed367e6cSBorislav Petkov 					 SNBEP_PMON_BOX_CTL_RST_CTRS)
121ed367e6cSBorislav Petkov #define IVBEP_PMON_RAW_EVENT_MASK		(SNBEP_PMON_CTL_EV_SEL_MASK | \
122ed367e6cSBorislav Petkov 					 SNBEP_PMON_CTL_UMASK_MASK | \
123ed367e6cSBorislav Petkov 					 SNBEP_PMON_CTL_EDGE_DET | \
124ed367e6cSBorislav Petkov 					 SNBEP_PMON_CTL_TRESH_MASK)
125ed367e6cSBorislav Petkov /* IVBEP Ubox */
126ed367e6cSBorislav Petkov #define IVBEP_U_MSR_PMON_GLOBAL_CTL		0xc00
127ed367e6cSBorislav Petkov #define IVBEP_U_PMON_GLOBAL_FRZ_ALL		(1 << 31)
128ed367e6cSBorislav Petkov #define IVBEP_U_PMON_GLOBAL_UNFRZ_ALL		(1 << 29)
129ed367e6cSBorislav Petkov 
130ed367e6cSBorislav Petkov #define IVBEP_U_MSR_PMON_RAW_EVENT_MASK	\
131ed367e6cSBorislav Petkov 				(SNBEP_PMON_CTL_EV_SEL_MASK | \
132ed367e6cSBorislav Petkov 				 SNBEP_PMON_CTL_UMASK_MASK | \
133ed367e6cSBorislav Petkov 				 SNBEP_PMON_CTL_EDGE_DET | \
134ed367e6cSBorislav Petkov 				 SNBEP_U_MSR_PMON_CTL_TRESH_MASK)
135ed367e6cSBorislav Petkov /* IVBEP Cbo */
136ed367e6cSBorislav Petkov #define IVBEP_CBO_MSR_PMON_RAW_EVENT_MASK		(IVBEP_PMON_RAW_EVENT_MASK | \
137ed367e6cSBorislav Petkov 						 SNBEP_CBO_PMON_CTL_TID_EN)
138ed367e6cSBorislav Petkov 
139ed367e6cSBorislav Petkov #define IVBEP_CB0_MSR_PMON_BOX_FILTER_TID		(0x1fULL << 0)
140ed367e6cSBorislav Petkov #define IVBEP_CB0_MSR_PMON_BOX_FILTER_LINK	(0xfULL << 5)
141ed367e6cSBorislav Petkov #define IVBEP_CB0_MSR_PMON_BOX_FILTER_STATE	(0x3fULL << 17)
142ed367e6cSBorislav Petkov #define IVBEP_CB0_MSR_PMON_BOX_FILTER_NID		(0xffffULL << 32)
143ed367e6cSBorislav Petkov #define IVBEP_CB0_MSR_PMON_BOX_FILTER_OPC		(0x1ffULL << 52)
144ed367e6cSBorislav Petkov #define IVBEP_CB0_MSR_PMON_BOX_FILTER_C6		(0x1ULL << 61)
145ed367e6cSBorislav Petkov #define IVBEP_CB0_MSR_PMON_BOX_FILTER_NC		(0x1ULL << 62)
146ed367e6cSBorislav Petkov #define IVBEP_CB0_MSR_PMON_BOX_FILTER_ISOC	(0x1ULL << 63)
147ed367e6cSBorislav Petkov 
148ed367e6cSBorislav Petkov /* IVBEP home agent */
149ed367e6cSBorislav Petkov #define IVBEP_HA_PCI_PMON_CTL_Q_OCC_RST		(1 << 16)
150ed367e6cSBorislav Petkov #define IVBEP_HA_PCI_PMON_RAW_EVENT_MASK		\
151ed367e6cSBorislav Petkov 				(IVBEP_PMON_RAW_EVENT_MASK | \
152ed367e6cSBorislav Petkov 				 IVBEP_HA_PCI_PMON_CTL_Q_OCC_RST)
153ed367e6cSBorislav Petkov /* IVBEP PCU */
154ed367e6cSBorislav Petkov #define IVBEP_PCU_MSR_PMON_RAW_EVENT_MASK	\
155ed367e6cSBorislav Petkov 				(SNBEP_PMON_CTL_EV_SEL_MASK | \
156ed367e6cSBorislav Petkov 				 SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \
157ed367e6cSBorislav Petkov 				 SNBEP_PMON_CTL_EDGE_DET | \
158ed367e6cSBorislav Petkov 				 SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \
159ed367e6cSBorislav Petkov 				 SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \
160ed367e6cSBorislav Petkov 				 SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET)
161ed367e6cSBorislav Petkov /* IVBEP QPI */
162ed367e6cSBorislav Petkov #define IVBEP_QPI_PCI_PMON_RAW_EVENT_MASK	\
163ed367e6cSBorislav Petkov 				(IVBEP_PMON_RAW_EVENT_MASK | \
164ed367e6cSBorislav Petkov 				 SNBEP_PMON_CTL_EV_SEL_EXT)
165ed367e6cSBorislav Petkov 
166ed367e6cSBorislav Petkov #define __BITS_VALUE(x, i, n)  ((typeof(x))(((x) >> ((i) * (n))) & \
167ed367e6cSBorislav Petkov 				((1ULL << (n)) - 1)))
168ed367e6cSBorislav Petkov 
169ed367e6cSBorislav Petkov /* Haswell-EP Ubox */
170ed367e6cSBorislav Petkov #define HSWEP_U_MSR_PMON_CTR0			0x709
171ed367e6cSBorislav Petkov #define HSWEP_U_MSR_PMON_CTL0			0x705
172ed367e6cSBorislav Petkov #define HSWEP_U_MSR_PMON_FILTER			0x707
173ed367e6cSBorislav Petkov 
174ed367e6cSBorislav Petkov #define HSWEP_U_MSR_PMON_UCLK_FIXED_CTL		0x703
175ed367e6cSBorislav Petkov #define HSWEP_U_MSR_PMON_UCLK_FIXED_CTR		0x704
176ed367e6cSBorislav Petkov 
177ed367e6cSBorislav Petkov #define HSWEP_U_MSR_PMON_BOX_FILTER_TID		(0x1 << 0)
178ed367e6cSBorislav Petkov #define HSWEP_U_MSR_PMON_BOX_FILTER_CID		(0x1fULL << 1)
179ed367e6cSBorislav Petkov #define HSWEP_U_MSR_PMON_BOX_FILTER_MASK \
180ed367e6cSBorislav Petkov 					(HSWEP_U_MSR_PMON_BOX_FILTER_TID | \
181ed367e6cSBorislav Petkov 					 HSWEP_U_MSR_PMON_BOX_FILTER_CID)
182ed367e6cSBorislav Petkov 
183ed367e6cSBorislav Petkov /* Haswell-EP CBo */
184ed367e6cSBorislav Petkov #define HSWEP_C0_MSR_PMON_CTR0			0xe08
185ed367e6cSBorislav Petkov #define HSWEP_C0_MSR_PMON_CTL0			0xe01
186ed367e6cSBorislav Petkov #define HSWEP_C0_MSR_PMON_BOX_CTL			0xe00
187ed367e6cSBorislav Petkov #define HSWEP_C0_MSR_PMON_BOX_FILTER0		0xe05
188ed367e6cSBorislav Petkov #define HSWEP_CBO_MSR_OFFSET			0x10
189ed367e6cSBorislav Petkov 
190ed367e6cSBorislav Petkov 
191ed367e6cSBorislav Petkov #define HSWEP_CB0_MSR_PMON_BOX_FILTER_TID		(0x3fULL << 0)
192ed367e6cSBorislav Petkov #define HSWEP_CB0_MSR_PMON_BOX_FILTER_LINK	(0xfULL << 6)
193ed367e6cSBorislav Petkov #define HSWEP_CB0_MSR_PMON_BOX_FILTER_STATE	(0x7fULL << 17)
194ed367e6cSBorislav Petkov #define HSWEP_CB0_MSR_PMON_BOX_FILTER_NID		(0xffffULL << 32)
195ed367e6cSBorislav Petkov #define HSWEP_CB0_MSR_PMON_BOX_FILTER_OPC		(0x1ffULL << 52)
196ed367e6cSBorislav Petkov #define HSWEP_CB0_MSR_PMON_BOX_FILTER_C6		(0x1ULL << 61)
197ed367e6cSBorislav Petkov #define HSWEP_CB0_MSR_PMON_BOX_FILTER_NC		(0x1ULL << 62)
198ed367e6cSBorislav Petkov #define HSWEP_CB0_MSR_PMON_BOX_FILTER_ISOC	(0x1ULL << 63)
199ed367e6cSBorislav Petkov 
200ed367e6cSBorislav Petkov 
201ed367e6cSBorislav Petkov /* Haswell-EP Sbox */
202ed367e6cSBorislav Petkov #define HSWEP_S0_MSR_PMON_CTR0			0x726
203ed367e6cSBorislav Petkov #define HSWEP_S0_MSR_PMON_CTL0			0x721
204ed367e6cSBorislav Petkov #define HSWEP_S0_MSR_PMON_BOX_CTL			0x720
205ed367e6cSBorislav Petkov #define HSWEP_SBOX_MSR_OFFSET			0xa
206ed367e6cSBorislav Petkov #define HSWEP_S_MSR_PMON_RAW_EVENT_MASK		(SNBEP_PMON_RAW_EVENT_MASK | \
207ed367e6cSBorislav Petkov 						 SNBEP_CBO_PMON_CTL_TID_EN)
208ed367e6cSBorislav Petkov 
209ed367e6cSBorislav Petkov /* Haswell-EP PCU */
210ed367e6cSBorislav Petkov #define HSWEP_PCU_MSR_PMON_CTR0			0x717
211ed367e6cSBorislav Petkov #define HSWEP_PCU_MSR_PMON_CTL0			0x711
212ed367e6cSBorislav Petkov #define HSWEP_PCU_MSR_PMON_BOX_CTL		0x710
213ed367e6cSBorislav Petkov #define HSWEP_PCU_MSR_PMON_BOX_FILTER		0x715
214ed367e6cSBorislav Petkov 
215ed367e6cSBorislav Petkov /* KNL Ubox */
216ed367e6cSBorislav Petkov #define KNL_U_MSR_PMON_RAW_EVENT_MASK \
217ed367e6cSBorislav Petkov 					(SNBEP_U_MSR_PMON_RAW_EVENT_MASK | \
218ed367e6cSBorislav Petkov 						SNBEP_CBO_PMON_CTL_TID_EN)
219ed367e6cSBorislav Petkov /* KNL CHA */
220ed367e6cSBorislav Petkov #define KNL_CHA_MSR_OFFSET			0xc
221ed367e6cSBorislav Petkov #define KNL_CHA_MSR_PMON_CTL_QOR		(1 << 16)
222ed367e6cSBorislav Petkov #define KNL_CHA_MSR_PMON_RAW_EVENT_MASK \
223ed367e6cSBorislav Petkov 					(SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK | \
224ed367e6cSBorislav Petkov 					 KNL_CHA_MSR_PMON_CTL_QOR)
225ed367e6cSBorislav Petkov #define KNL_CHA_MSR_PMON_BOX_FILTER_TID		0x1ff
226ed367e6cSBorislav Petkov #define KNL_CHA_MSR_PMON_BOX_FILTER_STATE	(7 << 18)
227ed367e6cSBorislav Petkov #define KNL_CHA_MSR_PMON_BOX_FILTER_OP		(0xfffffe2aULL << 32)
228ec336c87Shchrzani #define KNL_CHA_MSR_PMON_BOX_FILTER_REMOTE_NODE	(0x1ULL << 32)
229ec336c87Shchrzani #define KNL_CHA_MSR_PMON_BOX_FILTER_LOCAL_NODE	(0x1ULL << 33)
230ec336c87Shchrzani #define KNL_CHA_MSR_PMON_BOX_FILTER_NNC		(0x1ULL << 37)
231ed367e6cSBorislav Petkov 
232ed367e6cSBorislav Petkov /* KNL EDC/MC UCLK */
233ed367e6cSBorislav Petkov #define KNL_UCLK_MSR_PMON_CTR0_LOW		0x400
234ed367e6cSBorislav Petkov #define KNL_UCLK_MSR_PMON_CTL0			0x420
235ed367e6cSBorislav Petkov #define KNL_UCLK_MSR_PMON_BOX_CTL		0x430
236ed367e6cSBorislav Petkov #define KNL_UCLK_MSR_PMON_UCLK_FIXED_LOW	0x44c
237ed367e6cSBorislav Petkov #define KNL_UCLK_MSR_PMON_UCLK_FIXED_CTL	0x454
238ed367e6cSBorislav Petkov #define KNL_PMON_FIXED_CTL_EN			0x1
239ed367e6cSBorislav Petkov 
240ed367e6cSBorislav Petkov /* KNL EDC */
241ed367e6cSBorislav Petkov #define KNL_EDC0_ECLK_MSR_PMON_CTR0_LOW		0xa00
242ed367e6cSBorislav Petkov #define KNL_EDC0_ECLK_MSR_PMON_CTL0		0xa20
243ed367e6cSBorislav Petkov #define KNL_EDC0_ECLK_MSR_PMON_BOX_CTL		0xa30
244ed367e6cSBorislav Petkov #define KNL_EDC0_ECLK_MSR_PMON_ECLK_FIXED_LOW	0xa3c
245ed367e6cSBorislav Petkov #define KNL_EDC0_ECLK_MSR_PMON_ECLK_FIXED_CTL	0xa44
246ed367e6cSBorislav Petkov 
247ed367e6cSBorislav Petkov /* KNL MC */
248ed367e6cSBorislav Petkov #define KNL_MC0_CH0_MSR_PMON_CTR0_LOW		0xb00
249ed367e6cSBorislav Petkov #define KNL_MC0_CH0_MSR_PMON_CTL0		0xb20
250ed367e6cSBorislav Petkov #define KNL_MC0_CH0_MSR_PMON_BOX_CTL		0xb30
251ed367e6cSBorislav Petkov #define KNL_MC0_CH0_MSR_PMON_FIXED_LOW		0xb3c
252ed367e6cSBorislav Petkov #define KNL_MC0_CH0_MSR_PMON_FIXED_CTL		0xb44
253ed367e6cSBorislav Petkov 
254ed367e6cSBorislav Petkov /* KNL IRP */
255ed367e6cSBorislav Petkov #define KNL_IRP_PCI_PMON_BOX_CTL		0xf0
256ed367e6cSBorislav Petkov #define KNL_IRP_PCI_PMON_RAW_EVENT_MASK		(SNBEP_PMON_RAW_EVENT_MASK | \
257ed367e6cSBorislav Petkov 						 KNL_CHA_MSR_PMON_CTL_QOR)
258ed367e6cSBorislav Petkov /* KNL PCU */
259ed367e6cSBorislav Petkov #define KNL_PCU_PMON_CTL_EV_SEL_MASK		0x0000007f
260ed367e6cSBorislav Petkov #define KNL_PCU_PMON_CTL_USE_OCC_CTR		(1 << 7)
261ed367e6cSBorislav Petkov #define KNL_PCU_MSR_PMON_CTL_TRESH_MASK		0x3f000000
262ed367e6cSBorislav Petkov #define KNL_PCU_MSR_PMON_RAW_EVENT_MASK	\
263ed367e6cSBorislav Petkov 				(KNL_PCU_PMON_CTL_EV_SEL_MASK | \
264ed367e6cSBorislav Petkov 				 KNL_PCU_PMON_CTL_USE_OCC_CTR | \
265ed367e6cSBorislav Petkov 				 SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \
266ed367e6cSBorislav Petkov 				 SNBEP_PMON_CTL_EDGE_DET | \
267ed367e6cSBorislav Petkov 				 SNBEP_CBO_PMON_CTL_TID_EN | \
268ed367e6cSBorislav Petkov 				 SNBEP_PMON_CTL_INVERT | \
269ed367e6cSBorislav Petkov 				 KNL_PCU_MSR_PMON_CTL_TRESH_MASK | \
270ed367e6cSBorislav Petkov 				 SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \
271ed367e6cSBorislav Petkov 				 SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET)
272ed367e6cSBorislav Petkov 
273cd34cd97SKan Liang /* SKX pci bus to socket mapping */
274cd34cd97SKan Liang #define SKX_CPUNODEID			0xc0
275cd34cd97SKan Liang #define SKX_GIDNIDMAP			0xd4
276cd34cd97SKan Liang 
277bb42b3d3SRoman Sudarikov /*
278bb42b3d3SRoman Sudarikov  * The CPU_BUS_NUMBER MSR returns the values of the respective CPUBUSNO CSR
279bb42b3d3SRoman Sudarikov  * that BIOS programmed. MSR has package scope.
280bb42b3d3SRoman Sudarikov  * |  Bit  |  Default  |  Description
281bb42b3d3SRoman Sudarikov  * | [63]  |    00h    | VALID - When set, indicates the CPU bus
282bb42b3d3SRoman Sudarikov  *                       numbers have been initialized. (RO)
283bb42b3d3SRoman Sudarikov  * |[62:48]|    ---    | Reserved
284c681df88SIngo Molnar  * |[47:40]|    00h    | BUS_NUM_5 - Return the bus number BIOS assigned
285bb42b3d3SRoman Sudarikov  *                       CPUBUSNO(5). (RO)
286c681df88SIngo Molnar  * |[39:32]|    00h    | BUS_NUM_4 - Return the bus number BIOS assigned
287bb42b3d3SRoman Sudarikov  *                       CPUBUSNO(4). (RO)
288c681df88SIngo Molnar  * |[31:24]|    00h    | BUS_NUM_3 - Return the bus number BIOS assigned
289bb42b3d3SRoman Sudarikov  *                       CPUBUSNO(3). (RO)
290c681df88SIngo Molnar  * |[23:16]|    00h    | BUS_NUM_2 - Return the bus number BIOS assigned
291bb42b3d3SRoman Sudarikov  *                       CPUBUSNO(2). (RO)
292c681df88SIngo Molnar  * |[15:8] |    00h    | BUS_NUM_1 - Return the bus number BIOS assigned
293bb42b3d3SRoman Sudarikov  *                       CPUBUSNO(1). (RO)
294c681df88SIngo Molnar  * | [7:0] |    00h    | BUS_NUM_0 - Return the bus number BIOS assigned
295bb42b3d3SRoman Sudarikov  *                       CPUBUSNO(0). (RO)
296bb42b3d3SRoman Sudarikov  */
297bb42b3d3SRoman Sudarikov #define SKX_MSR_CPU_BUS_NUMBER		0x300
298bb42b3d3SRoman Sudarikov #define SKX_MSR_CPU_BUS_VALID_BIT	(1ULL << 63)
299bb42b3d3SRoman Sudarikov #define BUS_NUM_STRIDE			8
300bb42b3d3SRoman Sudarikov 
301cd34cd97SKan Liang /* SKX CHA */
302cd34cd97SKan Liang #define SKX_CHA_MSR_PMON_BOX_FILTER_TID		(0x1ffULL << 0)
303cd34cd97SKan Liang #define SKX_CHA_MSR_PMON_BOX_FILTER_LINK	(0xfULL << 9)
304cd34cd97SKan Liang #define SKX_CHA_MSR_PMON_BOX_FILTER_STATE	(0x3ffULL << 17)
305cd34cd97SKan Liang #define SKX_CHA_MSR_PMON_BOX_FILTER_REM		(0x1ULL << 32)
306cd34cd97SKan Liang #define SKX_CHA_MSR_PMON_BOX_FILTER_LOC		(0x1ULL << 33)
307cd34cd97SKan Liang #define SKX_CHA_MSR_PMON_BOX_FILTER_ALL_OPC	(0x1ULL << 35)
308cd34cd97SKan Liang #define SKX_CHA_MSR_PMON_BOX_FILTER_NM		(0x1ULL << 36)
309cd34cd97SKan Liang #define SKX_CHA_MSR_PMON_BOX_FILTER_NOT_NM	(0x1ULL << 37)
310cd34cd97SKan Liang #define SKX_CHA_MSR_PMON_BOX_FILTER_OPC0	(0x3ffULL << 41)
311cd34cd97SKan Liang #define SKX_CHA_MSR_PMON_BOX_FILTER_OPC1	(0x3ffULL << 51)
312cd34cd97SKan Liang #define SKX_CHA_MSR_PMON_BOX_FILTER_C6		(0x1ULL << 61)
313cd34cd97SKan Liang #define SKX_CHA_MSR_PMON_BOX_FILTER_NC		(0x1ULL << 62)
314cd34cd97SKan Liang #define SKX_CHA_MSR_PMON_BOX_FILTER_ISOC	(0x1ULL << 63)
315cd34cd97SKan Liang 
316cd34cd97SKan Liang /* SKX IIO */
317cd34cd97SKan Liang #define SKX_IIO0_MSR_PMON_CTL0		0xa48
318cd34cd97SKan Liang #define SKX_IIO0_MSR_PMON_CTR0		0xa41
319cd34cd97SKan Liang #define SKX_IIO0_MSR_PMON_BOX_CTL	0xa40
320cd34cd97SKan Liang #define SKX_IIO_MSR_OFFSET		0x20
321cd34cd97SKan Liang 
322cd34cd97SKan Liang #define SKX_PMON_CTL_TRESH_MASK		(0xff << 24)
323cd34cd97SKan Liang #define SKX_PMON_CTL_TRESH_MASK_EXT	(0xf)
324cd34cd97SKan Liang #define SKX_PMON_CTL_CH_MASK		(0xff << 4)
325cd34cd97SKan Liang #define SKX_PMON_CTL_FC_MASK		(0x7 << 12)
326cd34cd97SKan Liang #define SKX_IIO_PMON_RAW_EVENT_MASK	(SNBEP_PMON_CTL_EV_SEL_MASK | \
327cd34cd97SKan Liang 					 SNBEP_PMON_CTL_UMASK_MASK | \
328cd34cd97SKan Liang 					 SNBEP_PMON_CTL_EDGE_DET | \
329cd34cd97SKan Liang 					 SNBEP_PMON_CTL_INVERT | \
330cd34cd97SKan Liang 					 SKX_PMON_CTL_TRESH_MASK)
331cd34cd97SKan Liang #define SKX_IIO_PMON_RAW_EVENT_MASK_EXT	(SKX_PMON_CTL_TRESH_MASK_EXT | \
332cd34cd97SKan Liang 					 SKX_PMON_CTL_CH_MASK | \
333cd34cd97SKan Liang 					 SKX_PMON_CTL_FC_MASK)
334cd34cd97SKan Liang 
335cd34cd97SKan Liang /* SKX IRP */
336cd34cd97SKan Liang #define SKX_IRP0_MSR_PMON_CTL0		0xa5b
337cd34cd97SKan Liang #define SKX_IRP0_MSR_PMON_CTR0		0xa59
338cd34cd97SKan Liang #define SKX_IRP0_MSR_PMON_BOX_CTL	0xa58
339cd34cd97SKan Liang #define SKX_IRP_MSR_OFFSET		0x20
340cd34cd97SKan Liang 
341cd34cd97SKan Liang /* SKX UPI */
342cd34cd97SKan Liang #define SKX_UPI_PCI_PMON_CTL0		0x350
343cd34cd97SKan Liang #define SKX_UPI_PCI_PMON_CTR0		0x318
344cd34cd97SKan Liang #define SKX_UPI_PCI_PMON_BOX_CTL	0x378
345b3625980SStephane Eranian #define SKX_UPI_CTL_UMASK_EXT		0xffefff
346cd34cd97SKan Liang 
347cd34cd97SKan Liang /* SKX M2M */
348cd34cd97SKan Liang #define SKX_M2M_PCI_PMON_CTL0		0x228
349cd34cd97SKan Liang #define SKX_M2M_PCI_PMON_CTR0		0x200
350cd34cd97SKan Liang #define SKX_M2M_PCI_PMON_BOX_CTL	0x258
351cd34cd97SKan Liang 
352c1777be3SAlexander Antonov /* Memory Map registers device ID */
353c1777be3SAlexander Antonov #define SNR_ICX_MESH2IIO_MMAP_DID		0x9a2
354c1777be3SAlexander Antonov #define SNR_ICX_SAD_CONTROL_CFG		0x3f4
355c1777be3SAlexander Antonov 
356c1777be3SAlexander Antonov /* Getting I/O stack id in SAD_COTROL_CFG notation */
357c1777be3SAlexander Antonov #define SAD_CONTROL_STACK_ID(data)		(((data) >> 4) & 0x7)
358c1777be3SAlexander Antonov 
359210cc5f9SKan Liang /* SNR Ubox */
360210cc5f9SKan Liang #define SNR_U_MSR_PMON_CTR0			0x1f98
361210cc5f9SKan Liang #define SNR_U_MSR_PMON_CTL0			0x1f91
362210cc5f9SKan Liang #define SNR_U_MSR_PMON_UCLK_FIXED_CTL		0x1f93
363210cc5f9SKan Liang #define SNR_U_MSR_PMON_UCLK_FIXED_CTR		0x1f94
364210cc5f9SKan Liang 
365210cc5f9SKan Liang /* SNR CHA */
366210cc5f9SKan Liang #define SNR_CHA_RAW_EVENT_MASK_EXT		0x3ffffff
367210cc5f9SKan Liang #define SNR_CHA_MSR_PMON_CTL0			0x1c01
368210cc5f9SKan Liang #define SNR_CHA_MSR_PMON_CTR0			0x1c08
369210cc5f9SKan Liang #define SNR_CHA_MSR_PMON_BOX_CTL		0x1c00
370210cc5f9SKan Liang #define SNR_C0_MSR_PMON_BOX_FILTER0		0x1c05
371210cc5f9SKan Liang 
372210cc5f9SKan Liang 
373210cc5f9SKan Liang /* SNR IIO */
374210cc5f9SKan Liang #define SNR_IIO_MSR_PMON_CTL0			0x1e08
375210cc5f9SKan Liang #define SNR_IIO_MSR_PMON_CTR0			0x1e01
376210cc5f9SKan Liang #define SNR_IIO_MSR_PMON_BOX_CTL		0x1e00
377210cc5f9SKan Liang #define SNR_IIO_MSR_OFFSET			0x10
378210cc5f9SKan Liang #define SNR_IIO_PMON_RAW_EVENT_MASK_EXT		0x7ffff
379210cc5f9SKan Liang 
380210cc5f9SKan Liang /* SNR IRP */
381210cc5f9SKan Liang #define SNR_IRP0_MSR_PMON_CTL0			0x1ea8
382210cc5f9SKan Liang #define SNR_IRP0_MSR_PMON_CTR0			0x1ea1
383210cc5f9SKan Liang #define SNR_IRP0_MSR_PMON_BOX_CTL		0x1ea0
384210cc5f9SKan Liang #define SNR_IRP_MSR_OFFSET			0x10
385210cc5f9SKan Liang 
386210cc5f9SKan Liang /* SNR M2PCIE */
387210cc5f9SKan Liang #define SNR_M2PCIE_MSR_PMON_CTL0		0x1e58
388210cc5f9SKan Liang #define SNR_M2PCIE_MSR_PMON_CTR0		0x1e51
389210cc5f9SKan Liang #define SNR_M2PCIE_MSR_PMON_BOX_CTL		0x1e50
390210cc5f9SKan Liang #define SNR_M2PCIE_MSR_OFFSET			0x10
391210cc5f9SKan Liang 
392210cc5f9SKan Liang /* SNR PCU */
393210cc5f9SKan Liang #define SNR_PCU_MSR_PMON_CTL0			0x1ef1
394210cc5f9SKan Liang #define SNR_PCU_MSR_PMON_CTR0			0x1ef8
395210cc5f9SKan Liang #define SNR_PCU_MSR_PMON_BOX_CTL		0x1ef0
396210cc5f9SKan Liang #define SNR_PCU_MSR_PMON_BOX_FILTER		0x1efc
397210cc5f9SKan Liang 
398210cc5f9SKan Liang /* SNR M2M */
399210cc5f9SKan Liang #define SNR_M2M_PCI_PMON_CTL0			0x468
400210cc5f9SKan Liang #define SNR_M2M_PCI_PMON_CTR0			0x440
401210cc5f9SKan Liang #define SNR_M2M_PCI_PMON_BOX_CTL		0x438
402210cc5f9SKan Liang #define SNR_M2M_PCI_PMON_UMASK_EXT		0xff
403210cc5f9SKan Liang 
404a3b1e845SKan Liang /* SNR PCIE3 */
405a3b1e845SKan Liang #define SNR_PCIE3_PCI_PMON_CTL0			0x508
406a3b1e845SKan Liang #define SNR_PCIE3_PCI_PMON_CTR0			0x4e8
407a3b1e845SKan Liang #define SNR_PCIE3_PCI_PMON_BOX_CTL		0x4e0
408a3b1e845SKan Liang 
409ee49532bSKan Liang /* SNR IMC */
410ee49532bSKan Liang #define SNR_IMC_MMIO_PMON_FIXED_CTL		0x54
411ee49532bSKan Liang #define SNR_IMC_MMIO_PMON_FIXED_CTR		0x38
412ee49532bSKan Liang #define SNR_IMC_MMIO_PMON_CTL0			0x40
413ee49532bSKan Liang #define SNR_IMC_MMIO_PMON_CTR0			0x8
414ee49532bSKan Liang #define SNR_IMC_MMIO_PMON_BOX_CTL		0x22800
415ee49532bSKan Liang #define SNR_IMC_MMIO_OFFSET			0x4000
416ee49532bSKan Liang #define SNR_IMC_MMIO_SIZE			0x4000
417ee49532bSKan Liang #define SNR_IMC_MMIO_BASE_OFFSET		0xd0
418ee49532bSKan Liang #define SNR_IMC_MMIO_BASE_MASK			0x1FFFFFFF
419ee49532bSKan Liang #define SNR_IMC_MMIO_MEM0_OFFSET		0xd8
420ee49532bSKan Liang #define SNR_IMC_MMIO_MEM0_MASK			0x7FF
421ee49532bSKan Liang 
4222b3b76b5SKan Liang /* ICX CHA */
4232b3b76b5SKan Liang #define ICX_C34_MSR_PMON_CTR0			0xb68
4242b3b76b5SKan Liang #define ICX_C34_MSR_PMON_CTL0			0xb61
4252b3b76b5SKan Liang #define ICX_C34_MSR_PMON_BOX_CTL		0xb60
4262b3b76b5SKan Liang #define ICX_C34_MSR_PMON_BOX_FILTER0		0xb65
4272b3b76b5SKan Liang 
4282b3b76b5SKan Liang /* ICX IIO */
4292b3b76b5SKan Liang #define ICX_IIO_MSR_PMON_CTL0			0xa58
4302b3b76b5SKan Liang #define ICX_IIO_MSR_PMON_CTR0			0xa51
4312b3b76b5SKan Liang #define ICX_IIO_MSR_PMON_BOX_CTL		0xa50
4322b3b76b5SKan Liang 
4332b3b76b5SKan Liang /* ICX IRP */
4342b3b76b5SKan Liang #define ICX_IRP0_MSR_PMON_CTL0			0xa4d
4352b3b76b5SKan Liang #define ICX_IRP0_MSR_PMON_CTR0			0xa4b
4362b3b76b5SKan Liang #define ICX_IRP0_MSR_PMON_BOX_CTL		0xa4a
4372b3b76b5SKan Liang 
4382b3b76b5SKan Liang /* ICX M2PCIE */
4392b3b76b5SKan Liang #define ICX_M2PCIE_MSR_PMON_CTL0		0xa46
4402b3b76b5SKan Liang #define ICX_M2PCIE_MSR_PMON_CTR0		0xa41
4412b3b76b5SKan Liang #define ICX_M2PCIE_MSR_PMON_BOX_CTL		0xa40
4422b3b76b5SKan Liang 
4432b3b76b5SKan Liang /* ICX UPI */
4442b3b76b5SKan Liang #define ICX_UPI_PCI_PMON_CTL0			0x350
4452b3b76b5SKan Liang #define ICX_UPI_PCI_PMON_CTR0			0x320
4462b3b76b5SKan Liang #define ICX_UPI_PCI_PMON_BOX_CTL		0x318
4472b3b76b5SKan Liang #define ICX_UPI_CTL_UMASK_EXT			0xffffff
448*f680b6e6SAlexander Antonov #define ICX_UBOX_DID				0x3450
4492b3b76b5SKan Liang 
4502b3b76b5SKan Liang /* ICX M3UPI*/
4512b3b76b5SKan Liang #define ICX_M3UPI_PCI_PMON_CTL0			0xd8
4522b3b76b5SKan Liang #define ICX_M3UPI_PCI_PMON_CTR0			0xa8
4532b3b76b5SKan Liang #define ICX_M3UPI_PCI_PMON_BOX_CTL		0xa0
4542b3b76b5SKan Liang 
4552b3b76b5SKan Liang /* ICX IMC */
456496a18f0SKan Liang #define ICX_NUMBER_IMC_CHN			3
4572b3b76b5SKan Liang #define ICX_IMC_MEM_STRIDE			0x4
4582b3b76b5SKan Liang 
459949b1138SKan Liang /* SPR */
460949b1138SKan Liang #define SPR_RAW_EVENT_MASK_EXT			0xffffff
461949b1138SKan Liang 
462949b1138SKan Liang /* SPR CHA */
463949b1138SKan Liang #define SPR_CHA_PMON_CTL_TID_EN			(1 << 16)
464949b1138SKan Liang #define SPR_CHA_PMON_EVENT_MASK			(SNBEP_PMON_RAW_EVENT_MASK | \
465949b1138SKan Liang 						 SPR_CHA_PMON_CTL_TID_EN)
466949b1138SKan Liang #define SPR_CHA_PMON_BOX_FILTER_TID		0x3ff
467949b1138SKan Liang 
468949b1138SKan Liang #define SPR_C0_MSR_PMON_BOX_FILTER0		0x200e
469949b1138SKan Liang 
470ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
471ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(event2, event, "config:0-6");
472ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21");
473ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(use_occ_ctr, use_occ_ctr, "config:7");
474ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
475b3625980SStephane Eranian DEFINE_UNCORE_FORMAT_ATTR(umask_ext, umask, "config:8-15,32-43,45-55");
476210cc5f9SKan Liang DEFINE_UNCORE_FORMAT_ATTR(umask_ext2, umask, "config:8-15,32-57");
477210cc5f9SKan Liang DEFINE_UNCORE_FORMAT_ATTR(umask_ext3, umask, "config:8-15,32-39");
4782b3b76b5SKan Liang DEFINE_UNCORE_FORMAT_ATTR(umask_ext4, umask, "config:8-15,32-55");
479ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(qor, qor, "config:16");
480ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
481ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19");
482949b1138SKan Liang DEFINE_UNCORE_FORMAT_ATTR(tid_en2, tid_en, "config:16");
483ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
484cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(thresh9, thresh, "config:24-35");
485ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31");
486ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(thresh6, thresh, "config:24-29");
487ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(thresh5, thresh, "config:24-28");
488ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(occ_sel, occ_sel, "config:14-15");
489ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30");
490ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51");
491ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(occ_edge_det, occ_edge_det, "config:31");
492cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(ch_mask, ch_mask, "config:36-43");
493210cc5f9SKan Liang DEFINE_UNCORE_FORMAT_ATTR(ch_mask2, ch_mask, "config:36-47");
494cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(fc_mask, fc_mask, "config:44-46");
495210cc5f9SKan Liang DEFINE_UNCORE_FORMAT_ATTR(fc_mask2, fc_mask, "config:48-50");
496ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_tid, filter_tid, "config1:0-4");
497ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_tid2, filter_tid, "config1:0");
498ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_tid3, filter_tid, "config1:0-5");
499ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_tid4, filter_tid, "config1:0-8");
500210cc5f9SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_tid5, filter_tid, "config1:0-9");
501ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_cid, filter_cid, "config1:5");
502ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_link, filter_link, "config1:5-8");
503ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_link2, filter_link, "config1:6-8");
504ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_link3, filter_link, "config1:12");
505ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17");
506ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_nid2, filter_nid, "config1:32-47");
507ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22");
508ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_state2, filter_state, "config1:17-22");
509ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_state3, filter_state, "config1:17-23");
510ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_state4, filter_state, "config1:18-20");
511cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_state5, filter_state, "config1:17-26");
512cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_rem, filter_rem, "config1:32");
513cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_loc, filter_loc, "config1:33");
514cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_nm, filter_nm, "config1:36");
515cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_not_nm, filter_not_nm, "config1:37");
516ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_local, filter_local, "config1:33");
517ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_all_op, filter_all_op, "config1:35");
518ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_nnm, filter_nnm, "config1:37");
519ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31");
520ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_opc2, filter_opc, "config1:52-60");
521ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_opc3, filter_opc, "config1:41-60");
522cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_opc_0, filter_opc0, "config1:41-50");
523cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_opc_1, filter_opc1, "config1:51-60");
524ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_nc, filter_nc, "config1:62");
525ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_c6, filter_c6, "config1:61");
526ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_isoc, filter_isoc, "config1:63");
527ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_band0, filter_band0, "config1:0-7");
528ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_band1, filter_band1, "config1:8-15");
529ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_band2, filter_band2, "config1:16-23");
530ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_band3, filter_band3, "config1:24-31");
531ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_rds, match_rds, "config1:48-51");
532ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_rnid30, match_rnid30, "config1:32-35");
533ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_rnid4, match_rnid4, "config1:31");
534ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_dnid, match_dnid, "config1:13-17");
535ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_mc, match_mc, "config1:9-12");
536ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_opc, match_opc, "config1:5-8");
537ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_vnw, match_vnw, "config1:3-4");
538ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match0, match0, "config1:0-31");
539ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match1, match1, "config1:32-63");
540ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_rds, mask_rds, "config2:48-51");
541ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_rnid30, mask_rnid30, "config2:32-35");
542ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_rnid4, mask_rnid4, "config2:31");
543ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_dnid, mask_dnid, "config2:13-17");
544ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_mc, mask_mc, "config2:9-12");
545ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_opc, mask_opc, "config2:5-8");
546ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_vnw, mask_vnw, "config2:3-4");
547ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask0, mask0, "config2:0-31");
548ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask1, mask1, "config2:32-63");
549ed367e6cSBorislav Petkov 
550ed367e6cSBorislav Petkov static void snbep_uncore_pci_disable_box(struct intel_uncore_box *box)
551ed367e6cSBorislav Petkov {
552ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
553ed367e6cSBorislav Petkov 	int box_ctl = uncore_pci_box_ctl(box);
554ed367e6cSBorislav Petkov 	u32 config = 0;
555ed367e6cSBorislav Petkov 
556ed367e6cSBorislav Petkov 	if (!pci_read_config_dword(pdev, box_ctl, &config)) {
557ed367e6cSBorislav Petkov 		config |= SNBEP_PMON_BOX_CTL_FRZ;
558ed367e6cSBorislav Petkov 		pci_write_config_dword(pdev, box_ctl, config);
559ed367e6cSBorislav Petkov 	}
560ed367e6cSBorislav Petkov }
561ed367e6cSBorislav Petkov 
562ed367e6cSBorislav Petkov static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box)
563ed367e6cSBorislav Petkov {
564ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
565ed367e6cSBorislav Petkov 	int box_ctl = uncore_pci_box_ctl(box);
566ed367e6cSBorislav Petkov 	u32 config = 0;
567ed367e6cSBorislav Petkov 
568ed367e6cSBorislav Petkov 	if (!pci_read_config_dword(pdev, box_ctl, &config)) {
569ed367e6cSBorislav Petkov 		config &= ~SNBEP_PMON_BOX_CTL_FRZ;
570ed367e6cSBorislav Petkov 		pci_write_config_dword(pdev, box_ctl, config);
571ed367e6cSBorislav Petkov 	}
572ed367e6cSBorislav Petkov }
573ed367e6cSBorislav Petkov 
574ed367e6cSBorislav Petkov static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event)
575ed367e6cSBorislav Petkov {
576ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
577ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
578ed367e6cSBorislav Petkov 
579ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
580ed367e6cSBorislav Petkov }
581ed367e6cSBorislav Petkov 
582ed367e6cSBorislav Petkov static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box, struct perf_event *event)
583ed367e6cSBorislav Petkov {
584ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
585ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
586ed367e6cSBorislav Petkov 
587ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, hwc->config_base, hwc->config);
588ed367e6cSBorislav Petkov }
589ed367e6cSBorislav Petkov 
590ed367e6cSBorislav Petkov static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, struct perf_event *event)
591ed367e6cSBorislav Petkov {
592ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
593ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
594ed367e6cSBorislav Petkov 	u64 count = 0;
595ed367e6cSBorislav Petkov 
596ed367e6cSBorislav Petkov 	pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count);
597ed367e6cSBorislav Petkov 	pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1);
598ed367e6cSBorislav Petkov 
599ed367e6cSBorislav Petkov 	return count;
600ed367e6cSBorislav Petkov }
601ed367e6cSBorislav Petkov 
602ed367e6cSBorislav Petkov static void snbep_uncore_pci_init_box(struct intel_uncore_box *box)
603ed367e6cSBorislav Petkov {
604ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
605ed367e6cSBorislav Petkov 	int box_ctl = uncore_pci_box_ctl(box);
606ed367e6cSBorislav Petkov 
607ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, box_ctl, SNBEP_PMON_BOX_CTL_INT);
608ed367e6cSBorislav Petkov }
609ed367e6cSBorislav Petkov 
610ed367e6cSBorislav Petkov static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box)
611ed367e6cSBorislav Petkov {
612ed367e6cSBorislav Petkov 	u64 config;
613ed367e6cSBorislav Petkov 	unsigned msr;
614ed367e6cSBorislav Petkov 
615ed367e6cSBorislav Petkov 	msr = uncore_msr_box_ctl(box);
616ed367e6cSBorislav Petkov 	if (msr) {
617ed367e6cSBorislav Petkov 		rdmsrl(msr, config);
618ed367e6cSBorislav Petkov 		config |= SNBEP_PMON_BOX_CTL_FRZ;
619ed367e6cSBorislav Petkov 		wrmsrl(msr, config);
620ed367e6cSBorislav Petkov 	}
621ed367e6cSBorislav Petkov }
622ed367e6cSBorislav Petkov 
623ed367e6cSBorislav Petkov static void snbep_uncore_msr_enable_box(struct intel_uncore_box *box)
624ed367e6cSBorislav Petkov {
625ed367e6cSBorislav Petkov 	u64 config;
626ed367e6cSBorislav Petkov 	unsigned msr;
627ed367e6cSBorislav Petkov 
628ed367e6cSBorislav Petkov 	msr = uncore_msr_box_ctl(box);
629ed367e6cSBorislav Petkov 	if (msr) {
630ed367e6cSBorislav Petkov 		rdmsrl(msr, config);
631ed367e6cSBorislav Petkov 		config &= ~SNBEP_PMON_BOX_CTL_FRZ;
632ed367e6cSBorislav Petkov 		wrmsrl(msr, config);
633ed367e6cSBorislav Petkov 	}
634ed367e6cSBorislav Petkov }
635ed367e6cSBorislav Petkov 
636ed367e6cSBorislav Petkov static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
637ed367e6cSBorislav Petkov {
638ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
639ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
640ed367e6cSBorislav Petkov 
641ed367e6cSBorislav Petkov 	if (reg1->idx != EXTRA_REG_NONE)
642ed367e6cSBorislav Petkov 		wrmsrl(reg1->reg, uncore_shared_reg_config(box, 0));
643ed367e6cSBorislav Petkov 
644ed367e6cSBorislav Petkov 	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
645ed367e6cSBorislav Petkov }
646ed367e6cSBorislav Petkov 
647ed367e6cSBorislav Petkov static void snbep_uncore_msr_disable_event(struct intel_uncore_box *box,
648ed367e6cSBorislav Petkov 					struct perf_event *event)
649ed367e6cSBorislav Petkov {
650ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
651ed367e6cSBorislav Petkov 
652ed367e6cSBorislav Petkov 	wrmsrl(hwc->config_base, hwc->config);
653ed367e6cSBorislav Petkov }
654ed367e6cSBorislav Petkov 
655ed367e6cSBorislav Petkov static void snbep_uncore_msr_init_box(struct intel_uncore_box *box)
656ed367e6cSBorislav Petkov {
657ed367e6cSBorislav Petkov 	unsigned msr = uncore_msr_box_ctl(box);
658ed367e6cSBorislav Petkov 
659ed367e6cSBorislav Petkov 	if (msr)
660ed367e6cSBorislav Petkov 		wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT);
661ed367e6cSBorislav Petkov }
662ed367e6cSBorislav Petkov 
663ed367e6cSBorislav Petkov static struct attribute *snbep_uncore_formats_attr[] = {
664ed367e6cSBorislav Petkov 	&format_attr_event.attr,
665ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
666ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
667ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
668ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
669ed367e6cSBorislav Petkov 	NULL,
670ed367e6cSBorislav Petkov };
671ed367e6cSBorislav Petkov 
672ed367e6cSBorislav Petkov static struct attribute *snbep_uncore_ubox_formats_attr[] = {
673ed367e6cSBorislav Petkov 	&format_attr_event.attr,
674ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
675ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
676ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
677ed367e6cSBorislav Petkov 	&format_attr_thresh5.attr,
678ed367e6cSBorislav Petkov 	NULL,
679ed367e6cSBorislav Petkov };
680ed367e6cSBorislav Petkov 
681ed367e6cSBorislav Petkov static struct attribute *snbep_uncore_cbox_formats_attr[] = {
682ed367e6cSBorislav Petkov 	&format_attr_event.attr,
683ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
684ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
685ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
686ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
687ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
688ed367e6cSBorislav Petkov 	&format_attr_filter_tid.attr,
689ed367e6cSBorislav Petkov 	&format_attr_filter_nid.attr,
690ed367e6cSBorislav Petkov 	&format_attr_filter_state.attr,
691ed367e6cSBorislav Petkov 	&format_attr_filter_opc.attr,
692ed367e6cSBorislav Petkov 	NULL,
693ed367e6cSBorislav Petkov };
694ed367e6cSBorislav Petkov 
695ed367e6cSBorislav Petkov static struct attribute *snbep_uncore_pcu_formats_attr[] = {
696cb225252SKan Liang 	&format_attr_event.attr,
697ed367e6cSBorislav Petkov 	&format_attr_occ_sel.attr,
698ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
699ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
700ed367e6cSBorislav Petkov 	&format_attr_thresh5.attr,
701ed367e6cSBorislav Petkov 	&format_attr_occ_invert.attr,
702ed367e6cSBorislav Petkov 	&format_attr_occ_edge.attr,
703ed367e6cSBorislav Petkov 	&format_attr_filter_band0.attr,
704ed367e6cSBorislav Petkov 	&format_attr_filter_band1.attr,
705ed367e6cSBorislav Petkov 	&format_attr_filter_band2.attr,
706ed367e6cSBorislav Petkov 	&format_attr_filter_band3.attr,
707ed367e6cSBorislav Petkov 	NULL,
708ed367e6cSBorislav Petkov };
709ed367e6cSBorislav Petkov 
710ed367e6cSBorislav Petkov static struct attribute *snbep_uncore_qpi_formats_attr[] = {
711ed367e6cSBorislav Petkov 	&format_attr_event_ext.attr,
712ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
713ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
714ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
715ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
716ed367e6cSBorislav Petkov 	&format_attr_match_rds.attr,
717ed367e6cSBorislav Petkov 	&format_attr_match_rnid30.attr,
718ed367e6cSBorislav Petkov 	&format_attr_match_rnid4.attr,
719ed367e6cSBorislav Petkov 	&format_attr_match_dnid.attr,
720ed367e6cSBorislav Petkov 	&format_attr_match_mc.attr,
721ed367e6cSBorislav Petkov 	&format_attr_match_opc.attr,
722ed367e6cSBorislav Petkov 	&format_attr_match_vnw.attr,
723ed367e6cSBorislav Petkov 	&format_attr_match0.attr,
724ed367e6cSBorislav Petkov 	&format_attr_match1.attr,
725ed367e6cSBorislav Petkov 	&format_attr_mask_rds.attr,
726ed367e6cSBorislav Petkov 	&format_attr_mask_rnid30.attr,
727ed367e6cSBorislav Petkov 	&format_attr_mask_rnid4.attr,
728ed367e6cSBorislav Petkov 	&format_attr_mask_dnid.attr,
729ed367e6cSBorislav Petkov 	&format_attr_mask_mc.attr,
730ed367e6cSBorislav Petkov 	&format_attr_mask_opc.attr,
731ed367e6cSBorislav Petkov 	&format_attr_mask_vnw.attr,
732ed367e6cSBorislav Petkov 	&format_attr_mask0.attr,
733ed367e6cSBorislav Petkov 	&format_attr_mask1.attr,
734ed367e6cSBorislav Petkov 	NULL,
735ed367e6cSBorislav Petkov };
736ed367e6cSBorislav Petkov 
737ed367e6cSBorislav Petkov static struct uncore_event_desc snbep_uncore_imc_events[] = {
738ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(clockticks,      "event=0xff,umask=0x00"),
739ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_read,  "event=0x04,umask=0x03"),
740ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_read.scale, "6.103515625e-5"),
741ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_read.unit, "MiB"),
742ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"),
743ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_write.scale, "6.103515625e-5"),
744ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_write.unit, "MiB"),
745ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ },
746ed367e6cSBorislav Petkov };
747ed367e6cSBorislav Petkov 
748ed367e6cSBorislav Petkov static struct uncore_event_desc snbep_uncore_qpi_events[] = {
749ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(clockticks,       "event=0x14"),
750ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(txl_flits_active, "event=0x00,umask=0x06"),
751ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(drs_data,         "event=0x102,umask=0x08"),
752ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(ncb_data,         "event=0x103,umask=0x04"),
753ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ },
754ed367e6cSBorislav Petkov };
755ed367e6cSBorislav Petkov 
75645bd07adSArvind Yadav static const struct attribute_group snbep_uncore_format_group = {
757ed367e6cSBorislav Petkov 	.name = "format",
758ed367e6cSBorislav Petkov 	.attrs = snbep_uncore_formats_attr,
759ed367e6cSBorislav Petkov };
760ed367e6cSBorislav Petkov 
76145bd07adSArvind Yadav static const struct attribute_group snbep_uncore_ubox_format_group = {
762ed367e6cSBorislav Petkov 	.name = "format",
763ed367e6cSBorislav Petkov 	.attrs = snbep_uncore_ubox_formats_attr,
764ed367e6cSBorislav Petkov };
765ed367e6cSBorislav Petkov 
76645bd07adSArvind Yadav static const struct attribute_group snbep_uncore_cbox_format_group = {
767ed367e6cSBorislav Petkov 	.name = "format",
768ed367e6cSBorislav Petkov 	.attrs = snbep_uncore_cbox_formats_attr,
769ed367e6cSBorislav Petkov };
770ed367e6cSBorislav Petkov 
77145bd07adSArvind Yadav static const struct attribute_group snbep_uncore_pcu_format_group = {
772ed367e6cSBorislav Petkov 	.name = "format",
773ed367e6cSBorislav Petkov 	.attrs = snbep_uncore_pcu_formats_attr,
774ed367e6cSBorislav Petkov };
775ed367e6cSBorislav Petkov 
77645bd07adSArvind Yadav static const struct attribute_group snbep_uncore_qpi_format_group = {
777ed367e6cSBorislav Petkov 	.name = "format",
778ed367e6cSBorislav Petkov 	.attrs = snbep_uncore_qpi_formats_attr,
779ed367e6cSBorislav Petkov };
780ed367e6cSBorislav Petkov 
781ed367e6cSBorislav Petkov #define __SNBEP_UNCORE_MSR_OPS_COMMON_INIT()			\
782ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_msr_disable_box,		\
783ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_msr_enable_box,		\
784ed367e6cSBorislav Petkov 	.disable_event	= snbep_uncore_msr_disable_event,	\
785ed367e6cSBorislav Petkov 	.enable_event	= snbep_uncore_msr_enable_event,	\
786ed367e6cSBorislav Petkov 	.read_counter	= uncore_msr_read_counter
787ed367e6cSBorislav Petkov 
788ed367e6cSBorislav Petkov #define SNBEP_UNCORE_MSR_OPS_COMMON_INIT()			\
789ed367e6cSBorislav Petkov 	__SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),			\
790ed367e6cSBorislav Petkov 	.init_box	= snbep_uncore_msr_init_box		\
791ed367e6cSBorislav Petkov 
792ed367e6cSBorislav Petkov static struct intel_uncore_ops snbep_uncore_msr_ops = {
793ed367e6cSBorislav Petkov 	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
794ed367e6cSBorislav Petkov };
795ed367e6cSBorislav Petkov 
796ed367e6cSBorislav Petkov #define SNBEP_UNCORE_PCI_OPS_COMMON_INIT()			\
797ed367e6cSBorislav Petkov 	.init_box	= snbep_uncore_pci_init_box,		\
798ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_pci_disable_box,		\
799ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_pci_enable_box,		\
800ed367e6cSBorislav Petkov 	.disable_event	= snbep_uncore_pci_disable_event,	\
801ed367e6cSBorislav Petkov 	.read_counter	= snbep_uncore_pci_read_counter
802ed367e6cSBorislav Petkov 
803ed367e6cSBorislav Petkov static struct intel_uncore_ops snbep_uncore_pci_ops = {
804ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_OPS_COMMON_INIT(),
805ed367e6cSBorislav Petkov 	.enable_event	= snbep_uncore_pci_enable_event,	\
806ed367e6cSBorislav Petkov };
807ed367e6cSBorislav Petkov 
808ed367e6cSBorislav Petkov static struct event_constraint snbep_uncore_cbox_constraints[] = {
809ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x01, 0x1),
810ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x02, 0x3),
811ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x04, 0x3),
812ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x05, 0x3),
813ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x07, 0x3),
814ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x09, 0x3),
815ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
816ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
817ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x13, 0x3),
818ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1b, 0xc),
819ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1c, 0xc),
820ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1d, 0xc),
821ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1e, 0xc),
8221134c2b5SPeter Zijlstra 	UNCORE_EVENT_CONSTRAINT(0x1f, 0xe),
823ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
824ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
825ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
826ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
827ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
828ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
829ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
830ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
831ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
832ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
833ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
834ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x3b, 0x1),
835ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
836ed367e6cSBorislav Petkov };
837ed367e6cSBorislav Petkov 
838ed367e6cSBorislav Petkov static struct event_constraint snbep_uncore_r2pcie_constraints[] = {
839ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
840ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
841ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x12, 0x1),
842ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
843ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
844ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
845ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
846ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
847ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
848ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
849ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
850ed367e6cSBorislav Petkov };
851ed367e6cSBorislav Petkov 
852ed367e6cSBorislav Petkov static struct event_constraint snbep_uncore_r3qpi_constraints[] = {
853ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
854ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
855ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
856ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
857ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
858ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
859ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
860ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
861ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
862ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
863ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
864ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
865ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
866ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2a, 0x3),
867ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2b, 0x3),
868ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
869ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
870ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
871ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
872ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x30, 0x3),
873ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
874ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
875ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
876ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
877ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
878ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
879ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
880ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
881ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
882ed367e6cSBorislav Petkov };
883ed367e6cSBorislav Petkov 
884ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_ubox = {
885ed367e6cSBorislav Petkov 	.name		= "ubox",
886ed367e6cSBorislav Petkov 	.num_counters   = 2,
887ed367e6cSBorislav Petkov 	.num_boxes	= 1,
888ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
889ed367e6cSBorislav Petkov 	.fixed_ctr_bits	= 48,
890ed367e6cSBorislav Petkov 	.perf_ctr	= SNBEP_U_MSR_PMON_CTR0,
891ed367e6cSBorislav Petkov 	.event_ctl	= SNBEP_U_MSR_PMON_CTL0,
892ed367e6cSBorislav Petkov 	.event_mask	= SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
893ed367e6cSBorislav Petkov 	.fixed_ctr	= SNBEP_U_MSR_PMON_UCLK_FIXED_CTR,
894ed367e6cSBorislav Petkov 	.fixed_ctl	= SNBEP_U_MSR_PMON_UCLK_FIXED_CTL,
895ed367e6cSBorislav Petkov 	.ops		= &snbep_uncore_msr_ops,
896ed367e6cSBorislav Petkov 	.format_group	= &snbep_uncore_ubox_format_group,
897ed367e6cSBorislav Petkov };
898ed367e6cSBorislav Petkov 
899ed367e6cSBorislav Petkov static struct extra_reg snbep_uncore_cbox_extra_regs[] = {
900ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
901ed367e6cSBorislav Petkov 				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
902ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
903ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0x6),
904ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
905ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0x6),
906ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
907ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0x6),
908ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x6),
909ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x8),
910ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x8),
911ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0xa),
912ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0xa),
913ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x2),
914ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x2),
915ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x2),
916ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x2),
917ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x8),
918ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x8),
919ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0xa),
920ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0xa),
921ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x2),
922ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x2),
923ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x2),
924ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x2),
925ed367e6cSBorislav Petkov 	EVENT_EXTRA_END
926ed367e6cSBorislav Petkov };
927ed367e6cSBorislav Petkov 
928ed367e6cSBorislav Petkov static void snbep_cbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
929ed367e6cSBorislav Petkov {
930ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
931ed367e6cSBorislav Petkov 	struct intel_uncore_extra_reg *er = &box->shared_regs[0];
932ed367e6cSBorislav Petkov 	int i;
933ed367e6cSBorislav Petkov 
934ed367e6cSBorislav Petkov 	if (uncore_box_is_fake(box))
935ed367e6cSBorislav Petkov 		return;
936ed367e6cSBorislav Petkov 
937ed367e6cSBorislav Petkov 	for (i = 0; i < 5; i++) {
938ed367e6cSBorislav Petkov 		if (reg1->alloc & (0x1 << i))
939ed367e6cSBorislav Petkov 			atomic_sub(1 << (i * 6), &er->ref);
940ed367e6cSBorislav Petkov 	}
941ed367e6cSBorislav Petkov 	reg1->alloc = 0;
942ed367e6cSBorislav Petkov }
943ed367e6cSBorislav Petkov 
944ed367e6cSBorislav Petkov static struct event_constraint *
945ed367e6cSBorislav Petkov __snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event,
946ed367e6cSBorislav Petkov 			    u64 (*cbox_filter_mask)(int fields))
947ed367e6cSBorislav Petkov {
948ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
949ed367e6cSBorislav Petkov 	struct intel_uncore_extra_reg *er = &box->shared_regs[0];
950ed367e6cSBorislav Petkov 	int i, alloc = 0;
951ed367e6cSBorislav Petkov 	unsigned long flags;
952ed367e6cSBorislav Petkov 	u64 mask;
953ed367e6cSBorislav Petkov 
954ed367e6cSBorislav Petkov 	if (reg1->idx == EXTRA_REG_NONE)
955ed367e6cSBorislav Petkov 		return NULL;
956ed367e6cSBorislav Petkov 
957ed367e6cSBorislav Petkov 	raw_spin_lock_irqsave(&er->lock, flags);
958ed367e6cSBorislav Petkov 	for (i = 0; i < 5; i++) {
959ed367e6cSBorislav Petkov 		if (!(reg1->idx & (0x1 << i)))
960ed367e6cSBorislav Petkov 			continue;
961ed367e6cSBorislav Petkov 		if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i)))
962ed367e6cSBorislav Petkov 			continue;
963ed367e6cSBorislav Petkov 
964ed367e6cSBorislav Petkov 		mask = cbox_filter_mask(0x1 << i);
965ed367e6cSBorislav Petkov 		if (!__BITS_VALUE(atomic_read(&er->ref), i, 6) ||
966ed367e6cSBorislav Petkov 		    !((reg1->config ^ er->config) & mask)) {
967ed367e6cSBorislav Petkov 			atomic_add(1 << (i * 6), &er->ref);
968ed367e6cSBorislav Petkov 			er->config &= ~mask;
969ed367e6cSBorislav Petkov 			er->config |= reg1->config & mask;
970ed367e6cSBorislav Petkov 			alloc |= (0x1 << i);
971ed367e6cSBorislav Petkov 		} else {
972ed367e6cSBorislav Petkov 			break;
973ed367e6cSBorislav Petkov 		}
974ed367e6cSBorislav Petkov 	}
975ed367e6cSBorislav Petkov 	raw_spin_unlock_irqrestore(&er->lock, flags);
976ed367e6cSBorislav Petkov 	if (i < 5)
977ed367e6cSBorislav Petkov 		goto fail;
978ed367e6cSBorislav Petkov 
979ed367e6cSBorislav Petkov 	if (!uncore_box_is_fake(box))
980ed367e6cSBorislav Petkov 		reg1->alloc |= alloc;
981ed367e6cSBorislav Petkov 
982ed367e6cSBorislav Petkov 	return NULL;
983ed367e6cSBorislav Petkov fail:
984ed367e6cSBorislav Petkov 	for (; i >= 0; i--) {
985ed367e6cSBorislav Petkov 		if (alloc & (0x1 << i))
986ed367e6cSBorislav Petkov 			atomic_sub(1 << (i * 6), &er->ref);
987ed367e6cSBorislav Petkov 	}
988ed367e6cSBorislav Petkov 	return &uncore_constraint_empty;
989ed367e6cSBorislav Petkov }
990ed367e6cSBorislav Petkov 
991ed367e6cSBorislav Petkov static u64 snbep_cbox_filter_mask(int fields)
992ed367e6cSBorislav Petkov {
993ed367e6cSBorislav Petkov 	u64 mask = 0;
994ed367e6cSBorislav Petkov 
995ed367e6cSBorislav Petkov 	if (fields & 0x1)
996ed367e6cSBorislav Petkov 		mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_TID;
997ed367e6cSBorislav Petkov 	if (fields & 0x2)
998ed367e6cSBorislav Petkov 		mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_NID;
999ed367e6cSBorislav Petkov 	if (fields & 0x4)
1000ed367e6cSBorislav Petkov 		mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_STATE;
1001ed367e6cSBorislav Petkov 	if (fields & 0x8)
1002ed367e6cSBorislav Petkov 		mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_OPC;
1003ed367e6cSBorislav Petkov 
1004ed367e6cSBorislav Petkov 	return mask;
1005ed367e6cSBorislav Petkov }
1006ed367e6cSBorislav Petkov 
1007ed367e6cSBorislav Petkov static struct event_constraint *
1008ed367e6cSBorislav Petkov snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
1009ed367e6cSBorislav Petkov {
1010ed367e6cSBorislav Petkov 	return __snbep_cbox_get_constraint(box, event, snbep_cbox_filter_mask);
1011ed367e6cSBorislav Petkov }
1012ed367e6cSBorislav Petkov 
1013ed367e6cSBorislav Petkov static int snbep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
1014ed367e6cSBorislav Petkov {
1015ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
1016ed367e6cSBorislav Petkov 	struct extra_reg *er;
1017ed367e6cSBorislav Petkov 	int idx = 0;
1018ed367e6cSBorislav Petkov 
1019ed367e6cSBorislav Petkov 	for (er = snbep_uncore_cbox_extra_regs; er->msr; er++) {
1020ed367e6cSBorislav Petkov 		if (er->event != (event->hw.config & er->config_mask))
1021ed367e6cSBorislav Petkov 			continue;
1022ed367e6cSBorislav Petkov 		idx |= er->idx;
1023ed367e6cSBorislav Petkov 	}
1024ed367e6cSBorislav Petkov 
1025ed367e6cSBorislav Petkov 	if (idx) {
1026ed367e6cSBorislav Petkov 		reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER +
1027ed367e6cSBorislav Petkov 			SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
1028ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1 & snbep_cbox_filter_mask(idx);
1029ed367e6cSBorislav Petkov 		reg1->idx = idx;
1030ed367e6cSBorislav Petkov 	}
1031ed367e6cSBorislav Petkov 	return 0;
1032ed367e6cSBorislav Petkov }
1033ed367e6cSBorislav Petkov 
1034ed367e6cSBorislav Petkov static struct intel_uncore_ops snbep_uncore_cbox_ops = {
1035ed367e6cSBorislav Petkov 	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
1036ed367e6cSBorislav Petkov 	.hw_config		= snbep_cbox_hw_config,
1037ed367e6cSBorislav Petkov 	.get_constraint		= snbep_cbox_get_constraint,
1038ed367e6cSBorislav Petkov 	.put_constraint		= snbep_cbox_put_constraint,
1039ed367e6cSBorislav Petkov };
1040ed367e6cSBorislav Petkov 
1041ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_cbox = {
1042ed367e6cSBorislav Petkov 	.name			= "cbox",
1043ed367e6cSBorislav Petkov 	.num_counters		= 4,
1044ed367e6cSBorislav Petkov 	.num_boxes		= 8,
1045ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 44,
1046ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_C0_MSR_PMON_CTL0,
1047ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_C0_MSR_PMON_CTR0,
1048ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
1049ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_C0_MSR_PMON_BOX_CTL,
1050ed367e6cSBorislav Petkov 	.msr_offset		= SNBEP_CBO_MSR_OFFSET,
1051ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
1052ed367e6cSBorislav Petkov 	.constraints		= snbep_uncore_cbox_constraints,
1053ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_cbox_ops,
1054ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_cbox_format_group,
1055ed367e6cSBorislav Petkov };
1056ed367e6cSBorislav Petkov 
1057ed367e6cSBorislav Petkov static u64 snbep_pcu_alter_er(struct perf_event *event, int new_idx, bool modify)
1058ed367e6cSBorislav Petkov {
1059ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1060ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
1061ed367e6cSBorislav Petkov 	u64 config = reg1->config;
1062ed367e6cSBorislav Petkov 
1063ed367e6cSBorislav Petkov 	if (new_idx > reg1->idx)
1064ed367e6cSBorislav Petkov 		config <<= 8 * (new_idx - reg1->idx);
1065ed367e6cSBorislav Petkov 	else
1066ed367e6cSBorislav Petkov 		config >>= 8 * (reg1->idx - new_idx);
1067ed367e6cSBorislav Petkov 
1068ed367e6cSBorislav Petkov 	if (modify) {
1069ed367e6cSBorislav Petkov 		hwc->config += new_idx - reg1->idx;
1070ed367e6cSBorislav Petkov 		reg1->config = config;
1071ed367e6cSBorislav Petkov 		reg1->idx = new_idx;
1072ed367e6cSBorislav Petkov 	}
1073ed367e6cSBorislav Petkov 	return config;
1074ed367e6cSBorislav Petkov }
1075ed367e6cSBorislav Petkov 
1076ed367e6cSBorislav Petkov static struct event_constraint *
1077ed367e6cSBorislav Petkov snbep_pcu_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
1078ed367e6cSBorislav Petkov {
1079ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
1080ed367e6cSBorislav Petkov 	struct intel_uncore_extra_reg *er = &box->shared_regs[0];
1081ed367e6cSBorislav Petkov 	unsigned long flags;
1082ed367e6cSBorislav Petkov 	int idx = reg1->idx;
1083ed367e6cSBorislav Petkov 	u64 mask, config1 = reg1->config;
1084ed367e6cSBorislav Petkov 	bool ok = false;
1085ed367e6cSBorislav Petkov 
1086ed367e6cSBorislav Petkov 	if (reg1->idx == EXTRA_REG_NONE ||
1087ed367e6cSBorislav Petkov 	    (!uncore_box_is_fake(box) && reg1->alloc))
1088ed367e6cSBorislav Petkov 		return NULL;
1089ed367e6cSBorislav Petkov again:
1090ed367e6cSBorislav Petkov 	mask = 0xffULL << (idx * 8);
1091ed367e6cSBorislav Petkov 	raw_spin_lock_irqsave(&er->lock, flags);
1092ed367e6cSBorislav Petkov 	if (!__BITS_VALUE(atomic_read(&er->ref), idx, 8) ||
1093ed367e6cSBorislav Petkov 	    !((config1 ^ er->config) & mask)) {
1094ed367e6cSBorislav Petkov 		atomic_add(1 << (idx * 8), &er->ref);
1095ed367e6cSBorislav Petkov 		er->config &= ~mask;
1096ed367e6cSBorislav Petkov 		er->config |= config1 & mask;
1097ed367e6cSBorislav Petkov 		ok = true;
1098ed367e6cSBorislav Petkov 	}
1099ed367e6cSBorislav Petkov 	raw_spin_unlock_irqrestore(&er->lock, flags);
1100ed367e6cSBorislav Petkov 
1101ed367e6cSBorislav Petkov 	if (!ok) {
1102ed367e6cSBorislav Petkov 		idx = (idx + 1) % 4;
1103ed367e6cSBorislav Petkov 		if (idx != reg1->idx) {
1104ed367e6cSBorislav Petkov 			config1 = snbep_pcu_alter_er(event, idx, false);
1105ed367e6cSBorislav Petkov 			goto again;
1106ed367e6cSBorislav Petkov 		}
1107ed367e6cSBorislav Petkov 		return &uncore_constraint_empty;
1108ed367e6cSBorislav Petkov 	}
1109ed367e6cSBorislav Petkov 
1110ed367e6cSBorislav Petkov 	if (!uncore_box_is_fake(box)) {
1111ed367e6cSBorislav Petkov 		if (idx != reg1->idx)
1112ed367e6cSBorislav Petkov 			snbep_pcu_alter_er(event, idx, true);
1113ed367e6cSBorislav Petkov 		reg1->alloc = 1;
1114ed367e6cSBorislav Petkov 	}
1115ed367e6cSBorislav Petkov 	return NULL;
1116ed367e6cSBorislav Petkov }
1117ed367e6cSBorislav Petkov 
1118ed367e6cSBorislav Petkov static void snbep_pcu_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
1119ed367e6cSBorislav Petkov {
1120ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
1121ed367e6cSBorislav Petkov 	struct intel_uncore_extra_reg *er = &box->shared_regs[0];
1122ed367e6cSBorislav Petkov 
1123ed367e6cSBorislav Petkov 	if (uncore_box_is_fake(box) || !reg1->alloc)
1124ed367e6cSBorislav Petkov 		return;
1125ed367e6cSBorislav Petkov 
1126ed367e6cSBorislav Petkov 	atomic_sub(1 << (reg1->idx * 8), &er->ref);
1127ed367e6cSBorislav Petkov 	reg1->alloc = 0;
1128ed367e6cSBorislav Petkov }
1129ed367e6cSBorislav Petkov 
1130ed367e6cSBorislav Petkov static int snbep_pcu_hw_config(struct intel_uncore_box *box, struct perf_event *event)
1131ed367e6cSBorislav Petkov {
1132ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1133ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
1134ed367e6cSBorislav Petkov 	int ev_sel = hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK;
1135ed367e6cSBorislav Petkov 
1136ed367e6cSBorislav Petkov 	if (ev_sel >= 0xb && ev_sel <= 0xe) {
1137ed367e6cSBorislav Petkov 		reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER;
1138ed367e6cSBorislav Petkov 		reg1->idx = ev_sel - 0xb;
1139ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1 & (0xff << (reg1->idx * 8));
1140ed367e6cSBorislav Petkov 	}
1141ed367e6cSBorislav Petkov 	return 0;
1142ed367e6cSBorislav Petkov }
1143ed367e6cSBorislav Petkov 
1144ed367e6cSBorislav Petkov static struct intel_uncore_ops snbep_uncore_pcu_ops = {
1145ed367e6cSBorislav Petkov 	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
1146ed367e6cSBorislav Petkov 	.hw_config		= snbep_pcu_hw_config,
1147ed367e6cSBorislav Petkov 	.get_constraint		= snbep_pcu_get_constraint,
1148ed367e6cSBorislav Petkov 	.put_constraint		= snbep_pcu_put_constraint,
1149ed367e6cSBorislav Petkov };
1150ed367e6cSBorislav Petkov 
1151ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_pcu = {
1152ed367e6cSBorislav Petkov 	.name			= "pcu",
1153ed367e6cSBorislav Petkov 	.num_counters		= 4,
1154ed367e6cSBorislav Petkov 	.num_boxes		= 1,
1155ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
1156ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCU_MSR_PMON_CTR0,
1157ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCU_MSR_PMON_CTL0,
1158ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
1159ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCU_MSR_PMON_BOX_CTL,
1160ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
1161ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_pcu_ops,
1162ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_pcu_format_group,
1163ed367e6cSBorislav Petkov };
1164ed367e6cSBorislav Petkov 
1165ed367e6cSBorislav Petkov static struct intel_uncore_type *snbep_msr_uncores[] = {
1166ed367e6cSBorislav Petkov 	&snbep_uncore_ubox,
1167ed367e6cSBorislav Petkov 	&snbep_uncore_cbox,
1168ed367e6cSBorislav Petkov 	&snbep_uncore_pcu,
1169ed367e6cSBorislav Petkov 	NULL,
1170ed367e6cSBorislav Petkov };
1171ed367e6cSBorislav Petkov 
1172ed367e6cSBorislav Petkov void snbep_uncore_cpu_init(void)
1173ed367e6cSBorislav Petkov {
1174ed367e6cSBorislav Petkov 	if (snbep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
1175ed367e6cSBorislav Petkov 		snbep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
1176ed367e6cSBorislav Petkov 	uncore_msr_uncores = snbep_msr_uncores;
1177ed367e6cSBorislav Petkov }
1178ed367e6cSBorislav Petkov 
1179ed367e6cSBorislav Petkov enum {
1180ed367e6cSBorislav Petkov 	SNBEP_PCI_QPI_PORT0_FILTER,
1181ed367e6cSBorislav Petkov 	SNBEP_PCI_QPI_PORT1_FILTER,
1182156c8b58SKan Liang 	BDX_PCI_QPI_PORT2_FILTER,
1183ed367e6cSBorislav Petkov };
1184ed367e6cSBorislav Petkov 
1185ed367e6cSBorislav Petkov static int snbep_qpi_hw_config(struct intel_uncore_box *box, struct perf_event *event)
1186ed367e6cSBorislav Petkov {
1187ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1188ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
1189ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
1190ed367e6cSBorislav Petkov 
1191ed367e6cSBorislav Petkov 	if ((hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK) == 0x38) {
1192ed367e6cSBorislav Petkov 		reg1->idx = 0;
1193ed367e6cSBorislav Petkov 		reg1->reg = SNBEP_Q_Py_PCI_PMON_PKT_MATCH0;
1194ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1;
1195ed367e6cSBorislav Petkov 		reg2->reg = SNBEP_Q_Py_PCI_PMON_PKT_MASK0;
1196ed367e6cSBorislav Petkov 		reg2->config = event->attr.config2;
1197ed367e6cSBorislav Petkov 	}
1198ed367e6cSBorislav Petkov 	return 0;
1199ed367e6cSBorislav Petkov }
1200ed367e6cSBorislav Petkov 
1201ed367e6cSBorislav Petkov static void snbep_qpi_enable_event(struct intel_uncore_box *box, struct perf_event *event)
1202ed367e6cSBorislav Petkov {
1203ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
1204ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1205ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
1206ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
1207ed367e6cSBorislav Petkov 
1208ed367e6cSBorislav Petkov 	if (reg1->idx != EXTRA_REG_NONE) {
1209ed367e6cSBorislav Petkov 		int idx = box->pmu->pmu_idx + SNBEP_PCI_QPI_PORT0_FILTER;
1210b0529b9cSKan Liang 		int die = box->dieid;
1211b0529b9cSKan Liang 		struct pci_dev *filter_pdev = uncore_extra_pci_dev[die].dev[idx];
1212cf6d445fSThomas Gleixner 
1213ed367e6cSBorislav Petkov 		if (filter_pdev) {
1214ed367e6cSBorislav Petkov 			pci_write_config_dword(filter_pdev, reg1->reg,
1215ed367e6cSBorislav Petkov 						(u32)reg1->config);
1216ed367e6cSBorislav Petkov 			pci_write_config_dword(filter_pdev, reg1->reg + 4,
1217ed367e6cSBorislav Petkov 						(u32)(reg1->config >> 32));
1218ed367e6cSBorislav Petkov 			pci_write_config_dword(filter_pdev, reg2->reg,
1219ed367e6cSBorislav Petkov 						(u32)reg2->config);
1220ed367e6cSBorislav Petkov 			pci_write_config_dword(filter_pdev, reg2->reg + 4,
1221ed367e6cSBorislav Petkov 						(u32)(reg2->config >> 32));
1222ed367e6cSBorislav Petkov 		}
1223ed367e6cSBorislav Petkov 	}
1224ed367e6cSBorislav Petkov 
1225ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
1226ed367e6cSBorislav Petkov }
1227ed367e6cSBorislav Petkov 
1228ed367e6cSBorislav Petkov static struct intel_uncore_ops snbep_uncore_qpi_ops = {
1229ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_OPS_COMMON_INIT(),
1230ed367e6cSBorislav Petkov 	.enable_event		= snbep_qpi_enable_event,
1231ed367e6cSBorislav Petkov 	.hw_config		= snbep_qpi_hw_config,
1232ed367e6cSBorislav Petkov 	.get_constraint		= uncore_get_constraint,
1233ed367e6cSBorislav Petkov 	.put_constraint		= uncore_put_constraint,
1234ed367e6cSBorislav Petkov };
1235ed367e6cSBorislav Petkov 
1236ed367e6cSBorislav Petkov #define SNBEP_UNCORE_PCI_COMMON_INIT()				\
1237ed367e6cSBorislav Petkov 	.perf_ctr	= SNBEP_PCI_PMON_CTR0,			\
1238ed367e6cSBorislav Petkov 	.event_ctl	= SNBEP_PCI_PMON_CTL0,			\
1239ed367e6cSBorislav Petkov 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,		\
1240ed367e6cSBorislav Petkov 	.box_ctl	= SNBEP_PCI_PMON_BOX_CTL,		\
1241ed367e6cSBorislav Petkov 	.ops		= &snbep_uncore_pci_ops,		\
1242ed367e6cSBorislav Petkov 	.format_group	= &snbep_uncore_format_group
1243ed367e6cSBorislav Petkov 
1244ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_ha = {
1245ed367e6cSBorislav Petkov 	.name		= "ha",
1246ed367e6cSBorislav Petkov 	.num_counters   = 4,
1247ed367e6cSBorislav Petkov 	.num_boxes	= 1,
1248ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
1249ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
1250ed367e6cSBorislav Petkov };
1251ed367e6cSBorislav Petkov 
1252ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_imc = {
1253ed367e6cSBorislav Petkov 	.name		= "imc",
1254ed367e6cSBorislav Petkov 	.num_counters   = 4,
1255ed367e6cSBorislav Petkov 	.num_boxes	= 4,
1256ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
1257ed367e6cSBorislav Petkov 	.fixed_ctr_bits	= 48,
1258ed367e6cSBorislav Petkov 	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
1259ed367e6cSBorislav Petkov 	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
1260ed367e6cSBorislav Petkov 	.event_descs	= snbep_uncore_imc_events,
1261ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
1262ed367e6cSBorislav Petkov };
1263ed367e6cSBorislav Petkov 
1264ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_qpi = {
1265ed367e6cSBorislav Petkov 	.name			= "qpi",
1266ed367e6cSBorislav Petkov 	.num_counters		= 4,
1267ed367e6cSBorislav Petkov 	.num_boxes		= 2,
1268ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
1269ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
1270ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCI_PMON_CTL0,
1271ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
1272ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
1273ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
1274ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_qpi_ops,
1275ed367e6cSBorislav Petkov 	.event_descs		= snbep_uncore_qpi_events,
1276ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_qpi_format_group,
1277ed367e6cSBorislav Petkov };
1278ed367e6cSBorislav Petkov 
1279ed367e6cSBorislav Petkov 
1280ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_r2pcie = {
1281ed367e6cSBorislav Petkov 	.name		= "r2pcie",
1282ed367e6cSBorislav Petkov 	.num_counters   = 4,
1283ed367e6cSBorislav Petkov 	.num_boxes	= 1,
1284ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
1285ed367e6cSBorislav Petkov 	.constraints	= snbep_uncore_r2pcie_constraints,
1286ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
1287ed367e6cSBorislav Petkov };
1288ed367e6cSBorislav Petkov 
1289ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_r3qpi = {
1290ed367e6cSBorislav Petkov 	.name		= "r3qpi",
1291ed367e6cSBorislav Petkov 	.num_counters   = 3,
1292ed367e6cSBorislav Petkov 	.num_boxes	= 2,
1293ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
1294ed367e6cSBorislav Petkov 	.constraints	= snbep_uncore_r3qpi_constraints,
1295ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
1296ed367e6cSBorislav Petkov };
1297ed367e6cSBorislav Petkov 
1298ed367e6cSBorislav Petkov enum {
1299ed367e6cSBorislav Petkov 	SNBEP_PCI_UNCORE_HA,
1300ed367e6cSBorislav Petkov 	SNBEP_PCI_UNCORE_IMC,
1301ed367e6cSBorislav Petkov 	SNBEP_PCI_UNCORE_QPI,
1302ed367e6cSBorislav Petkov 	SNBEP_PCI_UNCORE_R2PCIE,
1303ed367e6cSBorislav Petkov 	SNBEP_PCI_UNCORE_R3QPI,
1304ed367e6cSBorislav Petkov };
1305ed367e6cSBorislav Petkov 
1306ed367e6cSBorislav Petkov static struct intel_uncore_type *snbep_pci_uncores[] = {
1307ed367e6cSBorislav Petkov 	[SNBEP_PCI_UNCORE_HA]		= &snbep_uncore_ha,
1308ed367e6cSBorislav Petkov 	[SNBEP_PCI_UNCORE_IMC]		= &snbep_uncore_imc,
1309ed367e6cSBorislav Petkov 	[SNBEP_PCI_UNCORE_QPI]		= &snbep_uncore_qpi,
1310ed367e6cSBorislav Petkov 	[SNBEP_PCI_UNCORE_R2PCIE]	= &snbep_uncore_r2pcie,
1311ed367e6cSBorislav Petkov 	[SNBEP_PCI_UNCORE_R3QPI]	= &snbep_uncore_r3qpi,
1312ed367e6cSBorislav Petkov 	NULL,
1313ed367e6cSBorislav Petkov };
1314ed367e6cSBorislav Petkov 
1315ed367e6cSBorislav Petkov static const struct pci_device_id snbep_uncore_pci_ids[] = {
1316ed367e6cSBorislav Petkov 	{ /* Home Agent */
1317ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA),
1318ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_HA, 0),
1319ed367e6cSBorislav Petkov 	},
1320ed367e6cSBorislav Petkov 	{ /* MC Channel 0 */
1321ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0),
1322ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 0),
1323ed367e6cSBorislav Petkov 	},
1324ed367e6cSBorislav Petkov 	{ /* MC Channel 1 */
1325ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1),
1326ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 1),
1327ed367e6cSBorislav Petkov 	},
1328ed367e6cSBorislav Petkov 	{ /* MC Channel 2 */
1329ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2),
1330ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 2),
1331ed367e6cSBorislav Petkov 	},
1332ed367e6cSBorislav Petkov 	{ /* MC Channel 3 */
1333ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3),
1334ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 3),
1335ed367e6cSBorislav Petkov 	},
1336ed367e6cSBorislav Petkov 	{ /* QPI Port 0 */
1337ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0),
1338ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 0),
1339ed367e6cSBorislav Petkov 	},
1340ed367e6cSBorislav Petkov 	{ /* QPI Port 1 */
1341ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1),
1342ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 1),
1343ed367e6cSBorislav Petkov 	},
1344ed367e6cSBorislav Petkov 	{ /* R2PCIe */
1345ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE),
1346ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R2PCIE, 0),
1347ed367e6cSBorislav Petkov 	},
1348ed367e6cSBorislav Petkov 	{ /* R3QPI Link 0 */
1349ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0),
1350ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 0),
1351ed367e6cSBorislav Petkov 	},
1352ed367e6cSBorislav Petkov 	{ /* R3QPI Link 1 */
1353ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1),
1354ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 1),
1355ed367e6cSBorislav Petkov 	},
1356ed367e6cSBorislav Petkov 	{ /* QPI Port 0 filter  */
1357ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c86),
1358ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
1359ed367e6cSBorislav Petkov 						   SNBEP_PCI_QPI_PORT0_FILTER),
1360ed367e6cSBorislav Petkov 	},
1361ed367e6cSBorislav Petkov 	{ /* QPI Port 0 filter  */
1362ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c96),
1363ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
1364ed367e6cSBorislav Petkov 						   SNBEP_PCI_QPI_PORT1_FILTER),
1365ed367e6cSBorislav Petkov 	},
1366ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ }
1367ed367e6cSBorislav Petkov };
1368ed367e6cSBorislav Petkov 
1369ed367e6cSBorislav Petkov static struct pci_driver snbep_uncore_pci_driver = {
1370ed367e6cSBorislav Petkov 	.name		= "snbep_uncore",
1371ed367e6cSBorislav Petkov 	.id_table	= snbep_uncore_pci_ids,
1372ed367e6cSBorislav Petkov };
1373ed367e6cSBorislav Petkov 
13749e63a789SKan Liang #define NODE_ID_MASK	0x7
13759e63a789SKan Liang 
1376c4aebdb3SAlexander Antonov /* Each three bits from 0 to 23 of GIDNIDMAP register correspond Node ID. */
1377c4aebdb3SAlexander Antonov #define GIDNIDMAP(config, id)	(((config) >> (3 * (id))) & 0x7)
1378c4aebdb3SAlexander Antonov 
1379c4aebdb3SAlexander Antonov static int upi_nodeid_groupid(struct pci_dev *ubox_dev, int nodeid_loc, int idmap_loc,
1380c4aebdb3SAlexander Antonov 			      int *nodeid, int *groupid)
1381c4aebdb3SAlexander Antonov {
1382c4aebdb3SAlexander Antonov 	int ret;
1383c4aebdb3SAlexander Antonov 
1384c4aebdb3SAlexander Antonov 	/* get the Node ID of the local register */
1385c4aebdb3SAlexander Antonov 	ret = pci_read_config_dword(ubox_dev, nodeid_loc, nodeid);
1386c4aebdb3SAlexander Antonov 	if (ret)
1387c4aebdb3SAlexander Antonov 		goto err;
1388c4aebdb3SAlexander Antonov 
1389c4aebdb3SAlexander Antonov 	*nodeid = *nodeid & NODE_ID_MASK;
1390c4aebdb3SAlexander Antonov 	/* get the Node ID mapping */
1391c4aebdb3SAlexander Antonov 	ret = pci_read_config_dword(ubox_dev, idmap_loc, groupid);
1392c4aebdb3SAlexander Antonov 	if (ret)
1393c4aebdb3SAlexander Antonov 		goto err;
1394c4aebdb3SAlexander Antonov err:
1395c4aebdb3SAlexander Antonov 	return ret;
1396c4aebdb3SAlexander Antonov }
1397c4aebdb3SAlexander Antonov 
1398ed367e6cSBorislav Petkov /*
1399ed367e6cSBorislav Petkov  * build pci bus to socket mapping
1400ed367e6cSBorislav Petkov  */
140168ce4a0dSKan Liang static int snbep_pci2phy_map_init(int devid, int nodeid_loc, int idmap_loc, bool reverse)
1402ed367e6cSBorislav Petkov {
1403ed367e6cSBorislav Petkov 	struct pci_dev *ubox_dev = NULL;
1404ba9506beSSteve Wahl 	int i, bus, nodeid, segment, die_id;
1405ed367e6cSBorislav Petkov 	struct pci2phy_map *map;
1406ed367e6cSBorislav Petkov 	int err = 0;
1407ed367e6cSBorislav Petkov 	u32 config = 0;
1408ed367e6cSBorislav Petkov 
1409ed367e6cSBorislav Petkov 	while (1) {
1410ed367e6cSBorislav Petkov 		/* find the UBOX device */
1411ed367e6cSBorislav Petkov 		ubox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, devid, ubox_dev);
1412ed367e6cSBorislav Petkov 		if (!ubox_dev)
1413ed367e6cSBorislav Petkov 			break;
1414ed367e6cSBorislav Petkov 		bus = ubox_dev->bus->number;
14159a7832ceSSteve Wahl 		/*
14169a7832ceSSteve Wahl 		 * The nodeid and idmap registers only contain enough
14179a7832ceSSteve Wahl 		 * information to handle 8 nodes.  On systems with more
14189a7832ceSSteve Wahl 		 * than 8 nodes, we need to rely on NUMA information,
14199a7832ceSSteve Wahl 		 * filled in from BIOS supplied information, to determine
14209a7832ceSSteve Wahl 		 * the topology.
14219a7832ceSSteve Wahl 		 */
14229a7832ceSSteve Wahl 		if (nr_node_ids <= 8) {
1423c4aebdb3SAlexander Antonov 			err = upi_nodeid_groupid(ubox_dev, nodeid_loc, idmap_loc,
1424c4aebdb3SAlexander Antonov 						 &nodeid, &config);
1425ed367e6cSBorislav Petkov 			if (err)
1426ed367e6cSBorislav Petkov 				break;
1427ed367e6cSBorislav Petkov 
1428ed367e6cSBorislav Petkov 			segment = pci_domain_nr(ubox_dev->bus);
1429ed367e6cSBorislav Petkov 			raw_spin_lock(&pci2phy_map_lock);
1430ed367e6cSBorislav Petkov 			map = __find_pci2phy_map(segment);
1431ed367e6cSBorislav Petkov 			if (!map) {
1432ed367e6cSBorislav Petkov 				raw_spin_unlock(&pci2phy_map_lock);
1433ed367e6cSBorislav Petkov 				err = -ENOMEM;
1434ed367e6cSBorislav Petkov 				break;
1435ed367e6cSBorislav Petkov 			}
1436ed367e6cSBorislav Petkov 
1437ed367e6cSBorislav Petkov 			/*
1438ed367e6cSBorislav Petkov 			 * every three bits in the Node ID mapping register maps
1439ed367e6cSBorislav Petkov 			 * to a particular node.
1440ed367e6cSBorislav Petkov 			 */
1441ed367e6cSBorislav Petkov 			for (i = 0; i < 8; i++) {
1442c4aebdb3SAlexander Antonov 				if (nodeid == GIDNIDMAP(config, i)) {
1443ba9506beSSteve Wahl 					if (topology_max_die_per_package() > 1)
1444ba9506beSSteve Wahl 						die_id = i;
1445ba9506beSSteve Wahl 					else
1446ba9506beSSteve Wahl 						die_id = topology_phys_to_logical_pkg(i);
14474a0e3ff3SKan Liang 					if (die_id < 0)
14484a0e3ff3SKan Liang 						die_id = -ENODEV;
1449ba9506beSSteve Wahl 					map->pbus_to_dieid[bus] = die_id;
1450ed367e6cSBorislav Petkov 					break;
1451ed367e6cSBorislav Petkov 				}
1452ed367e6cSBorislav Petkov 			}
1453ed367e6cSBorislav Petkov 			raw_spin_unlock(&pci2phy_map_lock);
14549a7832ceSSteve Wahl 		} else {
14559a7832ceSSteve Wahl 			int node = pcibus_to_node(ubox_dev->bus);
14569a7832ceSSteve Wahl 			int cpu;
14579a7832ceSSteve Wahl 
14589a7832ceSSteve Wahl 			segment = pci_domain_nr(ubox_dev->bus);
14599a7832ceSSteve Wahl 			raw_spin_lock(&pci2phy_map_lock);
14609a7832ceSSteve Wahl 			map = __find_pci2phy_map(segment);
14619a7832ceSSteve Wahl 			if (!map) {
14629a7832ceSSteve Wahl 				raw_spin_unlock(&pci2phy_map_lock);
14639a7832ceSSteve Wahl 				err = -ENOMEM;
14649a7832ceSSteve Wahl 				break;
14659a7832ceSSteve Wahl 			}
14669a7832ceSSteve Wahl 
14679a7832ceSSteve Wahl 			die_id = -1;
14689a7832ceSSteve Wahl 			for_each_cpu(cpu, cpumask_of_pcibus(ubox_dev->bus)) {
14699a7832ceSSteve Wahl 				struct cpuinfo_x86 *c = &cpu_data(cpu);
14709a7832ceSSteve Wahl 
14719a7832ceSSteve Wahl 				if (c->initialized && cpu_to_node(cpu) == node) {
14729a7832ceSSteve Wahl 					map->pbus_to_dieid[bus] = die_id = c->logical_die_id;
14739a7832ceSSteve Wahl 					break;
14749a7832ceSSteve Wahl 				}
14759a7832ceSSteve Wahl 			}
14769a7832ceSSteve Wahl 			raw_spin_unlock(&pci2phy_map_lock);
14779a7832ceSSteve Wahl 
14789a7832ceSSteve Wahl 			if (WARN_ON_ONCE(die_id == -1)) {
14799a7832ceSSteve Wahl 				err = -EINVAL;
14809a7832ceSSteve Wahl 				break;
14819a7832ceSSteve Wahl 			}
14829a7832ceSSteve Wahl 		}
1483ed367e6cSBorislav Petkov 	}
1484ed367e6cSBorislav Petkov 
1485ed367e6cSBorislav Petkov 	if (!err) {
1486ed367e6cSBorislav Petkov 		/*
1487ed367e6cSBorislav Petkov 		 * For PCI bus with no UBOX device, find the next bus
1488ed367e6cSBorislav Petkov 		 * that has UBOX device and use its mapping.
1489ed367e6cSBorislav Petkov 		 */
1490ed367e6cSBorislav Petkov 		raw_spin_lock(&pci2phy_map_lock);
1491ed367e6cSBorislav Petkov 		list_for_each_entry(map, &pci2phy_map_head, list) {
1492ed367e6cSBorislav Petkov 			i = -1;
149368ce4a0dSKan Liang 			if (reverse) {
1494ed367e6cSBorislav Petkov 				for (bus = 255; bus >= 0; bus--) {
14954a0e3ff3SKan Liang 					if (map->pbus_to_dieid[bus] != -1)
1496ba9506beSSteve Wahl 						i = map->pbus_to_dieid[bus];
1497ed367e6cSBorislav Petkov 					else
1498ba9506beSSteve Wahl 						map->pbus_to_dieid[bus] = i;
1499ed367e6cSBorislav Petkov 				}
150068ce4a0dSKan Liang 			} else {
150168ce4a0dSKan Liang 				for (bus = 0; bus <= 255; bus++) {
15024a0e3ff3SKan Liang 					if (map->pbus_to_dieid[bus] != -1)
1503ba9506beSSteve Wahl 						i = map->pbus_to_dieid[bus];
150468ce4a0dSKan Liang 					else
1505ba9506beSSteve Wahl 						map->pbus_to_dieid[bus] = i;
150668ce4a0dSKan Liang 				}
150768ce4a0dSKan Liang 			}
1508ed367e6cSBorislav Petkov 		}
1509ed367e6cSBorislav Petkov 		raw_spin_unlock(&pci2phy_map_lock);
1510ed367e6cSBorislav Petkov 	}
1511ed367e6cSBorislav Petkov 
1512ed367e6cSBorislav Petkov 	pci_dev_put(ubox_dev);
1513ed367e6cSBorislav Petkov 
1514ed367e6cSBorislav Petkov 	return err ? pcibios_err_to_errno(err) : 0;
1515ed367e6cSBorislav Petkov }
1516ed367e6cSBorislav Petkov 
1517ed367e6cSBorislav Petkov int snbep_uncore_pci_init(void)
1518ed367e6cSBorislav Petkov {
151968ce4a0dSKan Liang 	int ret = snbep_pci2phy_map_init(0x3ce0, SNBEP_CPUNODEID, SNBEP_GIDNIDMAP, true);
1520ed367e6cSBorislav Petkov 	if (ret)
1521ed367e6cSBorislav Petkov 		return ret;
1522ed367e6cSBorislav Petkov 	uncore_pci_uncores = snbep_pci_uncores;
1523ed367e6cSBorislav Petkov 	uncore_pci_driver = &snbep_uncore_pci_driver;
1524ed367e6cSBorislav Petkov 	return 0;
1525ed367e6cSBorislav Petkov }
1526ed367e6cSBorislav Petkov /* end of Sandy Bridge-EP uncore support */
1527ed367e6cSBorislav Petkov 
1528ed367e6cSBorislav Petkov /* IvyTown uncore support */
1529ed367e6cSBorislav Petkov static void ivbep_uncore_msr_init_box(struct intel_uncore_box *box)
1530ed367e6cSBorislav Petkov {
1531ed367e6cSBorislav Petkov 	unsigned msr = uncore_msr_box_ctl(box);
1532ed367e6cSBorislav Petkov 	if (msr)
1533ed367e6cSBorislav Petkov 		wrmsrl(msr, IVBEP_PMON_BOX_CTL_INT);
1534ed367e6cSBorislav Petkov }
1535ed367e6cSBorislav Petkov 
1536ed367e6cSBorislav Petkov static void ivbep_uncore_pci_init_box(struct intel_uncore_box *box)
1537ed367e6cSBorislav Petkov {
1538ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
1539ed367e6cSBorislav Petkov 
1540ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, IVBEP_PMON_BOX_CTL_INT);
1541ed367e6cSBorislav Petkov }
1542ed367e6cSBorislav Petkov 
1543ed367e6cSBorislav Petkov #define IVBEP_UNCORE_MSR_OPS_COMMON_INIT()			\
1544ed367e6cSBorislav Petkov 	.init_box	= ivbep_uncore_msr_init_box,		\
1545ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_msr_disable_box,		\
1546ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_msr_enable_box,		\
1547ed367e6cSBorislav Petkov 	.disable_event	= snbep_uncore_msr_disable_event,	\
1548ed367e6cSBorislav Petkov 	.enable_event	= snbep_uncore_msr_enable_event,	\
1549ed367e6cSBorislav Petkov 	.read_counter	= uncore_msr_read_counter
1550ed367e6cSBorislav Petkov 
1551ed367e6cSBorislav Petkov static struct intel_uncore_ops ivbep_uncore_msr_ops = {
1552ed367e6cSBorislav Petkov 	IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
1553ed367e6cSBorislav Petkov };
1554ed367e6cSBorislav Petkov 
1555ed367e6cSBorislav Petkov static struct intel_uncore_ops ivbep_uncore_pci_ops = {
1556ed367e6cSBorislav Petkov 	.init_box	= ivbep_uncore_pci_init_box,
1557ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_pci_disable_box,
1558ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_pci_enable_box,
1559ed367e6cSBorislav Petkov 	.disable_event	= snbep_uncore_pci_disable_event,
1560ed367e6cSBorislav Petkov 	.enable_event	= snbep_uncore_pci_enable_event,
1561ed367e6cSBorislav Petkov 	.read_counter	= snbep_uncore_pci_read_counter,
1562ed367e6cSBorislav Petkov };
1563ed367e6cSBorislav Petkov 
1564ed367e6cSBorislav Petkov #define IVBEP_UNCORE_PCI_COMMON_INIT()				\
1565ed367e6cSBorislav Petkov 	.perf_ctr	= SNBEP_PCI_PMON_CTR0,			\
1566ed367e6cSBorislav Petkov 	.event_ctl	= SNBEP_PCI_PMON_CTL0,			\
1567ed367e6cSBorislav Petkov 	.event_mask	= IVBEP_PMON_RAW_EVENT_MASK,		\
1568ed367e6cSBorislav Petkov 	.box_ctl	= SNBEP_PCI_PMON_BOX_CTL,		\
1569ed367e6cSBorislav Petkov 	.ops		= &ivbep_uncore_pci_ops,			\
1570ed367e6cSBorislav Petkov 	.format_group	= &ivbep_uncore_format_group
1571ed367e6cSBorislav Petkov 
1572ed367e6cSBorislav Petkov static struct attribute *ivbep_uncore_formats_attr[] = {
1573ed367e6cSBorislav Petkov 	&format_attr_event.attr,
1574ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
1575ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
1576ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
1577ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
1578ed367e6cSBorislav Petkov 	NULL,
1579ed367e6cSBorislav Petkov };
1580ed367e6cSBorislav Petkov 
1581ed367e6cSBorislav Petkov static struct attribute *ivbep_uncore_ubox_formats_attr[] = {
1582ed367e6cSBorislav Petkov 	&format_attr_event.attr,
1583ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
1584ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
1585ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
1586ed367e6cSBorislav Petkov 	&format_attr_thresh5.attr,
1587ed367e6cSBorislav Petkov 	NULL,
1588ed367e6cSBorislav Petkov };
1589ed367e6cSBorislav Petkov 
1590ed367e6cSBorislav Petkov static struct attribute *ivbep_uncore_cbox_formats_attr[] = {
1591ed367e6cSBorislav Petkov 	&format_attr_event.attr,
1592ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
1593ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
1594ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
1595ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
1596ed367e6cSBorislav Petkov 	&format_attr_filter_tid.attr,
1597ed367e6cSBorislav Petkov 	&format_attr_filter_link.attr,
1598ed367e6cSBorislav Petkov 	&format_attr_filter_state2.attr,
1599ed367e6cSBorislav Petkov 	&format_attr_filter_nid2.attr,
1600ed367e6cSBorislav Petkov 	&format_attr_filter_opc2.attr,
1601ed367e6cSBorislav Petkov 	&format_attr_filter_nc.attr,
1602ed367e6cSBorislav Petkov 	&format_attr_filter_c6.attr,
1603ed367e6cSBorislav Petkov 	&format_attr_filter_isoc.attr,
1604ed367e6cSBorislav Petkov 	NULL,
1605ed367e6cSBorislav Petkov };
1606ed367e6cSBorislav Petkov 
1607ed367e6cSBorislav Petkov static struct attribute *ivbep_uncore_pcu_formats_attr[] = {
1608cb225252SKan Liang 	&format_attr_event.attr,
1609ed367e6cSBorislav Petkov 	&format_attr_occ_sel.attr,
1610ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
1611ed367e6cSBorislav Petkov 	&format_attr_thresh5.attr,
1612ed367e6cSBorislav Petkov 	&format_attr_occ_invert.attr,
1613ed367e6cSBorislav Petkov 	&format_attr_occ_edge.attr,
1614ed367e6cSBorislav Petkov 	&format_attr_filter_band0.attr,
1615ed367e6cSBorislav Petkov 	&format_attr_filter_band1.attr,
1616ed367e6cSBorislav Petkov 	&format_attr_filter_band2.attr,
1617ed367e6cSBorislav Petkov 	&format_attr_filter_band3.attr,
1618ed367e6cSBorislav Petkov 	NULL,
1619ed367e6cSBorislav Petkov };
1620ed367e6cSBorislav Petkov 
1621ed367e6cSBorislav Petkov static struct attribute *ivbep_uncore_qpi_formats_attr[] = {
1622ed367e6cSBorislav Petkov 	&format_attr_event_ext.attr,
1623ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
1624ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
1625ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
1626ed367e6cSBorislav Petkov 	&format_attr_match_rds.attr,
1627ed367e6cSBorislav Petkov 	&format_attr_match_rnid30.attr,
1628ed367e6cSBorislav Petkov 	&format_attr_match_rnid4.attr,
1629ed367e6cSBorislav Petkov 	&format_attr_match_dnid.attr,
1630ed367e6cSBorislav Petkov 	&format_attr_match_mc.attr,
1631ed367e6cSBorislav Petkov 	&format_attr_match_opc.attr,
1632ed367e6cSBorislav Petkov 	&format_attr_match_vnw.attr,
1633ed367e6cSBorislav Petkov 	&format_attr_match0.attr,
1634ed367e6cSBorislav Petkov 	&format_attr_match1.attr,
1635ed367e6cSBorislav Petkov 	&format_attr_mask_rds.attr,
1636ed367e6cSBorislav Petkov 	&format_attr_mask_rnid30.attr,
1637ed367e6cSBorislav Petkov 	&format_attr_mask_rnid4.attr,
1638ed367e6cSBorislav Petkov 	&format_attr_mask_dnid.attr,
1639ed367e6cSBorislav Petkov 	&format_attr_mask_mc.attr,
1640ed367e6cSBorislav Petkov 	&format_attr_mask_opc.attr,
1641ed367e6cSBorislav Petkov 	&format_attr_mask_vnw.attr,
1642ed367e6cSBorislav Petkov 	&format_attr_mask0.attr,
1643ed367e6cSBorislav Petkov 	&format_attr_mask1.attr,
1644ed367e6cSBorislav Petkov 	NULL,
1645ed367e6cSBorislav Petkov };
1646ed367e6cSBorislav Petkov 
164745bd07adSArvind Yadav static const struct attribute_group ivbep_uncore_format_group = {
1648ed367e6cSBorislav Petkov 	.name = "format",
1649ed367e6cSBorislav Petkov 	.attrs = ivbep_uncore_formats_attr,
1650ed367e6cSBorislav Petkov };
1651ed367e6cSBorislav Petkov 
165245bd07adSArvind Yadav static const struct attribute_group ivbep_uncore_ubox_format_group = {
1653ed367e6cSBorislav Petkov 	.name = "format",
1654ed367e6cSBorislav Petkov 	.attrs = ivbep_uncore_ubox_formats_attr,
1655ed367e6cSBorislav Petkov };
1656ed367e6cSBorislav Petkov 
165745bd07adSArvind Yadav static const struct attribute_group ivbep_uncore_cbox_format_group = {
1658ed367e6cSBorislav Petkov 	.name = "format",
1659ed367e6cSBorislav Petkov 	.attrs = ivbep_uncore_cbox_formats_attr,
1660ed367e6cSBorislav Petkov };
1661ed367e6cSBorislav Petkov 
166245bd07adSArvind Yadav static const struct attribute_group ivbep_uncore_pcu_format_group = {
1663ed367e6cSBorislav Petkov 	.name = "format",
1664ed367e6cSBorislav Petkov 	.attrs = ivbep_uncore_pcu_formats_attr,
1665ed367e6cSBorislav Petkov };
1666ed367e6cSBorislav Petkov 
166745bd07adSArvind Yadav static const struct attribute_group ivbep_uncore_qpi_format_group = {
1668ed367e6cSBorislav Petkov 	.name = "format",
1669ed367e6cSBorislav Petkov 	.attrs = ivbep_uncore_qpi_formats_attr,
1670ed367e6cSBorislav Petkov };
1671ed367e6cSBorislav Petkov 
1672ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_ubox = {
1673ed367e6cSBorislav Petkov 	.name		= "ubox",
1674ed367e6cSBorislav Petkov 	.num_counters   = 2,
1675ed367e6cSBorislav Petkov 	.num_boxes	= 1,
1676ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
1677ed367e6cSBorislav Petkov 	.fixed_ctr_bits	= 48,
1678ed367e6cSBorislav Petkov 	.perf_ctr	= SNBEP_U_MSR_PMON_CTR0,
1679ed367e6cSBorislav Petkov 	.event_ctl	= SNBEP_U_MSR_PMON_CTL0,
1680ed367e6cSBorislav Petkov 	.event_mask	= IVBEP_U_MSR_PMON_RAW_EVENT_MASK,
1681ed367e6cSBorislav Petkov 	.fixed_ctr	= SNBEP_U_MSR_PMON_UCLK_FIXED_CTR,
1682ed367e6cSBorislav Petkov 	.fixed_ctl	= SNBEP_U_MSR_PMON_UCLK_FIXED_CTL,
1683ed367e6cSBorislav Petkov 	.ops		= &ivbep_uncore_msr_ops,
1684ed367e6cSBorislav Petkov 	.format_group	= &ivbep_uncore_ubox_format_group,
1685ed367e6cSBorislav Petkov };
1686ed367e6cSBorislav Petkov 
1687ed367e6cSBorislav Petkov static struct extra_reg ivbep_uncore_cbox_extra_regs[] = {
1688ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
1689ed367e6cSBorislav Petkov 				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
1690ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x1031, 0x10ff, 0x2),
1691ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4),
1692ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0xc),
1693ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x5134, 0xffff, 0xc),
1694ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
1695ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0xc),
1696ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
1697ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0xc),
1698ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
1699ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0xc),
1700ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x10),
1701ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10),
1702ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10),
1703ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2335, 0xffff, 0x10),
1704ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0x18),
1705ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0x18),
1706ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x8),
1707ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x8),
1708ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x8),
1709ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x8),
1710ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8135, 0xffff, 0x10),
1711ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8335, 0xffff, 0x10),
1712ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x10),
1713ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x10),
1714ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2136, 0xffff, 0x10),
1715ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2336, 0xffff, 0x10),
1716ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0x18),
1717ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0x18),
1718ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x8),
1719ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x8),
1720ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x8),
1721ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x5036, 0xffff, 0x8),
1722ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8136, 0xffff, 0x10),
1723ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8336, 0xffff, 0x10),
1724ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x8),
1725ed367e6cSBorislav Petkov 	EVENT_EXTRA_END
1726ed367e6cSBorislav Petkov };
1727ed367e6cSBorislav Petkov 
1728ed367e6cSBorislav Petkov static u64 ivbep_cbox_filter_mask(int fields)
1729ed367e6cSBorislav Petkov {
1730ed367e6cSBorislav Petkov 	u64 mask = 0;
1731ed367e6cSBorislav Petkov 
1732ed367e6cSBorislav Petkov 	if (fields & 0x1)
1733ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_TID;
1734ed367e6cSBorislav Petkov 	if (fields & 0x2)
1735ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_LINK;
1736ed367e6cSBorislav Petkov 	if (fields & 0x4)
1737ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_STATE;
1738ed367e6cSBorislav Petkov 	if (fields & 0x8)
1739ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_NID;
1740ed367e6cSBorislav Petkov 	if (fields & 0x10) {
1741ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_OPC;
1742ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_NC;
1743ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_C6;
1744ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_ISOC;
1745ed367e6cSBorislav Petkov 	}
1746ed367e6cSBorislav Petkov 
1747ed367e6cSBorislav Petkov 	return mask;
1748ed367e6cSBorislav Petkov }
1749ed367e6cSBorislav Petkov 
1750ed367e6cSBorislav Petkov static struct event_constraint *
1751ed367e6cSBorislav Petkov ivbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
1752ed367e6cSBorislav Petkov {
1753ed367e6cSBorislav Petkov 	return __snbep_cbox_get_constraint(box, event, ivbep_cbox_filter_mask);
1754ed367e6cSBorislav Petkov }
1755ed367e6cSBorislav Petkov 
1756ed367e6cSBorislav Petkov static int ivbep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
1757ed367e6cSBorislav Petkov {
1758ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
1759ed367e6cSBorislav Petkov 	struct extra_reg *er;
1760ed367e6cSBorislav Petkov 	int idx = 0;
1761ed367e6cSBorislav Petkov 
1762ed367e6cSBorislav Petkov 	for (er = ivbep_uncore_cbox_extra_regs; er->msr; er++) {
1763ed367e6cSBorislav Petkov 		if (er->event != (event->hw.config & er->config_mask))
1764ed367e6cSBorislav Petkov 			continue;
1765ed367e6cSBorislav Petkov 		idx |= er->idx;
1766ed367e6cSBorislav Petkov 	}
1767ed367e6cSBorislav Petkov 
1768ed367e6cSBorislav Petkov 	if (idx) {
1769ed367e6cSBorislav Petkov 		reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER +
1770ed367e6cSBorislav Petkov 			SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
1771ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1 & ivbep_cbox_filter_mask(idx);
1772ed367e6cSBorislav Petkov 		reg1->idx = idx;
1773ed367e6cSBorislav Petkov 	}
1774ed367e6cSBorislav Petkov 	return 0;
1775ed367e6cSBorislav Petkov }
1776ed367e6cSBorislav Petkov 
1777ed367e6cSBorislav Petkov static void ivbep_cbox_enable_event(struct intel_uncore_box *box, struct perf_event *event)
1778ed367e6cSBorislav Petkov {
1779ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1780ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
1781ed367e6cSBorislav Petkov 
1782ed367e6cSBorislav Petkov 	if (reg1->idx != EXTRA_REG_NONE) {
1783ed367e6cSBorislav Petkov 		u64 filter = uncore_shared_reg_config(box, 0);
1784ed367e6cSBorislav Petkov 		wrmsrl(reg1->reg, filter & 0xffffffff);
1785ed367e6cSBorislav Petkov 		wrmsrl(reg1->reg + 6, filter >> 32);
1786ed367e6cSBorislav Petkov 	}
1787ed367e6cSBorislav Petkov 
1788ed367e6cSBorislav Petkov 	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
1789ed367e6cSBorislav Petkov }
1790ed367e6cSBorislav Petkov 
1791ed367e6cSBorislav Petkov static struct intel_uncore_ops ivbep_uncore_cbox_ops = {
1792ed367e6cSBorislav Petkov 	.init_box		= ivbep_uncore_msr_init_box,
1793ed367e6cSBorislav Petkov 	.disable_box		= snbep_uncore_msr_disable_box,
1794ed367e6cSBorislav Petkov 	.enable_box		= snbep_uncore_msr_enable_box,
1795ed367e6cSBorislav Petkov 	.disable_event		= snbep_uncore_msr_disable_event,
1796ed367e6cSBorislav Petkov 	.enable_event		= ivbep_cbox_enable_event,
1797ed367e6cSBorislav Petkov 	.read_counter		= uncore_msr_read_counter,
1798ed367e6cSBorislav Petkov 	.hw_config		= ivbep_cbox_hw_config,
1799ed367e6cSBorislav Petkov 	.get_constraint		= ivbep_cbox_get_constraint,
1800ed367e6cSBorislav Petkov 	.put_constraint		= snbep_cbox_put_constraint,
1801ed367e6cSBorislav Petkov };
1802ed367e6cSBorislav Petkov 
1803ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_cbox = {
1804ed367e6cSBorislav Petkov 	.name			= "cbox",
1805ed367e6cSBorislav Petkov 	.num_counters		= 4,
1806ed367e6cSBorislav Petkov 	.num_boxes		= 15,
1807ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 44,
1808ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_C0_MSR_PMON_CTL0,
1809ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_C0_MSR_PMON_CTR0,
1810ed367e6cSBorislav Petkov 	.event_mask		= IVBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
1811ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_C0_MSR_PMON_BOX_CTL,
1812ed367e6cSBorislav Petkov 	.msr_offset		= SNBEP_CBO_MSR_OFFSET,
1813ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
1814ed367e6cSBorislav Petkov 	.constraints		= snbep_uncore_cbox_constraints,
1815ed367e6cSBorislav Petkov 	.ops			= &ivbep_uncore_cbox_ops,
1816ed367e6cSBorislav Petkov 	.format_group		= &ivbep_uncore_cbox_format_group,
1817ed367e6cSBorislav Petkov };
1818ed367e6cSBorislav Petkov 
1819ed367e6cSBorislav Petkov static struct intel_uncore_ops ivbep_uncore_pcu_ops = {
1820ed367e6cSBorislav Petkov 	IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
1821ed367e6cSBorislav Petkov 	.hw_config		= snbep_pcu_hw_config,
1822ed367e6cSBorislav Petkov 	.get_constraint		= snbep_pcu_get_constraint,
1823ed367e6cSBorislav Petkov 	.put_constraint		= snbep_pcu_put_constraint,
1824ed367e6cSBorislav Petkov };
1825ed367e6cSBorislav Petkov 
1826ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_pcu = {
1827ed367e6cSBorislav Petkov 	.name			= "pcu",
1828ed367e6cSBorislav Petkov 	.num_counters		= 4,
1829ed367e6cSBorislav Petkov 	.num_boxes		= 1,
1830ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
1831ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCU_MSR_PMON_CTR0,
1832ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCU_MSR_PMON_CTL0,
1833ed367e6cSBorislav Petkov 	.event_mask		= IVBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
1834ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCU_MSR_PMON_BOX_CTL,
1835ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
1836ed367e6cSBorislav Petkov 	.ops			= &ivbep_uncore_pcu_ops,
1837ed367e6cSBorislav Petkov 	.format_group		= &ivbep_uncore_pcu_format_group,
1838ed367e6cSBorislav Petkov };
1839ed367e6cSBorislav Petkov 
1840ed367e6cSBorislav Petkov static struct intel_uncore_type *ivbep_msr_uncores[] = {
1841ed367e6cSBorislav Petkov 	&ivbep_uncore_ubox,
1842ed367e6cSBorislav Petkov 	&ivbep_uncore_cbox,
1843ed367e6cSBorislav Petkov 	&ivbep_uncore_pcu,
1844ed367e6cSBorislav Petkov 	NULL,
1845ed367e6cSBorislav Petkov };
1846ed367e6cSBorislav Petkov 
1847ed367e6cSBorislav Petkov void ivbep_uncore_cpu_init(void)
1848ed367e6cSBorislav Petkov {
1849ed367e6cSBorislav Petkov 	if (ivbep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
1850ed367e6cSBorislav Petkov 		ivbep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
1851ed367e6cSBorislav Petkov 	uncore_msr_uncores = ivbep_msr_uncores;
1852ed367e6cSBorislav Petkov }
1853ed367e6cSBorislav Petkov 
1854ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_ha = {
1855ed367e6cSBorislav Petkov 	.name		= "ha",
1856ed367e6cSBorislav Petkov 	.num_counters   = 4,
1857ed367e6cSBorislav Petkov 	.num_boxes	= 2,
1858ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
1859ed367e6cSBorislav Petkov 	IVBEP_UNCORE_PCI_COMMON_INIT(),
1860ed367e6cSBorislav Petkov };
1861ed367e6cSBorislav Petkov 
1862ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_imc = {
1863ed367e6cSBorislav Petkov 	.name		= "imc",
1864ed367e6cSBorislav Petkov 	.num_counters   = 4,
1865ed367e6cSBorislav Petkov 	.num_boxes	= 8,
1866ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
1867ed367e6cSBorislav Petkov 	.fixed_ctr_bits	= 48,
1868ed367e6cSBorislav Petkov 	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
1869ed367e6cSBorislav Petkov 	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
1870ed367e6cSBorislav Petkov 	.event_descs	= snbep_uncore_imc_events,
1871ed367e6cSBorislav Petkov 	IVBEP_UNCORE_PCI_COMMON_INIT(),
1872ed367e6cSBorislav Petkov };
1873ed367e6cSBorislav Petkov 
1874ed367e6cSBorislav Petkov /* registers in IRP boxes are not properly aligned */
1875ed367e6cSBorislav Petkov static unsigned ivbep_uncore_irp_ctls[] = {0xd8, 0xdc, 0xe0, 0xe4};
1876ed367e6cSBorislav Petkov static unsigned ivbep_uncore_irp_ctrs[] = {0xa0, 0xb0, 0xb8, 0xc0};
1877ed367e6cSBorislav Petkov 
1878ed367e6cSBorislav Petkov static void ivbep_uncore_irp_enable_event(struct intel_uncore_box *box, struct perf_event *event)
1879ed367e6cSBorislav Petkov {
1880ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
1881ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1882ed367e6cSBorislav Petkov 
1883ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, ivbep_uncore_irp_ctls[hwc->idx],
1884ed367e6cSBorislav Petkov 			       hwc->config | SNBEP_PMON_CTL_EN);
1885ed367e6cSBorislav Petkov }
1886ed367e6cSBorislav Petkov 
1887ed367e6cSBorislav Petkov static void ivbep_uncore_irp_disable_event(struct intel_uncore_box *box, struct perf_event *event)
1888ed367e6cSBorislav Petkov {
1889ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
1890ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1891ed367e6cSBorislav Petkov 
1892ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, ivbep_uncore_irp_ctls[hwc->idx], hwc->config);
1893ed367e6cSBorislav Petkov }
1894ed367e6cSBorislav Petkov 
1895ed367e6cSBorislav Petkov static u64 ivbep_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event)
1896ed367e6cSBorislav Petkov {
1897ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
1898ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1899ed367e6cSBorislav Petkov 	u64 count = 0;
1900ed367e6cSBorislav Petkov 
1901ed367e6cSBorislav Petkov 	pci_read_config_dword(pdev, ivbep_uncore_irp_ctrs[hwc->idx], (u32 *)&count);
1902ed367e6cSBorislav Petkov 	pci_read_config_dword(pdev, ivbep_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1);
1903ed367e6cSBorislav Petkov 
1904ed367e6cSBorislav Petkov 	return count;
1905ed367e6cSBorislav Petkov }
1906ed367e6cSBorislav Petkov 
1907ed367e6cSBorislav Petkov static struct intel_uncore_ops ivbep_uncore_irp_ops = {
1908ed367e6cSBorislav Petkov 	.init_box	= ivbep_uncore_pci_init_box,
1909ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_pci_disable_box,
1910ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_pci_enable_box,
1911ed367e6cSBorislav Petkov 	.disable_event	= ivbep_uncore_irp_disable_event,
1912ed367e6cSBorislav Petkov 	.enable_event	= ivbep_uncore_irp_enable_event,
1913ed367e6cSBorislav Petkov 	.read_counter	= ivbep_uncore_irp_read_counter,
1914ed367e6cSBorislav Petkov };
1915ed367e6cSBorislav Petkov 
1916ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_irp = {
1917ed367e6cSBorislav Petkov 	.name			= "irp",
1918ed367e6cSBorislav Petkov 	.num_counters		= 4,
1919ed367e6cSBorislav Petkov 	.num_boxes		= 1,
1920ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
1921ed367e6cSBorislav Petkov 	.event_mask		= IVBEP_PMON_RAW_EVENT_MASK,
1922ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
1923ed367e6cSBorislav Petkov 	.ops			= &ivbep_uncore_irp_ops,
1924ed367e6cSBorislav Petkov 	.format_group		= &ivbep_uncore_format_group,
1925ed367e6cSBorislav Petkov };
1926ed367e6cSBorislav Petkov 
1927ed367e6cSBorislav Petkov static struct intel_uncore_ops ivbep_uncore_qpi_ops = {
1928ed367e6cSBorislav Petkov 	.init_box	= ivbep_uncore_pci_init_box,
1929ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_pci_disable_box,
1930ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_pci_enable_box,
1931ed367e6cSBorislav Petkov 	.disable_event	= snbep_uncore_pci_disable_event,
1932ed367e6cSBorislav Petkov 	.enable_event	= snbep_qpi_enable_event,
1933ed367e6cSBorislav Petkov 	.read_counter	= snbep_uncore_pci_read_counter,
1934ed367e6cSBorislav Petkov 	.hw_config	= snbep_qpi_hw_config,
1935ed367e6cSBorislav Petkov 	.get_constraint	= uncore_get_constraint,
1936ed367e6cSBorislav Petkov 	.put_constraint	= uncore_put_constraint,
1937ed367e6cSBorislav Petkov };
1938ed367e6cSBorislav Petkov 
1939ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_qpi = {
1940ed367e6cSBorislav Petkov 	.name			= "qpi",
1941ed367e6cSBorislav Petkov 	.num_counters		= 4,
1942ed367e6cSBorislav Petkov 	.num_boxes		= 3,
1943ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
1944ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
1945ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCI_PMON_CTL0,
1946ed367e6cSBorislav Petkov 	.event_mask		= IVBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
1947ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
1948ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
1949ed367e6cSBorislav Petkov 	.ops			= &ivbep_uncore_qpi_ops,
1950ed367e6cSBorislav Petkov 	.format_group		= &ivbep_uncore_qpi_format_group,
1951ed367e6cSBorislav Petkov };
1952ed367e6cSBorislav Petkov 
1953ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_r2pcie = {
1954ed367e6cSBorislav Petkov 	.name		= "r2pcie",
1955ed367e6cSBorislav Petkov 	.num_counters   = 4,
1956ed367e6cSBorislav Petkov 	.num_boxes	= 1,
1957ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
1958ed367e6cSBorislav Petkov 	.constraints	= snbep_uncore_r2pcie_constraints,
1959ed367e6cSBorislav Petkov 	IVBEP_UNCORE_PCI_COMMON_INIT(),
1960ed367e6cSBorislav Petkov };
1961ed367e6cSBorislav Petkov 
1962ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_r3qpi = {
1963ed367e6cSBorislav Petkov 	.name		= "r3qpi",
1964ed367e6cSBorislav Petkov 	.num_counters   = 3,
1965ed367e6cSBorislav Petkov 	.num_boxes	= 2,
1966ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
1967ed367e6cSBorislav Petkov 	.constraints	= snbep_uncore_r3qpi_constraints,
1968ed367e6cSBorislav Petkov 	IVBEP_UNCORE_PCI_COMMON_INIT(),
1969ed367e6cSBorislav Petkov };
1970ed367e6cSBorislav Petkov 
1971ed367e6cSBorislav Petkov enum {
1972ed367e6cSBorislav Petkov 	IVBEP_PCI_UNCORE_HA,
1973ed367e6cSBorislav Petkov 	IVBEP_PCI_UNCORE_IMC,
1974ed367e6cSBorislav Petkov 	IVBEP_PCI_UNCORE_IRP,
1975ed367e6cSBorislav Petkov 	IVBEP_PCI_UNCORE_QPI,
1976ed367e6cSBorislav Petkov 	IVBEP_PCI_UNCORE_R2PCIE,
1977ed367e6cSBorislav Petkov 	IVBEP_PCI_UNCORE_R3QPI,
1978ed367e6cSBorislav Petkov };
1979ed367e6cSBorislav Petkov 
1980ed367e6cSBorislav Petkov static struct intel_uncore_type *ivbep_pci_uncores[] = {
1981ed367e6cSBorislav Petkov 	[IVBEP_PCI_UNCORE_HA]	= &ivbep_uncore_ha,
1982ed367e6cSBorislav Petkov 	[IVBEP_PCI_UNCORE_IMC]	= &ivbep_uncore_imc,
1983ed367e6cSBorislav Petkov 	[IVBEP_PCI_UNCORE_IRP]	= &ivbep_uncore_irp,
1984ed367e6cSBorislav Petkov 	[IVBEP_PCI_UNCORE_QPI]	= &ivbep_uncore_qpi,
1985ed367e6cSBorislav Petkov 	[IVBEP_PCI_UNCORE_R2PCIE]	= &ivbep_uncore_r2pcie,
1986ed367e6cSBorislav Petkov 	[IVBEP_PCI_UNCORE_R3QPI]	= &ivbep_uncore_r3qpi,
1987ed367e6cSBorislav Petkov 	NULL,
1988ed367e6cSBorislav Petkov };
1989ed367e6cSBorislav Petkov 
1990ed367e6cSBorislav Petkov static const struct pci_device_id ivbep_uncore_pci_ids[] = {
1991ed367e6cSBorislav Petkov 	{ /* Home Agent 0 */
1992ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe30),
1993ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_HA, 0),
1994ed367e6cSBorislav Petkov 	},
1995ed367e6cSBorislav Petkov 	{ /* Home Agent 1 */
1996ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe38),
1997ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_HA, 1),
1998ed367e6cSBorislav Petkov 	},
1999ed367e6cSBorislav Petkov 	{ /* MC0 Channel 0 */
2000ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb4),
2001ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 0),
2002ed367e6cSBorislav Petkov 	},
2003ed367e6cSBorislav Petkov 	{ /* MC0 Channel 1 */
2004ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb5),
2005ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 1),
2006ed367e6cSBorislav Petkov 	},
2007ed367e6cSBorislav Petkov 	{ /* MC0 Channel 3 */
2008ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb0),
2009ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 2),
2010ed367e6cSBorislav Petkov 	},
2011ed367e6cSBorislav Petkov 	{ /* MC0 Channel 4 */
2012ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb1),
2013ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 3),
2014ed367e6cSBorislav Petkov 	},
2015ed367e6cSBorislav Petkov 	{ /* MC1 Channel 0 */
2016ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef4),
2017ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 4),
2018ed367e6cSBorislav Petkov 	},
2019ed367e6cSBorislav Petkov 	{ /* MC1 Channel 1 */
2020ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef5),
2021ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 5),
2022ed367e6cSBorislav Petkov 	},
2023ed367e6cSBorislav Petkov 	{ /* MC1 Channel 3 */
2024ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef0),
2025ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 6),
2026ed367e6cSBorislav Petkov 	},
2027ed367e6cSBorislav Petkov 	{ /* MC1 Channel 4 */
2028ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1),
2029ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 7),
2030ed367e6cSBorislav Petkov 	},
2031ed367e6cSBorislav Petkov 	{ /* IRP */
2032ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe39),
2033ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IRP, 0),
2034ed367e6cSBorislav Petkov 	},
2035ed367e6cSBorislav Petkov 	{ /* QPI0 Port 0 */
2036ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32),
2037ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 0),
2038ed367e6cSBorislav Petkov 	},
2039ed367e6cSBorislav Petkov 	{ /* QPI0 Port 1 */
2040ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe33),
2041ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 1),
2042ed367e6cSBorislav Petkov 	},
2043ed367e6cSBorislav Petkov 	{ /* QPI1 Port 2 */
2044ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3a),
2045ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 2),
2046ed367e6cSBorislav Petkov 	},
2047ed367e6cSBorislav Petkov 	{ /* R2PCIe */
2048ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe34),
2049ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R2PCIE, 0),
2050ed367e6cSBorislav Petkov 	},
2051ed367e6cSBorislav Petkov 	{ /* R3QPI0 Link 0 */
2052ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe36),
2053ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 0),
2054ed367e6cSBorislav Petkov 	},
2055ed367e6cSBorislav Petkov 	{ /* R3QPI0 Link 1 */
2056ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe37),
2057ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 1),
2058ed367e6cSBorislav Petkov 	},
2059ed367e6cSBorislav Petkov 	{ /* R3QPI1 Link 2 */
2060ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3e),
2061ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 2),
2062ed367e6cSBorislav Petkov 	},
2063ed367e6cSBorislav Petkov 	{ /* QPI Port 0 filter  */
2064ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe86),
2065ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
2066ed367e6cSBorislav Petkov 						   SNBEP_PCI_QPI_PORT0_FILTER),
2067ed367e6cSBorislav Petkov 	},
2068ed367e6cSBorislav Petkov 	{ /* QPI Port 0 filter  */
2069ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe96),
2070ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
2071ed367e6cSBorislav Petkov 						   SNBEP_PCI_QPI_PORT1_FILTER),
2072ed367e6cSBorislav Petkov 	},
2073ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ }
2074ed367e6cSBorislav Petkov };
2075ed367e6cSBorislav Petkov 
2076ed367e6cSBorislav Petkov static struct pci_driver ivbep_uncore_pci_driver = {
2077ed367e6cSBorislav Petkov 	.name		= "ivbep_uncore",
2078ed367e6cSBorislav Petkov 	.id_table	= ivbep_uncore_pci_ids,
2079ed367e6cSBorislav Petkov };
2080ed367e6cSBorislav Petkov 
2081ed367e6cSBorislav Petkov int ivbep_uncore_pci_init(void)
2082ed367e6cSBorislav Petkov {
208368ce4a0dSKan Liang 	int ret = snbep_pci2phy_map_init(0x0e1e, SNBEP_CPUNODEID, SNBEP_GIDNIDMAP, true);
2084ed367e6cSBorislav Petkov 	if (ret)
2085ed367e6cSBorislav Petkov 		return ret;
2086ed367e6cSBorislav Petkov 	uncore_pci_uncores = ivbep_pci_uncores;
2087ed367e6cSBorislav Petkov 	uncore_pci_driver = &ivbep_uncore_pci_driver;
2088ed367e6cSBorislav Petkov 	return 0;
2089ed367e6cSBorislav Petkov }
2090ed367e6cSBorislav Petkov /* end of IvyTown uncore support */
2091ed367e6cSBorislav Petkov 
2092ed367e6cSBorislav Petkov /* KNL uncore support */
2093ed367e6cSBorislav Petkov static struct attribute *knl_uncore_ubox_formats_attr[] = {
2094ed367e6cSBorislav Petkov 	&format_attr_event.attr,
2095ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
2096ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2097ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
2098ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
2099ed367e6cSBorislav Petkov 	&format_attr_thresh5.attr,
2100ed367e6cSBorislav Petkov 	NULL,
2101ed367e6cSBorislav Petkov };
2102ed367e6cSBorislav Petkov 
210345bd07adSArvind Yadav static const struct attribute_group knl_uncore_ubox_format_group = {
2104ed367e6cSBorislav Petkov 	.name = "format",
2105ed367e6cSBorislav Petkov 	.attrs = knl_uncore_ubox_formats_attr,
2106ed367e6cSBorislav Petkov };
2107ed367e6cSBorislav Petkov 
2108ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_ubox = {
2109ed367e6cSBorislav Petkov 	.name			= "ubox",
2110ed367e6cSBorislav Petkov 	.num_counters		= 2,
2111ed367e6cSBorislav Petkov 	.num_boxes		= 1,
2112ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2113ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
2114ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_U_MSR_PMON_CTR0,
2115ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_U_MSR_PMON_CTL0,
2116ed367e6cSBorislav Petkov 	.event_mask		= KNL_U_MSR_PMON_RAW_EVENT_MASK,
2117ed367e6cSBorislav Petkov 	.fixed_ctr		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
2118ed367e6cSBorislav Petkov 	.fixed_ctl		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
2119ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_msr_ops,
2120ed367e6cSBorislav Petkov 	.format_group		= &knl_uncore_ubox_format_group,
2121ed367e6cSBorislav Petkov };
2122ed367e6cSBorislav Petkov 
2123ed367e6cSBorislav Petkov static struct attribute *knl_uncore_cha_formats_attr[] = {
2124ed367e6cSBorislav Petkov 	&format_attr_event.attr,
2125ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
2126ed367e6cSBorislav Petkov 	&format_attr_qor.attr,
2127ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2128ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
2129ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
2130ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
2131ed367e6cSBorislav Petkov 	&format_attr_filter_tid4.attr,
2132ed367e6cSBorislav Petkov 	&format_attr_filter_link3.attr,
2133ed367e6cSBorislav Petkov 	&format_attr_filter_state4.attr,
2134ed367e6cSBorislav Petkov 	&format_attr_filter_local.attr,
2135ed367e6cSBorislav Petkov 	&format_attr_filter_all_op.attr,
2136ed367e6cSBorislav Petkov 	&format_attr_filter_nnm.attr,
2137ed367e6cSBorislav Petkov 	&format_attr_filter_opc3.attr,
2138ed367e6cSBorislav Petkov 	&format_attr_filter_nc.attr,
2139ed367e6cSBorislav Petkov 	&format_attr_filter_isoc.attr,
2140ed367e6cSBorislav Petkov 	NULL,
2141ed367e6cSBorislav Petkov };
2142ed367e6cSBorislav Petkov 
214345bd07adSArvind Yadav static const struct attribute_group knl_uncore_cha_format_group = {
2144ed367e6cSBorislav Petkov 	.name = "format",
2145ed367e6cSBorislav Petkov 	.attrs = knl_uncore_cha_formats_attr,
2146ed367e6cSBorislav Petkov };
2147ed367e6cSBorislav Petkov 
2148ed367e6cSBorislav Petkov static struct event_constraint knl_uncore_cha_constraints[] = {
2149ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
2150ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1f, 0x1),
2151ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
2152ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
2153ed367e6cSBorislav Petkov };
2154ed367e6cSBorislav Petkov 
2155ed367e6cSBorislav Petkov static struct extra_reg knl_uncore_cha_extra_regs[] = {
2156ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
2157ed367e6cSBorislav Petkov 				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
2158ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x3d, 0xff, 0x2),
2159ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x35, 0xff, 0x4),
2160ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x36, 0xff, 0x4),
2161ed367e6cSBorislav Petkov 	EVENT_EXTRA_END
2162ed367e6cSBorislav Petkov };
2163ed367e6cSBorislav Petkov 
2164ed367e6cSBorislav Petkov static u64 knl_cha_filter_mask(int fields)
2165ed367e6cSBorislav Petkov {
2166ed367e6cSBorislav Petkov 	u64 mask = 0;
2167ed367e6cSBorislav Petkov 
2168ed367e6cSBorislav Petkov 	if (fields & 0x1)
2169ed367e6cSBorislav Petkov 		mask |= KNL_CHA_MSR_PMON_BOX_FILTER_TID;
2170ed367e6cSBorislav Petkov 	if (fields & 0x2)
2171ed367e6cSBorislav Petkov 		mask |= KNL_CHA_MSR_PMON_BOX_FILTER_STATE;
2172ed367e6cSBorislav Petkov 	if (fields & 0x4)
2173ed367e6cSBorislav Petkov 		mask |= KNL_CHA_MSR_PMON_BOX_FILTER_OP;
2174ed367e6cSBorislav Petkov 	return mask;
2175ed367e6cSBorislav Petkov }
2176ed367e6cSBorislav Petkov 
2177ed367e6cSBorislav Petkov static struct event_constraint *
2178ed367e6cSBorislav Petkov knl_cha_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
2179ed367e6cSBorislav Petkov {
2180ed367e6cSBorislav Petkov 	return __snbep_cbox_get_constraint(box, event, knl_cha_filter_mask);
2181ed367e6cSBorislav Petkov }
2182ed367e6cSBorislav Petkov 
2183ed367e6cSBorislav Petkov static int knl_cha_hw_config(struct intel_uncore_box *box,
2184ed367e6cSBorislav Petkov 			     struct perf_event *event)
2185ed367e6cSBorislav Petkov {
2186ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
2187ed367e6cSBorislav Petkov 	struct extra_reg *er;
2188ed367e6cSBorislav Petkov 	int idx = 0;
2189ed367e6cSBorislav Petkov 
2190ed367e6cSBorislav Petkov 	for (er = knl_uncore_cha_extra_regs; er->msr; er++) {
2191ed367e6cSBorislav Petkov 		if (er->event != (event->hw.config & er->config_mask))
2192ed367e6cSBorislav Petkov 			continue;
2193ed367e6cSBorislav Petkov 		idx |= er->idx;
2194ed367e6cSBorislav Petkov 	}
2195ed367e6cSBorislav Petkov 
2196ed367e6cSBorislav Petkov 	if (idx) {
2197ed367e6cSBorislav Petkov 		reg1->reg = HSWEP_C0_MSR_PMON_BOX_FILTER0 +
2198ed367e6cSBorislav Petkov 			    KNL_CHA_MSR_OFFSET * box->pmu->pmu_idx;
2199ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1 & knl_cha_filter_mask(idx);
2200ec336c87Shchrzani 
2201ec336c87Shchrzani 		reg1->config |= KNL_CHA_MSR_PMON_BOX_FILTER_REMOTE_NODE;
2202ec336c87Shchrzani 		reg1->config |= KNL_CHA_MSR_PMON_BOX_FILTER_LOCAL_NODE;
2203ec336c87Shchrzani 		reg1->config |= KNL_CHA_MSR_PMON_BOX_FILTER_NNC;
2204ed367e6cSBorislav Petkov 		reg1->idx = idx;
2205ed367e6cSBorislav Petkov 	}
2206ed367e6cSBorislav Petkov 	return 0;
2207ed367e6cSBorislav Petkov }
2208ed367e6cSBorislav Petkov 
2209ed367e6cSBorislav Petkov static void hswep_cbox_enable_event(struct intel_uncore_box *box,
2210ed367e6cSBorislav Petkov 				    struct perf_event *event);
2211ed367e6cSBorislav Petkov 
2212ed367e6cSBorislav Petkov static struct intel_uncore_ops knl_uncore_cha_ops = {
2213ed367e6cSBorislav Petkov 	.init_box		= snbep_uncore_msr_init_box,
2214ed367e6cSBorislav Petkov 	.disable_box		= snbep_uncore_msr_disable_box,
2215ed367e6cSBorislav Petkov 	.enable_box		= snbep_uncore_msr_enable_box,
2216ed367e6cSBorislav Petkov 	.disable_event		= snbep_uncore_msr_disable_event,
2217ed367e6cSBorislav Petkov 	.enable_event		= hswep_cbox_enable_event,
2218ed367e6cSBorislav Petkov 	.read_counter		= uncore_msr_read_counter,
2219ed367e6cSBorislav Petkov 	.hw_config		= knl_cha_hw_config,
2220ed367e6cSBorislav Petkov 	.get_constraint		= knl_cha_get_constraint,
2221ed367e6cSBorislav Petkov 	.put_constraint		= snbep_cbox_put_constraint,
2222ed367e6cSBorislav Petkov };
2223ed367e6cSBorislav Petkov 
2224ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_cha = {
2225ed367e6cSBorislav Petkov 	.name			= "cha",
2226ed367e6cSBorislav Petkov 	.num_counters		= 4,
2227ed367e6cSBorislav Petkov 	.num_boxes		= 38,
2228ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2229ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_C0_MSR_PMON_CTL0,
2230ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_C0_MSR_PMON_CTR0,
2231ed367e6cSBorislav Petkov 	.event_mask		= KNL_CHA_MSR_PMON_RAW_EVENT_MASK,
2232ed367e6cSBorislav Petkov 	.box_ctl		= HSWEP_C0_MSR_PMON_BOX_CTL,
2233ed367e6cSBorislav Petkov 	.msr_offset		= KNL_CHA_MSR_OFFSET,
2234ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
2235ed367e6cSBorislav Petkov 	.constraints		= knl_uncore_cha_constraints,
2236ed367e6cSBorislav Petkov 	.ops			= &knl_uncore_cha_ops,
2237ed367e6cSBorislav Petkov 	.format_group		= &knl_uncore_cha_format_group,
2238ed367e6cSBorislav Petkov };
2239ed367e6cSBorislav Petkov 
2240ed367e6cSBorislav Petkov static struct attribute *knl_uncore_pcu_formats_attr[] = {
2241ed367e6cSBorislav Petkov 	&format_attr_event2.attr,
2242ed367e6cSBorislav Petkov 	&format_attr_use_occ_ctr.attr,
2243ed367e6cSBorislav Petkov 	&format_attr_occ_sel.attr,
2244ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2245ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
2246ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
2247ed367e6cSBorislav Petkov 	&format_attr_thresh6.attr,
2248ed367e6cSBorislav Petkov 	&format_attr_occ_invert.attr,
2249ed367e6cSBorislav Petkov 	&format_attr_occ_edge_det.attr,
2250ed367e6cSBorislav Petkov 	NULL,
2251ed367e6cSBorislav Petkov };
2252ed367e6cSBorislav Petkov 
225345bd07adSArvind Yadav static const struct attribute_group knl_uncore_pcu_format_group = {
2254ed367e6cSBorislav Petkov 	.name = "format",
2255ed367e6cSBorislav Petkov 	.attrs = knl_uncore_pcu_formats_attr,
2256ed367e6cSBorislav Petkov };
2257ed367e6cSBorislav Petkov 
2258ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_pcu = {
2259ed367e6cSBorislav Petkov 	.name			= "pcu",
2260ed367e6cSBorislav Petkov 	.num_counters		= 4,
2261ed367e6cSBorislav Petkov 	.num_boxes		= 1,
2262ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2263ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_PCU_MSR_PMON_CTR0,
2264ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_PCU_MSR_PMON_CTL0,
2265ed367e6cSBorislav Petkov 	.event_mask		= KNL_PCU_MSR_PMON_RAW_EVENT_MASK,
2266ed367e6cSBorislav Petkov 	.box_ctl		= HSWEP_PCU_MSR_PMON_BOX_CTL,
2267ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_msr_ops,
2268ed367e6cSBorislav Petkov 	.format_group		= &knl_uncore_pcu_format_group,
2269ed367e6cSBorislav Petkov };
2270ed367e6cSBorislav Petkov 
2271ed367e6cSBorislav Petkov static struct intel_uncore_type *knl_msr_uncores[] = {
2272ed367e6cSBorislav Petkov 	&knl_uncore_ubox,
2273ed367e6cSBorislav Petkov 	&knl_uncore_cha,
2274ed367e6cSBorislav Petkov 	&knl_uncore_pcu,
2275ed367e6cSBorislav Petkov 	NULL,
2276ed367e6cSBorislav Petkov };
2277ed367e6cSBorislav Petkov 
2278ed367e6cSBorislav Petkov void knl_uncore_cpu_init(void)
2279ed367e6cSBorislav Petkov {
2280ed367e6cSBorislav Petkov 	uncore_msr_uncores = knl_msr_uncores;
2281ed367e6cSBorislav Petkov }
2282ed367e6cSBorislav Petkov 
2283ed367e6cSBorislav Petkov static void knl_uncore_imc_enable_box(struct intel_uncore_box *box)
2284ed367e6cSBorislav Petkov {
2285ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
2286ed367e6cSBorislav Petkov 	int box_ctl = uncore_pci_box_ctl(box);
2287ed367e6cSBorislav Petkov 
2288ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, box_ctl, 0);
2289ed367e6cSBorislav Petkov }
2290ed367e6cSBorislav Petkov 
2291ed367e6cSBorislav Petkov static void knl_uncore_imc_enable_event(struct intel_uncore_box *box,
2292ed367e6cSBorislav Petkov 					struct perf_event *event)
2293ed367e6cSBorislav Petkov {
2294ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
2295ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
2296ed367e6cSBorislav Petkov 
2297ed367e6cSBorislav Petkov 	if ((event->attr.config & SNBEP_PMON_CTL_EV_SEL_MASK)
2298ed367e6cSBorislav Petkov 							== UNCORE_FIXED_EVENT)
2299ed367e6cSBorislav Petkov 		pci_write_config_dword(pdev, hwc->config_base,
2300ed367e6cSBorislav Petkov 				       hwc->config | KNL_PMON_FIXED_CTL_EN);
2301ed367e6cSBorislav Petkov 	else
2302ed367e6cSBorislav Petkov 		pci_write_config_dword(pdev, hwc->config_base,
2303ed367e6cSBorislav Petkov 				       hwc->config | SNBEP_PMON_CTL_EN);
2304ed367e6cSBorislav Petkov }
2305ed367e6cSBorislav Petkov 
2306ed367e6cSBorislav Petkov static struct intel_uncore_ops knl_uncore_imc_ops = {
2307ed367e6cSBorislav Petkov 	.init_box	= snbep_uncore_pci_init_box,
2308ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_pci_disable_box,
2309ed367e6cSBorislav Petkov 	.enable_box	= knl_uncore_imc_enable_box,
2310ed367e6cSBorislav Petkov 	.read_counter	= snbep_uncore_pci_read_counter,
2311ed367e6cSBorislav Petkov 	.enable_event	= knl_uncore_imc_enable_event,
2312ed367e6cSBorislav Petkov 	.disable_event	= snbep_uncore_pci_disable_event,
2313ed367e6cSBorislav Petkov };
2314ed367e6cSBorislav Petkov 
2315ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_imc_uclk = {
2316ed367e6cSBorislav Petkov 	.name			= "imc_uclk",
2317ed367e6cSBorislav Petkov 	.num_counters		= 4,
2318ed367e6cSBorislav Petkov 	.num_boxes		= 2,
2319ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2320ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
2321ed367e6cSBorislav Petkov 	.perf_ctr		= KNL_UCLK_MSR_PMON_CTR0_LOW,
2322ed367e6cSBorislav Petkov 	.event_ctl		= KNL_UCLK_MSR_PMON_CTL0,
2323ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
2324ed367e6cSBorislav Petkov 	.fixed_ctr		= KNL_UCLK_MSR_PMON_UCLK_FIXED_LOW,
2325ed367e6cSBorislav Petkov 	.fixed_ctl		= KNL_UCLK_MSR_PMON_UCLK_FIXED_CTL,
2326ed367e6cSBorislav Petkov 	.box_ctl		= KNL_UCLK_MSR_PMON_BOX_CTL,
2327ed367e6cSBorislav Petkov 	.ops			= &knl_uncore_imc_ops,
2328ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_format_group,
2329ed367e6cSBorislav Petkov };
2330ed367e6cSBorislav Petkov 
2331ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_imc_dclk = {
2332ed367e6cSBorislav Petkov 	.name			= "imc",
2333ed367e6cSBorislav Petkov 	.num_counters		= 4,
2334ed367e6cSBorislav Petkov 	.num_boxes		= 6,
2335ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2336ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
2337ed367e6cSBorislav Petkov 	.perf_ctr		= KNL_MC0_CH0_MSR_PMON_CTR0_LOW,
2338ed367e6cSBorislav Petkov 	.event_ctl		= KNL_MC0_CH0_MSR_PMON_CTL0,
2339ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
2340ed367e6cSBorislav Petkov 	.fixed_ctr		= KNL_MC0_CH0_MSR_PMON_FIXED_LOW,
2341ed367e6cSBorislav Petkov 	.fixed_ctl		= KNL_MC0_CH0_MSR_PMON_FIXED_CTL,
2342ed367e6cSBorislav Petkov 	.box_ctl		= KNL_MC0_CH0_MSR_PMON_BOX_CTL,
2343ed367e6cSBorislav Petkov 	.ops			= &knl_uncore_imc_ops,
2344ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_format_group,
2345ed367e6cSBorislav Petkov };
2346ed367e6cSBorislav Petkov 
2347ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_edc_uclk = {
2348ed367e6cSBorislav Petkov 	.name			= "edc_uclk",
2349ed367e6cSBorislav Petkov 	.num_counters		= 4,
2350ed367e6cSBorislav Petkov 	.num_boxes		= 8,
2351ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2352ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
2353ed367e6cSBorislav Petkov 	.perf_ctr		= KNL_UCLK_MSR_PMON_CTR0_LOW,
2354ed367e6cSBorislav Petkov 	.event_ctl		= KNL_UCLK_MSR_PMON_CTL0,
2355ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
2356ed367e6cSBorislav Petkov 	.fixed_ctr		= KNL_UCLK_MSR_PMON_UCLK_FIXED_LOW,
2357ed367e6cSBorislav Petkov 	.fixed_ctl		= KNL_UCLK_MSR_PMON_UCLK_FIXED_CTL,
2358ed367e6cSBorislav Petkov 	.box_ctl		= KNL_UCLK_MSR_PMON_BOX_CTL,
2359ed367e6cSBorislav Petkov 	.ops			= &knl_uncore_imc_ops,
2360ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_format_group,
2361ed367e6cSBorislav Petkov };
2362ed367e6cSBorislav Petkov 
2363ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_edc_eclk = {
2364ed367e6cSBorislav Petkov 	.name			= "edc_eclk",
2365ed367e6cSBorislav Petkov 	.num_counters		= 4,
2366ed367e6cSBorislav Petkov 	.num_boxes		= 8,
2367ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2368ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
2369ed367e6cSBorislav Petkov 	.perf_ctr		= KNL_EDC0_ECLK_MSR_PMON_CTR0_LOW,
2370ed367e6cSBorislav Petkov 	.event_ctl		= KNL_EDC0_ECLK_MSR_PMON_CTL0,
2371ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
2372ed367e6cSBorislav Petkov 	.fixed_ctr		= KNL_EDC0_ECLK_MSR_PMON_ECLK_FIXED_LOW,
2373ed367e6cSBorislav Petkov 	.fixed_ctl		= KNL_EDC0_ECLK_MSR_PMON_ECLK_FIXED_CTL,
2374ed367e6cSBorislav Petkov 	.box_ctl		= KNL_EDC0_ECLK_MSR_PMON_BOX_CTL,
2375ed367e6cSBorislav Petkov 	.ops			= &knl_uncore_imc_ops,
2376ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_format_group,
2377ed367e6cSBorislav Petkov };
2378ed367e6cSBorislav Petkov 
2379ed367e6cSBorislav Petkov static struct event_constraint knl_uncore_m2pcie_constraints[] = {
2380ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
2381ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
2382ed367e6cSBorislav Petkov };
2383ed367e6cSBorislav Petkov 
2384ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_m2pcie = {
2385ed367e6cSBorislav Petkov 	.name		= "m2pcie",
2386ed367e6cSBorislav Petkov 	.num_counters   = 4,
2387ed367e6cSBorislav Petkov 	.num_boxes	= 1,
2388ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
2389ed367e6cSBorislav Petkov 	.constraints	= knl_uncore_m2pcie_constraints,
2390ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
2391ed367e6cSBorislav Petkov };
2392ed367e6cSBorislav Petkov 
2393ed367e6cSBorislav Petkov static struct attribute *knl_uncore_irp_formats_attr[] = {
2394ed367e6cSBorislav Petkov 	&format_attr_event.attr,
2395ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
2396ed367e6cSBorislav Petkov 	&format_attr_qor.attr,
2397ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2398ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
2399ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
2400ed367e6cSBorislav Petkov 	NULL,
2401ed367e6cSBorislav Petkov };
2402ed367e6cSBorislav Petkov 
240345bd07adSArvind Yadav static const struct attribute_group knl_uncore_irp_format_group = {
2404ed367e6cSBorislav Petkov 	.name = "format",
2405ed367e6cSBorislav Petkov 	.attrs = knl_uncore_irp_formats_attr,
2406ed367e6cSBorislav Petkov };
2407ed367e6cSBorislav Petkov 
2408ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_irp = {
2409ed367e6cSBorislav Petkov 	.name			= "irp",
2410ed367e6cSBorislav Petkov 	.num_counters		= 2,
2411ed367e6cSBorislav Petkov 	.num_boxes		= 1,
2412ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2413ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
2414ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCI_PMON_CTL0,
2415ed367e6cSBorislav Petkov 	.event_mask		= KNL_IRP_PCI_PMON_RAW_EVENT_MASK,
2416ed367e6cSBorislav Petkov 	.box_ctl		= KNL_IRP_PCI_PMON_BOX_CTL,
2417ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_pci_ops,
2418ed367e6cSBorislav Petkov 	.format_group		= &knl_uncore_irp_format_group,
2419ed367e6cSBorislav Petkov };
2420ed367e6cSBorislav Petkov 
2421ed367e6cSBorislav Petkov enum {
2422ed367e6cSBorislav Petkov 	KNL_PCI_UNCORE_MC_UCLK,
2423ed367e6cSBorislav Petkov 	KNL_PCI_UNCORE_MC_DCLK,
2424ed367e6cSBorislav Petkov 	KNL_PCI_UNCORE_EDC_UCLK,
2425ed367e6cSBorislav Petkov 	KNL_PCI_UNCORE_EDC_ECLK,
2426ed367e6cSBorislav Petkov 	KNL_PCI_UNCORE_M2PCIE,
2427ed367e6cSBorislav Petkov 	KNL_PCI_UNCORE_IRP,
2428ed367e6cSBorislav Petkov };
2429ed367e6cSBorislav Petkov 
2430ed367e6cSBorislav Petkov static struct intel_uncore_type *knl_pci_uncores[] = {
2431ed367e6cSBorislav Petkov 	[KNL_PCI_UNCORE_MC_UCLK]	= &knl_uncore_imc_uclk,
2432ed367e6cSBorislav Petkov 	[KNL_PCI_UNCORE_MC_DCLK]	= &knl_uncore_imc_dclk,
2433ed367e6cSBorislav Petkov 	[KNL_PCI_UNCORE_EDC_UCLK]	= &knl_uncore_edc_uclk,
2434ed367e6cSBorislav Petkov 	[KNL_PCI_UNCORE_EDC_ECLK]	= &knl_uncore_edc_eclk,
2435ed367e6cSBorislav Petkov 	[KNL_PCI_UNCORE_M2PCIE]		= &knl_uncore_m2pcie,
2436ed367e6cSBorislav Petkov 	[KNL_PCI_UNCORE_IRP]		= &knl_uncore_irp,
2437ed367e6cSBorislav Petkov 	NULL,
2438ed367e6cSBorislav Petkov };
2439ed367e6cSBorislav Petkov 
2440ed367e6cSBorislav Petkov /*
2441ed367e6cSBorislav Petkov  * KNL uses a common PCI device ID for multiple instances of an Uncore PMU
2442ed367e6cSBorislav Petkov  * device type. prior to KNL, each instance of a PMU device type had a unique
2443ed367e6cSBorislav Petkov  * device ID.
2444ed367e6cSBorislav Petkov  *
2445ed367e6cSBorislav Petkov  *	PCI Device ID	Uncore PMU Devices
2446ed367e6cSBorislav Petkov  *	----------------------------------
2447ed367e6cSBorislav Petkov  *	0x7841		MC0 UClk, MC1 UClk
2448ed367e6cSBorislav Petkov  *	0x7843		MC0 DClk CH 0, MC0 DClk CH 1, MC0 DClk CH 2,
2449ed367e6cSBorislav Petkov  *			MC1 DClk CH 0, MC1 DClk CH 1, MC1 DClk CH 2
2450ed367e6cSBorislav Petkov  *	0x7833		EDC0 UClk, EDC1 UClk, EDC2 UClk, EDC3 UClk,
2451ed367e6cSBorislav Petkov  *			EDC4 UClk, EDC5 UClk, EDC6 UClk, EDC7 UClk
2452ed367e6cSBorislav Petkov  *	0x7835		EDC0 EClk, EDC1 EClk, EDC2 EClk, EDC3 EClk,
2453ed367e6cSBorislav Petkov  *			EDC4 EClk, EDC5 EClk, EDC6 EClk, EDC7 EClk
2454ed367e6cSBorislav Petkov  *	0x7817		M2PCIe
2455ed367e6cSBorislav Petkov  *	0x7814		IRP
2456ed367e6cSBorislav Petkov */
2457ed367e6cSBorislav Petkov 
2458ed367e6cSBorislav Petkov static const struct pci_device_id knl_uncore_pci_ids[] = {
2459a54fa079SKan Liang 	{ /* MC0 UClk */
2460ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7841),
2461a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(10, 0, KNL_PCI_UNCORE_MC_UCLK, 0),
2462ed367e6cSBorislav Petkov 	},
2463a54fa079SKan Liang 	{ /* MC1 UClk */
2464a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7841),
2465a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(11, 0, KNL_PCI_UNCORE_MC_UCLK, 1),
2466a54fa079SKan Liang 	},
2467a54fa079SKan Liang 	{ /* MC0 DClk CH 0 */
2468ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7843),
2469a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(8, 2, KNL_PCI_UNCORE_MC_DCLK, 0),
2470ed367e6cSBorislav Petkov 	},
2471a54fa079SKan Liang 	{ /* MC0 DClk CH 1 */
2472a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7843),
2473a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(8, 3, KNL_PCI_UNCORE_MC_DCLK, 1),
2474a54fa079SKan Liang 	},
2475a54fa079SKan Liang 	{ /* MC0 DClk CH 2 */
2476a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7843),
2477a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(8, 4, KNL_PCI_UNCORE_MC_DCLK, 2),
2478a54fa079SKan Liang 	},
2479a54fa079SKan Liang 	{ /* MC1 DClk CH 0 */
2480a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7843),
2481a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(9, 2, KNL_PCI_UNCORE_MC_DCLK, 3),
2482a54fa079SKan Liang 	},
2483a54fa079SKan Liang 	{ /* MC1 DClk CH 1 */
2484a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7843),
2485a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(9, 3, KNL_PCI_UNCORE_MC_DCLK, 4),
2486a54fa079SKan Liang 	},
2487a54fa079SKan Liang 	{ /* MC1 DClk CH 2 */
2488a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7843),
2489a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(9, 4, KNL_PCI_UNCORE_MC_DCLK, 5),
2490a54fa079SKan Liang 	},
2491a54fa079SKan Liang 	{ /* EDC0 UClk */
2492ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2493a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(15, 0, KNL_PCI_UNCORE_EDC_UCLK, 0),
2494ed367e6cSBorislav Petkov 	},
2495a54fa079SKan Liang 	{ /* EDC1 UClk */
2496a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2497a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(16, 0, KNL_PCI_UNCORE_EDC_UCLK, 1),
2498a54fa079SKan Liang 	},
2499a54fa079SKan Liang 	{ /* EDC2 UClk */
2500a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2501a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(17, 0, KNL_PCI_UNCORE_EDC_UCLK, 2),
2502a54fa079SKan Liang 	},
2503a54fa079SKan Liang 	{ /* EDC3 UClk */
2504a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2505a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(18, 0, KNL_PCI_UNCORE_EDC_UCLK, 3),
2506a54fa079SKan Liang 	},
2507a54fa079SKan Liang 	{ /* EDC4 UClk */
2508a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2509a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(19, 0, KNL_PCI_UNCORE_EDC_UCLK, 4),
2510a54fa079SKan Liang 	},
2511a54fa079SKan Liang 	{ /* EDC5 UClk */
2512a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2513a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(20, 0, KNL_PCI_UNCORE_EDC_UCLK, 5),
2514a54fa079SKan Liang 	},
2515a54fa079SKan Liang 	{ /* EDC6 UClk */
2516a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2517a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(21, 0, KNL_PCI_UNCORE_EDC_UCLK, 6),
2518a54fa079SKan Liang 	},
2519a54fa079SKan Liang 	{ /* EDC7 UClk */
2520a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2521a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(22, 0, KNL_PCI_UNCORE_EDC_UCLK, 7),
2522a54fa079SKan Liang 	},
2523a54fa079SKan Liang 	{ /* EDC0 EClk */
2524ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2525a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(24, 2, KNL_PCI_UNCORE_EDC_ECLK, 0),
2526a54fa079SKan Liang 	},
2527a54fa079SKan Liang 	{ /* EDC1 EClk */
2528a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2529a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(25, 2, KNL_PCI_UNCORE_EDC_ECLK, 1),
2530a54fa079SKan Liang 	},
2531a54fa079SKan Liang 	{ /* EDC2 EClk */
2532a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2533a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(26, 2, KNL_PCI_UNCORE_EDC_ECLK, 2),
2534a54fa079SKan Liang 	},
2535a54fa079SKan Liang 	{ /* EDC3 EClk */
2536a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2537a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(27, 2, KNL_PCI_UNCORE_EDC_ECLK, 3),
2538a54fa079SKan Liang 	},
2539a54fa079SKan Liang 	{ /* EDC4 EClk */
2540a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2541a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(28, 2, KNL_PCI_UNCORE_EDC_ECLK, 4),
2542a54fa079SKan Liang 	},
2543a54fa079SKan Liang 	{ /* EDC5 EClk */
2544a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2545a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(29, 2, KNL_PCI_UNCORE_EDC_ECLK, 5),
2546a54fa079SKan Liang 	},
2547a54fa079SKan Liang 	{ /* EDC6 EClk */
2548a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2549a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(30, 2, KNL_PCI_UNCORE_EDC_ECLK, 6),
2550a54fa079SKan Liang 	},
2551a54fa079SKan Liang 	{ /* EDC7 EClk */
2552a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2553a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(31, 2, KNL_PCI_UNCORE_EDC_ECLK, 7),
2554ed367e6cSBorislav Petkov 	},
2555ed367e6cSBorislav Petkov 	{ /* M2PCIe */
2556ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7817),
2557ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(KNL_PCI_UNCORE_M2PCIE, 0),
2558ed367e6cSBorislav Petkov 	},
2559ed367e6cSBorislav Petkov 	{ /* IRP */
2560ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7814),
2561ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(KNL_PCI_UNCORE_IRP, 0),
2562ed367e6cSBorislav Petkov 	},
2563ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ }
2564ed367e6cSBorislav Petkov };
2565ed367e6cSBorislav Petkov 
2566ed367e6cSBorislav Petkov static struct pci_driver knl_uncore_pci_driver = {
2567ed367e6cSBorislav Petkov 	.name		= "knl_uncore",
2568ed367e6cSBorislav Petkov 	.id_table	= knl_uncore_pci_ids,
2569ed367e6cSBorislav Petkov };
2570ed367e6cSBorislav Petkov 
2571ed367e6cSBorislav Petkov int knl_uncore_pci_init(void)
2572ed367e6cSBorislav Petkov {
2573ed367e6cSBorislav Petkov 	int ret;
2574ed367e6cSBorislav Petkov 
2575ed367e6cSBorislav Petkov 	/* All KNL PCI based PMON units are on the same PCI bus except IRP */
2576ed367e6cSBorislav Petkov 	ret = snb_pci2phy_map_init(0x7814); /* IRP */
2577ed367e6cSBorislav Petkov 	if (ret)
2578ed367e6cSBorislav Petkov 		return ret;
2579ed367e6cSBorislav Petkov 	ret = snb_pci2phy_map_init(0x7817); /* M2PCIe */
2580ed367e6cSBorislav Petkov 	if (ret)
2581ed367e6cSBorislav Petkov 		return ret;
2582ed367e6cSBorislav Petkov 	uncore_pci_uncores = knl_pci_uncores;
2583ed367e6cSBorislav Petkov 	uncore_pci_driver = &knl_uncore_pci_driver;
2584ed367e6cSBorislav Petkov 	return 0;
2585ed367e6cSBorislav Petkov }
2586ed367e6cSBorislav Petkov 
2587ed367e6cSBorislav Petkov /* end of KNL uncore support */
2588ed367e6cSBorislav Petkov 
2589ed367e6cSBorislav Petkov /* Haswell-EP uncore support */
2590ed367e6cSBorislav Petkov static struct attribute *hswep_uncore_ubox_formats_attr[] = {
2591ed367e6cSBorislav Petkov 	&format_attr_event.attr,
2592ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
2593ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2594ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
2595ed367e6cSBorislav Petkov 	&format_attr_thresh5.attr,
2596ed367e6cSBorislav Petkov 	&format_attr_filter_tid2.attr,
2597ed367e6cSBorislav Petkov 	&format_attr_filter_cid.attr,
2598ed367e6cSBorislav Petkov 	NULL,
2599ed367e6cSBorislav Petkov };
2600ed367e6cSBorislav Petkov 
260145bd07adSArvind Yadav static const struct attribute_group hswep_uncore_ubox_format_group = {
2602ed367e6cSBorislav Petkov 	.name = "format",
2603ed367e6cSBorislav Petkov 	.attrs = hswep_uncore_ubox_formats_attr,
2604ed367e6cSBorislav Petkov };
2605ed367e6cSBorislav Petkov 
2606ed367e6cSBorislav Petkov static int hswep_ubox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
2607ed367e6cSBorislav Petkov {
2608ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
2609ed367e6cSBorislav Petkov 	reg1->reg = HSWEP_U_MSR_PMON_FILTER;
2610ed367e6cSBorislav Petkov 	reg1->config = event->attr.config1 & HSWEP_U_MSR_PMON_BOX_FILTER_MASK;
2611ed367e6cSBorislav Petkov 	reg1->idx = 0;
2612ed367e6cSBorislav Petkov 	return 0;
2613ed367e6cSBorislav Petkov }
2614ed367e6cSBorislav Petkov 
2615ed367e6cSBorislav Petkov static struct intel_uncore_ops hswep_uncore_ubox_ops = {
2616ed367e6cSBorislav Petkov 	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
2617ed367e6cSBorislav Petkov 	.hw_config		= hswep_ubox_hw_config,
2618ed367e6cSBorislav Petkov 	.get_constraint		= uncore_get_constraint,
2619ed367e6cSBorislav Petkov 	.put_constraint		= uncore_put_constraint,
2620ed367e6cSBorislav Petkov };
2621ed367e6cSBorislav Petkov 
2622ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_ubox = {
2623ed367e6cSBorislav Petkov 	.name			= "ubox",
2624ed367e6cSBorislav Petkov 	.num_counters		= 2,
2625ed367e6cSBorislav Petkov 	.num_boxes		= 1,
2626ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 44,
2627ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
2628ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_U_MSR_PMON_CTR0,
2629ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_U_MSR_PMON_CTL0,
2630ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
2631ed367e6cSBorislav Petkov 	.fixed_ctr		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
2632ed367e6cSBorislav Petkov 	.fixed_ctl		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
2633ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
2634ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_ubox_ops,
2635ed367e6cSBorislav Petkov 	.format_group		= &hswep_uncore_ubox_format_group,
2636ed367e6cSBorislav Petkov };
2637ed367e6cSBorislav Petkov 
2638ed367e6cSBorislav Petkov static struct attribute *hswep_uncore_cbox_formats_attr[] = {
2639ed367e6cSBorislav Petkov 	&format_attr_event.attr,
2640ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
2641ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2642ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
2643ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
2644ed367e6cSBorislav Petkov 	&format_attr_filter_tid3.attr,
2645ed367e6cSBorislav Petkov 	&format_attr_filter_link2.attr,
2646ed367e6cSBorislav Petkov 	&format_attr_filter_state3.attr,
2647ed367e6cSBorislav Petkov 	&format_attr_filter_nid2.attr,
2648ed367e6cSBorislav Petkov 	&format_attr_filter_opc2.attr,
2649ed367e6cSBorislav Petkov 	&format_attr_filter_nc.attr,
2650ed367e6cSBorislav Petkov 	&format_attr_filter_c6.attr,
2651ed367e6cSBorislav Petkov 	&format_attr_filter_isoc.attr,
2652ed367e6cSBorislav Petkov 	NULL,
2653ed367e6cSBorislav Petkov };
2654ed367e6cSBorislav Petkov 
265545bd07adSArvind Yadav static const struct attribute_group hswep_uncore_cbox_format_group = {
2656ed367e6cSBorislav Petkov 	.name = "format",
2657ed367e6cSBorislav Petkov 	.attrs = hswep_uncore_cbox_formats_attr,
2658ed367e6cSBorislav Petkov };
2659ed367e6cSBorislav Petkov 
2660ed367e6cSBorislav Petkov static struct event_constraint hswep_uncore_cbox_constraints[] = {
2661ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x01, 0x1),
2662ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x09, 0x1),
2663ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
2664ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
2665ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
2666ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x3b, 0x1),
2667ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x3e, 0x1),
2668ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
2669ed367e6cSBorislav Petkov };
2670ed367e6cSBorislav Petkov 
2671ed367e6cSBorislav Petkov static struct extra_reg hswep_uncore_cbox_extra_regs[] = {
2672ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
2673ed367e6cSBorislav Petkov 				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
2674ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
2675ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
2676ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
2677ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4),
2678ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2134, 0xffff, 0x4),
2679ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x4),
2680ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x8),
2681ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4028, 0x40ff, 0x8),
2682ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4032, 0x40ff, 0x8),
2683ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4029, 0x40ff, 0x8),
2684ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4033, 0x40ff, 0x8),
2685ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x402A, 0x40ff, 0x8),
2686ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x12),
2687ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10),
2688ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0x18),
2689ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x8),
2690ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x8),
2691ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x8),
2692ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0x18),
2693ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x8),
2694ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2335, 0xffff, 0x10),
2695ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8335, 0xffff, 0x10),
2696ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10),
2697ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8135, 0xffff, 0x10),
2698ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x10),
2699ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x10),
2700ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0x18),
2701ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x8),
2702ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x8),
2703ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0x18),
2704ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x8),
2705ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2336, 0xffff, 0x10),
2706ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8336, 0xffff, 0x10),
2707ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2136, 0xffff, 0x10),
2708ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8136, 0xffff, 0x10),
2709ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x5036, 0xffff, 0x8),
2710ed367e6cSBorislav Petkov 	EVENT_EXTRA_END
2711ed367e6cSBorislav Petkov };
2712ed367e6cSBorislav Petkov 
2713ed367e6cSBorislav Petkov static u64 hswep_cbox_filter_mask(int fields)
2714ed367e6cSBorislav Petkov {
2715ed367e6cSBorislav Petkov 	u64 mask = 0;
2716ed367e6cSBorislav Petkov 	if (fields & 0x1)
2717ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_TID;
2718ed367e6cSBorislav Petkov 	if (fields & 0x2)
2719ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_LINK;
2720ed367e6cSBorislav Petkov 	if (fields & 0x4)
2721ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_STATE;
2722ed367e6cSBorislav Petkov 	if (fields & 0x8)
2723ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_NID;
2724ed367e6cSBorislav Petkov 	if (fields & 0x10) {
2725ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_OPC;
2726ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_NC;
2727ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_C6;
2728ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_ISOC;
2729ed367e6cSBorislav Petkov 	}
2730ed367e6cSBorislav Petkov 	return mask;
2731ed367e6cSBorislav Petkov }
2732ed367e6cSBorislav Petkov 
2733ed367e6cSBorislav Petkov static struct event_constraint *
2734ed367e6cSBorislav Petkov hswep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
2735ed367e6cSBorislav Petkov {
2736ed367e6cSBorislav Petkov 	return __snbep_cbox_get_constraint(box, event, hswep_cbox_filter_mask);
2737ed367e6cSBorislav Petkov }
2738ed367e6cSBorislav Petkov 
2739ed367e6cSBorislav Petkov static int hswep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
2740ed367e6cSBorislav Petkov {
2741ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
2742ed367e6cSBorislav Petkov 	struct extra_reg *er;
2743ed367e6cSBorislav Petkov 	int idx = 0;
2744ed367e6cSBorislav Petkov 
2745ed367e6cSBorislav Petkov 	for (er = hswep_uncore_cbox_extra_regs; er->msr; er++) {
2746ed367e6cSBorislav Petkov 		if (er->event != (event->hw.config & er->config_mask))
2747ed367e6cSBorislav Petkov 			continue;
2748ed367e6cSBorislav Petkov 		idx |= er->idx;
2749ed367e6cSBorislav Petkov 	}
2750ed367e6cSBorislav Petkov 
2751ed367e6cSBorislav Petkov 	if (idx) {
2752ed367e6cSBorislav Petkov 		reg1->reg = HSWEP_C0_MSR_PMON_BOX_FILTER0 +
2753ed367e6cSBorislav Petkov 			    HSWEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
2754ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1 & hswep_cbox_filter_mask(idx);
2755ed367e6cSBorislav Petkov 		reg1->idx = idx;
2756ed367e6cSBorislav Petkov 	}
2757ed367e6cSBorislav Petkov 	return 0;
2758ed367e6cSBorislav Petkov }
2759ed367e6cSBorislav Petkov 
2760ed367e6cSBorislav Petkov static void hswep_cbox_enable_event(struct intel_uncore_box *box,
2761ed367e6cSBorislav Petkov 				  struct perf_event *event)
2762ed367e6cSBorislav Petkov {
2763ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
2764ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
2765ed367e6cSBorislav Petkov 
2766ed367e6cSBorislav Petkov 	if (reg1->idx != EXTRA_REG_NONE) {
2767ed367e6cSBorislav Petkov 		u64 filter = uncore_shared_reg_config(box, 0);
2768ed367e6cSBorislav Petkov 		wrmsrl(reg1->reg, filter & 0xffffffff);
2769ed367e6cSBorislav Petkov 		wrmsrl(reg1->reg + 1, filter >> 32);
2770ed367e6cSBorislav Petkov 	}
2771ed367e6cSBorislav Petkov 
2772ed367e6cSBorislav Petkov 	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
2773ed367e6cSBorislav Petkov }
2774ed367e6cSBorislav Petkov 
2775ed367e6cSBorislav Petkov static struct intel_uncore_ops hswep_uncore_cbox_ops = {
2776ed367e6cSBorislav Petkov 	.init_box		= snbep_uncore_msr_init_box,
2777ed367e6cSBorislav Petkov 	.disable_box		= snbep_uncore_msr_disable_box,
2778ed367e6cSBorislav Petkov 	.enable_box		= snbep_uncore_msr_enable_box,
2779ed367e6cSBorislav Petkov 	.disable_event		= snbep_uncore_msr_disable_event,
2780ed367e6cSBorislav Petkov 	.enable_event		= hswep_cbox_enable_event,
2781ed367e6cSBorislav Petkov 	.read_counter		= uncore_msr_read_counter,
2782ed367e6cSBorislav Petkov 	.hw_config		= hswep_cbox_hw_config,
2783ed367e6cSBorislav Petkov 	.get_constraint		= hswep_cbox_get_constraint,
2784ed367e6cSBorislav Petkov 	.put_constraint		= snbep_cbox_put_constraint,
2785ed367e6cSBorislav Petkov };
2786ed367e6cSBorislav Petkov 
2787ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_cbox = {
2788ed367e6cSBorislav Petkov 	.name			= "cbox",
2789ed367e6cSBorislav Petkov 	.num_counters		= 4,
2790ed367e6cSBorislav Petkov 	.num_boxes		= 18,
2791ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2792ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_C0_MSR_PMON_CTL0,
2793ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_C0_MSR_PMON_CTR0,
2794ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
2795ed367e6cSBorislav Petkov 	.box_ctl		= HSWEP_C0_MSR_PMON_BOX_CTL,
2796ed367e6cSBorislav Petkov 	.msr_offset		= HSWEP_CBO_MSR_OFFSET,
2797ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
2798ed367e6cSBorislav Petkov 	.constraints		= hswep_uncore_cbox_constraints,
2799ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_cbox_ops,
2800ed367e6cSBorislav Petkov 	.format_group		= &hswep_uncore_cbox_format_group,
2801ed367e6cSBorislav Petkov };
2802ed367e6cSBorislav Petkov 
2803ed367e6cSBorislav Petkov /*
2804ed367e6cSBorislav Petkov  * Write SBOX Initialization register bit by bit to avoid spurious #GPs
2805ed367e6cSBorislav Petkov  */
2806ed367e6cSBorislav Petkov static void hswep_uncore_sbox_msr_init_box(struct intel_uncore_box *box)
2807ed367e6cSBorislav Petkov {
2808ed367e6cSBorislav Petkov 	unsigned msr = uncore_msr_box_ctl(box);
2809ed367e6cSBorislav Petkov 
2810ed367e6cSBorislav Petkov 	if (msr) {
2811ed367e6cSBorislav Petkov 		u64 init = SNBEP_PMON_BOX_CTL_INT;
2812ed367e6cSBorislav Petkov 		u64 flags = 0;
2813ed367e6cSBorislav Petkov 		int i;
2814ed367e6cSBorislav Petkov 
2815ed367e6cSBorislav Petkov 		for_each_set_bit(i, (unsigned long *)&init, 64) {
2816ed367e6cSBorislav Petkov 			flags |= (1ULL << i);
2817ed367e6cSBorislav Petkov 			wrmsrl(msr, flags);
2818ed367e6cSBorislav Petkov 		}
2819ed367e6cSBorislav Petkov 	}
2820ed367e6cSBorislav Petkov }
2821ed367e6cSBorislav Petkov 
2822ed367e6cSBorislav Petkov static struct intel_uncore_ops hswep_uncore_sbox_msr_ops = {
2823ed367e6cSBorislav Petkov 	__SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
2824ed367e6cSBorislav Petkov 	.init_box		= hswep_uncore_sbox_msr_init_box
2825ed367e6cSBorislav Petkov };
2826ed367e6cSBorislav Petkov 
2827ed367e6cSBorislav Petkov static struct attribute *hswep_uncore_sbox_formats_attr[] = {
2828ed367e6cSBorislav Petkov 	&format_attr_event.attr,
2829ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
2830ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2831ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
2832ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
2833ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
2834ed367e6cSBorislav Petkov 	NULL,
2835ed367e6cSBorislav Petkov };
2836ed367e6cSBorislav Petkov 
283745bd07adSArvind Yadav static const struct attribute_group hswep_uncore_sbox_format_group = {
2838ed367e6cSBorislav Petkov 	.name = "format",
2839ed367e6cSBorislav Petkov 	.attrs = hswep_uncore_sbox_formats_attr,
2840ed367e6cSBorislav Petkov };
2841ed367e6cSBorislav Petkov 
2842ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_sbox = {
2843ed367e6cSBorislav Petkov 	.name			= "sbox",
2844ed367e6cSBorislav Petkov 	.num_counters		= 4,
2845ed367e6cSBorislav Petkov 	.num_boxes		= 4,
2846ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 44,
2847ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_S0_MSR_PMON_CTL0,
2848ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_S0_MSR_PMON_CTR0,
2849ed367e6cSBorislav Petkov 	.event_mask		= HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
2850ed367e6cSBorislav Petkov 	.box_ctl		= HSWEP_S0_MSR_PMON_BOX_CTL,
2851ed367e6cSBorislav Petkov 	.msr_offset		= HSWEP_SBOX_MSR_OFFSET,
2852ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_sbox_msr_ops,
2853ed367e6cSBorislav Petkov 	.format_group		= &hswep_uncore_sbox_format_group,
2854ed367e6cSBorislav Petkov };
2855ed367e6cSBorislav Petkov 
2856ed367e6cSBorislav Petkov static int hswep_pcu_hw_config(struct intel_uncore_box *box, struct perf_event *event)
2857ed367e6cSBorislav Petkov {
2858ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
2859ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
2860ed367e6cSBorislav Petkov 	int ev_sel = hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK;
2861ed367e6cSBorislav Petkov 
2862ed367e6cSBorislav Petkov 	if (ev_sel >= 0xb && ev_sel <= 0xe) {
2863ed367e6cSBorislav Petkov 		reg1->reg = HSWEP_PCU_MSR_PMON_BOX_FILTER;
2864ed367e6cSBorislav Petkov 		reg1->idx = ev_sel - 0xb;
2865ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1 & (0xff << reg1->idx);
2866ed367e6cSBorislav Petkov 	}
2867ed367e6cSBorislav Petkov 	return 0;
2868ed367e6cSBorislav Petkov }
2869ed367e6cSBorislav Petkov 
2870ed367e6cSBorislav Petkov static struct intel_uncore_ops hswep_uncore_pcu_ops = {
2871ed367e6cSBorislav Petkov 	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
2872ed367e6cSBorislav Petkov 	.hw_config		= hswep_pcu_hw_config,
2873ed367e6cSBorislav Petkov 	.get_constraint		= snbep_pcu_get_constraint,
2874ed367e6cSBorislav Petkov 	.put_constraint		= snbep_pcu_put_constraint,
2875ed367e6cSBorislav Petkov };
2876ed367e6cSBorislav Petkov 
2877ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_pcu = {
2878ed367e6cSBorislav Petkov 	.name			= "pcu",
2879ed367e6cSBorislav Petkov 	.num_counters		= 4,
2880ed367e6cSBorislav Petkov 	.num_boxes		= 1,
2881ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2882ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_PCU_MSR_PMON_CTR0,
2883ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_PCU_MSR_PMON_CTL0,
2884ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
2885ed367e6cSBorislav Petkov 	.box_ctl		= HSWEP_PCU_MSR_PMON_BOX_CTL,
2886ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
2887ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_pcu_ops,
2888ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_pcu_format_group,
2889ed367e6cSBorislav Petkov };
2890ed367e6cSBorislav Petkov 
2891ed367e6cSBorislav Petkov static struct intel_uncore_type *hswep_msr_uncores[] = {
2892ed367e6cSBorislav Petkov 	&hswep_uncore_ubox,
2893ed367e6cSBorislav Petkov 	&hswep_uncore_cbox,
2894ed367e6cSBorislav Petkov 	&hswep_uncore_sbox,
2895ed367e6cSBorislav Petkov 	&hswep_uncore_pcu,
2896ed367e6cSBorislav Petkov 	NULL,
2897ed367e6cSBorislav Petkov };
2898ed367e6cSBorislav Petkov 
28999d480158SKan Liang #define HSWEP_PCU_DID			0x2fc0
29009d480158SKan Liang #define HSWEP_PCU_CAPID4_OFFET		0x94
29019d480158SKan Liang #define hswep_get_chop(_cap)		(((_cap) >> 6) & 0x3)
29029d480158SKan Liang 
29039d480158SKan Liang static bool hswep_has_limit_sbox(unsigned int device)
29049d480158SKan Liang {
29059d480158SKan Liang 	struct pci_dev *dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
29069d480158SKan Liang 	u32 capid4;
29079d480158SKan Liang 
29089d480158SKan Liang 	if (!dev)
29099d480158SKan Liang 		return false;
29109d480158SKan Liang 
29119d480158SKan Liang 	pci_read_config_dword(dev, HSWEP_PCU_CAPID4_OFFET, &capid4);
29129d480158SKan Liang 	if (!hswep_get_chop(capid4))
29139d480158SKan Liang 		return true;
29149d480158SKan Liang 
29159d480158SKan Liang 	return false;
29169d480158SKan Liang }
29179d480158SKan Liang 
2918ed367e6cSBorislav Petkov void hswep_uncore_cpu_init(void)
2919ed367e6cSBorislav Petkov {
2920ed367e6cSBorislav Petkov 	if (hswep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
2921ed367e6cSBorislav Petkov 		hswep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
2922ed367e6cSBorislav Petkov 
2923ed367e6cSBorislav Petkov 	/* Detect 6-8 core systems with only two SBOXes */
29249d480158SKan Liang 	if (hswep_has_limit_sbox(HSWEP_PCU_DID))
2925ed367e6cSBorislav Petkov 		hswep_uncore_sbox.num_boxes = 2;
2926ed367e6cSBorislav Petkov 
2927ed367e6cSBorislav Petkov 	uncore_msr_uncores = hswep_msr_uncores;
2928ed367e6cSBorislav Petkov }
2929ed367e6cSBorislav Petkov 
2930ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_ha = {
2931ed367e6cSBorislav Petkov 	.name		= "ha",
293210e9e7bdSKan Liang 	.num_counters   = 4,
2933ed367e6cSBorislav Petkov 	.num_boxes	= 2,
2934ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
2935ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
2936ed367e6cSBorislav Petkov };
2937ed367e6cSBorislav Petkov 
2938ed367e6cSBorislav Petkov static struct uncore_event_desc hswep_uncore_imc_events[] = {
2939ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(clockticks,      "event=0x00,umask=0x00"),
2940ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_read,  "event=0x04,umask=0x03"),
2941ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_read.scale, "6.103515625e-5"),
2942ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_read.unit, "MiB"),
2943ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"),
2944ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_write.scale, "6.103515625e-5"),
2945ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_write.unit, "MiB"),
2946ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ },
2947ed367e6cSBorislav Petkov };
2948ed367e6cSBorislav Petkov 
2949ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_imc = {
2950ed367e6cSBorislav Petkov 	.name		= "imc",
295110e9e7bdSKan Liang 	.num_counters   = 4,
2952ed367e6cSBorislav Petkov 	.num_boxes	= 8,
2953ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
2954ed367e6cSBorislav Petkov 	.fixed_ctr_bits	= 48,
2955ed367e6cSBorislav Petkov 	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
2956ed367e6cSBorislav Petkov 	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
2957ed367e6cSBorislav Petkov 	.event_descs	= hswep_uncore_imc_events,
2958ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
2959ed367e6cSBorislav Petkov };
2960ed367e6cSBorislav Petkov 
2961ed367e6cSBorislav Petkov static unsigned hswep_uncore_irp_ctrs[] = {0xa0, 0xa8, 0xb0, 0xb8};
2962ed367e6cSBorislav Petkov 
2963ed367e6cSBorislav Petkov static u64 hswep_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event)
2964ed367e6cSBorislav Petkov {
2965ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
2966ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
2967ed367e6cSBorislav Petkov 	u64 count = 0;
2968ed367e6cSBorislav Petkov 
2969ed367e6cSBorislav Petkov 	pci_read_config_dword(pdev, hswep_uncore_irp_ctrs[hwc->idx], (u32 *)&count);
2970ed367e6cSBorislav Petkov 	pci_read_config_dword(pdev, hswep_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1);
2971ed367e6cSBorislav Petkov 
2972ed367e6cSBorislav Petkov 	return count;
2973ed367e6cSBorislav Petkov }
2974ed367e6cSBorislav Petkov 
2975ed367e6cSBorislav Petkov static struct intel_uncore_ops hswep_uncore_irp_ops = {
2976ed367e6cSBorislav Petkov 	.init_box	= snbep_uncore_pci_init_box,
2977ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_pci_disable_box,
2978ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_pci_enable_box,
2979ed367e6cSBorislav Petkov 	.disable_event	= ivbep_uncore_irp_disable_event,
2980ed367e6cSBorislav Petkov 	.enable_event	= ivbep_uncore_irp_enable_event,
2981ed367e6cSBorislav Petkov 	.read_counter	= hswep_uncore_irp_read_counter,
2982ed367e6cSBorislav Petkov };
2983ed367e6cSBorislav Petkov 
2984ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_irp = {
2985ed367e6cSBorislav Petkov 	.name			= "irp",
2986ed367e6cSBorislav Petkov 	.num_counters		= 4,
2987ed367e6cSBorislav Petkov 	.num_boxes		= 1,
2988ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2989ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
2990ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
2991ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_irp_ops,
2992ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_format_group,
2993ed367e6cSBorislav Petkov };
2994ed367e6cSBorislav Petkov 
2995ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_qpi = {
2996ed367e6cSBorislav Petkov 	.name			= "qpi",
299710e9e7bdSKan Liang 	.num_counters		= 4,
2998ed367e6cSBorislav Petkov 	.num_boxes		= 3,
2999ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
3000ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
3001ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCI_PMON_CTL0,
3002ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
3003ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
3004ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
3005ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_qpi_ops,
3006ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_qpi_format_group,
3007ed367e6cSBorislav Petkov };
3008ed367e6cSBorislav Petkov 
3009ed367e6cSBorislav Petkov static struct event_constraint hswep_uncore_r2pcie_constraints[] = {
3010ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
3011ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
3012ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
3013ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x1),
3014ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x24, 0x1),
3015ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
3016ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
3017ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x27, 0x1),
3018ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
3019ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
3020ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2a, 0x1),
3021ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2b, 0x3),
3022ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
3023ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
3024ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
3025ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
3026ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
3027ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
3028ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
3029ed367e6cSBorislav Petkov };
3030ed367e6cSBorislav Petkov 
3031ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_r2pcie = {
3032ed367e6cSBorislav Petkov 	.name		= "r2pcie",
3033ed367e6cSBorislav Petkov 	.num_counters   = 4,
3034ed367e6cSBorislav Petkov 	.num_boxes	= 1,
3035ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
3036ed367e6cSBorislav Petkov 	.constraints	= hswep_uncore_r2pcie_constraints,
3037ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
3038ed367e6cSBorislav Petkov };
3039ed367e6cSBorislav Petkov 
3040ed367e6cSBorislav Petkov static struct event_constraint hswep_uncore_r3qpi_constraints[] = {
3041ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x01, 0x3),
3042ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x07, 0x7),
3043ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x08, 0x7),
3044ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x09, 0x7),
3045ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x0a, 0x7),
3046ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x0e, 0x7),
3047ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
3048ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
3049ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
3050ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
3051ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
3052ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x15, 0x3),
3053ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1f, 0x3),
3054ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
3055ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
3056ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
3057ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
3058ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
3059ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
3060ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
3061ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
3062ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
3063ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
3064ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
3065ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
3066ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
3067ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
3068ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
3069ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
3070ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
3071ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
3072ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
3073ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
3074ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
3075ed367e6cSBorislav Petkov };
3076ed367e6cSBorislav Petkov 
3077ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_r3qpi = {
3078ed367e6cSBorislav Petkov 	.name		= "r3qpi",
307910e9e7bdSKan Liang 	.num_counters   = 3,
3080ed367e6cSBorislav Petkov 	.num_boxes	= 3,
3081ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
3082ed367e6cSBorislav Petkov 	.constraints	= hswep_uncore_r3qpi_constraints,
3083ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
3084ed367e6cSBorislav Petkov };
3085ed367e6cSBorislav Petkov 
3086ed367e6cSBorislav Petkov enum {
3087ed367e6cSBorislav Petkov 	HSWEP_PCI_UNCORE_HA,
3088ed367e6cSBorislav Petkov 	HSWEP_PCI_UNCORE_IMC,
3089ed367e6cSBorislav Petkov 	HSWEP_PCI_UNCORE_IRP,
3090ed367e6cSBorislav Petkov 	HSWEP_PCI_UNCORE_QPI,
3091ed367e6cSBorislav Petkov 	HSWEP_PCI_UNCORE_R2PCIE,
3092ed367e6cSBorislav Petkov 	HSWEP_PCI_UNCORE_R3QPI,
3093ed367e6cSBorislav Petkov };
3094ed367e6cSBorislav Petkov 
3095ed367e6cSBorislav Petkov static struct intel_uncore_type *hswep_pci_uncores[] = {
3096ed367e6cSBorislav Petkov 	[HSWEP_PCI_UNCORE_HA]	= &hswep_uncore_ha,
3097ed367e6cSBorislav Petkov 	[HSWEP_PCI_UNCORE_IMC]	= &hswep_uncore_imc,
3098ed367e6cSBorislav Petkov 	[HSWEP_PCI_UNCORE_IRP]	= &hswep_uncore_irp,
3099ed367e6cSBorislav Petkov 	[HSWEP_PCI_UNCORE_QPI]	= &hswep_uncore_qpi,
3100ed367e6cSBorislav Petkov 	[HSWEP_PCI_UNCORE_R2PCIE]	= &hswep_uncore_r2pcie,
3101ed367e6cSBorislav Petkov 	[HSWEP_PCI_UNCORE_R3QPI]	= &hswep_uncore_r3qpi,
3102ed367e6cSBorislav Petkov 	NULL,
3103ed367e6cSBorislav Petkov };
3104ed367e6cSBorislav Petkov 
3105ed367e6cSBorislav Petkov static const struct pci_device_id hswep_uncore_pci_ids[] = {
3106ed367e6cSBorislav Petkov 	{ /* Home Agent 0 */
3107ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f30),
3108ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_HA, 0),
3109ed367e6cSBorislav Petkov 	},
3110ed367e6cSBorislav Petkov 	{ /* Home Agent 1 */
3111ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f38),
3112ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_HA, 1),
3113ed367e6cSBorislav Petkov 	},
3114ed367e6cSBorislav Petkov 	{ /* MC0 Channel 0 */
3115ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb0),
3116ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 0),
3117ed367e6cSBorislav Petkov 	},
3118ed367e6cSBorislav Petkov 	{ /* MC0 Channel 1 */
3119ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb1),
3120ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 1),
3121ed367e6cSBorislav Petkov 	},
3122ed367e6cSBorislav Petkov 	{ /* MC0 Channel 2 */
3123ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb4),
3124ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 2),
3125ed367e6cSBorislav Petkov 	},
3126ed367e6cSBorislav Petkov 	{ /* MC0 Channel 3 */
3127ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb5),
3128ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 3),
3129ed367e6cSBorislav Petkov 	},
3130ed367e6cSBorislav Petkov 	{ /* MC1 Channel 0 */
3131ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd0),
3132ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 4),
3133ed367e6cSBorislav Petkov 	},
3134ed367e6cSBorislav Petkov 	{ /* MC1 Channel 1 */
3135ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd1),
3136ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 5),
3137ed367e6cSBorislav Petkov 	},
3138ed367e6cSBorislav Petkov 	{ /* MC1 Channel 2 */
3139ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd4),
3140ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 6),
3141ed367e6cSBorislav Petkov 	},
3142ed367e6cSBorislav Petkov 	{ /* MC1 Channel 3 */
3143ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd5),
3144ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 7),
3145ed367e6cSBorislav Petkov 	},
3146ed367e6cSBorislav Petkov 	{ /* IRP */
3147ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f39),
3148ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IRP, 0),
3149ed367e6cSBorislav Petkov 	},
3150ed367e6cSBorislav Petkov 	{ /* QPI0 Port 0 */
3151ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f32),
3152ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 0),
3153ed367e6cSBorislav Petkov 	},
3154ed367e6cSBorislav Petkov 	{ /* QPI0 Port 1 */
3155ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f33),
3156ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 1),
3157ed367e6cSBorislav Petkov 	},
3158ed367e6cSBorislav Petkov 	{ /* QPI1 Port 2 */
3159ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f3a),
3160ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 2),
3161ed367e6cSBorislav Petkov 	},
3162ed367e6cSBorislav Petkov 	{ /* R2PCIe */
3163ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f34),
3164ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R2PCIE, 0),
3165ed367e6cSBorislav Petkov 	},
3166ed367e6cSBorislav Petkov 	{ /* R3QPI0 Link 0 */
3167ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f36),
3168ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 0),
3169ed367e6cSBorislav Petkov 	},
3170ed367e6cSBorislav Petkov 	{ /* R3QPI0 Link 1 */
3171ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f37),
3172ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 1),
3173ed367e6cSBorislav Petkov 	},
3174ed367e6cSBorislav Petkov 	{ /* R3QPI1 Link 2 */
3175ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f3e),
3176ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 2),
3177ed367e6cSBorislav Petkov 	},
3178ed367e6cSBorislav Petkov 	{ /* QPI Port 0 filter  */
3179ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f86),
3180ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
3181ed367e6cSBorislav Petkov 						   SNBEP_PCI_QPI_PORT0_FILTER),
3182ed367e6cSBorislav Petkov 	},
3183ed367e6cSBorislav Petkov 	{ /* QPI Port 1 filter  */
3184ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f96),
3185ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
3186ed367e6cSBorislav Petkov 						   SNBEP_PCI_QPI_PORT1_FILTER),
3187ed367e6cSBorislav Petkov 	},
3188ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ }
3189ed367e6cSBorislav Petkov };
3190ed367e6cSBorislav Petkov 
3191ed367e6cSBorislav Petkov static struct pci_driver hswep_uncore_pci_driver = {
3192ed367e6cSBorislav Petkov 	.name		= "hswep_uncore",
3193ed367e6cSBorislav Petkov 	.id_table	= hswep_uncore_pci_ids,
3194ed367e6cSBorislav Petkov };
3195ed367e6cSBorislav Petkov 
3196ed367e6cSBorislav Petkov int hswep_uncore_pci_init(void)
3197ed367e6cSBorislav Petkov {
319868ce4a0dSKan Liang 	int ret = snbep_pci2phy_map_init(0x2f1e, SNBEP_CPUNODEID, SNBEP_GIDNIDMAP, true);
3199ed367e6cSBorislav Petkov 	if (ret)
3200ed367e6cSBorislav Petkov 		return ret;
3201ed367e6cSBorislav Petkov 	uncore_pci_uncores = hswep_pci_uncores;
3202ed367e6cSBorislav Petkov 	uncore_pci_driver = &hswep_uncore_pci_driver;
3203ed367e6cSBorislav Petkov 	return 0;
3204ed367e6cSBorislav Petkov }
3205ed367e6cSBorislav Petkov /* end of Haswell-EP uncore support */
3206ed367e6cSBorislav Petkov 
3207ed367e6cSBorislav Petkov /* BDX uncore support */
3208ed367e6cSBorislav Petkov 
3209ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_ubox = {
3210ed367e6cSBorislav Petkov 	.name			= "ubox",
3211ed367e6cSBorislav Petkov 	.num_counters		= 2,
3212ed367e6cSBorislav Petkov 	.num_boxes		= 1,
3213ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
3214ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
3215ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_U_MSR_PMON_CTR0,
3216ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_U_MSR_PMON_CTL0,
3217ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
3218ed367e6cSBorislav Petkov 	.fixed_ctr		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
3219ed367e6cSBorislav Petkov 	.fixed_ctl		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
3220ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
3221ed367e6cSBorislav Petkov 	.ops			= &ivbep_uncore_msr_ops,
3222ed367e6cSBorislav Petkov 	.format_group		= &ivbep_uncore_ubox_format_group,
3223ed367e6cSBorislav Petkov };
3224ed367e6cSBorislav Petkov 
3225ed367e6cSBorislav Petkov static struct event_constraint bdx_uncore_cbox_constraints[] = {
3226ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x09, 0x3),
3227ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
3228ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
3229ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x3e, 0x1),
3230ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
3231ed367e6cSBorislav Petkov };
3232ed367e6cSBorislav Petkov 
3233ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_cbox = {
3234ed367e6cSBorislav Petkov 	.name			= "cbox",
3235ed367e6cSBorislav Petkov 	.num_counters		= 4,
3236ed367e6cSBorislav Petkov 	.num_boxes		= 24,
3237ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
3238ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_C0_MSR_PMON_CTL0,
3239ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_C0_MSR_PMON_CTR0,
3240ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
3241ed367e6cSBorislav Petkov 	.box_ctl		= HSWEP_C0_MSR_PMON_BOX_CTL,
3242ed367e6cSBorislav Petkov 	.msr_offset		= HSWEP_CBO_MSR_OFFSET,
3243ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
3244ed367e6cSBorislav Petkov 	.constraints		= bdx_uncore_cbox_constraints,
3245ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_cbox_ops,
3246ed367e6cSBorislav Petkov 	.format_group		= &hswep_uncore_cbox_format_group,
3247ed367e6cSBorislav Petkov };
3248ed367e6cSBorislav Petkov 
3249d7717587SStephane Eranian static struct intel_uncore_type bdx_uncore_sbox = {
3250d7717587SStephane Eranian 	.name			= "sbox",
3251d7717587SStephane Eranian 	.num_counters		= 4,
3252d7717587SStephane Eranian 	.num_boxes		= 4,
3253d7717587SStephane Eranian 	.perf_ctr_bits		= 48,
3254d7717587SStephane Eranian 	.event_ctl		= HSWEP_S0_MSR_PMON_CTL0,
3255d7717587SStephane Eranian 	.perf_ctr		= HSWEP_S0_MSR_PMON_CTR0,
3256d7717587SStephane Eranian 	.event_mask		= HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
3257d7717587SStephane Eranian 	.box_ctl		= HSWEP_S0_MSR_PMON_BOX_CTL,
3258d7717587SStephane Eranian 	.msr_offset		= HSWEP_SBOX_MSR_OFFSET,
3259d7717587SStephane Eranian 	.ops			= &hswep_uncore_sbox_msr_ops,
3260d7717587SStephane Eranian 	.format_group		= &hswep_uncore_sbox_format_group,
3261d7717587SStephane Eranian };
3262d7717587SStephane Eranian 
3263d7717587SStephane Eranian #define BDX_MSR_UNCORE_SBOX	3
3264d7717587SStephane Eranian 
3265ed367e6cSBorislav Petkov static struct intel_uncore_type *bdx_msr_uncores[] = {
3266ed367e6cSBorislav Petkov 	&bdx_uncore_ubox,
3267ed367e6cSBorislav Petkov 	&bdx_uncore_cbox,
3268ed367e6cSBorislav Petkov 	&hswep_uncore_pcu,
3269d7717587SStephane Eranian 	&bdx_uncore_sbox,
3270ed367e6cSBorislav Petkov 	NULL,
3271ed367e6cSBorislav Petkov };
3272ed367e6cSBorislav Petkov 
3273bb9fbe1bSKan Liang /* Bit 7 'Use Occupancy' is not available for counter 0 on BDX */
3274bb9fbe1bSKan Liang static struct event_constraint bdx_uncore_pcu_constraints[] = {
3275bb9fbe1bSKan Liang 	EVENT_CONSTRAINT(0x80, 0xe, 0x80),
3276bb9fbe1bSKan Liang 	EVENT_CONSTRAINT_END
3277bb9fbe1bSKan Liang };
3278bb9fbe1bSKan Liang 
32799d480158SKan Liang #define BDX_PCU_DID			0x6fc0
32809d480158SKan Liang 
3281ed367e6cSBorislav Petkov void bdx_uncore_cpu_init(void)
3282ed367e6cSBorislav Petkov {
3283ed367e6cSBorislav Petkov 	if (bdx_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
3284ed367e6cSBorislav Petkov 		bdx_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
3285ed367e6cSBorislav Petkov 	uncore_msr_uncores = bdx_msr_uncores;
3286bb9fbe1bSKan Liang 
328715a3e845SOskar Senft 	/* Detect systems with no SBOXes */
32889d480158SKan Liang 	if ((boot_cpu_data.x86_model == 86) || hswep_has_limit_sbox(BDX_PCU_DID))
32899d480158SKan Liang 		uncore_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL;
3290d7717587SStephane Eranian 
3291bb9fbe1bSKan Liang 	hswep_uncore_pcu.constraints = bdx_uncore_pcu_constraints;
3292ed367e6cSBorislav Petkov }
3293ed367e6cSBorislav Petkov 
3294ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_ha = {
3295ed367e6cSBorislav Petkov 	.name		= "ha",
3296ed367e6cSBorislav Petkov 	.num_counters   = 4,
3297ed367e6cSBorislav Petkov 	.num_boxes	= 2,
3298ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
3299ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
3300ed367e6cSBorislav Petkov };
3301ed367e6cSBorislav Petkov 
3302ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_imc = {
3303ed367e6cSBorislav Petkov 	.name		= "imc",
330410e9e7bdSKan Liang 	.num_counters   = 4,
3305ed367e6cSBorislav Petkov 	.num_boxes	= 8,
3306ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
3307ed367e6cSBorislav Petkov 	.fixed_ctr_bits	= 48,
3308ed367e6cSBorislav Petkov 	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
3309ed367e6cSBorislav Petkov 	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
3310ed367e6cSBorislav Petkov 	.event_descs	= hswep_uncore_imc_events,
3311ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
3312ed367e6cSBorislav Petkov };
3313ed367e6cSBorislav Petkov 
3314ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_irp = {
3315ed367e6cSBorislav Petkov 	.name			= "irp",
3316ed367e6cSBorislav Petkov 	.num_counters		= 4,
3317ed367e6cSBorislav Petkov 	.num_boxes		= 1,
3318ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
3319ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
3320ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
3321ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_irp_ops,
3322ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_format_group,
3323ed367e6cSBorislav Petkov };
3324ed367e6cSBorislav Petkov 
3325ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_qpi = {
3326ed367e6cSBorislav Petkov 	.name			= "qpi",
3327ed367e6cSBorislav Petkov 	.num_counters		= 4,
3328ed367e6cSBorislav Petkov 	.num_boxes		= 3,
3329ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
3330ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
3331ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCI_PMON_CTL0,
3332ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
3333ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
3334ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
3335ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_qpi_ops,
3336ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_qpi_format_group,
3337ed367e6cSBorislav Petkov };
3338ed367e6cSBorislav Petkov 
3339ed367e6cSBorislav Petkov static struct event_constraint bdx_uncore_r2pcie_constraints[] = {
3340ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
3341ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
3342ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
3343ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x1),
3344ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
3345ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
3346ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
3347ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
3348ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
3349ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
3350ed367e6cSBorislav Petkov };
3351ed367e6cSBorislav Petkov 
3352ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_r2pcie = {
3353ed367e6cSBorislav Petkov 	.name		= "r2pcie",
3354ed367e6cSBorislav Petkov 	.num_counters   = 4,
3355ed367e6cSBorislav Petkov 	.num_boxes	= 1,
3356ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
3357ed367e6cSBorislav Petkov 	.constraints	= bdx_uncore_r2pcie_constraints,
3358ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
3359ed367e6cSBorislav Petkov };
3360ed367e6cSBorislav Petkov 
3361ed367e6cSBorislav Petkov static struct event_constraint bdx_uncore_r3qpi_constraints[] = {
3362ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x01, 0x7),
3363ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x07, 0x7),
3364ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x08, 0x7),
3365ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x09, 0x7),
3366ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x0a, 0x7),
3367ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x0e, 0x7),
3368ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
3369ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
3370ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
3371ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
3372ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x15, 0x3),
3373ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1f, 0x3),
3374ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
3375ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
3376ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
3377ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
3378ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
3379ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
3380ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
3381ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
3382ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
3383ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
3384ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
3385ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
3386ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
3387ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
3388ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
3389ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
3390ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
3391ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
3392ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
3393ed367e6cSBorislav Petkov };
3394ed367e6cSBorislav Petkov 
3395ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_r3qpi = {
3396ed367e6cSBorislav Petkov 	.name		= "r3qpi",
3397ed367e6cSBorislav Petkov 	.num_counters   = 3,
3398ed367e6cSBorislav Petkov 	.num_boxes	= 3,
3399ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
3400ed367e6cSBorislav Petkov 	.constraints	= bdx_uncore_r3qpi_constraints,
3401ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
3402ed367e6cSBorislav Petkov };
3403ed367e6cSBorislav Petkov 
3404ed367e6cSBorislav Petkov enum {
3405ed367e6cSBorislav Petkov 	BDX_PCI_UNCORE_HA,
3406ed367e6cSBorislav Petkov 	BDX_PCI_UNCORE_IMC,
3407ed367e6cSBorislav Petkov 	BDX_PCI_UNCORE_IRP,
3408ed367e6cSBorislav Petkov 	BDX_PCI_UNCORE_QPI,
3409ed367e6cSBorislav Petkov 	BDX_PCI_UNCORE_R2PCIE,
3410ed367e6cSBorislav Petkov 	BDX_PCI_UNCORE_R3QPI,
3411ed367e6cSBorislav Petkov };
3412ed367e6cSBorislav Petkov 
3413ed367e6cSBorislav Petkov static struct intel_uncore_type *bdx_pci_uncores[] = {
3414ed367e6cSBorislav Petkov 	[BDX_PCI_UNCORE_HA]	= &bdx_uncore_ha,
3415ed367e6cSBorislav Petkov 	[BDX_PCI_UNCORE_IMC]	= &bdx_uncore_imc,
3416ed367e6cSBorislav Petkov 	[BDX_PCI_UNCORE_IRP]	= &bdx_uncore_irp,
3417ed367e6cSBorislav Petkov 	[BDX_PCI_UNCORE_QPI]	= &bdx_uncore_qpi,
3418ed367e6cSBorislav Petkov 	[BDX_PCI_UNCORE_R2PCIE]	= &bdx_uncore_r2pcie,
3419ed367e6cSBorislav Petkov 	[BDX_PCI_UNCORE_R3QPI]	= &bdx_uncore_r3qpi,
3420ed367e6cSBorislav Petkov 	NULL,
3421ed367e6cSBorislav Petkov };
3422ed367e6cSBorislav Petkov 
3423ed367e6cSBorislav Petkov static const struct pci_device_id bdx_uncore_pci_ids[] = {
3424ed367e6cSBorislav Petkov 	{ /* Home Agent 0 */
3425ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f30),
3426ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_HA, 0),
3427ed367e6cSBorislav Petkov 	},
3428ed367e6cSBorislav Petkov 	{ /* Home Agent 1 */
3429ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f38),
3430ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_HA, 1),
3431ed367e6cSBorislav Petkov 	},
3432ed367e6cSBorislav Petkov 	{ /* MC0 Channel 0 */
3433ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb0),
3434ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 0),
3435ed367e6cSBorislav Petkov 	},
3436ed367e6cSBorislav Petkov 	{ /* MC0 Channel 1 */
3437ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb1),
3438ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 1),
3439ed367e6cSBorislav Petkov 	},
3440ed367e6cSBorislav Petkov 	{ /* MC0 Channel 2 */
3441ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb4),
3442ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 2),
3443ed367e6cSBorislav Petkov 	},
3444ed367e6cSBorislav Petkov 	{ /* MC0 Channel 3 */
3445ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb5),
3446ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 3),
3447ed367e6cSBorislav Petkov 	},
3448ed367e6cSBorislav Petkov 	{ /* MC1 Channel 0 */
3449ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fd0),
3450ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 4),
3451ed367e6cSBorislav Petkov 	},
3452ed367e6cSBorislav Petkov 	{ /* MC1 Channel 1 */
3453ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fd1),
3454ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 5),
3455ed367e6cSBorislav Petkov 	},
3456ed367e6cSBorislav Petkov 	{ /* MC1 Channel 2 */
3457ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fd4),
3458ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 6),
3459ed367e6cSBorislav Petkov 	},
3460ed367e6cSBorislav Petkov 	{ /* MC1 Channel 3 */
3461ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fd5),
3462ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 7),
3463ed367e6cSBorislav Petkov 	},
3464ed367e6cSBorislav Petkov 	{ /* IRP */
3465ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f39),
3466ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IRP, 0),
3467ed367e6cSBorislav Petkov 	},
3468ed367e6cSBorislav Petkov 	{ /* QPI0 Port 0 */
3469ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f32),
3470ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_QPI, 0),
3471ed367e6cSBorislav Petkov 	},
3472ed367e6cSBorislav Petkov 	{ /* QPI0 Port 1 */
3473ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f33),
3474ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_QPI, 1),
3475ed367e6cSBorislav Petkov 	},
3476ed367e6cSBorislav Petkov 	{ /* QPI1 Port 2 */
3477ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f3a),
3478ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_QPI, 2),
3479ed367e6cSBorislav Petkov 	},
3480ed367e6cSBorislav Petkov 	{ /* R2PCIe */
3481ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f34),
3482ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R2PCIE, 0),
3483ed367e6cSBorislav Petkov 	},
3484ed367e6cSBorislav Petkov 	{ /* R3QPI0 Link 0 */
3485ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f36),
3486ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R3QPI, 0),
3487ed367e6cSBorislav Petkov 	},
3488ed367e6cSBorislav Petkov 	{ /* R3QPI0 Link 1 */
3489ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f37),
3490ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R3QPI, 1),
3491ed367e6cSBorislav Petkov 	},
3492ed367e6cSBorislav Petkov 	{ /* R3QPI1 Link 2 */
3493ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f3e),
3494ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R3QPI, 2),
3495ed367e6cSBorislav Petkov 	},
3496ed367e6cSBorislav Petkov 	{ /* QPI Port 0 filter  */
3497ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f86),
3498156c8b58SKan Liang 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
3499156c8b58SKan Liang 						   SNBEP_PCI_QPI_PORT0_FILTER),
3500ed367e6cSBorislav Petkov 	},
3501ed367e6cSBorislav Petkov 	{ /* QPI Port 1 filter  */
3502ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f96),
3503156c8b58SKan Liang 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
3504156c8b58SKan Liang 						   SNBEP_PCI_QPI_PORT1_FILTER),
3505ed367e6cSBorislav Petkov 	},
3506ed367e6cSBorislav Petkov 	{ /* QPI Port 2 filter  */
3507ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f46),
3508156c8b58SKan Liang 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
3509156c8b58SKan Liang 						   BDX_PCI_QPI_PORT2_FILTER),
3510ed367e6cSBorislav Petkov 	},
3511ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ }
3512ed367e6cSBorislav Petkov };
3513ed367e6cSBorislav Petkov 
3514ed367e6cSBorislav Petkov static struct pci_driver bdx_uncore_pci_driver = {
3515ed367e6cSBorislav Petkov 	.name		= "bdx_uncore",
3516ed367e6cSBorislav Petkov 	.id_table	= bdx_uncore_pci_ids,
3517ed367e6cSBorislav Petkov };
3518ed367e6cSBorislav Petkov 
3519ed367e6cSBorislav Petkov int bdx_uncore_pci_init(void)
3520ed367e6cSBorislav Petkov {
352168ce4a0dSKan Liang 	int ret = snbep_pci2phy_map_init(0x6f1e, SNBEP_CPUNODEID, SNBEP_GIDNIDMAP, true);
3522ed367e6cSBorislav Petkov 
3523ed367e6cSBorislav Petkov 	if (ret)
3524ed367e6cSBorislav Petkov 		return ret;
3525ed367e6cSBorislav Petkov 	uncore_pci_uncores = bdx_pci_uncores;
3526ed367e6cSBorislav Petkov 	uncore_pci_driver = &bdx_uncore_pci_driver;
3527ed367e6cSBorislav Petkov 	return 0;
3528ed367e6cSBorislav Petkov }
3529ed367e6cSBorislav Petkov 
3530ed367e6cSBorislav Petkov /* end of BDX uncore support */
3531cd34cd97SKan Liang 
3532cd34cd97SKan Liang /* SKX uncore support */
3533cd34cd97SKan Liang 
3534cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_ubox = {
3535cd34cd97SKan Liang 	.name			= "ubox",
3536cd34cd97SKan Liang 	.num_counters		= 2,
3537cd34cd97SKan Liang 	.num_boxes		= 1,
3538cd34cd97SKan Liang 	.perf_ctr_bits		= 48,
3539cd34cd97SKan Liang 	.fixed_ctr_bits		= 48,
3540cd34cd97SKan Liang 	.perf_ctr		= HSWEP_U_MSR_PMON_CTR0,
3541cd34cd97SKan Liang 	.event_ctl		= HSWEP_U_MSR_PMON_CTL0,
3542cd34cd97SKan Liang 	.event_mask		= SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
3543cd34cd97SKan Liang 	.fixed_ctr		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
3544cd34cd97SKan Liang 	.fixed_ctl		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
3545cd34cd97SKan Liang 	.ops			= &ivbep_uncore_msr_ops,
3546cd34cd97SKan Liang 	.format_group		= &ivbep_uncore_ubox_format_group,
3547cd34cd97SKan Liang };
3548cd34cd97SKan Liang 
3549cd34cd97SKan Liang static struct attribute *skx_uncore_cha_formats_attr[] = {
3550cd34cd97SKan Liang 	&format_attr_event.attr,
3551cd34cd97SKan Liang 	&format_attr_umask.attr,
3552cd34cd97SKan Liang 	&format_attr_edge.attr,
3553cd34cd97SKan Liang 	&format_attr_tid_en.attr,
3554cd34cd97SKan Liang 	&format_attr_inv.attr,
3555cd34cd97SKan Liang 	&format_attr_thresh8.attr,
3556cd34cd97SKan Liang 	&format_attr_filter_tid4.attr,
3557cd34cd97SKan Liang 	&format_attr_filter_state5.attr,
3558cd34cd97SKan Liang 	&format_attr_filter_rem.attr,
3559cd34cd97SKan Liang 	&format_attr_filter_loc.attr,
3560cd34cd97SKan Liang 	&format_attr_filter_nm.attr,
3561cd34cd97SKan Liang 	&format_attr_filter_all_op.attr,
3562cd34cd97SKan Liang 	&format_attr_filter_not_nm.attr,
3563cd34cd97SKan Liang 	&format_attr_filter_opc_0.attr,
3564cd34cd97SKan Liang 	&format_attr_filter_opc_1.attr,
3565cd34cd97SKan Liang 	&format_attr_filter_nc.attr,
3566cd34cd97SKan Liang 	&format_attr_filter_isoc.attr,
3567cd34cd97SKan Liang 	NULL,
3568cd34cd97SKan Liang };
3569cd34cd97SKan Liang 
357045bd07adSArvind Yadav static const struct attribute_group skx_uncore_chabox_format_group = {
3571cd34cd97SKan Liang 	.name = "format",
3572cd34cd97SKan Liang 	.attrs = skx_uncore_cha_formats_attr,
3573cd34cd97SKan Liang };
3574cd34cd97SKan Liang 
3575cd34cd97SKan Liang static struct event_constraint skx_uncore_chabox_constraints[] = {
3576cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
3577cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
3578cd34cd97SKan Liang 	EVENT_CONSTRAINT_END
3579cd34cd97SKan Liang };
3580cd34cd97SKan Liang 
3581cd34cd97SKan Liang static struct extra_reg skx_uncore_cha_extra_regs[] = {
3582cd34cd97SKan Liang 	SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
3583cd34cd97SKan Liang 	SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
3584cd34cd97SKan Liang 	SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
3585cd34cd97SKan Liang 	SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4),
3586c3f02682SKan Liang 	SNBEP_CBO_EVENT_EXTRA_REG(0x3134, 0xffff, 0x4),
3587c3f02682SKan Liang 	SNBEP_CBO_EVENT_EXTRA_REG(0x9134, 0xffff, 0x4),
35888aa7b7b4SStephane Eranian 	SNBEP_CBO_EVENT_EXTRA_REG(0x35, 0xff, 0x8),
35898aa7b7b4SStephane Eranian 	SNBEP_CBO_EVENT_EXTRA_REG(0x36, 0xff, 0x8),
3590e340895cSStephane Eranian 	SNBEP_CBO_EVENT_EXTRA_REG(0x38, 0xff, 0x3),
3591ba883b4aSStephane Eranian 	EVENT_EXTRA_END
3592cd34cd97SKan Liang };
3593cd34cd97SKan Liang 
3594cd34cd97SKan Liang static u64 skx_cha_filter_mask(int fields)
3595cd34cd97SKan Liang {
3596cd34cd97SKan Liang 	u64 mask = 0;
3597cd34cd97SKan Liang 
3598cd34cd97SKan Liang 	if (fields & 0x1)
3599cd34cd97SKan Liang 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_TID;
3600cd34cd97SKan Liang 	if (fields & 0x2)
3601cd34cd97SKan Liang 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_LINK;
3602cd34cd97SKan Liang 	if (fields & 0x4)
3603cd34cd97SKan Liang 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_STATE;
36048aa7b7b4SStephane Eranian 	if (fields & 0x8) {
36058aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_REM;
36068aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_LOC;
36078aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_ALL_OPC;
36088aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_NM;
36098aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_NOT_NM;
36108aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_OPC0;
36118aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_OPC1;
36128aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_NC;
36138aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_ISOC;
36148aa7b7b4SStephane Eranian 	}
3615cd34cd97SKan Liang 	return mask;
3616cd34cd97SKan Liang }
3617cd34cd97SKan Liang 
3618cd34cd97SKan Liang static struct event_constraint *
3619cd34cd97SKan Liang skx_cha_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
3620cd34cd97SKan Liang {
3621cd34cd97SKan Liang 	return __snbep_cbox_get_constraint(box, event, skx_cha_filter_mask);
3622cd34cd97SKan Liang }
3623cd34cd97SKan Liang 
3624cd34cd97SKan Liang static int skx_cha_hw_config(struct intel_uncore_box *box, struct perf_event *event)
3625cd34cd97SKan Liang {
3626cd34cd97SKan Liang 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
3627cd34cd97SKan Liang 	struct extra_reg *er;
3628cd34cd97SKan Liang 	int idx = 0;
3629e324234eSAlexander Antonov 	/* Any of the CHA events may be filtered by Thread/Core-ID.*/
3630e324234eSAlexander Antonov 	if (event->hw.config & SNBEP_CBO_PMON_CTL_TID_EN)
3631e324234eSAlexander Antonov 		idx = SKX_CHA_MSR_PMON_BOX_FILTER_TID;
3632cd34cd97SKan Liang 
3633cd34cd97SKan Liang 	for (er = skx_uncore_cha_extra_regs; er->msr; er++) {
3634cd34cd97SKan Liang 		if (er->event != (event->hw.config & er->config_mask))
3635cd34cd97SKan Liang 			continue;
3636cd34cd97SKan Liang 		idx |= er->idx;
3637cd34cd97SKan Liang 	}
3638cd34cd97SKan Liang 
3639cd34cd97SKan Liang 	if (idx) {
3640cd34cd97SKan Liang 		reg1->reg = HSWEP_C0_MSR_PMON_BOX_FILTER0 +
3641cd34cd97SKan Liang 			    HSWEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
3642cd34cd97SKan Liang 		reg1->config = event->attr.config1 & skx_cha_filter_mask(idx);
3643cd34cd97SKan Liang 		reg1->idx = idx;
3644cd34cd97SKan Liang 	}
3645cd34cd97SKan Liang 	return 0;
3646cd34cd97SKan Liang }
3647cd34cd97SKan Liang 
3648cd34cd97SKan Liang static struct intel_uncore_ops skx_uncore_chabox_ops = {
3649cd34cd97SKan Liang 	/* There is no frz_en for chabox ctl */
3650cd34cd97SKan Liang 	.init_box		= ivbep_uncore_msr_init_box,
3651cd34cd97SKan Liang 	.disable_box		= snbep_uncore_msr_disable_box,
3652cd34cd97SKan Liang 	.enable_box		= snbep_uncore_msr_enable_box,
3653cd34cd97SKan Liang 	.disable_event		= snbep_uncore_msr_disable_event,
3654cd34cd97SKan Liang 	.enable_event		= hswep_cbox_enable_event,
3655cd34cd97SKan Liang 	.read_counter		= uncore_msr_read_counter,
3656cd34cd97SKan Liang 	.hw_config		= skx_cha_hw_config,
3657cd34cd97SKan Liang 	.get_constraint		= skx_cha_get_constraint,
3658cd34cd97SKan Liang 	.put_constraint		= snbep_cbox_put_constraint,
3659cd34cd97SKan Liang };
3660cd34cd97SKan Liang 
3661cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_chabox = {
3662cd34cd97SKan Liang 	.name			= "cha",
3663cd34cd97SKan Liang 	.num_counters		= 4,
3664cd34cd97SKan Liang 	.perf_ctr_bits		= 48,
3665cd34cd97SKan Liang 	.event_ctl		= HSWEP_C0_MSR_PMON_CTL0,
3666cd34cd97SKan Liang 	.perf_ctr		= HSWEP_C0_MSR_PMON_CTR0,
3667cd34cd97SKan Liang 	.event_mask		= HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
3668cd34cd97SKan Liang 	.box_ctl		= HSWEP_C0_MSR_PMON_BOX_CTL,
3669cd34cd97SKan Liang 	.msr_offset		= HSWEP_CBO_MSR_OFFSET,
3670cd34cd97SKan Liang 	.num_shared_regs	= 1,
3671cd34cd97SKan Liang 	.constraints		= skx_uncore_chabox_constraints,
3672cd34cd97SKan Liang 	.ops			= &skx_uncore_chabox_ops,
3673cd34cd97SKan Liang 	.format_group		= &skx_uncore_chabox_format_group,
3674cd34cd97SKan Liang };
3675cd34cd97SKan Liang 
3676cd34cd97SKan Liang static struct attribute *skx_uncore_iio_formats_attr[] = {
3677cd34cd97SKan Liang 	&format_attr_event.attr,
3678cd34cd97SKan Liang 	&format_attr_umask.attr,
3679cd34cd97SKan Liang 	&format_attr_edge.attr,
3680cd34cd97SKan Liang 	&format_attr_inv.attr,
3681cd34cd97SKan Liang 	&format_attr_thresh9.attr,
3682cd34cd97SKan Liang 	&format_attr_ch_mask.attr,
3683cd34cd97SKan Liang 	&format_attr_fc_mask.attr,
3684cd34cd97SKan Liang 	NULL,
3685cd34cd97SKan Liang };
3686cd34cd97SKan Liang 
368745bd07adSArvind Yadav static const struct attribute_group skx_uncore_iio_format_group = {
3688cd34cd97SKan Liang 	.name = "format",
3689cd34cd97SKan Liang 	.attrs = skx_uncore_iio_formats_attr,
3690cd34cd97SKan Liang };
3691cd34cd97SKan Liang 
3692cd34cd97SKan Liang static struct event_constraint skx_uncore_iio_constraints[] = {
3693cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x83, 0x3),
3694cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x88, 0xc),
3695cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x95, 0xc),
3696cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0xc0, 0xc),
3697cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0xc5, 0xc),
3698cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0xd4, 0xc),
36993866ae31SAlexander Antonov 	UNCORE_EVENT_CONSTRAINT(0xd5, 0xc),
3700cd34cd97SKan Liang 	EVENT_CONSTRAINT_END
3701cd34cd97SKan Liang };
3702cd34cd97SKan Liang 
3703cd34cd97SKan Liang static void skx_iio_enable_event(struct intel_uncore_box *box,
3704cd34cd97SKan Liang 				 struct perf_event *event)
3705cd34cd97SKan Liang {
3706cd34cd97SKan Liang 	struct hw_perf_event *hwc = &event->hw;
3707cd34cd97SKan Liang 
3708cd34cd97SKan Liang 	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
3709cd34cd97SKan Liang }
3710cd34cd97SKan Liang 
3711cd34cd97SKan Liang static struct intel_uncore_ops skx_uncore_iio_ops = {
3712cd34cd97SKan Liang 	.init_box		= ivbep_uncore_msr_init_box,
3713cd34cd97SKan Liang 	.disable_box		= snbep_uncore_msr_disable_box,
3714cd34cd97SKan Liang 	.enable_box		= snbep_uncore_msr_enable_box,
3715cd34cd97SKan Liang 	.disable_event		= snbep_uncore_msr_disable_event,
3716cd34cd97SKan Liang 	.enable_event		= skx_iio_enable_event,
3717cd34cd97SKan Liang 	.read_counter		= uncore_msr_read_counter,
3718cd34cd97SKan Liang };
3719cd34cd97SKan Liang 
37204d13be8aSAlexander Antonov static struct intel_uncore_topology *pmu_topology(struct intel_uncore_pmu *pmu, int die)
3721bb42b3d3SRoman Sudarikov {
37224d13be8aSAlexander Antonov 	int idx;
37234d13be8aSAlexander Antonov 
37244d13be8aSAlexander Antonov 	for (idx = 0; idx < pmu->type->num_boxes; idx++) {
37254d13be8aSAlexander Antonov 		if (pmu->type->topology[die][idx].pmu_idx == pmu->pmu_idx)
37264d13be8aSAlexander Antonov 			return &pmu->type->topology[die][idx];
37274d13be8aSAlexander Antonov 	}
37284d13be8aSAlexander Antonov 
37294d13be8aSAlexander Antonov 	return NULL;
3730bb42b3d3SRoman Sudarikov }
3731bb42b3d3SRoman Sudarikov 
3732bb42b3d3SRoman Sudarikov static umode_t
3733f471fac7SAlexander Antonov pmu_iio_mapping_visible(struct kobject *kobj, struct attribute *attr,
3734f471fac7SAlexander Antonov 			 int die, int zero_bus_pmu)
3735bb42b3d3SRoman Sudarikov {
3736bb42b3d3SRoman Sudarikov 	struct intel_uncore_pmu *pmu = dev_to_uncore_pmu(kobj_to_dev(kobj));
37374d13be8aSAlexander Antonov 	struct intel_uncore_topology *pmut = pmu_topology(pmu, die);
3738bb42b3d3SRoman Sudarikov 
37394d13be8aSAlexander Antonov 	return (pmut && !pmut->iio->pci_bus_no && pmu->pmu_idx != zero_bus_pmu) ? 0 : attr->mode;
3740f471fac7SAlexander Antonov }
3741f471fac7SAlexander Antonov 
3742f471fac7SAlexander Antonov static umode_t
3743f471fac7SAlexander Antonov skx_iio_mapping_visible(struct kobject *kobj, struct attribute *attr, int die)
3744f471fac7SAlexander Antonov {
3745f471fac7SAlexander Antonov 	/* Root bus 0x00 is valid only for pmu_idx = 0. */
3746f471fac7SAlexander Antonov 	return pmu_iio_mapping_visible(kobj, attr, die, 0);
3747bb42b3d3SRoman Sudarikov }
3748bb42b3d3SRoman Sudarikov 
3749bb42b3d3SRoman Sudarikov static ssize_t skx_iio_mapping_show(struct device *dev,
3750bb42b3d3SRoman Sudarikov 				    struct device_attribute *attr, char *buf)
3751bb42b3d3SRoman Sudarikov {
3752cface032SAlexander Antonov 	struct intel_uncore_pmu *pmu = dev_to_uncore_pmu(dev);
3753bb42b3d3SRoman Sudarikov 	struct dev_ext_attribute *ea = to_dev_ext_attribute(attr);
3754bb42b3d3SRoman Sudarikov 	long die = (long)ea->var;
37554d13be8aSAlexander Antonov 	struct intel_uncore_topology *pmut = pmu_topology(pmu, die);
3756bb42b3d3SRoman Sudarikov 
37574d13be8aSAlexander Antonov 	return sprintf(buf, "%04x:%02x\n", pmut ? pmut->iio->segment : 0,
37584d13be8aSAlexander Antonov 					   pmut ? pmut->iio->pci_bus_no : 0);
3759bb42b3d3SRoman Sudarikov }
3760bb42b3d3SRoman Sudarikov 
3761bb42b3d3SRoman Sudarikov static int skx_msr_cpu_bus_read(int cpu, u64 *topology)
3762bb42b3d3SRoman Sudarikov {
3763bb42b3d3SRoman Sudarikov 	u64 msr_value;
3764bb42b3d3SRoman Sudarikov 
3765bb42b3d3SRoman Sudarikov 	if (rdmsrl_on_cpu(cpu, SKX_MSR_CPU_BUS_NUMBER, &msr_value) ||
3766bb42b3d3SRoman Sudarikov 			!(msr_value & SKX_MSR_CPU_BUS_VALID_BIT))
3767bb42b3d3SRoman Sudarikov 		return -ENXIO;
3768bb42b3d3SRoman Sudarikov 
3769bb42b3d3SRoman Sudarikov 	*topology = msr_value;
3770bb42b3d3SRoman Sudarikov 
3771bb42b3d3SRoman Sudarikov 	return 0;
3772bb42b3d3SRoman Sudarikov }
3773bb42b3d3SRoman Sudarikov 
3774bb42b3d3SRoman Sudarikov static int die_to_cpu(int die)
3775bb42b3d3SRoman Sudarikov {
3776bb42b3d3SRoman Sudarikov 	int res = 0, cpu, current_die;
3777bb42b3d3SRoman Sudarikov 	/*
3778bb42b3d3SRoman Sudarikov 	 * Using cpus_read_lock() to ensure cpu is not going down between
3779bb42b3d3SRoman Sudarikov 	 * looking at cpu_online_mask.
3780bb42b3d3SRoman Sudarikov 	 */
3781bb42b3d3SRoman Sudarikov 	cpus_read_lock();
3782bb42b3d3SRoman Sudarikov 	for_each_online_cpu(cpu) {
3783bb42b3d3SRoman Sudarikov 		current_die = topology_logical_die_id(cpu);
3784bb42b3d3SRoman Sudarikov 		if (current_die == die) {
3785bb42b3d3SRoman Sudarikov 			res = cpu;
3786bb42b3d3SRoman Sudarikov 			break;
3787bb42b3d3SRoman Sudarikov 		}
3788bb42b3d3SRoman Sudarikov 	}
3789bb42b3d3SRoman Sudarikov 	cpus_read_unlock();
3790bb42b3d3SRoman Sudarikov 	return res;
3791bb42b3d3SRoman Sudarikov }
3792bb42b3d3SRoman Sudarikov 
37934d13be8aSAlexander Antonov enum {
37944d13be8aSAlexander Antonov 	IIO_TOPOLOGY_TYPE,
3795cee4eebdSAlexander Antonov 	UPI_TOPOLOGY_TYPE,
37964d13be8aSAlexander Antonov 	TOPOLOGY_MAX
37974d13be8aSAlexander Antonov };
37984d13be8aSAlexander Antonov 
37994d13be8aSAlexander Antonov static const size_t topology_size[TOPOLOGY_MAX] = {
3800cee4eebdSAlexander Antonov 	sizeof(*((struct intel_uncore_topology *)NULL)->iio),
3801cee4eebdSAlexander Antonov 	sizeof(*((struct intel_uncore_topology *)NULL)->upi)
38024d13be8aSAlexander Antonov };
38034d13be8aSAlexander Antonov 
38044d13be8aSAlexander Antonov static int pmu_alloc_topology(struct intel_uncore_type *type, int topology_type)
38054d13be8aSAlexander Antonov {
38064d13be8aSAlexander Antonov 	int die, idx;
38074d13be8aSAlexander Antonov 	struct intel_uncore_topology **topology;
38084d13be8aSAlexander Antonov 
38094d13be8aSAlexander Antonov 	if (!type->num_boxes)
38104d13be8aSAlexander Antonov 		return -EPERM;
38114d13be8aSAlexander Antonov 
38124d13be8aSAlexander Antonov 	topology = kcalloc(uncore_max_dies(), sizeof(*topology), GFP_KERNEL);
38134d13be8aSAlexander Antonov 	if (!topology)
38144d13be8aSAlexander Antonov 		goto err;
38154d13be8aSAlexander Antonov 
38164d13be8aSAlexander Antonov 	for (die = 0; die < uncore_max_dies(); die++) {
38174d13be8aSAlexander Antonov 		topology[die] = kcalloc(type->num_boxes, sizeof(**topology), GFP_KERNEL);
38184d13be8aSAlexander Antonov 		if (!topology[die])
38194d13be8aSAlexander Antonov 			goto clear;
38204d13be8aSAlexander Antonov 		for (idx = 0; idx < type->num_boxes; idx++) {
38214d13be8aSAlexander Antonov 			topology[die][idx].untyped = kcalloc(type->num_boxes,
38224d13be8aSAlexander Antonov 							     topology_size[topology_type],
38234d13be8aSAlexander Antonov 							     GFP_KERNEL);
38244d13be8aSAlexander Antonov 			if (!topology[die][idx].untyped)
38254d13be8aSAlexander Antonov 				goto clear;
38264d13be8aSAlexander Antonov 		}
38274d13be8aSAlexander Antonov 	}
38284d13be8aSAlexander Antonov 
38294d13be8aSAlexander Antonov 	type->topology = topology;
38304d13be8aSAlexander Antonov 
38314d13be8aSAlexander Antonov 	return 0;
38324d13be8aSAlexander Antonov clear:
38334d13be8aSAlexander Antonov 	for (; die >= 0; die--) {
38344d13be8aSAlexander Antonov 		for (idx = 0; idx < type->num_boxes; idx++)
38354d13be8aSAlexander Antonov 			kfree(topology[die][idx].untyped);
38364d13be8aSAlexander Antonov 		kfree(topology[die]);
38374d13be8aSAlexander Antonov 	}
38384d13be8aSAlexander Antonov 	kfree(topology);
38394d13be8aSAlexander Antonov err:
38404d13be8aSAlexander Antonov 	return -ENOMEM;
38414d13be8aSAlexander Antonov }
38424d13be8aSAlexander Antonov 
38434d13be8aSAlexander Antonov static void pmu_free_topology(struct intel_uncore_type *type)
38444d13be8aSAlexander Antonov {
38454d13be8aSAlexander Antonov 	int die, idx;
38464d13be8aSAlexander Antonov 
38474d13be8aSAlexander Antonov 	if (type->topology) {
38484d13be8aSAlexander Antonov 		for (die = 0; die < uncore_max_dies(); die++) {
38494d13be8aSAlexander Antonov 			for (idx = 0; idx < type->num_boxes; idx++)
38504d13be8aSAlexander Antonov 				kfree(type->topology[die][idx].untyped);
38514d13be8aSAlexander Antonov 			kfree(type->topology[die]);
38524d13be8aSAlexander Antonov 		}
38534d13be8aSAlexander Antonov 		kfree(type->topology);
38544d13be8aSAlexander Antonov 		type->topology = NULL;
38554d13be8aSAlexander Antonov 	}
38564d13be8aSAlexander Antonov }
38574d13be8aSAlexander Antonov 
385807813e2aSAlexander Antonov static int skx_pmu_get_topology(struct intel_uncore_type *type,
385907813e2aSAlexander Antonov 				 int (*topology_cb)(struct intel_uncore_type*, int, int, u64))
3860bb42b3d3SRoman Sudarikov {
3861cface032SAlexander Antonov 	int die, ret = -EPERM;
386207813e2aSAlexander Antonov 	u64 cpu_bus_msr;
3863bb42b3d3SRoman Sudarikov 
3864cface032SAlexander Antonov 	for (die = 0; die < uncore_max_dies(); die++) {
386507813e2aSAlexander Antonov 		ret = skx_msr_cpu_bus_read(die_to_cpu(die), &cpu_bus_msr);
3866cface032SAlexander Antonov 		if (ret)
3867cface032SAlexander Antonov 			break;
3868cface032SAlexander Antonov 
3869cface032SAlexander Antonov 		ret = uncore_die_to_segment(die);
3870cface032SAlexander Antonov 		if (ret < 0)
3871cface032SAlexander Antonov 			break;
3872cface032SAlexander Antonov 
387307813e2aSAlexander Antonov 		ret = topology_cb(type, ret, die, cpu_bus_msr);
387407813e2aSAlexander Antonov 		if (ret)
387507813e2aSAlexander Antonov 			break;
3876cface032SAlexander Antonov 	}
3877cface032SAlexander Antonov 
3878cface032SAlexander Antonov 	return ret;
3879bb42b3d3SRoman Sudarikov }
3880bb42b3d3SRoman Sudarikov 
388107813e2aSAlexander Antonov static int skx_iio_topology_cb(struct intel_uncore_type *type, int segment,
388207813e2aSAlexander Antonov 				int die, u64 cpu_bus_msr)
388307813e2aSAlexander Antonov {
388407813e2aSAlexander Antonov 	int idx;
388507813e2aSAlexander Antonov 	struct intel_uncore_topology *t;
388607813e2aSAlexander Antonov 
388707813e2aSAlexander Antonov 	for (idx = 0; idx < type->num_boxes; idx++) {
388807813e2aSAlexander Antonov 		t = &type->topology[die][idx];
388907813e2aSAlexander Antonov 		t->pmu_idx = idx;
389007813e2aSAlexander Antonov 		t->iio->segment = segment;
389107813e2aSAlexander Antonov 		t->iio->pci_bus_no = (cpu_bus_msr >> (idx * BUS_NUM_STRIDE)) & 0xff;
389207813e2aSAlexander Antonov 	}
389307813e2aSAlexander Antonov 
389407813e2aSAlexander Antonov 	return 0;
389507813e2aSAlexander Antonov }
389607813e2aSAlexander Antonov 
389707813e2aSAlexander Antonov static int skx_iio_get_topology(struct intel_uncore_type *type)
389807813e2aSAlexander Antonov {
389907813e2aSAlexander Antonov 	return skx_pmu_get_topology(type, skx_iio_topology_cb);
390007813e2aSAlexander Antonov }
390107813e2aSAlexander Antonov 
3902bb42b3d3SRoman Sudarikov static struct attribute_group skx_iio_mapping_group = {
3903bb42b3d3SRoman Sudarikov 	.is_visible	= skx_iio_mapping_visible,
3904bb42b3d3SRoman Sudarikov };
3905bb42b3d3SRoman Sudarikov 
3906bb42b3d3SRoman Sudarikov static const struct attribute_group *skx_iio_attr_update[] = {
3907bb42b3d3SRoman Sudarikov 	&skx_iio_mapping_group,
3908bb42b3d3SRoman Sudarikov 	NULL,
3909bb42b3d3SRoman Sudarikov };
3910bb42b3d3SRoman Sudarikov 
391165327833SAlexander Antonov static void pmu_clear_mapping_attr(const struct attribute_group **groups,
391265327833SAlexander Antonov 				   struct attribute_group *ag)
391365327833SAlexander Antonov {
391465327833SAlexander Antonov 	int i;
391565327833SAlexander Antonov 
391665327833SAlexander Antonov 	for (i = 0; groups[i]; i++) {
391765327833SAlexander Antonov 		if (groups[i] == ag) {
391865327833SAlexander Antonov 			for (i++; groups[i]; i++)
391965327833SAlexander Antonov 				groups[i - 1] = groups[i];
392065327833SAlexander Antonov 			groups[i - 1] = NULL;
392165327833SAlexander Antonov 			break;
392265327833SAlexander Antonov 		}
392365327833SAlexander Antonov 	}
392465327833SAlexander Antonov }
392565327833SAlexander Antonov 
3926f471fac7SAlexander Antonov static int
39274d13be8aSAlexander Antonov pmu_set_mapping(struct intel_uncore_type *type, struct attribute_group *ag,
39284d13be8aSAlexander Antonov 		ssize_t (*show)(struct device*, struct device_attribute*, char*),
39294d13be8aSAlexander Antonov 		int topology_type)
3930bb42b3d3SRoman Sudarikov {
3931bb42b3d3SRoman Sudarikov 	char buf[64];
3932bb42b3d3SRoman Sudarikov 	int ret;
3933bb42b3d3SRoman Sudarikov 	long die = -1;
3934bb42b3d3SRoman Sudarikov 	struct attribute **attrs = NULL;
3935bb42b3d3SRoman Sudarikov 	struct dev_ext_attribute *eas = NULL;
3936bb42b3d3SRoman Sudarikov 
39374d13be8aSAlexander Antonov 	ret = pmu_alloc_topology(type, topology_type);
3938cface032SAlexander Antonov 	if (ret < 0)
3939f797f05dSAlexander Antonov 		goto clear_attr_update;
3940f797f05dSAlexander Antonov 
39414d13be8aSAlexander Antonov 	ret = type->get_topology(type);
39424d13be8aSAlexander Antonov 	if (ret < 0)
39434d13be8aSAlexander Antonov 		goto clear_topology;
39444d13be8aSAlexander Antonov 
3945f797f05dSAlexander Antonov 	ret = -ENOMEM;
3946bb42b3d3SRoman Sudarikov 
3947bb42b3d3SRoman Sudarikov 	/* One more for NULL. */
3948bb42b3d3SRoman Sudarikov 	attrs = kcalloc((uncore_max_dies() + 1), sizeof(*attrs), GFP_KERNEL);
3949bb42b3d3SRoman Sudarikov 	if (!attrs)
3950d4ba0b06SKan Liang 		goto clear_topology;
3951bb42b3d3SRoman Sudarikov 
3952bb42b3d3SRoman Sudarikov 	eas = kcalloc(uncore_max_dies(), sizeof(*eas), GFP_KERNEL);
3953bb42b3d3SRoman Sudarikov 	if (!eas)
3954d4ba0b06SKan Liang 		goto clear_attrs;
3955bb42b3d3SRoman Sudarikov 
3956bb42b3d3SRoman Sudarikov 	for (die = 0; die < uncore_max_dies(); die++) {
39574d13be8aSAlexander Antonov 		snprintf(buf, sizeof(buf), "die%ld", die);
3958bb42b3d3SRoman Sudarikov 		sysfs_attr_init(&eas[die].attr.attr);
3959bb42b3d3SRoman Sudarikov 		eas[die].attr.attr.name = kstrdup(buf, GFP_KERNEL);
3960bb42b3d3SRoman Sudarikov 		if (!eas[die].attr.attr.name)
3961bb42b3d3SRoman Sudarikov 			goto err;
3962bb42b3d3SRoman Sudarikov 		eas[die].attr.attr.mode = 0444;
39634d13be8aSAlexander Antonov 		eas[die].attr.show = show;
3964bb42b3d3SRoman Sudarikov 		eas[die].attr.store = NULL;
3965bb42b3d3SRoman Sudarikov 		eas[die].var = (void *)die;
3966bb42b3d3SRoman Sudarikov 		attrs[die] = &eas[die].attr.attr;
3967bb42b3d3SRoman Sudarikov 	}
3968f471fac7SAlexander Antonov 	ag->attrs = attrs;
3969bb42b3d3SRoman Sudarikov 
3970bb42b3d3SRoman Sudarikov 	return 0;
3971bb42b3d3SRoman Sudarikov err:
3972bb42b3d3SRoman Sudarikov 	for (; die >= 0; die--)
3973bb42b3d3SRoman Sudarikov 		kfree(eas[die].attr.attr.name);
3974bb42b3d3SRoman Sudarikov 	kfree(eas);
3975d4ba0b06SKan Liang clear_attrs:
3976bb42b3d3SRoman Sudarikov 	kfree(attrs);
3977d4ba0b06SKan Liang clear_topology:
39784d13be8aSAlexander Antonov 	pmu_free_topology(type);
3979f797f05dSAlexander Antonov clear_attr_update:
398065327833SAlexander Antonov 	pmu_clear_mapping_attr(type->attr_update, ag);
3981f797f05dSAlexander Antonov 	return ret;
3982bb42b3d3SRoman Sudarikov }
3983bb42b3d3SRoman Sudarikov 
39843f2cbe38SAlexander Antonov static void
39854d13be8aSAlexander Antonov pmu_cleanup_mapping(struct intel_uncore_type *type, struct attribute_group *ag)
39863f2cbe38SAlexander Antonov {
39873f2cbe38SAlexander Antonov 	struct attribute **attr = ag->attrs;
39883f2cbe38SAlexander Antonov 
39893f2cbe38SAlexander Antonov 	if (!attr)
39903f2cbe38SAlexander Antonov 		return;
39913f2cbe38SAlexander Antonov 
39923f2cbe38SAlexander Antonov 	for (; *attr; attr++)
39933f2cbe38SAlexander Antonov 		kfree((*attr)->name);
39943f2cbe38SAlexander Antonov 	kfree(attr_to_ext_attr(*ag->attrs));
39953f2cbe38SAlexander Antonov 	kfree(ag->attrs);
39963f2cbe38SAlexander Antonov 	ag->attrs = NULL;
39974d13be8aSAlexander Antonov 	pmu_free_topology(type);
39984d13be8aSAlexander Antonov }
39994d13be8aSAlexander Antonov 
40004d13be8aSAlexander Antonov static int
40014d13be8aSAlexander Antonov pmu_iio_set_mapping(struct intel_uncore_type *type, struct attribute_group *ag)
40024d13be8aSAlexander Antonov {
40034d13be8aSAlexander Antonov 	return pmu_set_mapping(type, ag, skx_iio_mapping_show, IIO_TOPOLOGY_TYPE);
40043f2cbe38SAlexander Antonov }
40053f2cbe38SAlexander Antonov 
4006f471fac7SAlexander Antonov static int skx_iio_set_mapping(struct intel_uncore_type *type)
4007f471fac7SAlexander Antonov {
4008f471fac7SAlexander Antonov 	return pmu_iio_set_mapping(type, &skx_iio_mapping_group);
4009f471fac7SAlexander Antonov }
4010f471fac7SAlexander Antonov 
4011bb42b3d3SRoman Sudarikov static void skx_iio_cleanup_mapping(struct intel_uncore_type *type)
4012bb42b3d3SRoman Sudarikov {
40134d13be8aSAlexander Antonov 	pmu_cleanup_mapping(type, &skx_iio_mapping_group);
4014bb42b3d3SRoman Sudarikov }
4015bb42b3d3SRoman Sudarikov 
4016cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_iio = {
4017cd34cd97SKan Liang 	.name			= "iio",
4018cd34cd97SKan Liang 	.num_counters		= 4,
401929b46dfbSKan Liang 	.num_boxes		= 6,
4020cd34cd97SKan Liang 	.perf_ctr_bits		= 48,
4021cd34cd97SKan Liang 	.event_ctl		= SKX_IIO0_MSR_PMON_CTL0,
4022cd34cd97SKan Liang 	.perf_ctr		= SKX_IIO0_MSR_PMON_CTR0,
4023cd34cd97SKan Liang 	.event_mask		= SKX_IIO_PMON_RAW_EVENT_MASK,
4024cd34cd97SKan Liang 	.event_mask_ext		= SKX_IIO_PMON_RAW_EVENT_MASK_EXT,
4025cd34cd97SKan Liang 	.box_ctl		= SKX_IIO0_MSR_PMON_BOX_CTL,
4026cd34cd97SKan Liang 	.msr_offset		= SKX_IIO_MSR_OFFSET,
4027cd34cd97SKan Liang 	.constraints		= skx_uncore_iio_constraints,
4028cd34cd97SKan Liang 	.ops			= &skx_uncore_iio_ops,
4029cd34cd97SKan Liang 	.format_group		= &skx_uncore_iio_format_group,
4030bb42b3d3SRoman Sudarikov 	.attr_update		= skx_iio_attr_update,
4031f471fac7SAlexander Antonov 	.get_topology		= skx_iio_get_topology,
4032bb42b3d3SRoman Sudarikov 	.set_mapping		= skx_iio_set_mapping,
4033bb42b3d3SRoman Sudarikov 	.cleanup_mapping	= skx_iio_cleanup_mapping,
4034cd34cd97SKan Liang };
4035cd34cd97SKan Liang 
40360f519f03SKan Liang enum perf_uncore_iio_freerunning_type_id {
40370f519f03SKan Liang 	SKX_IIO_MSR_IOCLK			= 0,
40380f519f03SKan Liang 	SKX_IIO_MSR_BW				= 1,
40390f519f03SKan Liang 	SKX_IIO_MSR_UTIL			= 2,
40400f519f03SKan Liang 
40410f519f03SKan Liang 	SKX_IIO_FREERUNNING_TYPE_MAX,
40420f519f03SKan Liang };
40430f519f03SKan Liang 
40440f519f03SKan Liang 
40450f519f03SKan Liang static struct freerunning_counters skx_iio_freerunning[] = {
40460f519f03SKan Liang 	[SKX_IIO_MSR_IOCLK]	= { 0xa45, 0x1, 0x20, 1, 36 },
40470f519f03SKan Liang 	[SKX_IIO_MSR_BW]	= { 0xb00, 0x1, 0x10, 8, 36 },
40480f519f03SKan Liang 	[SKX_IIO_MSR_UTIL]	= { 0xb08, 0x1, 0x10, 8, 36 },
40490f519f03SKan Liang };
40500f519f03SKan Liang 
40510f519f03SKan Liang static struct uncore_event_desc skx_uncore_iio_freerunning_events[] = {
40520f519f03SKan Liang 	/* Free-Running IO CLOCKS Counter */
40530f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(ioclk,			"event=0xff,umask=0x10"),
40540f519f03SKan Liang 	/* Free-Running IIO BANDWIDTH Counters */
40550f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0,		"event=0xff,umask=0x20"),
40560f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale,	"3.814697266e-6"),
40570f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit,	"MiB"),
40580f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1,		"event=0xff,umask=0x21"),
40590f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale,	"3.814697266e-6"),
40600f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit,	"MiB"),
40610f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2,		"event=0xff,umask=0x22"),
40620f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale,	"3.814697266e-6"),
40630f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit,	"MiB"),
40640f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3,		"event=0xff,umask=0x23"),
40650f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale,	"3.814697266e-6"),
40660f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit,	"MiB"),
40670f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port0,		"event=0xff,umask=0x24"),
40680f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port0.scale,	"3.814697266e-6"),
40690f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port0.unit,	"MiB"),
40700f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port1,		"event=0xff,umask=0x25"),
40710f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port1.scale,	"3.814697266e-6"),
40720f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port1.unit,	"MiB"),
40730f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port2,		"event=0xff,umask=0x26"),
40740f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port2.scale,	"3.814697266e-6"),
40750f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port2.unit,	"MiB"),
40760f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port3,		"event=0xff,umask=0x27"),
40770f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port3.scale,	"3.814697266e-6"),
40780f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port3.unit,	"MiB"),
40790f519f03SKan Liang 	/* Free-running IIO UTILIZATION Counters */
40800f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_in_port0,		"event=0xff,umask=0x30"),
40810f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_out_port0,		"event=0xff,umask=0x31"),
40820f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_in_port1,		"event=0xff,umask=0x32"),
40830f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_out_port1,		"event=0xff,umask=0x33"),
40840f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_in_port2,		"event=0xff,umask=0x34"),
40850f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_out_port2,		"event=0xff,umask=0x35"),
40860f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_in_port3,		"event=0xff,umask=0x36"),
40870f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_out_port3,		"event=0xff,umask=0x37"),
40880f519f03SKan Liang 	{ /* end: all zeroes */ },
40890f519f03SKan Liang };
40900f519f03SKan Liang 
40910f519f03SKan Liang static struct intel_uncore_ops skx_uncore_iio_freerunning_ops = {
40920f519f03SKan Liang 	.read_counter		= uncore_msr_read_counter,
4093543ac280SKan Liang 	.hw_config		= uncore_freerunning_hw_config,
40940f519f03SKan Liang };
40950f519f03SKan Liang 
40960f519f03SKan Liang static struct attribute *skx_uncore_iio_freerunning_formats_attr[] = {
40970f519f03SKan Liang 	&format_attr_event.attr,
40980f519f03SKan Liang 	&format_attr_umask.attr,
40990f519f03SKan Liang 	NULL,
41000f519f03SKan Liang };
41010f519f03SKan Liang 
41020f519f03SKan Liang static const struct attribute_group skx_uncore_iio_freerunning_format_group = {
41030f519f03SKan Liang 	.name = "format",
41040f519f03SKan Liang 	.attrs = skx_uncore_iio_freerunning_formats_attr,
41050f519f03SKan Liang };
41060f519f03SKan Liang 
41070f519f03SKan Liang static struct intel_uncore_type skx_uncore_iio_free_running = {
41080f519f03SKan Liang 	.name			= "iio_free_running",
41090f519f03SKan Liang 	.num_counters		= 17,
41100f519f03SKan Liang 	.num_boxes		= 6,
41110f519f03SKan Liang 	.num_freerunning_types	= SKX_IIO_FREERUNNING_TYPE_MAX,
41120f519f03SKan Liang 	.freerunning		= skx_iio_freerunning,
41130f519f03SKan Liang 	.ops			= &skx_uncore_iio_freerunning_ops,
41140f519f03SKan Liang 	.event_descs		= skx_uncore_iio_freerunning_events,
41150f519f03SKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
41160f519f03SKan Liang };
41170f519f03SKan Liang 
4118cd34cd97SKan Liang static struct attribute *skx_uncore_formats_attr[] = {
4119cd34cd97SKan Liang 	&format_attr_event.attr,
4120cd34cd97SKan Liang 	&format_attr_umask.attr,
4121cd34cd97SKan Liang 	&format_attr_edge.attr,
4122cd34cd97SKan Liang 	&format_attr_inv.attr,
4123cd34cd97SKan Liang 	&format_attr_thresh8.attr,
4124cd34cd97SKan Liang 	NULL,
4125cd34cd97SKan Liang };
4126cd34cd97SKan Liang 
412745bd07adSArvind Yadav static const struct attribute_group skx_uncore_format_group = {
4128cd34cd97SKan Liang 	.name = "format",
4129cd34cd97SKan Liang 	.attrs = skx_uncore_formats_attr,
4130cd34cd97SKan Liang };
4131cd34cd97SKan Liang 
4132cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_irp = {
4133cd34cd97SKan Liang 	.name			= "irp",
4134cd34cd97SKan Liang 	.num_counters		= 2,
413529b46dfbSKan Liang 	.num_boxes		= 6,
4136cd34cd97SKan Liang 	.perf_ctr_bits		= 48,
4137cd34cd97SKan Liang 	.event_ctl		= SKX_IRP0_MSR_PMON_CTL0,
4138cd34cd97SKan Liang 	.perf_ctr		= SKX_IRP0_MSR_PMON_CTR0,
4139cd34cd97SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
4140cd34cd97SKan Liang 	.box_ctl		= SKX_IRP0_MSR_PMON_BOX_CTL,
4141cd34cd97SKan Liang 	.msr_offset		= SKX_IRP_MSR_OFFSET,
4142cd34cd97SKan Liang 	.ops			= &skx_uncore_iio_ops,
4143cd34cd97SKan Liang 	.format_group		= &skx_uncore_format_group,
4144cd34cd97SKan Liang };
4145cd34cd97SKan Liang 
4146bab4e569SKan Liang static struct attribute *skx_uncore_pcu_formats_attr[] = {
4147bab4e569SKan Liang 	&format_attr_event.attr,
4148bab4e569SKan Liang 	&format_attr_umask.attr,
4149bab4e569SKan Liang 	&format_attr_edge.attr,
4150bab4e569SKan Liang 	&format_attr_inv.attr,
4151bab4e569SKan Liang 	&format_attr_thresh8.attr,
4152bab4e569SKan Liang 	&format_attr_occ_invert.attr,
4153bab4e569SKan Liang 	&format_attr_occ_edge_det.attr,
4154bab4e569SKan Liang 	&format_attr_filter_band0.attr,
4155bab4e569SKan Liang 	&format_attr_filter_band1.attr,
4156bab4e569SKan Liang 	&format_attr_filter_band2.attr,
4157bab4e569SKan Liang 	&format_attr_filter_band3.attr,
4158bab4e569SKan Liang 	NULL,
4159bab4e569SKan Liang };
4160bab4e569SKan Liang 
4161bab4e569SKan Liang static struct attribute_group skx_uncore_pcu_format_group = {
4162bab4e569SKan Liang 	.name = "format",
4163bab4e569SKan Liang 	.attrs = skx_uncore_pcu_formats_attr,
4164bab4e569SKan Liang };
4165bab4e569SKan Liang 
4166cd34cd97SKan Liang static struct intel_uncore_ops skx_uncore_pcu_ops = {
4167cd34cd97SKan Liang 	IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
4168cd34cd97SKan Liang 	.hw_config		= hswep_pcu_hw_config,
4169cd34cd97SKan Liang 	.get_constraint		= snbep_pcu_get_constraint,
4170cd34cd97SKan Liang 	.put_constraint		= snbep_pcu_put_constraint,
4171cd34cd97SKan Liang };
4172cd34cd97SKan Liang 
4173cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_pcu = {
4174cd34cd97SKan Liang 	.name			= "pcu",
4175cd34cd97SKan Liang 	.num_counters		= 4,
4176cd34cd97SKan Liang 	.num_boxes		= 1,
4177cd34cd97SKan Liang 	.perf_ctr_bits		= 48,
4178cd34cd97SKan Liang 	.perf_ctr		= HSWEP_PCU_MSR_PMON_CTR0,
4179cd34cd97SKan Liang 	.event_ctl		= HSWEP_PCU_MSR_PMON_CTL0,
4180cd34cd97SKan Liang 	.event_mask		= SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
4181cd34cd97SKan Liang 	.box_ctl		= HSWEP_PCU_MSR_PMON_BOX_CTL,
4182cd34cd97SKan Liang 	.num_shared_regs	= 1,
4183cd34cd97SKan Liang 	.ops			= &skx_uncore_pcu_ops,
4184bab4e569SKan Liang 	.format_group		= &skx_uncore_pcu_format_group,
4185cd34cd97SKan Liang };
4186cd34cd97SKan Liang 
4187cd34cd97SKan Liang static struct intel_uncore_type *skx_msr_uncores[] = {
4188cd34cd97SKan Liang 	&skx_uncore_ubox,
4189cd34cd97SKan Liang 	&skx_uncore_chabox,
4190cd34cd97SKan Liang 	&skx_uncore_iio,
41910f519f03SKan Liang 	&skx_uncore_iio_free_running,
4192cd34cd97SKan Liang 	&skx_uncore_irp,
4193cd34cd97SKan Liang 	&skx_uncore_pcu,
4194cd34cd97SKan Liang 	NULL,
4195cd34cd97SKan Liang };
4196cd34cd97SKan Liang 
4197320b0651SKan Liang /*
4198320b0651SKan Liang  * To determine the number of CHAs, it should read bits 27:0 in the CAPID6
4199320b0651SKan Liang  * register which located at Device 30, Function 3, Offset 0x9C. PCI ID 0x2083.
4200320b0651SKan Liang  */
4201320b0651SKan Liang #define SKX_CAPID6		0x9c
4202320b0651SKan Liang #define SKX_CHA_BIT_MASK	GENMASK(27, 0)
4203320b0651SKan Liang 
4204cd34cd97SKan Liang static int skx_count_chabox(void)
4205cd34cd97SKan Liang {
4206320b0651SKan Liang 	struct pci_dev *dev = NULL;
4207320b0651SKan Liang 	u32 val = 0;
4208cd34cd97SKan Liang 
4209320b0651SKan Liang 	dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x2083, dev);
4210320b0651SKan Liang 	if (!dev)
4211320b0651SKan Liang 		goto out;
4212cd34cd97SKan Liang 
4213320b0651SKan Liang 	pci_read_config_dword(dev, SKX_CAPID6, &val);
4214320b0651SKan Liang 	val &= SKX_CHA_BIT_MASK;
4215320b0651SKan Liang out:
4216320b0651SKan Liang 	pci_dev_put(dev);
4217320b0651SKan Liang 	return hweight32(val);
4218cd34cd97SKan Liang }
4219cd34cd97SKan Liang 
4220cd34cd97SKan Liang void skx_uncore_cpu_init(void)
4221cd34cd97SKan Liang {
4222cd34cd97SKan Liang 	skx_uncore_chabox.num_boxes = skx_count_chabox();
4223cd34cd97SKan Liang 	uncore_msr_uncores = skx_msr_uncores;
4224cd34cd97SKan Liang }
4225cd34cd97SKan Liang 
4226cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_imc = {
4227cd34cd97SKan Liang 	.name		= "imc",
4228cd34cd97SKan Liang 	.num_counters   = 4,
4229cd34cd97SKan Liang 	.num_boxes	= 6,
4230cd34cd97SKan Liang 	.perf_ctr_bits	= 48,
4231cd34cd97SKan Liang 	.fixed_ctr_bits	= 48,
4232cd34cd97SKan Liang 	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
4233cd34cd97SKan Liang 	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
4234cd34cd97SKan Liang 	.event_descs	= hswep_uncore_imc_events,
4235cd34cd97SKan Liang 	.perf_ctr	= SNBEP_PCI_PMON_CTR0,
4236cd34cd97SKan Liang 	.event_ctl	= SNBEP_PCI_PMON_CTL0,
4237cd34cd97SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4238cd34cd97SKan Liang 	.box_ctl	= SNBEP_PCI_PMON_BOX_CTL,
4239cd34cd97SKan Liang 	.ops		= &ivbep_uncore_pci_ops,
4240cd34cd97SKan Liang 	.format_group	= &skx_uncore_format_group,
4241cd34cd97SKan Liang };
4242cd34cd97SKan Liang 
4243cd34cd97SKan Liang static struct attribute *skx_upi_uncore_formats_attr[] = {
424431766094SKan Liang 	&format_attr_event.attr,
4245cd34cd97SKan Liang 	&format_attr_umask_ext.attr,
4246cd34cd97SKan Liang 	&format_attr_edge.attr,
4247cd34cd97SKan Liang 	&format_attr_inv.attr,
4248cd34cd97SKan Liang 	&format_attr_thresh8.attr,
4249cd34cd97SKan Liang 	NULL,
4250cd34cd97SKan Liang };
4251cd34cd97SKan Liang 
425245bd07adSArvind Yadav static const struct attribute_group skx_upi_uncore_format_group = {
4253cd34cd97SKan Liang 	.name = "format",
4254cd34cd97SKan Liang 	.attrs = skx_upi_uncore_formats_attr,
4255cd34cd97SKan Liang };
4256cd34cd97SKan Liang 
4257cd34cd97SKan Liang static void skx_upi_uncore_pci_init_box(struct intel_uncore_box *box)
4258cd34cd97SKan Liang {
4259cd34cd97SKan Liang 	struct pci_dev *pdev = box->pci_dev;
4260cd34cd97SKan Liang 
4261cd34cd97SKan Liang 	__set_bit(UNCORE_BOX_FLAG_CTL_OFFS8, &box->flags);
4262cd34cd97SKan Liang 	pci_write_config_dword(pdev, SKX_UPI_PCI_PMON_BOX_CTL, IVBEP_PMON_BOX_CTL_INT);
4263cd34cd97SKan Liang }
4264cd34cd97SKan Liang 
4265cd34cd97SKan Liang static struct intel_uncore_ops skx_upi_uncore_pci_ops = {
4266cd34cd97SKan Liang 	.init_box	= skx_upi_uncore_pci_init_box,
4267cd34cd97SKan Liang 	.disable_box	= snbep_uncore_pci_disable_box,
4268cd34cd97SKan Liang 	.enable_box	= snbep_uncore_pci_enable_box,
4269cd34cd97SKan Liang 	.disable_event	= snbep_uncore_pci_disable_event,
4270cd34cd97SKan Liang 	.enable_event	= snbep_uncore_pci_enable_event,
4271cd34cd97SKan Liang 	.read_counter	= snbep_uncore_pci_read_counter,
4272cd34cd97SKan Liang };
4273cd34cd97SKan Liang 
42744cfce57fSAlexander Antonov static umode_t
42754cfce57fSAlexander Antonov skx_upi_mapping_visible(struct kobject *kobj, struct attribute *attr, int die)
42764cfce57fSAlexander Antonov {
42774cfce57fSAlexander Antonov 	struct intel_uncore_pmu *pmu = dev_to_uncore_pmu(kobj_to_dev(kobj));
42784cfce57fSAlexander Antonov 
42794cfce57fSAlexander Antonov 	return pmu->type->topology[die][pmu->pmu_idx].upi->enabled ? attr->mode : 0;
42804cfce57fSAlexander Antonov }
42814cfce57fSAlexander Antonov 
42824cfce57fSAlexander Antonov static ssize_t skx_upi_mapping_show(struct device *dev,
42834cfce57fSAlexander Antonov 				    struct device_attribute *attr, char *buf)
42844cfce57fSAlexander Antonov {
42854cfce57fSAlexander Antonov 	struct intel_uncore_pmu *pmu = dev_to_uncore_pmu(dev);
42864cfce57fSAlexander Antonov 	struct dev_ext_attribute *ea = to_dev_ext_attribute(attr);
42874cfce57fSAlexander Antonov 	long die = (long)ea->var;
42884cfce57fSAlexander Antonov 	struct uncore_upi_topology *upi = pmu->type->topology[die][pmu->pmu_idx].upi;
42894cfce57fSAlexander Antonov 
42904cfce57fSAlexander Antonov 	return sysfs_emit(buf, "upi_%d,die_%d\n", upi->pmu_idx_to, upi->die_to);
42914cfce57fSAlexander Antonov }
42924cfce57fSAlexander Antonov 
42934cfce57fSAlexander Antonov #define SKX_UPI_REG_DID			0x2058
42944cfce57fSAlexander Antonov #define SKX_UPI_REGS_ADDR_DEVICE_LINK0	0x0e
42954cfce57fSAlexander Antonov #define SKX_UPI_REGS_ADDR_FUNCTION	0x00
42964cfce57fSAlexander Antonov 
42974cfce57fSAlexander Antonov /*
42984cfce57fSAlexander Antonov  * UPI Link Parameter 0
42994cfce57fSAlexander Antonov  * |  Bit  |  Default  |  Description
43004cfce57fSAlexander Antonov  * | 19:16 |     0h    | base_nodeid - The NodeID of the sending socket.
43014cfce57fSAlexander Antonov  * | 12:8  |    00h    | sending_port - The processor die port number of the sending port.
43024cfce57fSAlexander Antonov  */
43034cfce57fSAlexander Antonov #define SKX_KTILP0_OFFSET	0x94
43044cfce57fSAlexander Antonov 
43054cfce57fSAlexander Antonov /*
43064cfce57fSAlexander Antonov  * UPI Pcode Status. This register is used by PCode to store the link training status.
43074cfce57fSAlexander Antonov  * |  Bit  |  Default  |  Description
43084cfce57fSAlexander Antonov  * |   4   |     0h    | ll_status_valid — Bit indicates the valid training status
43094cfce57fSAlexander Antonov  *                       logged from PCode to the BIOS.
43104cfce57fSAlexander Antonov  */
43114cfce57fSAlexander Antonov #define SKX_KTIPCSTS_OFFSET	0x120
43124cfce57fSAlexander Antonov 
43134cfce57fSAlexander Antonov static int upi_fill_topology(struct pci_dev *dev, struct intel_uncore_topology *tp,
43144cfce57fSAlexander Antonov 			     int pmu_idx)
43154cfce57fSAlexander Antonov {
43164cfce57fSAlexander Antonov 	int ret;
43174cfce57fSAlexander Antonov 	u32 upi_conf;
43184cfce57fSAlexander Antonov 	struct uncore_upi_topology *upi = tp->upi;
43194cfce57fSAlexander Antonov 
43204cfce57fSAlexander Antonov 	tp->pmu_idx = pmu_idx;
43214cfce57fSAlexander Antonov 	ret = pci_read_config_dword(dev, SKX_KTIPCSTS_OFFSET, &upi_conf);
43224cfce57fSAlexander Antonov 	if (ret) {
43234cfce57fSAlexander Antonov 		ret = pcibios_err_to_errno(ret);
43244cfce57fSAlexander Antonov 		goto err;
43254cfce57fSAlexander Antonov 	}
43264cfce57fSAlexander Antonov 	upi->enabled = (upi_conf >> 4) & 1;
43274cfce57fSAlexander Antonov 	if (upi->enabled) {
43284cfce57fSAlexander Antonov 		ret = pci_read_config_dword(dev, SKX_KTILP0_OFFSET,
43294cfce57fSAlexander Antonov 					    &upi_conf);
43304cfce57fSAlexander Antonov 		if (ret) {
43314cfce57fSAlexander Antonov 			ret = pcibios_err_to_errno(ret);
43324cfce57fSAlexander Antonov 			goto err;
43334cfce57fSAlexander Antonov 		}
43344cfce57fSAlexander Antonov 		upi->die_to = (upi_conf >> 16) & 0xf;
43354cfce57fSAlexander Antonov 		upi->pmu_idx_to = (upi_conf >> 8) & 0x1f;
43364cfce57fSAlexander Antonov 	}
43374cfce57fSAlexander Antonov err:
43384cfce57fSAlexander Antonov 	return ret;
43394cfce57fSAlexander Antonov }
43404cfce57fSAlexander Antonov 
43414cfce57fSAlexander Antonov static int skx_upi_topology_cb(struct intel_uncore_type *type, int segment,
43424cfce57fSAlexander Antonov 				int die, u64 cpu_bus_msr)
43434cfce57fSAlexander Antonov {
43444cfce57fSAlexander Antonov 	int idx, ret;
43454cfce57fSAlexander Antonov 	struct intel_uncore_topology *upi;
43464cfce57fSAlexander Antonov 	unsigned int devfn;
43474cfce57fSAlexander Antonov 	struct pci_dev *dev = NULL;
43484cfce57fSAlexander Antonov 	u8 bus = cpu_bus_msr >> (3 * BUS_NUM_STRIDE);
43494cfce57fSAlexander Antonov 
43504cfce57fSAlexander Antonov 	for (idx = 0; idx < type->num_boxes; idx++) {
43514cfce57fSAlexander Antonov 		upi = &type->topology[die][idx];
43524cfce57fSAlexander Antonov 		devfn = PCI_DEVFN(SKX_UPI_REGS_ADDR_DEVICE_LINK0 + idx,
43534cfce57fSAlexander Antonov 				  SKX_UPI_REGS_ADDR_FUNCTION);
43544cfce57fSAlexander Antonov 		dev = pci_get_domain_bus_and_slot(segment, bus, devfn);
43554cfce57fSAlexander Antonov 		if (dev) {
43564cfce57fSAlexander Antonov 			ret = upi_fill_topology(dev, upi, idx);
43574cfce57fSAlexander Antonov 			if (ret)
43584cfce57fSAlexander Antonov 				break;
43594cfce57fSAlexander Antonov 		}
43604cfce57fSAlexander Antonov 	}
43614cfce57fSAlexander Antonov 
43624cfce57fSAlexander Antonov 	pci_dev_put(dev);
43634cfce57fSAlexander Antonov 	return ret;
43644cfce57fSAlexander Antonov }
43654cfce57fSAlexander Antonov 
43664cfce57fSAlexander Antonov static int skx_upi_get_topology(struct intel_uncore_type *type)
43674cfce57fSAlexander Antonov {
43684cfce57fSAlexander Antonov 	/* CPX case is not supported */
43694cfce57fSAlexander Antonov 	if (boot_cpu_data.x86_stepping == 11)
43704cfce57fSAlexander Antonov 		return -EPERM;
43714cfce57fSAlexander Antonov 
43724cfce57fSAlexander Antonov 	return skx_pmu_get_topology(type, skx_upi_topology_cb);
43734cfce57fSAlexander Antonov }
43744cfce57fSAlexander Antonov 
43754cfce57fSAlexander Antonov static struct attribute_group skx_upi_mapping_group = {
43764cfce57fSAlexander Antonov 	.is_visible	= skx_upi_mapping_visible,
43774cfce57fSAlexander Antonov };
43784cfce57fSAlexander Antonov 
43794cfce57fSAlexander Antonov static const struct attribute_group *skx_upi_attr_update[] = {
43804cfce57fSAlexander Antonov 	&skx_upi_mapping_group,
43814cfce57fSAlexander Antonov 	NULL
43824cfce57fSAlexander Antonov };
43834cfce57fSAlexander Antonov 
43844cfce57fSAlexander Antonov static int
43854cfce57fSAlexander Antonov pmu_upi_set_mapping(struct intel_uncore_type *type, struct attribute_group *ag)
43864cfce57fSAlexander Antonov {
43874cfce57fSAlexander Antonov 	return pmu_set_mapping(type, ag, skx_upi_mapping_show, UPI_TOPOLOGY_TYPE);
43884cfce57fSAlexander Antonov }
43894cfce57fSAlexander Antonov 
43904cfce57fSAlexander Antonov static int skx_upi_set_mapping(struct intel_uncore_type *type)
43914cfce57fSAlexander Antonov {
43924cfce57fSAlexander Antonov 	return pmu_upi_set_mapping(type, &skx_upi_mapping_group);
43934cfce57fSAlexander Antonov }
43944cfce57fSAlexander Antonov 
43954cfce57fSAlexander Antonov static void skx_upi_cleanup_mapping(struct intel_uncore_type *type)
43964cfce57fSAlexander Antonov {
43974cfce57fSAlexander Antonov 	pmu_cleanup_mapping(type, &skx_upi_mapping_group);
43984cfce57fSAlexander Antonov }
43994cfce57fSAlexander Antonov 
4400cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_upi = {
4401cd34cd97SKan Liang 	.name		= "upi",
4402cd34cd97SKan Liang 	.num_counters   = 4,
4403cd34cd97SKan Liang 	.num_boxes	= 3,
4404cd34cd97SKan Liang 	.perf_ctr_bits	= 48,
4405cd34cd97SKan Liang 	.perf_ctr	= SKX_UPI_PCI_PMON_CTR0,
4406cd34cd97SKan Liang 	.event_ctl	= SKX_UPI_PCI_PMON_CTL0,
4407b3625980SStephane Eranian 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4408b3625980SStephane Eranian 	.event_mask_ext = SKX_UPI_CTL_UMASK_EXT,
4409cd34cd97SKan Liang 	.box_ctl	= SKX_UPI_PCI_PMON_BOX_CTL,
4410cd34cd97SKan Liang 	.ops		= &skx_upi_uncore_pci_ops,
4411cd34cd97SKan Liang 	.format_group	= &skx_upi_uncore_format_group,
44124cfce57fSAlexander Antonov 	.attr_update	= skx_upi_attr_update,
44134cfce57fSAlexander Antonov 	.get_topology	= skx_upi_get_topology,
44144cfce57fSAlexander Antonov 	.set_mapping	= skx_upi_set_mapping,
44154cfce57fSAlexander Antonov 	.cleanup_mapping = skx_upi_cleanup_mapping,
4416cd34cd97SKan Liang };
4417cd34cd97SKan Liang 
4418cd34cd97SKan Liang static void skx_m2m_uncore_pci_init_box(struct intel_uncore_box *box)
4419cd34cd97SKan Liang {
4420cd34cd97SKan Liang 	struct pci_dev *pdev = box->pci_dev;
4421cd34cd97SKan Liang 
4422cd34cd97SKan Liang 	__set_bit(UNCORE_BOX_FLAG_CTL_OFFS8, &box->flags);
4423cd34cd97SKan Liang 	pci_write_config_dword(pdev, SKX_M2M_PCI_PMON_BOX_CTL, IVBEP_PMON_BOX_CTL_INT);
4424cd34cd97SKan Liang }
4425cd34cd97SKan Liang 
4426cd34cd97SKan Liang static struct intel_uncore_ops skx_m2m_uncore_pci_ops = {
4427cd34cd97SKan Liang 	.init_box	= skx_m2m_uncore_pci_init_box,
4428cd34cd97SKan Liang 	.disable_box	= snbep_uncore_pci_disable_box,
4429cd34cd97SKan Liang 	.enable_box	= snbep_uncore_pci_enable_box,
4430cd34cd97SKan Liang 	.disable_event	= snbep_uncore_pci_disable_event,
4431cd34cd97SKan Liang 	.enable_event	= snbep_uncore_pci_enable_event,
4432cd34cd97SKan Liang 	.read_counter	= snbep_uncore_pci_read_counter,
4433cd34cd97SKan Liang };
4434cd34cd97SKan Liang 
4435cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_m2m = {
4436cd34cd97SKan Liang 	.name		= "m2m",
4437cd34cd97SKan Liang 	.num_counters   = 4,
4438cd34cd97SKan Liang 	.num_boxes	= 2,
4439cd34cd97SKan Liang 	.perf_ctr_bits	= 48,
4440cd34cd97SKan Liang 	.perf_ctr	= SKX_M2M_PCI_PMON_CTR0,
4441cd34cd97SKan Liang 	.event_ctl	= SKX_M2M_PCI_PMON_CTL0,
4442cd34cd97SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4443cd34cd97SKan Liang 	.box_ctl	= SKX_M2M_PCI_PMON_BOX_CTL,
4444cd34cd97SKan Liang 	.ops		= &skx_m2m_uncore_pci_ops,
4445cd34cd97SKan Liang 	.format_group	= &skx_uncore_format_group,
4446cd34cd97SKan Liang };
4447cd34cd97SKan Liang 
4448cd34cd97SKan Liang static struct event_constraint skx_uncore_m2pcie_constraints[] = {
4449cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
4450cd34cd97SKan Liang 	EVENT_CONSTRAINT_END
4451cd34cd97SKan Liang };
4452cd34cd97SKan Liang 
4453cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_m2pcie = {
4454cd34cd97SKan Liang 	.name		= "m2pcie",
4455cd34cd97SKan Liang 	.num_counters   = 4,
4456cd34cd97SKan Liang 	.num_boxes	= 4,
4457cd34cd97SKan Liang 	.perf_ctr_bits	= 48,
4458cd34cd97SKan Liang 	.constraints	= skx_uncore_m2pcie_constraints,
4459cd34cd97SKan Liang 	.perf_ctr	= SNBEP_PCI_PMON_CTR0,
4460cd34cd97SKan Liang 	.event_ctl	= SNBEP_PCI_PMON_CTL0,
4461cd34cd97SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4462cd34cd97SKan Liang 	.box_ctl	= SNBEP_PCI_PMON_BOX_CTL,
4463cd34cd97SKan Liang 	.ops		= &ivbep_uncore_pci_ops,
4464cd34cd97SKan Liang 	.format_group	= &skx_uncore_format_group,
4465cd34cd97SKan Liang };
4466cd34cd97SKan Liang 
4467cd34cd97SKan Liang static struct event_constraint skx_uncore_m3upi_constraints[] = {
4468cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x1d, 0x1),
4469cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x1e, 0x1),
4470cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x40, 0x7),
4471cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x4e, 0x7),
4472cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x4f, 0x7),
4473cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x50, 0x7),
4474cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x51, 0x7),
4475cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x52, 0x7),
4476cd34cd97SKan Liang 	EVENT_CONSTRAINT_END
4477cd34cd97SKan Liang };
4478cd34cd97SKan Liang 
4479cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_m3upi = {
4480cd34cd97SKan Liang 	.name		= "m3upi",
4481cd34cd97SKan Liang 	.num_counters   = 3,
4482cd34cd97SKan Liang 	.num_boxes	= 3,
4483cd34cd97SKan Liang 	.perf_ctr_bits	= 48,
4484cd34cd97SKan Liang 	.constraints	= skx_uncore_m3upi_constraints,
4485cd34cd97SKan Liang 	.perf_ctr	= SNBEP_PCI_PMON_CTR0,
4486cd34cd97SKan Liang 	.event_ctl	= SNBEP_PCI_PMON_CTL0,
4487cd34cd97SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4488cd34cd97SKan Liang 	.box_ctl	= SNBEP_PCI_PMON_BOX_CTL,
4489cd34cd97SKan Liang 	.ops		= &ivbep_uncore_pci_ops,
4490cd34cd97SKan Liang 	.format_group	= &skx_uncore_format_group,
4491cd34cd97SKan Liang };
4492cd34cd97SKan Liang 
4493cd34cd97SKan Liang enum {
4494cd34cd97SKan Liang 	SKX_PCI_UNCORE_IMC,
4495cd34cd97SKan Liang 	SKX_PCI_UNCORE_M2M,
4496cd34cd97SKan Liang 	SKX_PCI_UNCORE_UPI,
4497cd34cd97SKan Liang 	SKX_PCI_UNCORE_M2PCIE,
4498cd34cd97SKan Liang 	SKX_PCI_UNCORE_M3UPI,
4499cd34cd97SKan Liang };
4500cd34cd97SKan Liang 
4501cd34cd97SKan Liang static struct intel_uncore_type *skx_pci_uncores[] = {
4502cd34cd97SKan Liang 	[SKX_PCI_UNCORE_IMC]	= &skx_uncore_imc,
4503cd34cd97SKan Liang 	[SKX_PCI_UNCORE_M2M]	= &skx_uncore_m2m,
4504cd34cd97SKan Liang 	[SKX_PCI_UNCORE_UPI]	= &skx_uncore_upi,
4505cd34cd97SKan Liang 	[SKX_PCI_UNCORE_M2PCIE]	= &skx_uncore_m2pcie,
4506cd34cd97SKan Liang 	[SKX_PCI_UNCORE_M3UPI]	= &skx_uncore_m3upi,
4507cd34cd97SKan Liang 	NULL,
4508cd34cd97SKan Liang };
4509cd34cd97SKan Liang 
4510cd34cd97SKan Liang static const struct pci_device_id skx_uncore_pci_ids[] = {
4511cd34cd97SKan Liang 	{ /* MC0 Channel 0 */
4512cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2042),
4513cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(10, 2, SKX_PCI_UNCORE_IMC, 0),
4514cd34cd97SKan Liang 	},
4515cd34cd97SKan Liang 	{ /* MC0 Channel 1 */
4516cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2046),
4517cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(10, 6, SKX_PCI_UNCORE_IMC, 1),
4518cd34cd97SKan Liang 	},
4519cd34cd97SKan Liang 	{ /* MC0 Channel 2 */
4520cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204a),
4521cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(11, 2, SKX_PCI_UNCORE_IMC, 2),
4522cd34cd97SKan Liang 	},
4523cd34cd97SKan Liang 	{ /* MC1 Channel 0 */
4524cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2042),
4525cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(12, 2, SKX_PCI_UNCORE_IMC, 3),
4526cd34cd97SKan Liang 	},
4527cd34cd97SKan Liang 	{ /* MC1 Channel 1 */
4528cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2046),
4529cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(12, 6, SKX_PCI_UNCORE_IMC, 4),
4530cd34cd97SKan Liang 	},
4531cd34cd97SKan Liang 	{ /* MC1 Channel 2 */
4532cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204a),
4533cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(13, 2, SKX_PCI_UNCORE_IMC, 5),
4534cd34cd97SKan Liang 	},
4535cd34cd97SKan Liang 	{ /* M2M0 */
4536cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2066),
4537cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(8, 0, SKX_PCI_UNCORE_M2M, 0),
4538cd34cd97SKan Liang 	},
4539cd34cd97SKan Liang 	{ /* M2M1 */
4540cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2066),
4541cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(9, 0, SKX_PCI_UNCORE_M2M, 1),
4542cd34cd97SKan Liang 	},
4543cd34cd97SKan Liang 	{ /* UPI0 Link 0 */
4544cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2058),
4545cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(14, 0, SKX_PCI_UNCORE_UPI, 0),
4546cd34cd97SKan Liang 	},
4547cd34cd97SKan Liang 	{ /* UPI0 Link 1 */
4548cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2058),
4549cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(15, 0, SKX_PCI_UNCORE_UPI, 1),
4550cd34cd97SKan Liang 	},
4551cd34cd97SKan Liang 	{ /* UPI1 Link 2 */
4552cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2058),
4553cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(16, 0, SKX_PCI_UNCORE_UPI, 2),
4554cd34cd97SKan Liang 	},
4555cd34cd97SKan Liang 	{ /* M2PCIe 0 */
4556cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2088),
4557cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(21, 1, SKX_PCI_UNCORE_M2PCIE, 0),
4558cd34cd97SKan Liang 	},
4559cd34cd97SKan Liang 	{ /* M2PCIe 1 */
4560cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2088),
4561cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(22, 1, SKX_PCI_UNCORE_M2PCIE, 1),
4562cd34cd97SKan Liang 	},
4563cd34cd97SKan Liang 	{ /* M2PCIe 2 */
4564cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2088),
4565cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(23, 1, SKX_PCI_UNCORE_M2PCIE, 2),
4566cd34cd97SKan Liang 	},
4567cd34cd97SKan Liang 	{ /* M2PCIe 3 */
4568cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2088),
4569cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(21, 5, SKX_PCI_UNCORE_M2PCIE, 3),
4570cd34cd97SKan Liang 	},
4571cd34cd97SKan Liang 	{ /* M3UPI0 Link 0 */
45729d92cfeaSKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204D),
45739d92cfeaSKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(18, 1, SKX_PCI_UNCORE_M3UPI, 0),
4574cd34cd97SKan Liang 	},
4575cd34cd97SKan Liang 	{ /* M3UPI0 Link 1 */
45769d92cfeaSKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204E),
45779d92cfeaSKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(18, 2, SKX_PCI_UNCORE_M3UPI, 1),
4578cd34cd97SKan Liang 	},
4579cd34cd97SKan Liang 	{ /* M3UPI1 Link 2 */
45809d92cfeaSKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204D),
45819d92cfeaSKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(18, 5, SKX_PCI_UNCORE_M3UPI, 2),
4582cd34cd97SKan Liang 	},
4583cd34cd97SKan Liang 	{ /* end: all zeroes */ }
4584cd34cd97SKan Liang };
4585cd34cd97SKan Liang 
4586cd34cd97SKan Liang 
4587cd34cd97SKan Liang static struct pci_driver skx_uncore_pci_driver = {
4588cd34cd97SKan Liang 	.name		= "skx_uncore",
4589cd34cd97SKan Liang 	.id_table	= skx_uncore_pci_ids,
4590cd34cd97SKan Liang };
4591cd34cd97SKan Liang 
4592cd34cd97SKan Liang int skx_uncore_pci_init(void)
4593cd34cd97SKan Liang {
4594cd34cd97SKan Liang 	/* need to double check pci address */
4595cd34cd97SKan Liang 	int ret = snbep_pci2phy_map_init(0x2014, SKX_CPUNODEID, SKX_GIDNIDMAP, false);
4596cd34cd97SKan Liang 
4597cd34cd97SKan Liang 	if (ret)
4598cd34cd97SKan Liang 		return ret;
4599cd34cd97SKan Liang 
4600cd34cd97SKan Liang 	uncore_pci_uncores = skx_pci_uncores;
4601cd34cd97SKan Liang 	uncore_pci_driver = &skx_uncore_pci_driver;
4602cd34cd97SKan Liang 	return 0;
4603cd34cd97SKan Liang }
4604cd34cd97SKan Liang 
4605cd34cd97SKan Liang /* end of SKX uncore support */
4606210cc5f9SKan Liang 
4607210cc5f9SKan Liang /* SNR uncore support */
4608210cc5f9SKan Liang 
4609210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_ubox = {
4610210cc5f9SKan Liang 	.name			= "ubox",
4611210cc5f9SKan Liang 	.num_counters		= 2,
4612210cc5f9SKan Liang 	.num_boxes		= 1,
4613210cc5f9SKan Liang 	.perf_ctr_bits		= 48,
4614210cc5f9SKan Liang 	.fixed_ctr_bits		= 48,
4615210cc5f9SKan Liang 	.perf_ctr		= SNR_U_MSR_PMON_CTR0,
4616210cc5f9SKan Liang 	.event_ctl		= SNR_U_MSR_PMON_CTL0,
4617210cc5f9SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
4618210cc5f9SKan Liang 	.fixed_ctr		= SNR_U_MSR_PMON_UCLK_FIXED_CTR,
4619210cc5f9SKan Liang 	.fixed_ctl		= SNR_U_MSR_PMON_UCLK_FIXED_CTL,
4620210cc5f9SKan Liang 	.ops			= &ivbep_uncore_msr_ops,
4621210cc5f9SKan Liang 	.format_group		= &ivbep_uncore_format_group,
4622210cc5f9SKan Liang };
4623210cc5f9SKan Liang 
4624210cc5f9SKan Liang static struct attribute *snr_uncore_cha_formats_attr[] = {
4625210cc5f9SKan Liang 	&format_attr_event.attr,
4626210cc5f9SKan Liang 	&format_attr_umask_ext2.attr,
4627210cc5f9SKan Liang 	&format_attr_edge.attr,
4628210cc5f9SKan Liang 	&format_attr_tid_en.attr,
4629210cc5f9SKan Liang 	&format_attr_inv.attr,
4630210cc5f9SKan Liang 	&format_attr_thresh8.attr,
4631210cc5f9SKan Liang 	&format_attr_filter_tid5.attr,
4632210cc5f9SKan Liang 	NULL,
4633210cc5f9SKan Liang };
4634210cc5f9SKan Liang static const struct attribute_group snr_uncore_chabox_format_group = {
4635210cc5f9SKan Liang 	.name = "format",
4636210cc5f9SKan Liang 	.attrs = snr_uncore_cha_formats_attr,
4637210cc5f9SKan Liang };
4638210cc5f9SKan Liang 
4639210cc5f9SKan Liang static int snr_cha_hw_config(struct intel_uncore_box *box, struct perf_event *event)
4640210cc5f9SKan Liang {
4641210cc5f9SKan Liang 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
4642210cc5f9SKan Liang 
4643210cc5f9SKan Liang 	reg1->reg = SNR_C0_MSR_PMON_BOX_FILTER0 +
4644210cc5f9SKan Liang 		    box->pmu->type->msr_offset * box->pmu->pmu_idx;
4645210cc5f9SKan Liang 	reg1->config = event->attr.config1 & SKX_CHA_MSR_PMON_BOX_FILTER_TID;
4646210cc5f9SKan Liang 	reg1->idx = 0;
4647210cc5f9SKan Liang 
4648210cc5f9SKan Liang 	return 0;
4649210cc5f9SKan Liang }
4650210cc5f9SKan Liang 
4651210cc5f9SKan Liang static void snr_cha_enable_event(struct intel_uncore_box *box,
4652210cc5f9SKan Liang 				   struct perf_event *event)
4653210cc5f9SKan Liang {
4654210cc5f9SKan Liang 	struct hw_perf_event *hwc = &event->hw;
4655210cc5f9SKan Liang 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
4656210cc5f9SKan Liang 
4657210cc5f9SKan Liang 	if (reg1->idx != EXTRA_REG_NONE)
4658210cc5f9SKan Liang 		wrmsrl(reg1->reg, reg1->config);
4659210cc5f9SKan Liang 
4660210cc5f9SKan Liang 	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
4661210cc5f9SKan Liang }
4662210cc5f9SKan Liang 
4663210cc5f9SKan Liang static struct intel_uncore_ops snr_uncore_chabox_ops = {
4664210cc5f9SKan Liang 	.init_box		= ivbep_uncore_msr_init_box,
4665210cc5f9SKan Liang 	.disable_box		= snbep_uncore_msr_disable_box,
4666210cc5f9SKan Liang 	.enable_box		= snbep_uncore_msr_enable_box,
4667210cc5f9SKan Liang 	.disable_event		= snbep_uncore_msr_disable_event,
4668210cc5f9SKan Liang 	.enable_event		= snr_cha_enable_event,
4669210cc5f9SKan Liang 	.read_counter		= uncore_msr_read_counter,
4670210cc5f9SKan Liang 	.hw_config		= snr_cha_hw_config,
4671210cc5f9SKan Liang };
4672210cc5f9SKan Liang 
4673210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_chabox = {
4674210cc5f9SKan Liang 	.name			= "cha",
4675210cc5f9SKan Liang 	.num_counters		= 4,
4676210cc5f9SKan Liang 	.num_boxes		= 6,
4677210cc5f9SKan Liang 	.perf_ctr_bits		= 48,
4678210cc5f9SKan Liang 	.event_ctl		= SNR_CHA_MSR_PMON_CTL0,
4679210cc5f9SKan Liang 	.perf_ctr		= SNR_CHA_MSR_PMON_CTR0,
4680210cc5f9SKan Liang 	.box_ctl		= SNR_CHA_MSR_PMON_BOX_CTL,
4681210cc5f9SKan Liang 	.msr_offset		= HSWEP_CBO_MSR_OFFSET,
4682210cc5f9SKan Liang 	.event_mask		= HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
4683210cc5f9SKan Liang 	.event_mask_ext		= SNR_CHA_RAW_EVENT_MASK_EXT,
4684210cc5f9SKan Liang 	.ops			= &snr_uncore_chabox_ops,
4685210cc5f9SKan Liang 	.format_group		= &snr_uncore_chabox_format_group,
4686210cc5f9SKan Liang };
4687210cc5f9SKan Liang 
4688210cc5f9SKan Liang static struct attribute *snr_uncore_iio_formats_attr[] = {
4689210cc5f9SKan Liang 	&format_attr_event.attr,
4690210cc5f9SKan Liang 	&format_attr_umask.attr,
4691210cc5f9SKan Liang 	&format_attr_edge.attr,
4692210cc5f9SKan Liang 	&format_attr_inv.attr,
4693210cc5f9SKan Liang 	&format_attr_thresh9.attr,
4694210cc5f9SKan Liang 	&format_attr_ch_mask2.attr,
4695210cc5f9SKan Liang 	&format_attr_fc_mask2.attr,
4696210cc5f9SKan Liang 	NULL,
4697210cc5f9SKan Liang };
4698210cc5f9SKan Liang 
4699210cc5f9SKan Liang static const struct attribute_group snr_uncore_iio_format_group = {
4700210cc5f9SKan Liang 	.name = "format",
4701210cc5f9SKan Liang 	.attrs = snr_uncore_iio_formats_attr,
4702210cc5f9SKan Liang };
4703210cc5f9SKan Liang 
4704c1777be3SAlexander Antonov static umode_t
4705c1777be3SAlexander Antonov snr_iio_mapping_visible(struct kobject *kobj, struct attribute *attr, int die)
4706c1777be3SAlexander Antonov {
4707c1777be3SAlexander Antonov 	/* Root bus 0x00 is valid only for pmu_idx = 1. */
4708c1777be3SAlexander Antonov 	return pmu_iio_mapping_visible(kobj, attr, die, 1);
4709c1777be3SAlexander Antonov }
4710c1777be3SAlexander Antonov 
4711c1777be3SAlexander Antonov static struct attribute_group snr_iio_mapping_group = {
4712c1777be3SAlexander Antonov 	.is_visible	= snr_iio_mapping_visible,
4713c1777be3SAlexander Antonov };
4714c1777be3SAlexander Antonov 
4715c1777be3SAlexander Antonov static const struct attribute_group *snr_iio_attr_update[] = {
4716c1777be3SAlexander Antonov 	&snr_iio_mapping_group,
4717c1777be3SAlexander Antonov 	NULL,
4718c1777be3SAlexander Antonov };
4719c1777be3SAlexander Antonov 
4720c1777be3SAlexander Antonov static int sad_cfg_iio_topology(struct intel_uncore_type *type, u8 *sad_pmon_mapping)
4721c1777be3SAlexander Antonov {
4722c1777be3SAlexander Antonov 	u32 sad_cfg;
4723c1777be3SAlexander Antonov 	int die, stack_id, ret = -EPERM;
4724c1777be3SAlexander Antonov 	struct pci_dev *dev = NULL;
4725c1777be3SAlexander Antonov 
4726c1777be3SAlexander Antonov 	while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL, SNR_ICX_MESH2IIO_MMAP_DID, dev))) {
4727c1777be3SAlexander Antonov 		ret = pci_read_config_dword(dev, SNR_ICX_SAD_CONTROL_CFG, &sad_cfg);
4728c1777be3SAlexander Antonov 		if (ret) {
4729c1777be3SAlexander Antonov 			ret = pcibios_err_to_errno(ret);
4730c1777be3SAlexander Antonov 			break;
4731c1777be3SAlexander Antonov 		}
4732c1777be3SAlexander Antonov 
4733c1777be3SAlexander Antonov 		die = uncore_pcibus_to_dieid(dev->bus);
4734c1777be3SAlexander Antonov 		stack_id = SAD_CONTROL_STACK_ID(sad_cfg);
4735c1777be3SAlexander Antonov 		if (die < 0 || stack_id >= type->num_boxes) {
4736c1777be3SAlexander Antonov 			ret = -EPERM;
4737c1777be3SAlexander Antonov 			break;
4738c1777be3SAlexander Antonov 		}
4739c1777be3SAlexander Antonov 
4740c1777be3SAlexander Antonov 		/* Convert stack id from SAD_CONTROL to PMON notation. */
4741c1777be3SAlexander Antonov 		stack_id = sad_pmon_mapping[stack_id];
4742c1777be3SAlexander Antonov 
47434d13be8aSAlexander Antonov 		type->topology[die][stack_id].iio->segment = pci_domain_nr(dev->bus);
47444d13be8aSAlexander Antonov 		type->topology[die][stack_id].pmu_idx = stack_id;
47454d13be8aSAlexander Antonov 		type->topology[die][stack_id].iio->pci_bus_no = dev->bus->number;
4746c1777be3SAlexander Antonov 	}
4747c1777be3SAlexander Antonov 
4748c1777be3SAlexander Antonov 	return ret;
4749c1777be3SAlexander Antonov }
4750c1777be3SAlexander Antonov 
4751c1777be3SAlexander Antonov /*
4752c1777be3SAlexander Antonov  * SNR has a static mapping of stack IDs from SAD_CONTROL_CFG notation to PMON
4753c1777be3SAlexander Antonov  */
4754c1777be3SAlexander Antonov enum {
4755c1777be3SAlexander Antonov 	SNR_QAT_PMON_ID,
4756c1777be3SAlexander Antonov 	SNR_CBDMA_DMI_PMON_ID,
4757c1777be3SAlexander Antonov 	SNR_NIS_PMON_ID,
4758c1777be3SAlexander Antonov 	SNR_DLB_PMON_ID,
4759c1777be3SAlexander Antonov 	SNR_PCIE_GEN3_PMON_ID
4760c1777be3SAlexander Antonov };
4761c1777be3SAlexander Antonov 
4762c1777be3SAlexander Antonov static u8 snr_sad_pmon_mapping[] = {
4763c1777be3SAlexander Antonov 	SNR_CBDMA_DMI_PMON_ID,
4764c1777be3SAlexander Antonov 	SNR_PCIE_GEN3_PMON_ID,
4765c1777be3SAlexander Antonov 	SNR_DLB_PMON_ID,
4766c1777be3SAlexander Antonov 	SNR_NIS_PMON_ID,
4767c1777be3SAlexander Antonov 	SNR_QAT_PMON_ID
4768c1777be3SAlexander Antonov };
4769c1777be3SAlexander Antonov 
4770c1777be3SAlexander Antonov static int snr_iio_get_topology(struct intel_uncore_type *type)
4771c1777be3SAlexander Antonov {
4772c1777be3SAlexander Antonov 	return sad_cfg_iio_topology(type, snr_sad_pmon_mapping);
4773c1777be3SAlexander Antonov }
4774c1777be3SAlexander Antonov 
4775c1777be3SAlexander Antonov static int snr_iio_set_mapping(struct intel_uncore_type *type)
4776c1777be3SAlexander Antonov {
4777c1777be3SAlexander Antonov 	return pmu_iio_set_mapping(type, &snr_iio_mapping_group);
4778c1777be3SAlexander Antonov }
4779c1777be3SAlexander Antonov 
47803f2cbe38SAlexander Antonov static void snr_iio_cleanup_mapping(struct intel_uncore_type *type)
47813f2cbe38SAlexander Antonov {
47824d13be8aSAlexander Antonov 	pmu_cleanup_mapping(type, &snr_iio_mapping_group);
47833f2cbe38SAlexander Antonov }
47843f2cbe38SAlexander Antonov 
4785bdc0feeeSAlexander Antonov static struct event_constraint snr_uncore_iio_constraints[] = {
4786bdc0feeeSAlexander Antonov 	UNCORE_EVENT_CONSTRAINT(0x83, 0x3),
4787bdc0feeeSAlexander Antonov 	UNCORE_EVENT_CONSTRAINT(0xc0, 0xc),
4788bdc0feeeSAlexander Antonov 	UNCORE_EVENT_CONSTRAINT(0xd5, 0xc),
4789bdc0feeeSAlexander Antonov 	EVENT_CONSTRAINT_END
4790bdc0feeeSAlexander Antonov };
4791bdc0feeeSAlexander Antonov 
4792210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_iio = {
4793210cc5f9SKan Liang 	.name			= "iio",
4794210cc5f9SKan Liang 	.num_counters		= 4,
4795210cc5f9SKan Liang 	.num_boxes		= 5,
4796210cc5f9SKan Liang 	.perf_ctr_bits		= 48,
4797210cc5f9SKan Liang 	.event_ctl		= SNR_IIO_MSR_PMON_CTL0,
4798210cc5f9SKan Liang 	.perf_ctr		= SNR_IIO_MSR_PMON_CTR0,
4799210cc5f9SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
4800210cc5f9SKan Liang 	.event_mask_ext		= SNR_IIO_PMON_RAW_EVENT_MASK_EXT,
4801210cc5f9SKan Liang 	.box_ctl		= SNR_IIO_MSR_PMON_BOX_CTL,
4802210cc5f9SKan Liang 	.msr_offset		= SNR_IIO_MSR_OFFSET,
4803bdc0feeeSAlexander Antonov 	.constraints		= snr_uncore_iio_constraints,
4804210cc5f9SKan Liang 	.ops			= &ivbep_uncore_msr_ops,
4805210cc5f9SKan Liang 	.format_group		= &snr_uncore_iio_format_group,
4806c1777be3SAlexander Antonov 	.attr_update		= snr_iio_attr_update,
4807c1777be3SAlexander Antonov 	.get_topology		= snr_iio_get_topology,
4808c1777be3SAlexander Antonov 	.set_mapping		= snr_iio_set_mapping,
48093f2cbe38SAlexander Antonov 	.cleanup_mapping	= snr_iio_cleanup_mapping,
4810210cc5f9SKan Liang };
4811210cc5f9SKan Liang 
4812210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_irp = {
4813210cc5f9SKan Liang 	.name			= "irp",
4814210cc5f9SKan Liang 	.num_counters		= 2,
4815210cc5f9SKan Liang 	.num_boxes		= 5,
4816210cc5f9SKan Liang 	.perf_ctr_bits		= 48,
4817210cc5f9SKan Liang 	.event_ctl		= SNR_IRP0_MSR_PMON_CTL0,
4818210cc5f9SKan Liang 	.perf_ctr		= SNR_IRP0_MSR_PMON_CTR0,
4819210cc5f9SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
4820210cc5f9SKan Liang 	.box_ctl		= SNR_IRP0_MSR_PMON_BOX_CTL,
4821210cc5f9SKan Liang 	.msr_offset		= SNR_IRP_MSR_OFFSET,
4822210cc5f9SKan Liang 	.ops			= &ivbep_uncore_msr_ops,
4823210cc5f9SKan Liang 	.format_group		= &ivbep_uncore_format_group,
4824210cc5f9SKan Liang };
4825210cc5f9SKan Liang 
4826210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_m2pcie = {
4827210cc5f9SKan Liang 	.name		= "m2pcie",
4828210cc5f9SKan Liang 	.num_counters	= 4,
4829210cc5f9SKan Liang 	.num_boxes	= 5,
4830210cc5f9SKan Liang 	.perf_ctr_bits	= 48,
4831210cc5f9SKan Liang 	.event_ctl	= SNR_M2PCIE_MSR_PMON_CTL0,
4832210cc5f9SKan Liang 	.perf_ctr	= SNR_M2PCIE_MSR_PMON_CTR0,
4833210cc5f9SKan Liang 	.box_ctl	= SNR_M2PCIE_MSR_PMON_BOX_CTL,
4834210cc5f9SKan Liang 	.msr_offset	= SNR_M2PCIE_MSR_OFFSET,
4835210cc5f9SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4836210cc5f9SKan Liang 	.ops		= &ivbep_uncore_msr_ops,
4837210cc5f9SKan Liang 	.format_group	= &ivbep_uncore_format_group,
4838210cc5f9SKan Liang };
4839210cc5f9SKan Liang 
4840210cc5f9SKan Liang static int snr_pcu_hw_config(struct intel_uncore_box *box, struct perf_event *event)
4841210cc5f9SKan Liang {
4842210cc5f9SKan Liang 	struct hw_perf_event *hwc = &event->hw;
4843210cc5f9SKan Liang 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
4844210cc5f9SKan Liang 	int ev_sel = hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK;
4845210cc5f9SKan Liang 
4846210cc5f9SKan Liang 	if (ev_sel >= 0xb && ev_sel <= 0xe) {
4847210cc5f9SKan Liang 		reg1->reg = SNR_PCU_MSR_PMON_BOX_FILTER;
4848210cc5f9SKan Liang 		reg1->idx = ev_sel - 0xb;
4849210cc5f9SKan Liang 		reg1->config = event->attr.config1 & (0xff << reg1->idx);
4850210cc5f9SKan Liang 	}
4851210cc5f9SKan Liang 	return 0;
4852210cc5f9SKan Liang }
4853210cc5f9SKan Liang 
4854210cc5f9SKan Liang static struct intel_uncore_ops snr_uncore_pcu_ops = {
4855210cc5f9SKan Liang 	IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
4856210cc5f9SKan Liang 	.hw_config		= snr_pcu_hw_config,
4857210cc5f9SKan Liang 	.get_constraint		= snbep_pcu_get_constraint,
4858210cc5f9SKan Liang 	.put_constraint		= snbep_pcu_put_constraint,
4859210cc5f9SKan Liang };
4860210cc5f9SKan Liang 
4861210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_pcu = {
4862210cc5f9SKan Liang 	.name			= "pcu",
4863210cc5f9SKan Liang 	.num_counters		= 4,
4864210cc5f9SKan Liang 	.num_boxes		= 1,
4865210cc5f9SKan Liang 	.perf_ctr_bits		= 48,
4866210cc5f9SKan Liang 	.perf_ctr		= SNR_PCU_MSR_PMON_CTR0,
4867210cc5f9SKan Liang 	.event_ctl		= SNR_PCU_MSR_PMON_CTL0,
4868210cc5f9SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
4869210cc5f9SKan Liang 	.box_ctl		= SNR_PCU_MSR_PMON_BOX_CTL,
4870210cc5f9SKan Liang 	.num_shared_regs	= 1,
4871210cc5f9SKan Liang 	.ops			= &snr_uncore_pcu_ops,
4872210cc5f9SKan Liang 	.format_group		= &skx_uncore_pcu_format_group,
4873210cc5f9SKan Liang };
4874210cc5f9SKan Liang 
4875210cc5f9SKan Liang enum perf_uncore_snr_iio_freerunning_type_id {
4876210cc5f9SKan Liang 	SNR_IIO_MSR_IOCLK,
4877210cc5f9SKan Liang 	SNR_IIO_MSR_BW_IN,
4878210cc5f9SKan Liang 
4879210cc5f9SKan Liang 	SNR_IIO_FREERUNNING_TYPE_MAX,
4880210cc5f9SKan Liang };
4881210cc5f9SKan Liang 
4882210cc5f9SKan Liang static struct freerunning_counters snr_iio_freerunning[] = {
4883210cc5f9SKan Liang 	[SNR_IIO_MSR_IOCLK]	= { 0x1eac, 0x1, 0x10, 1, 48 },
4884210cc5f9SKan Liang 	[SNR_IIO_MSR_BW_IN]	= { 0x1f00, 0x1, 0x10, 8, 48 },
4885210cc5f9SKan Liang };
4886210cc5f9SKan Liang 
4887210cc5f9SKan Liang static struct uncore_event_desc snr_uncore_iio_freerunning_events[] = {
4888210cc5f9SKan Liang 	/* Free-Running IIO CLOCKS Counter */
4889210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(ioclk,			"event=0xff,umask=0x10"),
4890210cc5f9SKan Liang 	/* Free-Running IIO BANDWIDTH IN Counters */
4891210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0,		"event=0xff,umask=0x20"),
4892210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale,	"3.814697266e-6"),
4893210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit,	"MiB"),
4894210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1,		"event=0xff,umask=0x21"),
4895210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale,	"3.814697266e-6"),
4896210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit,	"MiB"),
4897210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2,		"event=0xff,umask=0x22"),
4898210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale,	"3.814697266e-6"),
4899210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit,	"MiB"),
4900210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3,		"event=0xff,umask=0x23"),
4901210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale,	"3.814697266e-6"),
4902210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit,	"MiB"),
4903210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4,		"event=0xff,umask=0x24"),
4904210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4.scale,	"3.814697266e-6"),
4905210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4.unit,	"MiB"),
4906210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5,		"event=0xff,umask=0x25"),
4907210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5.scale,	"3.814697266e-6"),
4908210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5.unit,	"MiB"),
4909210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6,		"event=0xff,umask=0x26"),
4910210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6.scale,	"3.814697266e-6"),
4911210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6.unit,	"MiB"),
4912210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7,		"event=0xff,umask=0x27"),
4913210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7.scale,	"3.814697266e-6"),
4914210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7.unit,	"MiB"),
4915210cc5f9SKan Liang 	{ /* end: all zeroes */ },
4916210cc5f9SKan Liang };
4917210cc5f9SKan Liang 
4918210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_iio_free_running = {
4919210cc5f9SKan Liang 	.name			= "iio_free_running",
4920210cc5f9SKan Liang 	.num_counters		= 9,
4921210cc5f9SKan Liang 	.num_boxes		= 5,
4922210cc5f9SKan Liang 	.num_freerunning_types	= SNR_IIO_FREERUNNING_TYPE_MAX,
4923210cc5f9SKan Liang 	.freerunning		= snr_iio_freerunning,
4924210cc5f9SKan Liang 	.ops			= &skx_uncore_iio_freerunning_ops,
4925210cc5f9SKan Liang 	.event_descs		= snr_uncore_iio_freerunning_events,
4926210cc5f9SKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
4927210cc5f9SKan Liang };
4928210cc5f9SKan Liang 
4929210cc5f9SKan Liang static struct intel_uncore_type *snr_msr_uncores[] = {
4930210cc5f9SKan Liang 	&snr_uncore_ubox,
4931210cc5f9SKan Liang 	&snr_uncore_chabox,
4932210cc5f9SKan Liang 	&snr_uncore_iio,
4933210cc5f9SKan Liang 	&snr_uncore_irp,
4934210cc5f9SKan Liang 	&snr_uncore_m2pcie,
4935210cc5f9SKan Liang 	&snr_uncore_pcu,
4936210cc5f9SKan Liang 	&snr_uncore_iio_free_running,
4937210cc5f9SKan Liang 	NULL,
4938210cc5f9SKan Liang };
4939210cc5f9SKan Liang 
4940210cc5f9SKan Liang void snr_uncore_cpu_init(void)
4941210cc5f9SKan Liang {
4942210cc5f9SKan Liang 	uncore_msr_uncores = snr_msr_uncores;
4943210cc5f9SKan Liang }
4944210cc5f9SKan Liang 
4945210cc5f9SKan Liang static void snr_m2m_uncore_pci_init_box(struct intel_uncore_box *box)
4946210cc5f9SKan Liang {
4947210cc5f9SKan Liang 	struct pci_dev *pdev = box->pci_dev;
4948210cc5f9SKan Liang 	int box_ctl = uncore_pci_box_ctl(box);
4949210cc5f9SKan Liang 
4950210cc5f9SKan Liang 	__set_bit(UNCORE_BOX_FLAG_CTL_OFFS8, &box->flags);
4951210cc5f9SKan Liang 	pci_write_config_dword(pdev, box_ctl, IVBEP_PMON_BOX_CTL_INT);
4952210cc5f9SKan Liang }
4953210cc5f9SKan Liang 
4954210cc5f9SKan Liang static struct intel_uncore_ops snr_m2m_uncore_pci_ops = {
4955210cc5f9SKan Liang 	.init_box	= snr_m2m_uncore_pci_init_box,
4956210cc5f9SKan Liang 	.disable_box	= snbep_uncore_pci_disable_box,
4957210cc5f9SKan Liang 	.enable_box	= snbep_uncore_pci_enable_box,
4958210cc5f9SKan Liang 	.disable_event	= snbep_uncore_pci_disable_event,
4959210cc5f9SKan Liang 	.enable_event	= snbep_uncore_pci_enable_event,
4960210cc5f9SKan Liang 	.read_counter	= snbep_uncore_pci_read_counter,
4961210cc5f9SKan Liang };
4962210cc5f9SKan Liang 
4963210cc5f9SKan Liang static struct attribute *snr_m2m_uncore_formats_attr[] = {
4964210cc5f9SKan Liang 	&format_attr_event.attr,
4965210cc5f9SKan Liang 	&format_attr_umask_ext3.attr,
4966210cc5f9SKan Liang 	&format_attr_edge.attr,
4967210cc5f9SKan Liang 	&format_attr_inv.attr,
4968210cc5f9SKan Liang 	&format_attr_thresh8.attr,
4969210cc5f9SKan Liang 	NULL,
4970210cc5f9SKan Liang };
4971210cc5f9SKan Liang 
4972210cc5f9SKan Liang static const struct attribute_group snr_m2m_uncore_format_group = {
4973210cc5f9SKan Liang 	.name = "format",
4974210cc5f9SKan Liang 	.attrs = snr_m2m_uncore_formats_attr,
4975210cc5f9SKan Liang };
4976210cc5f9SKan Liang 
4977210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_m2m = {
4978210cc5f9SKan Liang 	.name		= "m2m",
4979210cc5f9SKan Liang 	.num_counters   = 4,
4980210cc5f9SKan Liang 	.num_boxes	= 1,
4981210cc5f9SKan Liang 	.perf_ctr_bits	= 48,
4982210cc5f9SKan Liang 	.perf_ctr	= SNR_M2M_PCI_PMON_CTR0,
4983210cc5f9SKan Liang 	.event_ctl	= SNR_M2M_PCI_PMON_CTL0,
4984210cc5f9SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4985210cc5f9SKan Liang 	.event_mask_ext	= SNR_M2M_PCI_PMON_UMASK_EXT,
4986210cc5f9SKan Liang 	.box_ctl	= SNR_M2M_PCI_PMON_BOX_CTL,
4987210cc5f9SKan Liang 	.ops		= &snr_m2m_uncore_pci_ops,
4988210cc5f9SKan Liang 	.format_group	= &snr_m2m_uncore_format_group,
4989210cc5f9SKan Liang };
4990210cc5f9SKan Liang 
4991a3b1e845SKan Liang static void snr_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event)
4992a3b1e845SKan Liang {
4993a3b1e845SKan Liang 	struct pci_dev *pdev = box->pci_dev;
4994a3b1e845SKan Liang 	struct hw_perf_event *hwc = &event->hw;
4995a3b1e845SKan Liang 
4996a3b1e845SKan Liang 	pci_write_config_dword(pdev, hwc->config_base, (u32)(hwc->config | SNBEP_PMON_CTL_EN));
4997a3b1e845SKan Liang 	pci_write_config_dword(pdev, hwc->config_base + 4, (u32)(hwc->config >> 32));
4998a3b1e845SKan Liang }
4999a3b1e845SKan Liang 
5000a3b1e845SKan Liang static struct intel_uncore_ops snr_pcie3_uncore_pci_ops = {
5001a3b1e845SKan Liang 	.init_box	= snr_m2m_uncore_pci_init_box,
5002a3b1e845SKan Liang 	.disable_box	= snbep_uncore_pci_disable_box,
5003a3b1e845SKan Liang 	.enable_box	= snbep_uncore_pci_enable_box,
5004a3b1e845SKan Liang 	.disable_event	= snbep_uncore_pci_disable_event,
5005a3b1e845SKan Liang 	.enable_event	= snr_uncore_pci_enable_event,
5006a3b1e845SKan Liang 	.read_counter	= snbep_uncore_pci_read_counter,
5007a3b1e845SKan Liang };
5008a3b1e845SKan Liang 
5009a3b1e845SKan Liang static struct intel_uncore_type snr_uncore_pcie3 = {
5010a3b1e845SKan Liang 	.name		= "pcie3",
5011a3b1e845SKan Liang 	.num_counters	= 4,
5012a3b1e845SKan Liang 	.num_boxes	= 1,
5013a3b1e845SKan Liang 	.perf_ctr_bits	= 48,
5014a3b1e845SKan Liang 	.perf_ctr	= SNR_PCIE3_PCI_PMON_CTR0,
5015a3b1e845SKan Liang 	.event_ctl	= SNR_PCIE3_PCI_PMON_CTL0,
5016a3b1e845SKan Liang 	.event_mask	= SKX_IIO_PMON_RAW_EVENT_MASK,
5017a3b1e845SKan Liang 	.event_mask_ext	= SKX_IIO_PMON_RAW_EVENT_MASK_EXT,
5018a3b1e845SKan Liang 	.box_ctl	= SNR_PCIE3_PCI_PMON_BOX_CTL,
5019a3b1e845SKan Liang 	.ops		= &snr_pcie3_uncore_pci_ops,
5020a3b1e845SKan Liang 	.format_group	= &skx_uncore_iio_format_group,
5021a3b1e845SKan Liang };
5022a3b1e845SKan Liang 
5023210cc5f9SKan Liang enum {
5024210cc5f9SKan Liang 	SNR_PCI_UNCORE_M2M,
5025a3b1e845SKan Liang 	SNR_PCI_UNCORE_PCIE3,
5026210cc5f9SKan Liang };
5027210cc5f9SKan Liang 
5028210cc5f9SKan Liang static struct intel_uncore_type *snr_pci_uncores[] = {
5029210cc5f9SKan Liang 	[SNR_PCI_UNCORE_M2M]		= &snr_uncore_m2m,
5030a3b1e845SKan Liang 	[SNR_PCI_UNCORE_PCIE3]		= &snr_uncore_pcie3,
5031210cc5f9SKan Liang 	NULL,
5032210cc5f9SKan Liang };
5033210cc5f9SKan Liang 
5034210cc5f9SKan Liang static const struct pci_device_id snr_uncore_pci_ids[] = {
5035210cc5f9SKan Liang 	{ /* M2M */
5036210cc5f9SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a),
5037210cc5f9SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(12, 0, SNR_PCI_UNCORE_M2M, 0),
5038210cc5f9SKan Liang 	},
5039210cc5f9SKan Liang 	{ /* end: all zeroes */ }
5040210cc5f9SKan Liang };
5041210cc5f9SKan Liang 
5042210cc5f9SKan Liang static struct pci_driver snr_uncore_pci_driver = {
5043210cc5f9SKan Liang 	.name		= "snr_uncore",
5044210cc5f9SKan Liang 	.id_table	= snr_uncore_pci_ids,
5045210cc5f9SKan Liang };
5046210cc5f9SKan Liang 
5047a3b1e845SKan Liang static const struct pci_device_id snr_uncore_pci_sub_ids[] = {
5048a3b1e845SKan Liang 	{ /* PCIe3 RP */
5049a3b1e845SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x334a),
5050a3b1e845SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(4, 0, SNR_PCI_UNCORE_PCIE3, 0),
5051a3b1e845SKan Liang 	},
5052a3b1e845SKan Liang 	{ /* end: all zeroes */ }
5053a3b1e845SKan Liang };
5054a3b1e845SKan Liang 
5055a3b1e845SKan Liang static struct pci_driver snr_uncore_pci_sub_driver = {
5056a3b1e845SKan Liang 	.name		= "snr_uncore_sub",
5057a3b1e845SKan Liang 	.id_table	= snr_uncore_pci_sub_ids,
5058a3b1e845SKan Liang };
5059a3b1e845SKan Liang 
5060210cc5f9SKan Liang int snr_uncore_pci_init(void)
5061210cc5f9SKan Liang {
5062210cc5f9SKan Liang 	/* SNR UBOX DID */
5063210cc5f9SKan Liang 	int ret = snbep_pci2phy_map_init(0x3460, SKX_CPUNODEID,
5064210cc5f9SKan Liang 					 SKX_GIDNIDMAP, true);
5065210cc5f9SKan Liang 
5066210cc5f9SKan Liang 	if (ret)
5067210cc5f9SKan Liang 		return ret;
5068210cc5f9SKan Liang 
5069210cc5f9SKan Liang 	uncore_pci_uncores = snr_pci_uncores;
5070210cc5f9SKan Liang 	uncore_pci_driver = &snr_uncore_pci_driver;
5071a3b1e845SKan Liang 	uncore_pci_sub_driver = &snr_uncore_pci_sub_driver;
5072210cc5f9SKan Liang 	return 0;
5073210cc5f9SKan Liang }
5074210cc5f9SKan Liang 
50751583971bSKan Liang #define SNR_MC_DEVICE_ID	0x3451
50761583971bSKan Liang 
50771583971bSKan Liang static struct pci_dev *snr_uncore_get_mc_dev(unsigned int device, int id)
5078ee49532bSKan Liang {
5079ee49532bSKan Liang 	struct pci_dev *mc_dev = NULL;
5080ba9506beSSteve Wahl 	int pkg;
5081ee49532bSKan Liang 
5082ee49532bSKan Liang 	while (1) {
50831583971bSKan Liang 		mc_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, mc_dev);
5084ee49532bSKan Liang 		if (!mc_dev)
5085ee49532bSKan Liang 			break;
5086ba9506beSSteve Wahl 		pkg = uncore_pcibus_to_dieid(mc_dev->bus);
5087ba9506beSSteve Wahl 		if (pkg == id)
5088ee49532bSKan Liang 			break;
5089ee49532bSKan Liang 	}
5090ee49532bSKan Liang 	return mc_dev;
5091ee49532bSKan Liang }
5092ee49532bSKan Liang 
50931583971bSKan Liang static int snr_uncore_mmio_map(struct intel_uncore_box *box,
50941583971bSKan Liang 			       unsigned int box_ctl, int mem_offset,
50951583971bSKan Liang 			       unsigned int device)
5096ee49532bSKan Liang {
50971583971bSKan Liang 	struct pci_dev *pdev = snr_uncore_get_mc_dev(device, box->dieid);
50981b94d31dSKan Liang 	struct intel_uncore_type *type = box->pmu->type;
5099ee49532bSKan Liang 	resource_size_t addr;
5100ee49532bSKan Liang 	u32 pci_dword;
5101ee49532bSKan Liang 
5102ee49532bSKan Liang 	if (!pdev)
51031583971bSKan Liang 		return -ENODEV;
5104ee49532bSKan Liang 
5105ee49532bSKan Liang 	pci_read_config_dword(pdev, SNR_IMC_MMIO_BASE_OFFSET, &pci_dword);
51060b3a8738SColin Ian King 	addr = ((resource_size_t)pci_dword & SNR_IMC_MMIO_BASE_MASK) << 23;
5107ee49532bSKan Liang 
51083442a9ecSKan Liang 	pci_read_config_dword(pdev, mem_offset, &pci_dword);
5109ee49532bSKan Liang 	addr |= (pci_dword & SNR_IMC_MMIO_MEM0_MASK) << 12;
5110ee49532bSKan Liang 
5111ee49532bSKan Liang 	addr += box_ctl;
5112ee49532bSKan Liang 
51131b94d31dSKan Liang 	box->io_addr = ioremap(addr, type->mmio_map_size);
51141b94d31dSKan Liang 	if (!box->io_addr) {
51151b94d31dSKan Liang 		pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
51161583971bSKan Liang 		return -EINVAL;
51171b94d31dSKan Liang 	}
5118ee49532bSKan Liang 
51191583971bSKan Liang 	return 0;
51201583971bSKan Liang }
51211583971bSKan Liang 
51221583971bSKan Liang static void __snr_uncore_mmio_init_box(struct intel_uncore_box *box,
51231583971bSKan Liang 				       unsigned int box_ctl, int mem_offset,
51241583971bSKan Liang 				       unsigned int device)
51251583971bSKan Liang {
51261583971bSKan Liang 	if (!snr_uncore_mmio_map(box, box_ctl, mem_offset, device))
5127ee49532bSKan Liang 		writel(IVBEP_PMON_BOX_CTL_INT, box->io_addr);
5128ee49532bSKan Liang }
5129ee49532bSKan Liang 
51303442a9ecSKan Liang static void snr_uncore_mmio_init_box(struct intel_uncore_box *box)
51313442a9ecSKan Liang {
51323442a9ecSKan Liang 	__snr_uncore_mmio_init_box(box, uncore_mmio_box_ctl(box),
51331583971bSKan Liang 				   SNR_IMC_MMIO_MEM0_OFFSET,
51341583971bSKan Liang 				   SNR_MC_DEVICE_ID);
51353442a9ecSKan Liang }
51363442a9ecSKan Liang 
5137ee49532bSKan Liang static void snr_uncore_mmio_disable_box(struct intel_uncore_box *box)
5138ee49532bSKan Liang {
5139ee49532bSKan Liang 	u32 config;
5140ee49532bSKan Liang 
5141ee49532bSKan Liang 	if (!box->io_addr)
5142ee49532bSKan Liang 		return;
5143ee49532bSKan Liang 
5144ee49532bSKan Liang 	config = readl(box->io_addr);
5145ee49532bSKan Liang 	config |= SNBEP_PMON_BOX_CTL_FRZ;
5146ee49532bSKan Liang 	writel(config, box->io_addr);
5147ee49532bSKan Liang }
5148ee49532bSKan Liang 
5149ee49532bSKan Liang static void snr_uncore_mmio_enable_box(struct intel_uncore_box *box)
5150ee49532bSKan Liang {
5151ee49532bSKan Liang 	u32 config;
5152ee49532bSKan Liang 
5153ee49532bSKan Liang 	if (!box->io_addr)
5154ee49532bSKan Liang 		return;
5155ee49532bSKan Liang 
5156ee49532bSKan Liang 	config = readl(box->io_addr);
5157ee49532bSKan Liang 	config &= ~SNBEP_PMON_BOX_CTL_FRZ;
5158ee49532bSKan Liang 	writel(config, box->io_addr);
5159ee49532bSKan Liang }
5160ee49532bSKan Liang 
5161ee49532bSKan Liang static void snr_uncore_mmio_enable_event(struct intel_uncore_box *box,
5162ee49532bSKan Liang 					   struct perf_event *event)
5163ee49532bSKan Liang {
5164ee49532bSKan Liang 	struct hw_perf_event *hwc = &event->hw;
5165ee49532bSKan Liang 
5166ee49532bSKan Liang 	if (!box->io_addr)
5167ee49532bSKan Liang 		return;
5168ee49532bSKan Liang 
5169f0171973SKan Liang 	if (!uncore_mmio_is_valid_offset(box, hwc->config_base))
5170f0171973SKan Liang 		return;
5171f0171973SKan Liang 
5172ee49532bSKan Liang 	writel(hwc->config | SNBEP_PMON_CTL_EN,
5173ee49532bSKan Liang 	       box->io_addr + hwc->config_base);
5174ee49532bSKan Liang }
5175ee49532bSKan Liang 
5176ee49532bSKan Liang static void snr_uncore_mmio_disable_event(struct intel_uncore_box *box,
5177ee49532bSKan Liang 					    struct perf_event *event)
5178ee49532bSKan Liang {
5179ee49532bSKan Liang 	struct hw_perf_event *hwc = &event->hw;
5180ee49532bSKan Liang 
5181ee49532bSKan Liang 	if (!box->io_addr)
5182ee49532bSKan Liang 		return;
5183ee49532bSKan Liang 
5184f0171973SKan Liang 	if (!uncore_mmio_is_valid_offset(box, hwc->config_base))
5185f0171973SKan Liang 		return;
5186f0171973SKan Liang 
5187ee49532bSKan Liang 	writel(hwc->config, box->io_addr + hwc->config_base);
5188ee49532bSKan Liang }
5189ee49532bSKan Liang 
5190ee49532bSKan Liang static struct intel_uncore_ops snr_uncore_mmio_ops = {
5191ee49532bSKan Liang 	.init_box	= snr_uncore_mmio_init_box,
5192ee49532bSKan Liang 	.exit_box	= uncore_mmio_exit_box,
5193ee49532bSKan Liang 	.disable_box	= snr_uncore_mmio_disable_box,
5194ee49532bSKan Liang 	.enable_box	= snr_uncore_mmio_enable_box,
5195ee49532bSKan Liang 	.disable_event	= snr_uncore_mmio_disable_event,
5196ee49532bSKan Liang 	.enable_event	= snr_uncore_mmio_enable_event,
5197ee49532bSKan Liang 	.read_counter	= uncore_mmio_read_counter,
5198ee49532bSKan Liang };
5199ee49532bSKan Liang 
5200ee49532bSKan Liang static struct uncore_event_desc snr_uncore_imc_events[] = {
5201ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(clockticks,      "event=0x00,umask=0x00"),
5202ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(cas_count_read,  "event=0x04,umask=0x0f"),
5203ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(cas_count_read.scale, "6.103515625e-5"),
5204ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(cas_count_read.unit, "MiB"),
5205ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x30"),
5206ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(cas_count_write.scale, "6.103515625e-5"),
5207ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(cas_count_write.unit, "MiB"),
5208ee49532bSKan Liang 	{ /* end: all zeroes */ },
5209ee49532bSKan Liang };
5210ee49532bSKan Liang 
5211ee49532bSKan Liang static struct intel_uncore_type snr_uncore_imc = {
5212ee49532bSKan Liang 	.name		= "imc",
5213ee49532bSKan Liang 	.num_counters   = 4,
5214ee49532bSKan Liang 	.num_boxes	= 2,
5215ee49532bSKan Liang 	.perf_ctr_bits	= 48,
5216ee49532bSKan Liang 	.fixed_ctr_bits	= 48,
5217ee49532bSKan Liang 	.fixed_ctr	= SNR_IMC_MMIO_PMON_FIXED_CTR,
5218ee49532bSKan Liang 	.fixed_ctl	= SNR_IMC_MMIO_PMON_FIXED_CTL,
5219ee49532bSKan Liang 	.event_descs	= snr_uncore_imc_events,
5220ee49532bSKan Liang 	.perf_ctr	= SNR_IMC_MMIO_PMON_CTR0,
5221ee49532bSKan Liang 	.event_ctl	= SNR_IMC_MMIO_PMON_CTL0,
5222ee49532bSKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
5223ee49532bSKan Liang 	.box_ctl	= SNR_IMC_MMIO_PMON_BOX_CTL,
5224ee49532bSKan Liang 	.mmio_offset	= SNR_IMC_MMIO_OFFSET,
52251b94d31dSKan Liang 	.mmio_map_size	= SNR_IMC_MMIO_SIZE,
5226ee49532bSKan Liang 	.ops		= &snr_uncore_mmio_ops,
5227ee49532bSKan Liang 	.format_group	= &skx_uncore_format_group,
5228ee49532bSKan Liang };
5229ee49532bSKan Liang 
5230ee49532bSKan Liang enum perf_uncore_snr_imc_freerunning_type_id {
5231ee49532bSKan Liang 	SNR_IMC_DCLK,
5232ee49532bSKan Liang 	SNR_IMC_DDR,
5233ee49532bSKan Liang 
5234ee49532bSKan Liang 	SNR_IMC_FREERUNNING_TYPE_MAX,
5235ee49532bSKan Liang };
5236ee49532bSKan Liang 
5237ee49532bSKan Liang static struct freerunning_counters snr_imc_freerunning[] = {
5238ee49532bSKan Liang 	[SNR_IMC_DCLK]	= { 0x22b0, 0x0, 0, 1, 48 },
5239ee49532bSKan Liang 	[SNR_IMC_DDR]	= { 0x2290, 0x8, 0, 2, 48 },
5240ee49532bSKan Liang };
5241ee49532bSKan Liang 
5242ee49532bSKan Liang static struct uncore_event_desc snr_uncore_imc_freerunning_events[] = {
5243ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(dclk,		"event=0xff,umask=0x10"),
5244ee49532bSKan Liang 
5245ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(read,		"event=0xff,umask=0x20"),
52468191016aSKan Liang 	INTEL_UNCORE_EVENT_DESC(read.scale,	"6.103515625e-5"),
5247ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(read.unit,	"MiB"),
5248ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(write,		"event=0xff,umask=0x21"),
52498191016aSKan Liang 	INTEL_UNCORE_EVENT_DESC(write.scale,	"6.103515625e-5"),
5250ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(write.unit,	"MiB"),
5251fa694ae5SKan Liang 	{ /* end: all zeroes */ },
5252ee49532bSKan Liang };
5253ee49532bSKan Liang 
5254ee49532bSKan Liang static struct intel_uncore_ops snr_uncore_imc_freerunning_ops = {
5255ee49532bSKan Liang 	.init_box	= snr_uncore_mmio_init_box,
5256ee49532bSKan Liang 	.exit_box	= uncore_mmio_exit_box,
5257ee49532bSKan Liang 	.read_counter	= uncore_mmio_read_counter,
5258ee49532bSKan Liang 	.hw_config	= uncore_freerunning_hw_config,
5259ee49532bSKan Liang };
5260ee49532bSKan Liang 
5261ee49532bSKan Liang static struct intel_uncore_type snr_uncore_imc_free_running = {
5262ee49532bSKan Liang 	.name			= "imc_free_running",
5263ee49532bSKan Liang 	.num_counters		= 3,
5264ee49532bSKan Liang 	.num_boxes		= 1,
5265ee49532bSKan Liang 	.num_freerunning_types	= SNR_IMC_FREERUNNING_TYPE_MAX,
52661b94d31dSKan Liang 	.mmio_map_size		= SNR_IMC_MMIO_SIZE,
5267ee49532bSKan Liang 	.freerunning		= snr_imc_freerunning,
5268ee49532bSKan Liang 	.ops			= &snr_uncore_imc_freerunning_ops,
5269ee49532bSKan Liang 	.event_descs		= snr_uncore_imc_freerunning_events,
5270ee49532bSKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
5271ee49532bSKan Liang };
5272ee49532bSKan Liang 
5273ee49532bSKan Liang static struct intel_uncore_type *snr_mmio_uncores[] = {
5274ee49532bSKan Liang 	&snr_uncore_imc,
5275ee49532bSKan Liang 	&snr_uncore_imc_free_running,
5276ee49532bSKan Liang 	NULL,
5277ee49532bSKan Liang };
5278ee49532bSKan Liang 
5279ee49532bSKan Liang void snr_uncore_mmio_init(void)
5280ee49532bSKan Liang {
5281ee49532bSKan Liang 	uncore_mmio_uncores = snr_mmio_uncores;
5282ee49532bSKan Liang }
5283ee49532bSKan Liang 
5284210cc5f9SKan Liang /* end of SNR uncore support */
52852b3b76b5SKan Liang 
52862b3b76b5SKan Liang /* ICX uncore support */
52872b3b76b5SKan Liang 
52882b3b76b5SKan Liang static unsigned icx_cha_msr_offsets[] = {
52892b3b76b5SKan Liang 	0x2a0, 0x2ae, 0x2bc, 0x2ca, 0x2d8, 0x2e6, 0x2f4, 0x302, 0x310,
52902b3b76b5SKan Liang 	0x31e, 0x32c, 0x33a, 0x348, 0x356, 0x364, 0x372, 0x380, 0x38e,
52912b3b76b5SKan Liang 	0x3aa, 0x3b8, 0x3c6, 0x3d4, 0x3e2, 0x3f0, 0x3fe, 0x40c, 0x41a,
52922b3b76b5SKan Liang 	0x428, 0x436, 0x444, 0x452, 0x460, 0x46e, 0x47c, 0x0,   0xe,
52932b3b76b5SKan Liang 	0x1c,  0x2a,  0x38,  0x46,
52942b3b76b5SKan Liang };
52952b3b76b5SKan Liang 
52962b3b76b5SKan Liang static int icx_cha_hw_config(struct intel_uncore_box *box, struct perf_event *event)
52972b3b76b5SKan Liang {
52982b3b76b5SKan Liang 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
52992b3b76b5SKan Liang 	bool tie_en = !!(event->hw.config & SNBEP_CBO_PMON_CTL_TID_EN);
53002b3b76b5SKan Liang 
53012b3b76b5SKan Liang 	if (tie_en) {
53022b3b76b5SKan Liang 		reg1->reg = ICX_C34_MSR_PMON_BOX_FILTER0 +
53032b3b76b5SKan Liang 			    icx_cha_msr_offsets[box->pmu->pmu_idx];
53042b3b76b5SKan Liang 		reg1->config = event->attr.config1 & SKX_CHA_MSR_PMON_BOX_FILTER_TID;
53052b3b76b5SKan Liang 		reg1->idx = 0;
53062b3b76b5SKan Liang 	}
53072b3b76b5SKan Liang 
53082b3b76b5SKan Liang 	return 0;
53092b3b76b5SKan Liang }
53102b3b76b5SKan Liang 
53112b3b76b5SKan Liang static struct intel_uncore_ops icx_uncore_chabox_ops = {
53122b3b76b5SKan Liang 	.init_box		= ivbep_uncore_msr_init_box,
53132b3b76b5SKan Liang 	.disable_box		= snbep_uncore_msr_disable_box,
53142b3b76b5SKan Liang 	.enable_box		= snbep_uncore_msr_enable_box,
53152b3b76b5SKan Liang 	.disable_event		= snbep_uncore_msr_disable_event,
53162b3b76b5SKan Liang 	.enable_event		= snr_cha_enable_event,
53172b3b76b5SKan Liang 	.read_counter		= uncore_msr_read_counter,
53182b3b76b5SKan Liang 	.hw_config		= icx_cha_hw_config,
53192b3b76b5SKan Liang };
53202b3b76b5SKan Liang 
53212b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_chabox = {
53222b3b76b5SKan Liang 	.name			= "cha",
53232b3b76b5SKan Liang 	.num_counters		= 4,
53242b3b76b5SKan Liang 	.perf_ctr_bits		= 48,
53252b3b76b5SKan Liang 	.event_ctl		= ICX_C34_MSR_PMON_CTL0,
53262b3b76b5SKan Liang 	.perf_ctr		= ICX_C34_MSR_PMON_CTR0,
53272b3b76b5SKan Liang 	.box_ctl		= ICX_C34_MSR_PMON_BOX_CTL,
53282b3b76b5SKan Liang 	.msr_offsets		= icx_cha_msr_offsets,
53292b3b76b5SKan Liang 	.event_mask		= HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
53302b3b76b5SKan Liang 	.event_mask_ext		= SNR_CHA_RAW_EVENT_MASK_EXT,
53312b3b76b5SKan Liang 	.constraints		= skx_uncore_chabox_constraints,
53322b3b76b5SKan Liang 	.ops			= &icx_uncore_chabox_ops,
53332b3b76b5SKan Liang 	.format_group		= &snr_uncore_chabox_format_group,
53342b3b76b5SKan Liang };
53352b3b76b5SKan Liang 
53362b3b76b5SKan Liang static unsigned icx_msr_offsets[] = {
53372b3b76b5SKan Liang 	0x0, 0x20, 0x40, 0x90, 0xb0, 0xd0,
53382b3b76b5SKan Liang };
53392b3b76b5SKan Liang 
53402b3b76b5SKan Liang static struct event_constraint icx_uncore_iio_constraints[] = {
53412b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x02, 0x3),
53422b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x03, 0x3),
53432b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x83, 0x3),
5344f42e8a60SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x88, 0xc),
53452b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0xc0, 0xc),
53462b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0xc5, 0xc),
5347f42e8a60SKan Liang 	UNCORE_EVENT_CONSTRAINT(0xd5, 0xc),
53482b3b76b5SKan Liang 	EVENT_CONSTRAINT_END
53492b3b76b5SKan Liang };
53502b3b76b5SKan Liang 
535110337e95SAlexander Antonov static umode_t
535210337e95SAlexander Antonov icx_iio_mapping_visible(struct kobject *kobj, struct attribute *attr, int die)
535310337e95SAlexander Antonov {
535410337e95SAlexander Antonov 	/* Root bus 0x00 is valid only for pmu_idx = 5. */
535510337e95SAlexander Antonov 	return pmu_iio_mapping_visible(kobj, attr, die, 5);
535610337e95SAlexander Antonov }
535710337e95SAlexander Antonov 
535810337e95SAlexander Antonov static struct attribute_group icx_iio_mapping_group = {
535910337e95SAlexander Antonov 	.is_visible	= icx_iio_mapping_visible,
536010337e95SAlexander Antonov };
536110337e95SAlexander Antonov 
536210337e95SAlexander Antonov static const struct attribute_group *icx_iio_attr_update[] = {
536310337e95SAlexander Antonov 	&icx_iio_mapping_group,
536410337e95SAlexander Antonov 	NULL,
536510337e95SAlexander Antonov };
536610337e95SAlexander Antonov 
536710337e95SAlexander Antonov /*
536810337e95SAlexander Antonov  * ICX has a static mapping of stack IDs from SAD_CONTROL_CFG notation to PMON
536910337e95SAlexander Antonov  */
537010337e95SAlexander Antonov enum {
537110337e95SAlexander Antonov 	ICX_PCIE1_PMON_ID,
537210337e95SAlexander Antonov 	ICX_PCIE2_PMON_ID,
537310337e95SAlexander Antonov 	ICX_PCIE3_PMON_ID,
537410337e95SAlexander Antonov 	ICX_PCIE4_PMON_ID,
537510337e95SAlexander Antonov 	ICX_PCIE5_PMON_ID,
537610337e95SAlexander Antonov 	ICX_CBDMA_DMI_PMON_ID
537710337e95SAlexander Antonov };
537810337e95SAlexander Antonov 
537910337e95SAlexander Antonov static u8 icx_sad_pmon_mapping[] = {
538010337e95SAlexander Antonov 	ICX_CBDMA_DMI_PMON_ID,
538110337e95SAlexander Antonov 	ICX_PCIE1_PMON_ID,
538210337e95SAlexander Antonov 	ICX_PCIE2_PMON_ID,
538310337e95SAlexander Antonov 	ICX_PCIE3_PMON_ID,
538410337e95SAlexander Antonov 	ICX_PCIE4_PMON_ID,
538510337e95SAlexander Antonov 	ICX_PCIE5_PMON_ID,
538610337e95SAlexander Antonov };
538710337e95SAlexander Antonov 
538810337e95SAlexander Antonov static int icx_iio_get_topology(struct intel_uncore_type *type)
538910337e95SAlexander Antonov {
539010337e95SAlexander Antonov 	return sad_cfg_iio_topology(type, icx_sad_pmon_mapping);
539110337e95SAlexander Antonov }
539210337e95SAlexander Antonov 
539310337e95SAlexander Antonov static int icx_iio_set_mapping(struct intel_uncore_type *type)
539410337e95SAlexander Antonov {
5395efe06270SAlexander Antonov 	/* Detect ICX-D system. This case is not supported */
5396efe06270SAlexander Antonov 	if (boot_cpu_data.x86_model == INTEL_FAM6_ICELAKE_D) {
5397efe06270SAlexander Antonov 		pmu_clear_mapping_attr(type->attr_update, &icx_iio_mapping_group);
5398efe06270SAlexander Antonov 		return -EPERM;
5399efe06270SAlexander Antonov 	}
540010337e95SAlexander Antonov 	return pmu_iio_set_mapping(type, &icx_iio_mapping_group);
540110337e95SAlexander Antonov }
540210337e95SAlexander Antonov 
54033f2cbe38SAlexander Antonov static void icx_iio_cleanup_mapping(struct intel_uncore_type *type)
54043f2cbe38SAlexander Antonov {
54054d13be8aSAlexander Antonov 	pmu_cleanup_mapping(type, &icx_iio_mapping_group);
54063f2cbe38SAlexander Antonov }
54073f2cbe38SAlexander Antonov 
54082b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_iio = {
54092b3b76b5SKan Liang 	.name			= "iio",
54102b3b76b5SKan Liang 	.num_counters		= 4,
54112b3b76b5SKan Liang 	.num_boxes		= 6,
54122b3b76b5SKan Liang 	.perf_ctr_bits		= 48,
54132b3b76b5SKan Liang 	.event_ctl		= ICX_IIO_MSR_PMON_CTL0,
54142b3b76b5SKan Liang 	.perf_ctr		= ICX_IIO_MSR_PMON_CTR0,
54152b3b76b5SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
54162b3b76b5SKan Liang 	.event_mask_ext		= SNR_IIO_PMON_RAW_EVENT_MASK_EXT,
54172b3b76b5SKan Liang 	.box_ctl		= ICX_IIO_MSR_PMON_BOX_CTL,
54182b3b76b5SKan Liang 	.msr_offsets		= icx_msr_offsets,
54192b3b76b5SKan Liang 	.constraints		= icx_uncore_iio_constraints,
54202b3b76b5SKan Liang 	.ops			= &skx_uncore_iio_ops,
54212b3b76b5SKan Liang 	.format_group		= &snr_uncore_iio_format_group,
542210337e95SAlexander Antonov 	.attr_update		= icx_iio_attr_update,
542310337e95SAlexander Antonov 	.get_topology		= icx_iio_get_topology,
542410337e95SAlexander Antonov 	.set_mapping		= icx_iio_set_mapping,
54253f2cbe38SAlexander Antonov 	.cleanup_mapping	= icx_iio_cleanup_mapping,
54262b3b76b5SKan Liang };
54272b3b76b5SKan Liang 
54282b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_irp = {
54292b3b76b5SKan Liang 	.name			= "irp",
54302b3b76b5SKan Liang 	.num_counters		= 2,
54312b3b76b5SKan Liang 	.num_boxes		= 6,
54322b3b76b5SKan Liang 	.perf_ctr_bits		= 48,
54332b3b76b5SKan Liang 	.event_ctl		= ICX_IRP0_MSR_PMON_CTL0,
54342b3b76b5SKan Liang 	.perf_ctr		= ICX_IRP0_MSR_PMON_CTR0,
54352b3b76b5SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
54362b3b76b5SKan Liang 	.box_ctl		= ICX_IRP0_MSR_PMON_BOX_CTL,
54372b3b76b5SKan Liang 	.msr_offsets		= icx_msr_offsets,
54382b3b76b5SKan Liang 	.ops			= &ivbep_uncore_msr_ops,
54392b3b76b5SKan Liang 	.format_group		= &ivbep_uncore_format_group,
54402b3b76b5SKan Liang };
54412b3b76b5SKan Liang 
54422b3b76b5SKan Liang static struct event_constraint icx_uncore_m2pcie_constraints[] = {
54432b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
54442b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
54452b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
54462b3b76b5SKan Liang 	EVENT_CONSTRAINT_END
54472b3b76b5SKan Liang };
54482b3b76b5SKan Liang 
54492b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_m2pcie = {
54502b3b76b5SKan Liang 	.name		= "m2pcie",
54512b3b76b5SKan Liang 	.num_counters	= 4,
54522b3b76b5SKan Liang 	.num_boxes	= 6,
54532b3b76b5SKan Liang 	.perf_ctr_bits	= 48,
54542b3b76b5SKan Liang 	.event_ctl	= ICX_M2PCIE_MSR_PMON_CTL0,
54552b3b76b5SKan Liang 	.perf_ctr	= ICX_M2PCIE_MSR_PMON_CTR0,
54562b3b76b5SKan Liang 	.box_ctl	= ICX_M2PCIE_MSR_PMON_BOX_CTL,
54572b3b76b5SKan Liang 	.msr_offsets	= icx_msr_offsets,
54582b3b76b5SKan Liang 	.constraints	= icx_uncore_m2pcie_constraints,
54592b3b76b5SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
54602b3b76b5SKan Liang 	.ops		= &ivbep_uncore_msr_ops,
54612b3b76b5SKan Liang 	.format_group	= &ivbep_uncore_format_group,
54622b3b76b5SKan Liang };
54632b3b76b5SKan Liang 
54642b3b76b5SKan Liang enum perf_uncore_icx_iio_freerunning_type_id {
54652b3b76b5SKan Liang 	ICX_IIO_MSR_IOCLK,
54662b3b76b5SKan Liang 	ICX_IIO_MSR_BW_IN,
54672b3b76b5SKan Liang 
54682b3b76b5SKan Liang 	ICX_IIO_FREERUNNING_TYPE_MAX,
54692b3b76b5SKan Liang };
54702b3b76b5SKan Liang 
54712b3b76b5SKan Liang static unsigned icx_iio_clk_freerunning_box_offsets[] = {
54722b3b76b5SKan Liang 	0x0, 0x20, 0x40, 0x90, 0xb0, 0xd0,
54732b3b76b5SKan Liang };
54742b3b76b5SKan Liang 
54752b3b76b5SKan Liang static unsigned icx_iio_bw_freerunning_box_offsets[] = {
54762b3b76b5SKan Liang 	0x0, 0x10, 0x20, 0x90, 0xa0, 0xb0,
54772b3b76b5SKan Liang };
54782b3b76b5SKan Liang 
54792b3b76b5SKan Liang static struct freerunning_counters icx_iio_freerunning[] = {
54802b3b76b5SKan Liang 	[ICX_IIO_MSR_IOCLK]	= { 0xa55, 0x1, 0x20, 1, 48, icx_iio_clk_freerunning_box_offsets },
54812b3b76b5SKan Liang 	[ICX_IIO_MSR_BW_IN]	= { 0xaa0, 0x1, 0x10, 8, 48, icx_iio_bw_freerunning_box_offsets },
54822b3b76b5SKan Liang };
54832b3b76b5SKan Liang 
54842b3b76b5SKan Liang static struct uncore_event_desc icx_uncore_iio_freerunning_events[] = {
54852b3b76b5SKan Liang 	/* Free-Running IIO CLOCKS Counter */
54862b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(ioclk,			"event=0xff,umask=0x10"),
54872b3b76b5SKan Liang 	/* Free-Running IIO BANDWIDTH IN Counters */
54882b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0,		"event=0xff,umask=0x20"),
54892b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale,	"3.814697266e-6"),
54902b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit,	"MiB"),
54912b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1,		"event=0xff,umask=0x21"),
54922b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale,	"3.814697266e-6"),
54932b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit,	"MiB"),
54942b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2,		"event=0xff,umask=0x22"),
54952b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale,	"3.814697266e-6"),
54962b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit,	"MiB"),
54972b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3,		"event=0xff,umask=0x23"),
54982b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale,	"3.814697266e-6"),
54992b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit,	"MiB"),
55002b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4,		"event=0xff,umask=0x24"),
55012b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4.scale,	"3.814697266e-6"),
55022b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4.unit,	"MiB"),
55032b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5,		"event=0xff,umask=0x25"),
55042b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5.scale,	"3.814697266e-6"),
55052b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5.unit,	"MiB"),
55062b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6,		"event=0xff,umask=0x26"),
55072b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6.scale,	"3.814697266e-6"),
55082b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6.unit,	"MiB"),
55092b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7,		"event=0xff,umask=0x27"),
55102b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7.scale,	"3.814697266e-6"),
55112b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7.unit,	"MiB"),
55122b3b76b5SKan Liang 	{ /* end: all zeroes */ },
55132b3b76b5SKan Liang };
55142b3b76b5SKan Liang 
55152b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_iio_free_running = {
55162b3b76b5SKan Liang 	.name			= "iio_free_running",
55172b3b76b5SKan Liang 	.num_counters		= 9,
55182b3b76b5SKan Liang 	.num_boxes		= 6,
55192b3b76b5SKan Liang 	.num_freerunning_types	= ICX_IIO_FREERUNNING_TYPE_MAX,
55202b3b76b5SKan Liang 	.freerunning		= icx_iio_freerunning,
55212b3b76b5SKan Liang 	.ops			= &skx_uncore_iio_freerunning_ops,
55222b3b76b5SKan Liang 	.event_descs		= icx_uncore_iio_freerunning_events,
55232b3b76b5SKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
55242b3b76b5SKan Liang };
55252b3b76b5SKan Liang 
55262b3b76b5SKan Liang static struct intel_uncore_type *icx_msr_uncores[] = {
55272b3b76b5SKan Liang 	&skx_uncore_ubox,
55282b3b76b5SKan Liang 	&icx_uncore_chabox,
55292b3b76b5SKan Liang 	&icx_uncore_iio,
55302b3b76b5SKan Liang 	&icx_uncore_irp,
55312b3b76b5SKan Liang 	&icx_uncore_m2pcie,
55322b3b76b5SKan Liang 	&skx_uncore_pcu,
55332b3b76b5SKan Liang 	&icx_uncore_iio_free_running,
55342b3b76b5SKan Liang 	NULL,
55352b3b76b5SKan Liang };
55362b3b76b5SKan Liang 
55372b3b76b5SKan Liang /*
55382b3b76b5SKan Liang  * To determine the number of CHAs, it should read CAPID6(Low) and CAPID7 (High)
55392b3b76b5SKan Liang  * registers which located at Device 30, Function 3
55402b3b76b5SKan Liang  */
55412b3b76b5SKan Liang #define ICX_CAPID6		0x9c
55422b3b76b5SKan Liang #define ICX_CAPID7		0xa0
55432b3b76b5SKan Liang 
55442b3b76b5SKan Liang static u64 icx_count_chabox(void)
55452b3b76b5SKan Liang {
55462b3b76b5SKan Liang 	struct pci_dev *dev = NULL;
55472b3b76b5SKan Liang 	u64 caps = 0;
55482b3b76b5SKan Liang 
55492b3b76b5SKan Liang 	dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x345b, dev);
55502b3b76b5SKan Liang 	if (!dev)
55512b3b76b5SKan Liang 		goto out;
55522b3b76b5SKan Liang 
55532b3b76b5SKan Liang 	pci_read_config_dword(dev, ICX_CAPID6, (u32 *)&caps);
55542b3b76b5SKan Liang 	pci_read_config_dword(dev, ICX_CAPID7, (u32 *)&caps + 1);
55552b3b76b5SKan Liang out:
55562b3b76b5SKan Liang 	pci_dev_put(dev);
55572b3b76b5SKan Liang 	return hweight64(caps);
55582b3b76b5SKan Liang }
55592b3b76b5SKan Liang 
55602b3b76b5SKan Liang void icx_uncore_cpu_init(void)
55612b3b76b5SKan Liang {
55622b3b76b5SKan Liang 	u64 num_boxes = icx_count_chabox();
55632b3b76b5SKan Liang 
55642b3b76b5SKan Liang 	if (WARN_ON(num_boxes > ARRAY_SIZE(icx_cha_msr_offsets)))
55652b3b76b5SKan Liang 		return;
55662b3b76b5SKan Liang 	icx_uncore_chabox.num_boxes = num_boxes;
55672b3b76b5SKan Liang 	uncore_msr_uncores = icx_msr_uncores;
55682b3b76b5SKan Liang }
55692b3b76b5SKan Liang 
55702b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_m2m = {
55712b3b76b5SKan Liang 	.name		= "m2m",
55722b3b76b5SKan Liang 	.num_counters   = 4,
55732b3b76b5SKan Liang 	.num_boxes	= 4,
55742b3b76b5SKan Liang 	.perf_ctr_bits	= 48,
55752b3b76b5SKan Liang 	.perf_ctr	= SNR_M2M_PCI_PMON_CTR0,
55762b3b76b5SKan Liang 	.event_ctl	= SNR_M2M_PCI_PMON_CTL0,
55772b3b76b5SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
5578848ff376SKan Liang 	.event_mask_ext	= SNR_M2M_PCI_PMON_UMASK_EXT,
55792b3b76b5SKan Liang 	.box_ctl	= SNR_M2M_PCI_PMON_BOX_CTL,
55802b3b76b5SKan Liang 	.ops		= &snr_m2m_uncore_pci_ops,
5581848ff376SKan Liang 	.format_group	= &snr_m2m_uncore_format_group,
55822b3b76b5SKan Liang };
55832b3b76b5SKan Liang 
55842b3b76b5SKan Liang static struct attribute *icx_upi_uncore_formats_attr[] = {
55852b3b76b5SKan Liang 	&format_attr_event.attr,
55862b3b76b5SKan Liang 	&format_attr_umask_ext4.attr,
55872b3b76b5SKan Liang 	&format_attr_edge.attr,
55882b3b76b5SKan Liang 	&format_attr_inv.attr,
55892b3b76b5SKan Liang 	&format_attr_thresh8.attr,
55902b3b76b5SKan Liang 	NULL,
55912b3b76b5SKan Liang };
55922b3b76b5SKan Liang 
55932b3b76b5SKan Liang static const struct attribute_group icx_upi_uncore_format_group = {
55942b3b76b5SKan Liang 	.name = "format",
55952b3b76b5SKan Liang 	.attrs = icx_upi_uncore_formats_attr,
55962b3b76b5SKan Liang };
55972b3b76b5SKan Liang 
5598*f680b6e6SAlexander Antonov #define ICX_UPI_REGS_ADDR_DEVICE_LINK0	0x02
5599*f680b6e6SAlexander Antonov #define ICX_UPI_REGS_ADDR_FUNCTION	0x01
5600*f680b6e6SAlexander Antonov 
5601*f680b6e6SAlexander Antonov static int discover_upi_topology(struct intel_uncore_type *type, int ubox_did, int dev_link0)
5602*f680b6e6SAlexander Antonov {
5603*f680b6e6SAlexander Antonov 	struct pci_dev *ubox = NULL;
5604*f680b6e6SAlexander Antonov 	struct pci_dev *dev = NULL;
5605*f680b6e6SAlexander Antonov 	u32 nid, gid;
5606*f680b6e6SAlexander Antonov 	int i, idx, ret = -EPERM;
5607*f680b6e6SAlexander Antonov 	struct intel_uncore_topology *upi;
5608*f680b6e6SAlexander Antonov 	unsigned int devfn;
5609*f680b6e6SAlexander Antonov 
5610*f680b6e6SAlexander Antonov 	/* GIDNIDMAP method supports machines which have less than 8 sockets. */
5611*f680b6e6SAlexander Antonov 	if (uncore_max_dies() > 8)
5612*f680b6e6SAlexander Antonov 		goto err;
5613*f680b6e6SAlexander Antonov 
5614*f680b6e6SAlexander Antonov 	while ((ubox = pci_get_device(PCI_VENDOR_ID_INTEL, ubox_did, ubox))) {
5615*f680b6e6SAlexander Antonov 		ret = upi_nodeid_groupid(ubox, SKX_CPUNODEID, SKX_GIDNIDMAP, &nid, &gid);
5616*f680b6e6SAlexander Antonov 		if (ret) {
5617*f680b6e6SAlexander Antonov 			ret = pcibios_err_to_errno(ret);
5618*f680b6e6SAlexander Antonov 			break;
5619*f680b6e6SAlexander Antonov 		}
5620*f680b6e6SAlexander Antonov 
5621*f680b6e6SAlexander Antonov 		for (i = 0; i < 8; i++) {
5622*f680b6e6SAlexander Antonov 			if (nid != GIDNIDMAP(gid, i))
5623*f680b6e6SAlexander Antonov 				continue;
5624*f680b6e6SAlexander Antonov 			for (idx = 0; idx < type->num_boxes; idx++) {
5625*f680b6e6SAlexander Antonov 				upi = &type->topology[nid][idx];
5626*f680b6e6SAlexander Antonov 				devfn = PCI_DEVFN(dev_link0 + idx, ICX_UPI_REGS_ADDR_FUNCTION);
5627*f680b6e6SAlexander Antonov 				dev = pci_get_domain_bus_and_slot(pci_domain_nr(ubox->bus),
5628*f680b6e6SAlexander Antonov 								  ubox->bus->number,
5629*f680b6e6SAlexander Antonov 								  devfn);
5630*f680b6e6SAlexander Antonov 				if (dev) {
5631*f680b6e6SAlexander Antonov 					ret = upi_fill_topology(dev, upi, idx);
5632*f680b6e6SAlexander Antonov 					if (ret)
5633*f680b6e6SAlexander Antonov 						goto err;
5634*f680b6e6SAlexander Antonov 				}
5635*f680b6e6SAlexander Antonov 			}
5636*f680b6e6SAlexander Antonov 		}
5637*f680b6e6SAlexander Antonov 	}
5638*f680b6e6SAlexander Antonov err:
5639*f680b6e6SAlexander Antonov 	pci_dev_put(ubox);
5640*f680b6e6SAlexander Antonov 	pci_dev_put(dev);
5641*f680b6e6SAlexander Antonov 	return ret;
5642*f680b6e6SAlexander Antonov }
5643*f680b6e6SAlexander Antonov 
5644*f680b6e6SAlexander Antonov static int icx_upi_get_topology(struct intel_uncore_type *type)
5645*f680b6e6SAlexander Antonov {
5646*f680b6e6SAlexander Antonov 	return discover_upi_topology(type, ICX_UBOX_DID, ICX_UPI_REGS_ADDR_DEVICE_LINK0);
5647*f680b6e6SAlexander Antonov }
5648*f680b6e6SAlexander Antonov 
5649*f680b6e6SAlexander Antonov static struct attribute_group icx_upi_mapping_group = {
5650*f680b6e6SAlexander Antonov 	.is_visible	= skx_upi_mapping_visible,
5651*f680b6e6SAlexander Antonov };
5652*f680b6e6SAlexander Antonov 
5653*f680b6e6SAlexander Antonov static const struct attribute_group *icx_upi_attr_update[] = {
5654*f680b6e6SAlexander Antonov 	&icx_upi_mapping_group,
5655*f680b6e6SAlexander Antonov 	NULL
5656*f680b6e6SAlexander Antonov };
5657*f680b6e6SAlexander Antonov 
5658*f680b6e6SAlexander Antonov static int icx_upi_set_mapping(struct intel_uncore_type *type)
5659*f680b6e6SAlexander Antonov {
5660*f680b6e6SAlexander Antonov 	return pmu_upi_set_mapping(type, &icx_upi_mapping_group);
5661*f680b6e6SAlexander Antonov }
5662*f680b6e6SAlexander Antonov 
5663*f680b6e6SAlexander Antonov static void icx_upi_cleanup_mapping(struct intel_uncore_type *type)
5664*f680b6e6SAlexander Antonov {
5665*f680b6e6SAlexander Antonov 	pmu_cleanup_mapping(type, &icx_upi_mapping_group);
5666*f680b6e6SAlexander Antonov }
5667*f680b6e6SAlexander Antonov 
56682b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_upi = {
56692b3b76b5SKan Liang 	.name		= "upi",
56702b3b76b5SKan Liang 	.num_counters   = 4,
56712b3b76b5SKan Liang 	.num_boxes	= 3,
56722b3b76b5SKan Liang 	.perf_ctr_bits	= 48,
56732b3b76b5SKan Liang 	.perf_ctr	= ICX_UPI_PCI_PMON_CTR0,
56742b3b76b5SKan Liang 	.event_ctl	= ICX_UPI_PCI_PMON_CTL0,
56752b3b76b5SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
56762b3b76b5SKan Liang 	.event_mask_ext = ICX_UPI_CTL_UMASK_EXT,
56772b3b76b5SKan Liang 	.box_ctl	= ICX_UPI_PCI_PMON_BOX_CTL,
56782b3b76b5SKan Liang 	.ops		= &skx_upi_uncore_pci_ops,
56792b3b76b5SKan Liang 	.format_group	= &icx_upi_uncore_format_group,
5680*f680b6e6SAlexander Antonov 	.attr_update	= icx_upi_attr_update,
5681*f680b6e6SAlexander Antonov 	.get_topology	= icx_upi_get_topology,
5682*f680b6e6SAlexander Antonov 	.set_mapping	= icx_upi_set_mapping,
5683*f680b6e6SAlexander Antonov 	.cleanup_mapping = icx_upi_cleanup_mapping,
56842b3b76b5SKan Liang };
56852b3b76b5SKan Liang 
56862b3b76b5SKan Liang static struct event_constraint icx_uncore_m3upi_constraints[] = {
56872b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x1c, 0x1),
56882b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x1d, 0x1),
56892b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x1e, 0x1),
56902b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x1f, 0x1),
56912b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x40, 0x7),
56922b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x4e, 0x7),
56932b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x4f, 0x7),
56942b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x50, 0x7),
56952b3b76b5SKan Liang 	EVENT_CONSTRAINT_END
56962b3b76b5SKan Liang };
56972b3b76b5SKan Liang 
56982b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_m3upi = {
56992b3b76b5SKan Liang 	.name		= "m3upi",
57002b3b76b5SKan Liang 	.num_counters   = 4,
57012b3b76b5SKan Liang 	.num_boxes	= 3,
57022b3b76b5SKan Liang 	.perf_ctr_bits	= 48,
57032b3b76b5SKan Liang 	.perf_ctr	= ICX_M3UPI_PCI_PMON_CTR0,
57042b3b76b5SKan Liang 	.event_ctl	= ICX_M3UPI_PCI_PMON_CTL0,
57052b3b76b5SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
57062b3b76b5SKan Liang 	.box_ctl	= ICX_M3UPI_PCI_PMON_BOX_CTL,
57072b3b76b5SKan Liang 	.constraints	= icx_uncore_m3upi_constraints,
57082b3b76b5SKan Liang 	.ops		= &ivbep_uncore_pci_ops,
57092b3b76b5SKan Liang 	.format_group	= &skx_uncore_format_group,
57102b3b76b5SKan Liang };
57112b3b76b5SKan Liang 
57122b3b76b5SKan Liang enum {
57132b3b76b5SKan Liang 	ICX_PCI_UNCORE_M2M,
57142b3b76b5SKan Liang 	ICX_PCI_UNCORE_UPI,
57152b3b76b5SKan Liang 	ICX_PCI_UNCORE_M3UPI,
57162b3b76b5SKan Liang };
57172b3b76b5SKan Liang 
57182b3b76b5SKan Liang static struct intel_uncore_type *icx_pci_uncores[] = {
57192b3b76b5SKan Liang 	[ICX_PCI_UNCORE_M2M]		= &icx_uncore_m2m,
57202b3b76b5SKan Liang 	[ICX_PCI_UNCORE_UPI]		= &icx_uncore_upi,
57212b3b76b5SKan Liang 	[ICX_PCI_UNCORE_M3UPI]		= &icx_uncore_m3upi,
57222b3b76b5SKan Liang 	NULL,
57232b3b76b5SKan Liang };
57242b3b76b5SKan Liang 
57252b3b76b5SKan Liang static const struct pci_device_id icx_uncore_pci_ids[] = {
57262b3b76b5SKan Liang 	{ /* M2M 0 */
57272b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a),
57282b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(12, 0, ICX_PCI_UNCORE_M2M, 0),
57292b3b76b5SKan Liang 	},
57302b3b76b5SKan Liang 	{ /* M2M 1 */
57312b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a),
57322b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(13, 0, ICX_PCI_UNCORE_M2M, 1),
57332b3b76b5SKan Liang 	},
57342b3b76b5SKan Liang 	{ /* M2M 2 */
57352b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a),
57362b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(14, 0, ICX_PCI_UNCORE_M2M, 2),
57372b3b76b5SKan Liang 	},
57382b3b76b5SKan Liang 	{ /* M2M 3 */
57392b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a),
57402b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(15, 0, ICX_PCI_UNCORE_M2M, 3),
57412b3b76b5SKan Liang 	},
57422b3b76b5SKan Liang 	{ /* UPI Link 0 */
57432b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3441),
57442b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(2, 1, ICX_PCI_UNCORE_UPI, 0),
57452b3b76b5SKan Liang 	},
57462b3b76b5SKan Liang 	{ /* UPI Link 1 */
57472b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3441),
57482b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(3, 1, ICX_PCI_UNCORE_UPI, 1),
57492b3b76b5SKan Liang 	},
57502b3b76b5SKan Liang 	{ /* UPI Link 2 */
57512b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3441),
57522b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(4, 1, ICX_PCI_UNCORE_UPI, 2),
57532b3b76b5SKan Liang 	},
57542b3b76b5SKan Liang 	{ /* M3UPI Link 0 */
57552b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3446),
57562b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(5, 1, ICX_PCI_UNCORE_M3UPI, 0),
57572b3b76b5SKan Liang 	},
57582b3b76b5SKan Liang 	{ /* M3UPI Link 1 */
57592b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3446),
57602b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(6, 1, ICX_PCI_UNCORE_M3UPI, 1),
57612b3b76b5SKan Liang 	},
57622b3b76b5SKan Liang 	{ /* M3UPI Link 2 */
57632b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3446),
57642b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(7, 1, ICX_PCI_UNCORE_M3UPI, 2),
57652b3b76b5SKan Liang 	},
57662b3b76b5SKan Liang 	{ /* end: all zeroes */ }
57672b3b76b5SKan Liang };
57682b3b76b5SKan Liang 
57692b3b76b5SKan Liang static struct pci_driver icx_uncore_pci_driver = {
57702b3b76b5SKan Liang 	.name		= "icx_uncore",
57712b3b76b5SKan Liang 	.id_table	= icx_uncore_pci_ids,
57722b3b76b5SKan Liang };
57732b3b76b5SKan Liang 
57742b3b76b5SKan Liang int icx_uncore_pci_init(void)
57752b3b76b5SKan Liang {
57762b3b76b5SKan Liang 	/* ICX UBOX DID */
57772b3b76b5SKan Liang 	int ret = snbep_pci2phy_map_init(0x3450, SKX_CPUNODEID,
57782b3b76b5SKan Liang 					 SKX_GIDNIDMAP, true);
57792b3b76b5SKan Liang 
57802b3b76b5SKan Liang 	if (ret)
57812b3b76b5SKan Liang 		return ret;
57822b3b76b5SKan Liang 
57832b3b76b5SKan Liang 	uncore_pci_uncores = icx_pci_uncores;
57842b3b76b5SKan Liang 	uncore_pci_driver = &icx_uncore_pci_driver;
57852b3b76b5SKan Liang 	return 0;
57862b3b76b5SKan Liang }
57872b3b76b5SKan Liang 
57882b3b76b5SKan Liang static void icx_uncore_imc_init_box(struct intel_uncore_box *box)
57892b3b76b5SKan Liang {
57902b3b76b5SKan Liang 	unsigned int box_ctl = box->pmu->type->box_ctl +
57912b3b76b5SKan Liang 			       box->pmu->type->mmio_offset * (box->pmu->pmu_idx % ICX_NUMBER_IMC_CHN);
57922b3b76b5SKan Liang 	int mem_offset = (box->pmu->pmu_idx / ICX_NUMBER_IMC_CHN) * ICX_IMC_MEM_STRIDE +
57932b3b76b5SKan Liang 			 SNR_IMC_MMIO_MEM0_OFFSET;
57942b3b76b5SKan Liang 
57951583971bSKan Liang 	__snr_uncore_mmio_init_box(box, box_ctl, mem_offset,
57961583971bSKan Liang 				   SNR_MC_DEVICE_ID);
57972b3b76b5SKan Liang }
57982b3b76b5SKan Liang 
57992b3b76b5SKan Liang static struct intel_uncore_ops icx_uncore_mmio_ops = {
58002b3b76b5SKan Liang 	.init_box	= icx_uncore_imc_init_box,
58012b3b76b5SKan Liang 	.exit_box	= uncore_mmio_exit_box,
58022b3b76b5SKan Liang 	.disable_box	= snr_uncore_mmio_disable_box,
58032b3b76b5SKan Liang 	.enable_box	= snr_uncore_mmio_enable_box,
58042b3b76b5SKan Liang 	.disable_event	= snr_uncore_mmio_disable_event,
58052b3b76b5SKan Liang 	.enable_event	= snr_uncore_mmio_enable_event,
58062b3b76b5SKan Liang 	.read_counter	= uncore_mmio_read_counter,
58072b3b76b5SKan Liang };
58082b3b76b5SKan Liang 
58092b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_imc = {
58102b3b76b5SKan Liang 	.name		= "imc",
58112b3b76b5SKan Liang 	.num_counters   = 4,
5812496a18f0SKan Liang 	.num_boxes	= 12,
58132b3b76b5SKan Liang 	.perf_ctr_bits	= 48,
58142b3b76b5SKan Liang 	.fixed_ctr_bits	= 48,
58152b3b76b5SKan Liang 	.fixed_ctr	= SNR_IMC_MMIO_PMON_FIXED_CTR,
58162b3b76b5SKan Liang 	.fixed_ctl	= SNR_IMC_MMIO_PMON_FIXED_CTL,
581796fd2e89SZhengjun Xing 	.event_descs	= snr_uncore_imc_events,
58182b3b76b5SKan Liang 	.perf_ctr	= SNR_IMC_MMIO_PMON_CTR0,
58192b3b76b5SKan Liang 	.event_ctl	= SNR_IMC_MMIO_PMON_CTL0,
58202b3b76b5SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
58212b3b76b5SKan Liang 	.box_ctl	= SNR_IMC_MMIO_PMON_BOX_CTL,
58222b3b76b5SKan Liang 	.mmio_offset	= SNR_IMC_MMIO_OFFSET,
58231b94d31dSKan Liang 	.mmio_map_size	= SNR_IMC_MMIO_SIZE,
58242b3b76b5SKan Liang 	.ops		= &icx_uncore_mmio_ops,
58252b3b76b5SKan Liang 	.format_group	= &skx_uncore_format_group,
58262b3b76b5SKan Liang };
58272b3b76b5SKan Liang 
58282b3b76b5SKan Liang enum perf_uncore_icx_imc_freerunning_type_id {
58292b3b76b5SKan Liang 	ICX_IMC_DCLK,
58302b3b76b5SKan Liang 	ICX_IMC_DDR,
58312b3b76b5SKan Liang 	ICX_IMC_DDRT,
58322b3b76b5SKan Liang 
58332b3b76b5SKan Liang 	ICX_IMC_FREERUNNING_TYPE_MAX,
58342b3b76b5SKan Liang };
58352b3b76b5SKan Liang 
58362b3b76b5SKan Liang static struct freerunning_counters icx_imc_freerunning[] = {
58372b3b76b5SKan Liang 	[ICX_IMC_DCLK]	= { 0x22b0, 0x0, 0, 1, 48 },
58382b3b76b5SKan Liang 	[ICX_IMC_DDR]	= { 0x2290, 0x8, 0, 2, 48 },
58392b3b76b5SKan Liang 	[ICX_IMC_DDRT]	= { 0x22a0, 0x8, 0, 2, 48 },
58402b3b76b5SKan Liang };
58412b3b76b5SKan Liang 
58422b3b76b5SKan Liang static struct uncore_event_desc icx_uncore_imc_freerunning_events[] = {
58432b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(dclk,			"event=0xff,umask=0x10"),
58442b3b76b5SKan Liang 
58452b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(read,			"event=0xff,umask=0x20"),
58468191016aSKan Liang 	INTEL_UNCORE_EVENT_DESC(read.scale,		"6.103515625e-5"),
58472b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(read.unit,		"MiB"),
58482b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(write,			"event=0xff,umask=0x21"),
58498191016aSKan Liang 	INTEL_UNCORE_EVENT_DESC(write.scale,		"6.103515625e-5"),
58502b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(write.unit,		"MiB"),
58512b3b76b5SKan Liang 
58522b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(ddrt_read,		"event=0xff,umask=0x30"),
58538191016aSKan Liang 	INTEL_UNCORE_EVENT_DESC(ddrt_read.scale,	"6.103515625e-5"),
58542b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(ddrt_read.unit,		"MiB"),
58552b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(ddrt_write,		"event=0xff,umask=0x31"),
58568191016aSKan Liang 	INTEL_UNCORE_EVENT_DESC(ddrt_write.scale,	"6.103515625e-5"),
58572b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(ddrt_write.unit,	"MiB"),
58582b3b76b5SKan Liang 	{ /* end: all zeroes */ },
58592b3b76b5SKan Liang };
58602b3b76b5SKan Liang 
58612b3b76b5SKan Liang static void icx_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
58622b3b76b5SKan Liang {
58632b3b76b5SKan Liang 	int mem_offset = box->pmu->pmu_idx * ICX_IMC_MEM_STRIDE +
58642b3b76b5SKan Liang 			 SNR_IMC_MMIO_MEM0_OFFSET;
58652b3b76b5SKan Liang 
58661583971bSKan Liang 	snr_uncore_mmio_map(box, uncore_mmio_box_ctl(box),
58671583971bSKan Liang 			    mem_offset, SNR_MC_DEVICE_ID);
58682b3b76b5SKan Liang }
58692b3b76b5SKan Liang 
58702b3b76b5SKan Liang static struct intel_uncore_ops icx_uncore_imc_freerunning_ops = {
58712b3b76b5SKan Liang 	.init_box	= icx_uncore_imc_freerunning_init_box,
58722b3b76b5SKan Liang 	.exit_box	= uncore_mmio_exit_box,
58732b3b76b5SKan Liang 	.read_counter	= uncore_mmio_read_counter,
58742b3b76b5SKan Liang 	.hw_config	= uncore_freerunning_hw_config,
58752b3b76b5SKan Liang };
58762b3b76b5SKan Liang 
58772b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_imc_free_running = {
58782b3b76b5SKan Liang 	.name			= "imc_free_running",
58792b3b76b5SKan Liang 	.num_counters		= 5,
58802b3b76b5SKan Liang 	.num_boxes		= 4,
58812b3b76b5SKan Liang 	.num_freerunning_types	= ICX_IMC_FREERUNNING_TYPE_MAX,
58821b94d31dSKan Liang 	.mmio_map_size		= SNR_IMC_MMIO_SIZE,
58832b3b76b5SKan Liang 	.freerunning		= icx_imc_freerunning,
58842b3b76b5SKan Liang 	.ops			= &icx_uncore_imc_freerunning_ops,
58852b3b76b5SKan Liang 	.event_descs		= icx_uncore_imc_freerunning_events,
58862b3b76b5SKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
58872b3b76b5SKan Liang };
58882b3b76b5SKan Liang 
58892b3b76b5SKan Liang static struct intel_uncore_type *icx_mmio_uncores[] = {
58902b3b76b5SKan Liang 	&icx_uncore_imc,
58912b3b76b5SKan Liang 	&icx_uncore_imc_free_running,
58922b3b76b5SKan Liang 	NULL,
58932b3b76b5SKan Liang };
58942b3b76b5SKan Liang 
58952b3b76b5SKan Liang void icx_uncore_mmio_init(void)
58962b3b76b5SKan Liang {
58972b3b76b5SKan Liang 	uncore_mmio_uncores = icx_mmio_uncores;
58982b3b76b5SKan Liang }
58992b3b76b5SKan Liang 
59002b3b76b5SKan Liang /* end of ICX uncore support */
5901c54c53d9SKan Liang 
5902c54c53d9SKan Liang /* SPR uncore support */
5903c54c53d9SKan Liang 
5904949b1138SKan Liang static void spr_uncore_msr_enable_event(struct intel_uncore_box *box,
5905949b1138SKan Liang 					struct perf_event *event)
5906949b1138SKan Liang {
5907949b1138SKan Liang 	struct hw_perf_event *hwc = &event->hw;
5908949b1138SKan Liang 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
5909949b1138SKan Liang 
5910949b1138SKan Liang 	if (reg1->idx != EXTRA_REG_NONE)
5911949b1138SKan Liang 		wrmsrl(reg1->reg, reg1->config);
5912949b1138SKan Liang 
5913949b1138SKan Liang 	wrmsrl(hwc->config_base, hwc->config);
5914949b1138SKan Liang }
5915949b1138SKan Liang 
5916949b1138SKan Liang static void spr_uncore_msr_disable_event(struct intel_uncore_box *box,
5917949b1138SKan Liang 					 struct perf_event *event)
5918949b1138SKan Liang {
5919949b1138SKan Liang 	struct hw_perf_event *hwc = &event->hw;
5920949b1138SKan Liang 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
5921949b1138SKan Liang 
5922949b1138SKan Liang 	if (reg1->idx != EXTRA_REG_NONE)
5923949b1138SKan Liang 		wrmsrl(reg1->reg, 0);
5924949b1138SKan Liang 
5925949b1138SKan Liang 	wrmsrl(hwc->config_base, 0);
5926949b1138SKan Liang }
5927949b1138SKan Liang 
5928949b1138SKan Liang static int spr_cha_hw_config(struct intel_uncore_box *box, struct perf_event *event)
5929949b1138SKan Liang {
5930949b1138SKan Liang 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
5931949b1138SKan Liang 	bool tie_en = !!(event->hw.config & SPR_CHA_PMON_CTL_TID_EN);
5932949b1138SKan Liang 	struct intel_uncore_type *type = box->pmu->type;
5933949b1138SKan Liang 
5934949b1138SKan Liang 	if (tie_en) {
5935949b1138SKan Liang 		reg1->reg = SPR_C0_MSR_PMON_BOX_FILTER0 +
5936949b1138SKan Liang 			    HSWEP_CBO_MSR_OFFSET * type->box_ids[box->pmu->pmu_idx];
5937949b1138SKan Liang 		reg1->config = event->attr.config1 & SPR_CHA_PMON_BOX_FILTER_TID;
5938949b1138SKan Liang 		reg1->idx = 0;
5939949b1138SKan Liang 	}
5940949b1138SKan Liang 
5941949b1138SKan Liang 	return 0;
5942949b1138SKan Liang }
5943949b1138SKan Liang 
5944949b1138SKan Liang static struct intel_uncore_ops spr_uncore_chabox_ops = {
5945949b1138SKan Liang 	.init_box		= intel_generic_uncore_msr_init_box,
5946949b1138SKan Liang 	.disable_box		= intel_generic_uncore_msr_disable_box,
5947949b1138SKan Liang 	.enable_box		= intel_generic_uncore_msr_enable_box,
5948949b1138SKan Liang 	.disable_event		= spr_uncore_msr_disable_event,
5949949b1138SKan Liang 	.enable_event		= spr_uncore_msr_enable_event,
5950949b1138SKan Liang 	.read_counter		= uncore_msr_read_counter,
5951949b1138SKan Liang 	.hw_config		= spr_cha_hw_config,
5952949b1138SKan Liang 	.get_constraint		= uncore_get_constraint,
5953949b1138SKan Liang 	.put_constraint		= uncore_put_constraint,
5954949b1138SKan Liang };
5955949b1138SKan Liang 
5956949b1138SKan Liang static struct attribute *spr_uncore_cha_formats_attr[] = {
5957949b1138SKan Liang 	&format_attr_event.attr,
5958949b1138SKan Liang 	&format_attr_umask_ext4.attr,
5959949b1138SKan Liang 	&format_attr_tid_en2.attr,
5960949b1138SKan Liang 	&format_attr_edge.attr,
5961949b1138SKan Liang 	&format_attr_inv.attr,
5962949b1138SKan Liang 	&format_attr_thresh8.attr,
5963949b1138SKan Liang 	&format_attr_filter_tid5.attr,
5964949b1138SKan Liang 	NULL,
5965949b1138SKan Liang };
5966949b1138SKan Liang static const struct attribute_group spr_uncore_chabox_format_group = {
5967949b1138SKan Liang 	.name = "format",
5968949b1138SKan Liang 	.attrs = spr_uncore_cha_formats_attr,
5969949b1138SKan Liang };
5970949b1138SKan Liang 
59718053f2d7SKan Liang static ssize_t alias_show(struct device *dev,
59728053f2d7SKan Liang 			  struct device_attribute *attr,
59738053f2d7SKan Liang 			  char *buf)
59748053f2d7SKan Liang {
59758053f2d7SKan Liang 	struct intel_uncore_pmu *pmu = dev_to_uncore_pmu(dev);
59768053f2d7SKan Liang 	char pmu_name[UNCORE_PMU_NAME_LEN];
59778053f2d7SKan Liang 
59788053f2d7SKan Liang 	uncore_get_alias_name(pmu_name, pmu);
59798053f2d7SKan Liang 	return sysfs_emit(buf, "%s\n", pmu_name);
59808053f2d7SKan Liang }
59818053f2d7SKan Liang 
59828053f2d7SKan Liang static DEVICE_ATTR_RO(alias);
59838053f2d7SKan Liang 
59848053f2d7SKan Liang static struct attribute *uncore_alias_attrs[] = {
59858053f2d7SKan Liang 	&dev_attr_alias.attr,
59868053f2d7SKan Liang 	NULL
59878053f2d7SKan Liang };
59888053f2d7SKan Liang 
59898053f2d7SKan Liang ATTRIBUTE_GROUPS(uncore_alias);
59908053f2d7SKan Liang 
5991949b1138SKan Liang static struct intel_uncore_type spr_uncore_chabox = {
5992949b1138SKan Liang 	.name			= "cha",
5993949b1138SKan Liang 	.event_mask		= SPR_CHA_PMON_EVENT_MASK,
5994949b1138SKan Liang 	.event_mask_ext		= SPR_RAW_EVENT_MASK_EXT,
5995949b1138SKan Liang 	.num_shared_regs	= 1,
59969d756e40SKan Liang 	.constraints		= skx_uncore_chabox_constraints,
5997949b1138SKan Liang 	.ops			= &spr_uncore_chabox_ops,
5998949b1138SKan Liang 	.format_group		= &spr_uncore_chabox_format_group,
59998053f2d7SKan Liang 	.attr_update		= uncore_alias_groups,
6000949b1138SKan Liang };
6001949b1138SKan Liang 
60023ba7095bSKan Liang static struct intel_uncore_type spr_uncore_iio = {
60033ba7095bSKan Liang 	.name			= "iio",
60043ba7095bSKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
60053ba7095bSKan Liang 	.event_mask_ext		= SNR_IIO_PMON_RAW_EVENT_MASK_EXT,
60063ba7095bSKan Liang 	.format_group		= &snr_uncore_iio_format_group,
60078053f2d7SKan Liang 	.attr_update		= uncore_alias_groups,
600867c5d443SKan Liang 	.constraints		= icx_uncore_iio_constraints,
60093ba7095bSKan Liang };
60103ba7095bSKan Liang 
6011e199eb51SKan Liang static struct attribute *spr_uncore_raw_formats_attr[] = {
6012e199eb51SKan Liang 	&format_attr_event.attr,
6013e199eb51SKan Liang 	&format_attr_umask_ext4.attr,
6014e199eb51SKan Liang 	&format_attr_edge.attr,
6015e199eb51SKan Liang 	&format_attr_inv.attr,
6016e199eb51SKan Liang 	&format_attr_thresh8.attr,
6017e199eb51SKan Liang 	NULL,
6018e199eb51SKan Liang };
6019e199eb51SKan Liang 
6020e199eb51SKan Liang static const struct attribute_group spr_uncore_raw_format_group = {
6021e199eb51SKan Liang 	.name			= "format",
6022e199eb51SKan Liang 	.attrs			= spr_uncore_raw_formats_attr,
6023e199eb51SKan Liang };
6024e199eb51SKan Liang 
6025e199eb51SKan Liang #define SPR_UNCORE_COMMON_FORMAT()				\
6026e199eb51SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,	\
6027e199eb51SKan Liang 	.event_mask_ext		= SPR_RAW_EVENT_MASK_EXT,	\
60288053f2d7SKan Liang 	.format_group		= &spr_uncore_raw_format_group,	\
60298053f2d7SKan Liang 	.attr_update		= uncore_alias_groups
6030e199eb51SKan Liang 
6031e199eb51SKan Liang static struct intel_uncore_type spr_uncore_irp = {
6032e199eb51SKan Liang 	SPR_UNCORE_COMMON_FORMAT(),
6033e199eb51SKan Liang 	.name			= "irp",
6034e199eb51SKan Liang 
6035e199eb51SKan Liang };
6036e199eb51SKan Liang 
6037f01d7d55SKan Liang static struct event_constraint spr_uncore_m2pcie_constraints[] = {
6038f01d7d55SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
6039f01d7d55SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
6040f01d7d55SKan Liang 	EVENT_CONSTRAINT_END
6041f01d7d55SKan Liang };
6042f01d7d55SKan Liang 
6043f85ef898SKan Liang static struct intel_uncore_type spr_uncore_m2pcie = {
6044f85ef898SKan Liang 	SPR_UNCORE_COMMON_FORMAT(),
6045f85ef898SKan Liang 	.name			= "m2pcie",
6046f01d7d55SKan Liang 	.constraints		= spr_uncore_m2pcie_constraints,
6047f85ef898SKan Liang };
6048f85ef898SKan Liang 
60490654dfdcSKan Liang static struct intel_uncore_type spr_uncore_pcu = {
60500654dfdcSKan Liang 	.name			= "pcu",
60518053f2d7SKan Liang 	.attr_update		= uncore_alias_groups,
60520654dfdcSKan Liang };
60530654dfdcSKan Liang 
605485f2e30fSKan Liang static void spr_uncore_mmio_enable_event(struct intel_uncore_box *box,
605585f2e30fSKan Liang 					 struct perf_event *event)
605685f2e30fSKan Liang {
605785f2e30fSKan Liang 	struct hw_perf_event *hwc = &event->hw;
605885f2e30fSKan Liang 
605985f2e30fSKan Liang 	if (!box->io_addr)
606085f2e30fSKan Liang 		return;
606185f2e30fSKan Liang 
606285f2e30fSKan Liang 	if (uncore_pmc_fixed(hwc->idx))
606385f2e30fSKan Liang 		writel(SNBEP_PMON_CTL_EN, box->io_addr + hwc->config_base);
606485f2e30fSKan Liang 	else
606585f2e30fSKan Liang 		writel(hwc->config, box->io_addr + hwc->config_base);
606685f2e30fSKan Liang }
606785f2e30fSKan Liang 
606885f2e30fSKan Liang static struct intel_uncore_ops spr_uncore_mmio_ops = {
606985f2e30fSKan Liang 	.init_box		= intel_generic_uncore_mmio_init_box,
607085f2e30fSKan Liang 	.exit_box		= uncore_mmio_exit_box,
607185f2e30fSKan Liang 	.disable_box		= intel_generic_uncore_mmio_disable_box,
607285f2e30fSKan Liang 	.enable_box		= intel_generic_uncore_mmio_enable_box,
607385f2e30fSKan Liang 	.disable_event		= intel_generic_uncore_mmio_disable_event,
607485f2e30fSKan Liang 	.enable_event		= spr_uncore_mmio_enable_event,
607585f2e30fSKan Liang 	.read_counter		= uncore_mmio_read_counter,
607685f2e30fSKan Liang };
607785f2e30fSKan Liang 
607885f2e30fSKan Liang static struct intel_uncore_type spr_uncore_imc = {
607985f2e30fSKan Liang 	SPR_UNCORE_COMMON_FORMAT(),
608085f2e30fSKan Liang 	.name			= "imc",
608185f2e30fSKan Liang 	.fixed_ctr_bits		= 48,
608285f2e30fSKan Liang 	.fixed_ctr		= SNR_IMC_MMIO_PMON_FIXED_CTR,
608385f2e30fSKan Liang 	.fixed_ctl		= SNR_IMC_MMIO_PMON_FIXED_CTL,
608485f2e30fSKan Liang 	.ops			= &spr_uncore_mmio_ops,
608585f2e30fSKan Liang };
608685f2e30fSKan Liang 
6087f57191edSKan Liang static void spr_uncore_pci_enable_event(struct intel_uncore_box *box,
6088f57191edSKan Liang 					struct perf_event *event)
6089f57191edSKan Liang {
6090f57191edSKan Liang 	struct pci_dev *pdev = box->pci_dev;
6091f57191edSKan Liang 	struct hw_perf_event *hwc = &event->hw;
6092f57191edSKan Liang 
6093f57191edSKan Liang 	pci_write_config_dword(pdev, hwc->config_base + 4, (u32)(hwc->config >> 32));
6094f57191edSKan Liang 	pci_write_config_dword(pdev, hwc->config_base, (u32)hwc->config);
6095f57191edSKan Liang }
6096f57191edSKan Liang 
6097f57191edSKan Liang static struct intel_uncore_ops spr_uncore_pci_ops = {
6098f57191edSKan Liang 	.init_box		= intel_generic_uncore_pci_init_box,
6099f57191edSKan Liang 	.disable_box		= intel_generic_uncore_pci_disable_box,
6100f57191edSKan Liang 	.enable_box		= intel_generic_uncore_pci_enable_box,
6101f57191edSKan Liang 	.disable_event		= intel_generic_uncore_pci_disable_event,
6102f57191edSKan Liang 	.enable_event		= spr_uncore_pci_enable_event,
6103f57191edSKan Liang 	.read_counter		= intel_generic_uncore_pci_read_counter,
6104f57191edSKan Liang };
6105f57191edSKan Liang 
6106f57191edSKan Liang #define SPR_UNCORE_PCI_COMMON_FORMAT()			\
6107f57191edSKan Liang 	SPR_UNCORE_COMMON_FORMAT(),			\
6108f57191edSKan Liang 	.ops			= &spr_uncore_pci_ops
6109f57191edSKan Liang 
6110f57191edSKan Liang static struct intel_uncore_type spr_uncore_m2m = {
6111f57191edSKan Liang 	SPR_UNCORE_PCI_COMMON_FORMAT(),
6112f57191edSKan Liang 	.name			= "m2m",
6113f57191edSKan Liang };
6114f57191edSKan Liang 
6115da5a9156SKan Liang static struct intel_uncore_type spr_uncore_upi = {
6116da5a9156SKan Liang 	SPR_UNCORE_PCI_COMMON_FORMAT(),
6117da5a9156SKan Liang 	.name			= "upi",
6118da5a9156SKan Liang };
6119da5a9156SKan Liang 
61202a8e51eaSKan Liang static struct intel_uncore_type spr_uncore_m3upi = {
61212a8e51eaSKan Liang 	SPR_UNCORE_PCI_COMMON_FORMAT(),
61222a8e51eaSKan Liang 	.name			= "m3upi",
61234034fb20SKan Liang 	.constraints		= icx_uncore_m3upi_constraints,
61242a8e51eaSKan Liang };
61252a8e51eaSKan Liang 
61260d771cafSKan Liang static struct intel_uncore_type spr_uncore_mdf = {
61270d771cafSKan Liang 	SPR_UNCORE_COMMON_FORMAT(),
61280d771cafSKan Liang 	.name			= "mdf",
61290d771cafSKan Liang };
61300d771cafSKan Liang 
6131c54c53d9SKan Liang #define UNCORE_SPR_NUM_UNCORE_TYPES		12
61320378c93aSKan Liang #define UNCORE_SPR_IIO				1
6133c76826a6SKan Liang #define UNCORE_SPR_IMC				6
6134c54c53d9SKan Liang 
6135c54c53d9SKan Liang static struct intel_uncore_type *spr_uncores[UNCORE_SPR_NUM_UNCORE_TYPES] = {
6136949b1138SKan Liang 	&spr_uncore_chabox,
61373ba7095bSKan Liang 	&spr_uncore_iio,
6138e199eb51SKan Liang 	&spr_uncore_irp,
6139f85ef898SKan Liang 	&spr_uncore_m2pcie,
61400654dfdcSKan Liang 	&spr_uncore_pcu,
6141c54c53d9SKan Liang 	NULL,
614285f2e30fSKan Liang 	&spr_uncore_imc,
6143f57191edSKan Liang 	&spr_uncore_m2m,
6144da5a9156SKan Liang 	&spr_uncore_upi,
61452a8e51eaSKan Liang 	&spr_uncore_m3upi,
6146c54c53d9SKan Liang 	NULL,
61470d771cafSKan Liang 	&spr_uncore_mdf,
6148c54c53d9SKan Liang };
6149c54c53d9SKan Liang 
61500378c93aSKan Liang enum perf_uncore_spr_iio_freerunning_type_id {
61510378c93aSKan Liang 	SPR_IIO_MSR_IOCLK,
61520378c93aSKan Liang 	SPR_IIO_MSR_BW_IN,
61530378c93aSKan Liang 	SPR_IIO_MSR_BW_OUT,
61540378c93aSKan Liang 
61550378c93aSKan Liang 	SPR_IIO_FREERUNNING_TYPE_MAX,
61560378c93aSKan Liang };
61570378c93aSKan Liang 
61580378c93aSKan Liang static struct freerunning_counters spr_iio_freerunning[] = {
61590378c93aSKan Liang 	[SPR_IIO_MSR_IOCLK]	= { 0x340e, 0x1, 0x10, 1, 48 },
61600378c93aSKan Liang 	[SPR_IIO_MSR_BW_IN]	= { 0x3800, 0x1, 0x10, 8, 48 },
61610378c93aSKan Liang 	[SPR_IIO_MSR_BW_OUT]	= { 0x3808, 0x1, 0x10, 8, 48 },
61620378c93aSKan Liang };
61630378c93aSKan Liang 
61640378c93aSKan Liang static struct uncore_event_desc spr_uncore_iio_freerunning_events[] = {
61650378c93aSKan Liang 	/* Free-Running IIO CLOCKS Counter */
61660378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(ioclk,			"event=0xff,umask=0x10"),
61670378c93aSKan Liang 	/* Free-Running IIO BANDWIDTH IN Counters */
61680378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0,		"event=0xff,umask=0x20"),
61690378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale,	"3.814697266e-6"),
61700378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit,	"MiB"),
61710378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1,		"event=0xff,umask=0x21"),
61720378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale,	"3.814697266e-6"),
61730378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit,	"MiB"),
61740378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2,		"event=0xff,umask=0x22"),
61750378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale,	"3.814697266e-6"),
61760378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit,	"MiB"),
61770378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3,		"event=0xff,umask=0x23"),
61780378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale,	"3.814697266e-6"),
61790378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit,	"MiB"),
61800378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4,		"event=0xff,umask=0x24"),
61810378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4.scale,	"3.814697266e-6"),
61820378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4.unit,	"MiB"),
61830378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5,		"event=0xff,umask=0x25"),
61840378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5.scale,	"3.814697266e-6"),
61850378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5.unit,	"MiB"),
61860378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6,		"event=0xff,umask=0x26"),
61870378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6.scale,	"3.814697266e-6"),
61880378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6.unit,	"MiB"),
61890378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7,		"event=0xff,umask=0x27"),
61900378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7.scale,	"3.814697266e-6"),
61910378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7.unit,	"MiB"),
61920378c93aSKan Liang 	/* Free-Running IIO BANDWIDTH OUT Counters */
61930378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port0,		"event=0xff,umask=0x30"),
61940378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port0.scale,	"3.814697266e-6"),
61950378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port0.unit,	"MiB"),
61960378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port1,		"event=0xff,umask=0x31"),
61970378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port1.scale,	"3.814697266e-6"),
61980378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port1.unit,	"MiB"),
61990378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port2,		"event=0xff,umask=0x32"),
62000378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port2.scale,	"3.814697266e-6"),
62010378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port2.unit,	"MiB"),
62020378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port3,		"event=0xff,umask=0x33"),
62030378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port3.scale,	"3.814697266e-6"),
62040378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port3.unit,	"MiB"),
62050378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port4,		"event=0xff,umask=0x34"),
62060378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port4.scale,	"3.814697266e-6"),
62070378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port4.unit,	"MiB"),
62080378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port5,		"event=0xff,umask=0x35"),
62090378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port5.scale,	"3.814697266e-6"),
62100378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port5.unit,	"MiB"),
62110378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port6,		"event=0xff,umask=0x36"),
62120378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port6.scale,	"3.814697266e-6"),
62130378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port6.unit,	"MiB"),
62140378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port7,		"event=0xff,umask=0x37"),
62150378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port7.scale,	"3.814697266e-6"),
62160378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port7.unit,	"MiB"),
62170378c93aSKan Liang 	{ /* end: all zeroes */ },
62180378c93aSKan Liang };
62190378c93aSKan Liang 
62200378c93aSKan Liang static struct intel_uncore_type spr_uncore_iio_free_running = {
62210378c93aSKan Liang 	.name			= "iio_free_running",
62220378c93aSKan Liang 	.num_counters		= 17,
62230378c93aSKan Liang 	.num_freerunning_types	= SPR_IIO_FREERUNNING_TYPE_MAX,
62240378c93aSKan Liang 	.freerunning		= spr_iio_freerunning,
62250378c93aSKan Liang 	.ops			= &skx_uncore_iio_freerunning_ops,
62260378c93aSKan Liang 	.event_descs		= spr_uncore_iio_freerunning_events,
62270378c93aSKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
62280378c93aSKan Liang };
62290378c93aSKan Liang 
6230c76826a6SKan Liang enum perf_uncore_spr_imc_freerunning_type_id {
6231c76826a6SKan Liang 	SPR_IMC_DCLK,
6232c76826a6SKan Liang 	SPR_IMC_PQ_CYCLES,
6233c76826a6SKan Liang 
6234c76826a6SKan Liang 	SPR_IMC_FREERUNNING_TYPE_MAX,
6235c76826a6SKan Liang };
6236c76826a6SKan Liang 
6237c76826a6SKan Liang static struct freerunning_counters spr_imc_freerunning[] = {
6238c76826a6SKan Liang 	[SPR_IMC_DCLK]		= { 0x22b0, 0x0, 0, 1, 48 },
6239c76826a6SKan Liang 	[SPR_IMC_PQ_CYCLES]	= { 0x2318, 0x8, 0, 2, 48 },
6240c76826a6SKan Liang };
6241c76826a6SKan Liang 
6242c76826a6SKan Liang static struct uncore_event_desc spr_uncore_imc_freerunning_events[] = {
6243c76826a6SKan Liang 	INTEL_UNCORE_EVENT_DESC(dclk,			"event=0xff,umask=0x10"),
6244c76826a6SKan Liang 
6245c76826a6SKan Liang 	INTEL_UNCORE_EVENT_DESC(rpq_cycles,		"event=0xff,umask=0x20"),
6246c76826a6SKan Liang 	INTEL_UNCORE_EVENT_DESC(wpq_cycles,		"event=0xff,umask=0x21"),
6247c76826a6SKan Liang 	{ /* end: all zeroes */ },
6248c76826a6SKan Liang };
6249c76826a6SKan Liang 
6250c76826a6SKan Liang #define SPR_MC_DEVICE_ID	0x3251
6251c76826a6SKan Liang 
6252c76826a6SKan Liang static void spr_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
6253c76826a6SKan Liang {
6254c76826a6SKan Liang 	int mem_offset = box->pmu->pmu_idx * ICX_IMC_MEM_STRIDE + SNR_IMC_MMIO_MEM0_OFFSET;
6255c76826a6SKan Liang 
6256c76826a6SKan Liang 	snr_uncore_mmio_map(box, uncore_mmio_box_ctl(box),
6257c76826a6SKan Liang 			    mem_offset, SPR_MC_DEVICE_ID);
6258c76826a6SKan Liang }
6259c76826a6SKan Liang 
6260c76826a6SKan Liang static struct intel_uncore_ops spr_uncore_imc_freerunning_ops = {
6261c76826a6SKan Liang 	.init_box	= spr_uncore_imc_freerunning_init_box,
6262c76826a6SKan Liang 	.exit_box	= uncore_mmio_exit_box,
6263c76826a6SKan Liang 	.read_counter	= uncore_mmio_read_counter,
6264c76826a6SKan Liang 	.hw_config	= uncore_freerunning_hw_config,
6265c76826a6SKan Liang };
6266c76826a6SKan Liang 
6267c76826a6SKan Liang static struct intel_uncore_type spr_uncore_imc_free_running = {
6268c76826a6SKan Liang 	.name			= "imc_free_running",
6269c76826a6SKan Liang 	.num_counters		= 3,
6270c76826a6SKan Liang 	.mmio_map_size		= SNR_IMC_MMIO_SIZE,
6271c76826a6SKan Liang 	.num_freerunning_types	= SPR_IMC_FREERUNNING_TYPE_MAX,
6272c76826a6SKan Liang 	.freerunning		= spr_imc_freerunning,
6273c76826a6SKan Liang 	.ops			= &spr_uncore_imc_freerunning_ops,
6274c76826a6SKan Liang 	.event_descs		= spr_uncore_imc_freerunning_events,
6275c76826a6SKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
6276c76826a6SKan Liang };
6277c76826a6SKan Liang 
62780378c93aSKan Liang #define UNCORE_SPR_MSR_EXTRA_UNCORES		1
6279c76826a6SKan Liang #define UNCORE_SPR_MMIO_EXTRA_UNCORES		1
62800378c93aSKan Liang 
62810378c93aSKan Liang static struct intel_uncore_type *spr_msr_uncores[UNCORE_SPR_MSR_EXTRA_UNCORES] = {
62820378c93aSKan Liang 	&spr_uncore_iio_free_running,
62830378c93aSKan Liang };
62840378c93aSKan Liang 
6285c76826a6SKan Liang static struct intel_uncore_type *spr_mmio_uncores[UNCORE_SPR_MMIO_EXTRA_UNCORES] = {
6286c76826a6SKan Liang 	&spr_uncore_imc_free_running,
6287c76826a6SKan Liang };
6288c76826a6SKan Liang 
6289c54c53d9SKan Liang static void uncore_type_customized_copy(struct intel_uncore_type *to_type,
6290c54c53d9SKan Liang 					struct intel_uncore_type *from_type)
6291c54c53d9SKan Liang {
6292c54c53d9SKan Liang 	if (!to_type || !from_type)
6293c54c53d9SKan Liang 		return;
6294c54c53d9SKan Liang 
6295c54c53d9SKan Liang 	if (from_type->name)
6296c54c53d9SKan Liang 		to_type->name = from_type->name;
6297c54c53d9SKan Liang 	if (from_type->fixed_ctr_bits)
6298c54c53d9SKan Liang 		to_type->fixed_ctr_bits = from_type->fixed_ctr_bits;
6299c54c53d9SKan Liang 	if (from_type->event_mask)
6300c54c53d9SKan Liang 		to_type->event_mask = from_type->event_mask;
6301c54c53d9SKan Liang 	if (from_type->event_mask_ext)
6302c54c53d9SKan Liang 		to_type->event_mask_ext = from_type->event_mask_ext;
6303c54c53d9SKan Liang 	if (from_type->fixed_ctr)
6304c54c53d9SKan Liang 		to_type->fixed_ctr = from_type->fixed_ctr;
6305c54c53d9SKan Liang 	if (from_type->fixed_ctl)
6306c54c53d9SKan Liang 		to_type->fixed_ctl = from_type->fixed_ctl;
6307c54c53d9SKan Liang 	if (from_type->fixed_ctr_bits)
6308c54c53d9SKan Liang 		to_type->fixed_ctr_bits = from_type->fixed_ctr_bits;
6309c54c53d9SKan Liang 	if (from_type->num_shared_regs)
6310c54c53d9SKan Liang 		to_type->num_shared_regs = from_type->num_shared_regs;
6311c54c53d9SKan Liang 	if (from_type->constraints)
6312c54c53d9SKan Liang 		to_type->constraints = from_type->constraints;
6313c54c53d9SKan Liang 	if (from_type->ops)
6314c54c53d9SKan Liang 		to_type->ops = from_type->ops;
6315c54c53d9SKan Liang 	if (from_type->event_descs)
6316c54c53d9SKan Liang 		to_type->event_descs = from_type->event_descs;
6317c54c53d9SKan Liang 	if (from_type->format_group)
6318c54c53d9SKan Liang 		to_type->format_group = from_type->format_group;
63198053f2d7SKan Liang 	if (from_type->attr_update)
63208053f2d7SKan Liang 		to_type->attr_update = from_type->attr_update;
6321c54c53d9SKan Liang }
6322c54c53d9SKan Liang 
6323c54c53d9SKan Liang static struct intel_uncore_type **
63240378c93aSKan Liang uncore_get_uncores(enum uncore_access_type type_id, int num_extra,
63250378c93aSKan Liang 		    struct intel_uncore_type **extra)
6326c54c53d9SKan Liang {
6327c54c53d9SKan Liang 	struct intel_uncore_type **types, **start_types;
63280378c93aSKan Liang 	int i;
6329c54c53d9SKan Liang 
63300378c93aSKan Liang 	start_types = types = intel_uncore_generic_init_uncores(type_id, num_extra);
6331c54c53d9SKan Liang 
6332c54c53d9SKan Liang 	/* Only copy the customized features */
6333c54c53d9SKan Liang 	for (; *types; types++) {
6334c54c53d9SKan Liang 		if ((*types)->type_id >= UNCORE_SPR_NUM_UNCORE_TYPES)
6335c54c53d9SKan Liang 			continue;
6336c54c53d9SKan Liang 		uncore_type_customized_copy(*types, spr_uncores[(*types)->type_id]);
6337c54c53d9SKan Liang 	}
6338c54c53d9SKan Liang 
63390378c93aSKan Liang 	for (i = 0; i < num_extra; i++, types++)
63400378c93aSKan Liang 		*types = extra[i];
63410378c93aSKan Liang 
6342c54c53d9SKan Liang 	return start_types;
6343c54c53d9SKan Liang }
6344c54c53d9SKan Liang 
63450378c93aSKan Liang static struct intel_uncore_type *
63460378c93aSKan Liang uncore_find_type_by_id(struct intel_uncore_type **types, int type_id)
63470378c93aSKan Liang {
63480378c93aSKan Liang 	for (; *types; types++) {
63490378c93aSKan Liang 		if (type_id == (*types)->type_id)
63500378c93aSKan Liang 			return *types;
63510378c93aSKan Liang 	}
63520378c93aSKan Liang 
63530378c93aSKan Liang 	return NULL;
63540378c93aSKan Liang }
63550378c93aSKan Liang 
63560378c93aSKan Liang static int uncore_type_max_boxes(struct intel_uncore_type **types,
63570378c93aSKan Liang 				 int type_id)
63580378c93aSKan Liang {
63590378c93aSKan Liang 	struct intel_uncore_type *type;
63600378c93aSKan Liang 	int i, max = 0;
63610378c93aSKan Liang 
63620378c93aSKan Liang 	type = uncore_find_type_by_id(types, type_id);
63630378c93aSKan Liang 	if (!type)
63640378c93aSKan Liang 		return 0;
63650378c93aSKan Liang 
63660378c93aSKan Liang 	for (i = 0; i < type->num_boxes; i++) {
63670378c93aSKan Liang 		if (type->box_ids[i] > max)
63680378c93aSKan Liang 			max = type->box_ids[i];
63690378c93aSKan Liang 	}
63700378c93aSKan Liang 
63710378c93aSKan Liang 	return max + 1;
63720378c93aSKan Liang }
63730378c93aSKan Liang 
6374c54c53d9SKan Liang void spr_uncore_cpu_init(void)
6375c54c53d9SKan Liang {
63760378c93aSKan Liang 	uncore_msr_uncores = uncore_get_uncores(UNCORE_ACCESS_MSR,
63770378c93aSKan Liang 						UNCORE_SPR_MSR_EXTRA_UNCORES,
63780378c93aSKan Liang 						spr_msr_uncores);
63790378c93aSKan Liang 
63800378c93aSKan Liang 	spr_uncore_iio_free_running.num_boxes = uncore_type_max_boxes(uncore_msr_uncores, UNCORE_SPR_IIO);
6381c54c53d9SKan Liang }
6382c54c53d9SKan Liang 
6383c54c53d9SKan Liang int spr_uncore_pci_init(void)
6384c54c53d9SKan Liang {
63850378c93aSKan Liang 	uncore_pci_uncores = uncore_get_uncores(UNCORE_ACCESS_PCI, 0, NULL);
6386c54c53d9SKan Liang 	return 0;
6387c54c53d9SKan Liang }
6388c54c53d9SKan Liang 
6389c54c53d9SKan Liang void spr_uncore_mmio_init(void)
6390c54c53d9SKan Liang {
6391c76826a6SKan Liang 	int ret = snbep_pci2phy_map_init(0x3250, SKX_CPUNODEID, SKX_GIDNIDMAP, true);
6392c76826a6SKan Liang 
6393c76826a6SKan Liang 	if (ret)
63940378c93aSKan Liang 		uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO, 0, NULL);
6395c76826a6SKan Liang 	else {
6396c76826a6SKan Liang 		uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO,
6397c76826a6SKan Liang 							 UNCORE_SPR_MMIO_EXTRA_UNCORES,
6398c76826a6SKan Liang 							 spr_mmio_uncores);
6399c76826a6SKan Liang 
6400c76826a6SKan Liang 		spr_uncore_imc_free_running.num_boxes = uncore_type_max_boxes(uncore_mmio_uncores, UNCORE_SPR_IMC) / 2;
6401c76826a6SKan Liang 	}
6402c54c53d9SKan Liang }
6403c54c53d9SKan Liang 
6404c54c53d9SKan Liang /* end of SPR uncore support */
6405