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
4482b3b76b5SKan Liang 
4492b3b76b5SKan Liang /* ICX M3UPI*/
4502b3b76b5SKan Liang #define ICX_M3UPI_PCI_PMON_CTL0			0xd8
4512b3b76b5SKan Liang #define ICX_M3UPI_PCI_PMON_CTR0			0xa8
4522b3b76b5SKan Liang #define ICX_M3UPI_PCI_PMON_BOX_CTL		0xa0
4532b3b76b5SKan Liang 
4542b3b76b5SKan Liang /* ICX IMC */
455496a18f0SKan Liang #define ICX_NUMBER_IMC_CHN			3
4562b3b76b5SKan Liang #define ICX_IMC_MEM_STRIDE			0x4
4572b3b76b5SKan Liang 
458949b1138SKan Liang /* SPR */
459949b1138SKan Liang #define SPR_RAW_EVENT_MASK_EXT			0xffffff
460949b1138SKan Liang 
461949b1138SKan Liang /* SPR CHA */
462949b1138SKan Liang #define SPR_CHA_PMON_CTL_TID_EN			(1 << 16)
463949b1138SKan Liang #define SPR_CHA_PMON_EVENT_MASK			(SNBEP_PMON_RAW_EVENT_MASK | \
464949b1138SKan Liang 						 SPR_CHA_PMON_CTL_TID_EN)
465949b1138SKan Liang #define SPR_CHA_PMON_BOX_FILTER_TID		0x3ff
466949b1138SKan Liang 
467949b1138SKan Liang #define SPR_C0_MSR_PMON_BOX_FILTER0		0x200e
468949b1138SKan Liang 
469ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
470ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(event2, event, "config:0-6");
471ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21");
472ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(use_occ_ctr, use_occ_ctr, "config:7");
473ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
474b3625980SStephane Eranian DEFINE_UNCORE_FORMAT_ATTR(umask_ext, umask, "config:8-15,32-43,45-55");
475210cc5f9SKan Liang DEFINE_UNCORE_FORMAT_ATTR(umask_ext2, umask, "config:8-15,32-57");
476210cc5f9SKan Liang DEFINE_UNCORE_FORMAT_ATTR(umask_ext3, umask, "config:8-15,32-39");
4772b3b76b5SKan Liang DEFINE_UNCORE_FORMAT_ATTR(umask_ext4, umask, "config:8-15,32-55");
478ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(qor, qor, "config:16");
479ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
480ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19");
481949b1138SKan Liang DEFINE_UNCORE_FORMAT_ATTR(tid_en2, tid_en, "config:16");
482ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
483cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(thresh9, thresh, "config:24-35");
484ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31");
485ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(thresh6, thresh, "config:24-29");
486ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(thresh5, thresh, "config:24-28");
487ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(occ_sel, occ_sel, "config:14-15");
488ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30");
489ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51");
490ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(occ_edge_det, occ_edge_det, "config:31");
491cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(ch_mask, ch_mask, "config:36-43");
492210cc5f9SKan Liang DEFINE_UNCORE_FORMAT_ATTR(ch_mask2, ch_mask, "config:36-47");
493cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(fc_mask, fc_mask, "config:44-46");
494210cc5f9SKan Liang DEFINE_UNCORE_FORMAT_ATTR(fc_mask2, fc_mask, "config:48-50");
495ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_tid, filter_tid, "config1:0-4");
496ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_tid2, filter_tid, "config1:0");
497ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_tid3, filter_tid, "config1:0-5");
498ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_tid4, filter_tid, "config1:0-8");
499210cc5f9SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_tid5, filter_tid, "config1:0-9");
500ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_cid, filter_cid, "config1:5");
501ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_link, filter_link, "config1:5-8");
502ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_link2, filter_link, "config1:6-8");
503ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_link3, filter_link, "config1:12");
504ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17");
505ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_nid2, filter_nid, "config1:32-47");
506ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22");
507ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_state2, filter_state, "config1:17-22");
508ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_state3, filter_state, "config1:17-23");
509ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_state4, filter_state, "config1:18-20");
510cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_state5, filter_state, "config1:17-26");
511cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_rem, filter_rem, "config1:32");
512cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_loc, filter_loc, "config1:33");
513cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_nm, filter_nm, "config1:36");
514cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_not_nm, filter_not_nm, "config1:37");
515ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_local, filter_local, "config1:33");
516ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_all_op, filter_all_op, "config1:35");
517ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_nnm, filter_nnm, "config1:37");
518ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31");
519ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_opc2, filter_opc, "config1:52-60");
520ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_opc3, filter_opc, "config1:41-60");
521cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_opc_0, filter_opc0, "config1:41-50");
522cd34cd97SKan Liang DEFINE_UNCORE_FORMAT_ATTR(filter_opc_1, filter_opc1, "config1:51-60");
523ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_nc, filter_nc, "config1:62");
524ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_c6, filter_c6, "config1:61");
525ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_isoc, filter_isoc, "config1:63");
526ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_band0, filter_band0, "config1:0-7");
527ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_band1, filter_band1, "config1:8-15");
528ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_band2, filter_band2, "config1:16-23");
529ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(filter_band3, filter_band3, "config1:24-31");
530ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_rds, match_rds, "config1:48-51");
531ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_rnid30, match_rnid30, "config1:32-35");
532ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_rnid4, match_rnid4, "config1:31");
533ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_dnid, match_dnid, "config1:13-17");
534ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_mc, match_mc, "config1:9-12");
535ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_opc, match_opc, "config1:5-8");
536ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match_vnw, match_vnw, "config1:3-4");
537ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match0, match0, "config1:0-31");
538ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(match1, match1, "config1:32-63");
539ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_rds, mask_rds, "config2:48-51");
540ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_rnid30, mask_rnid30, "config2:32-35");
541ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_rnid4, mask_rnid4, "config2:31");
542ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_dnid, mask_dnid, "config2:13-17");
543ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_mc, mask_mc, "config2:9-12");
544ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_opc, mask_opc, "config2:5-8");
545ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask_vnw, mask_vnw, "config2:3-4");
546ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask0, mask0, "config2:0-31");
547ed367e6cSBorislav Petkov DEFINE_UNCORE_FORMAT_ATTR(mask1, mask1, "config2:32-63");
548ed367e6cSBorislav Petkov 
549ed367e6cSBorislav Petkov static void snbep_uncore_pci_disable_box(struct intel_uncore_box *box)
550ed367e6cSBorislav Petkov {
551ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
552ed367e6cSBorislav Petkov 	int box_ctl = uncore_pci_box_ctl(box);
553ed367e6cSBorislav Petkov 	u32 config = 0;
554ed367e6cSBorislav Petkov 
555ed367e6cSBorislav Petkov 	if (!pci_read_config_dword(pdev, box_ctl, &config)) {
556ed367e6cSBorislav Petkov 		config |= SNBEP_PMON_BOX_CTL_FRZ;
557ed367e6cSBorislav Petkov 		pci_write_config_dword(pdev, box_ctl, config);
558ed367e6cSBorislav Petkov 	}
559ed367e6cSBorislav Petkov }
560ed367e6cSBorislav Petkov 
561ed367e6cSBorislav Petkov static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box)
562ed367e6cSBorislav Petkov {
563ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
564ed367e6cSBorislav Petkov 	int box_ctl = uncore_pci_box_ctl(box);
565ed367e6cSBorislav Petkov 	u32 config = 0;
566ed367e6cSBorislav Petkov 
567ed367e6cSBorislav Petkov 	if (!pci_read_config_dword(pdev, box_ctl, &config)) {
568ed367e6cSBorislav Petkov 		config &= ~SNBEP_PMON_BOX_CTL_FRZ;
569ed367e6cSBorislav Petkov 		pci_write_config_dword(pdev, box_ctl, config);
570ed367e6cSBorislav Petkov 	}
571ed367e6cSBorislav Petkov }
572ed367e6cSBorislav Petkov 
573ed367e6cSBorislav Petkov static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event)
574ed367e6cSBorislav Petkov {
575ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
576ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
577ed367e6cSBorislav Petkov 
578ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
579ed367e6cSBorislav Petkov }
580ed367e6cSBorislav Petkov 
581ed367e6cSBorislav Petkov static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box, struct perf_event *event)
582ed367e6cSBorislav Petkov {
583ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
584ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
585ed367e6cSBorislav Petkov 
586ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, hwc->config_base, hwc->config);
587ed367e6cSBorislav Petkov }
588ed367e6cSBorislav Petkov 
589ed367e6cSBorislav Petkov static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, struct perf_event *event)
590ed367e6cSBorislav Petkov {
591ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
592ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
593ed367e6cSBorislav Petkov 	u64 count = 0;
594ed367e6cSBorislav Petkov 
595ed367e6cSBorislav Petkov 	pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count);
596ed367e6cSBorislav Petkov 	pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1);
597ed367e6cSBorislav Petkov 
598ed367e6cSBorislav Petkov 	return count;
599ed367e6cSBorislav Petkov }
600ed367e6cSBorislav Petkov 
601ed367e6cSBorislav Petkov static void snbep_uncore_pci_init_box(struct intel_uncore_box *box)
602ed367e6cSBorislav Petkov {
603ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
604ed367e6cSBorislav Petkov 	int box_ctl = uncore_pci_box_ctl(box);
605ed367e6cSBorislav Petkov 
606ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, box_ctl, SNBEP_PMON_BOX_CTL_INT);
607ed367e6cSBorislav Petkov }
608ed367e6cSBorislav Petkov 
609ed367e6cSBorislav Petkov static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box)
610ed367e6cSBorislav Petkov {
611ed367e6cSBorislav Petkov 	u64 config;
612ed367e6cSBorislav Petkov 	unsigned msr;
613ed367e6cSBorislav Petkov 
614ed367e6cSBorislav Petkov 	msr = uncore_msr_box_ctl(box);
615ed367e6cSBorislav Petkov 	if (msr) {
616ed367e6cSBorislav Petkov 		rdmsrl(msr, config);
617ed367e6cSBorislav Petkov 		config |= SNBEP_PMON_BOX_CTL_FRZ;
618ed367e6cSBorislav Petkov 		wrmsrl(msr, config);
619ed367e6cSBorislav Petkov 	}
620ed367e6cSBorislav Petkov }
621ed367e6cSBorislav Petkov 
622ed367e6cSBorislav Petkov static void snbep_uncore_msr_enable_box(struct intel_uncore_box *box)
623ed367e6cSBorislav Petkov {
624ed367e6cSBorislav Petkov 	u64 config;
625ed367e6cSBorislav Petkov 	unsigned msr;
626ed367e6cSBorislav Petkov 
627ed367e6cSBorislav Petkov 	msr = uncore_msr_box_ctl(box);
628ed367e6cSBorislav Petkov 	if (msr) {
629ed367e6cSBorislav Petkov 		rdmsrl(msr, config);
630ed367e6cSBorislav Petkov 		config &= ~SNBEP_PMON_BOX_CTL_FRZ;
631ed367e6cSBorislav Petkov 		wrmsrl(msr, config);
632ed367e6cSBorislav Petkov 	}
633ed367e6cSBorislav Petkov }
634ed367e6cSBorislav Petkov 
635ed367e6cSBorislav Petkov static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
636ed367e6cSBorislav Petkov {
637ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
638ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
639ed367e6cSBorislav Petkov 
640ed367e6cSBorislav Petkov 	if (reg1->idx != EXTRA_REG_NONE)
641ed367e6cSBorislav Petkov 		wrmsrl(reg1->reg, uncore_shared_reg_config(box, 0));
642ed367e6cSBorislav Petkov 
643ed367e6cSBorislav Petkov 	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
644ed367e6cSBorislav Petkov }
645ed367e6cSBorislav Petkov 
646ed367e6cSBorislav Petkov static void snbep_uncore_msr_disable_event(struct intel_uncore_box *box,
647ed367e6cSBorislav Petkov 					struct perf_event *event)
648ed367e6cSBorislav Petkov {
649ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
650ed367e6cSBorislav Petkov 
651ed367e6cSBorislav Petkov 	wrmsrl(hwc->config_base, hwc->config);
652ed367e6cSBorislav Petkov }
653ed367e6cSBorislav Petkov 
654ed367e6cSBorislav Petkov static void snbep_uncore_msr_init_box(struct intel_uncore_box *box)
655ed367e6cSBorislav Petkov {
656ed367e6cSBorislav Petkov 	unsigned msr = uncore_msr_box_ctl(box);
657ed367e6cSBorislav Petkov 
658ed367e6cSBorislav Petkov 	if (msr)
659ed367e6cSBorislav Petkov 		wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT);
660ed367e6cSBorislav Petkov }
661ed367e6cSBorislav Petkov 
662ed367e6cSBorislav Petkov static struct attribute *snbep_uncore_formats_attr[] = {
663ed367e6cSBorislav Petkov 	&format_attr_event.attr,
664ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
665ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
666ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
667ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
668ed367e6cSBorislav Petkov 	NULL,
669ed367e6cSBorislav Petkov };
670ed367e6cSBorislav Petkov 
671ed367e6cSBorislav Petkov static struct attribute *snbep_uncore_ubox_formats_attr[] = {
672ed367e6cSBorislav Petkov 	&format_attr_event.attr,
673ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
674ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
675ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
676ed367e6cSBorislav Petkov 	&format_attr_thresh5.attr,
677ed367e6cSBorislav Petkov 	NULL,
678ed367e6cSBorislav Petkov };
679ed367e6cSBorislav Petkov 
680ed367e6cSBorislav Petkov static struct attribute *snbep_uncore_cbox_formats_attr[] = {
681ed367e6cSBorislav Petkov 	&format_attr_event.attr,
682ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
683ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
684ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
685ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
686ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
687ed367e6cSBorislav Petkov 	&format_attr_filter_tid.attr,
688ed367e6cSBorislav Petkov 	&format_attr_filter_nid.attr,
689ed367e6cSBorislav Petkov 	&format_attr_filter_state.attr,
690ed367e6cSBorislav Petkov 	&format_attr_filter_opc.attr,
691ed367e6cSBorislav Petkov 	NULL,
692ed367e6cSBorislav Petkov };
693ed367e6cSBorislav Petkov 
694ed367e6cSBorislav Petkov static struct attribute *snbep_uncore_pcu_formats_attr[] = {
695cb225252SKan Liang 	&format_attr_event.attr,
696ed367e6cSBorislav Petkov 	&format_attr_occ_sel.attr,
697ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
698ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
699ed367e6cSBorislav Petkov 	&format_attr_thresh5.attr,
700ed367e6cSBorislav Petkov 	&format_attr_occ_invert.attr,
701ed367e6cSBorislav Petkov 	&format_attr_occ_edge.attr,
702ed367e6cSBorislav Petkov 	&format_attr_filter_band0.attr,
703ed367e6cSBorislav Petkov 	&format_attr_filter_band1.attr,
704ed367e6cSBorislav Petkov 	&format_attr_filter_band2.attr,
705ed367e6cSBorislav Petkov 	&format_attr_filter_band3.attr,
706ed367e6cSBorislav Petkov 	NULL,
707ed367e6cSBorislav Petkov };
708ed367e6cSBorislav Petkov 
709ed367e6cSBorislav Petkov static struct attribute *snbep_uncore_qpi_formats_attr[] = {
710ed367e6cSBorislav Petkov 	&format_attr_event_ext.attr,
711ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
712ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
713ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
714ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
715ed367e6cSBorislav Petkov 	&format_attr_match_rds.attr,
716ed367e6cSBorislav Petkov 	&format_attr_match_rnid30.attr,
717ed367e6cSBorislav Petkov 	&format_attr_match_rnid4.attr,
718ed367e6cSBorislav Petkov 	&format_attr_match_dnid.attr,
719ed367e6cSBorislav Petkov 	&format_attr_match_mc.attr,
720ed367e6cSBorislav Petkov 	&format_attr_match_opc.attr,
721ed367e6cSBorislav Petkov 	&format_attr_match_vnw.attr,
722ed367e6cSBorislav Petkov 	&format_attr_match0.attr,
723ed367e6cSBorislav Petkov 	&format_attr_match1.attr,
724ed367e6cSBorislav Petkov 	&format_attr_mask_rds.attr,
725ed367e6cSBorislav Petkov 	&format_attr_mask_rnid30.attr,
726ed367e6cSBorislav Petkov 	&format_attr_mask_rnid4.attr,
727ed367e6cSBorislav Petkov 	&format_attr_mask_dnid.attr,
728ed367e6cSBorislav Petkov 	&format_attr_mask_mc.attr,
729ed367e6cSBorislav Petkov 	&format_attr_mask_opc.attr,
730ed367e6cSBorislav Petkov 	&format_attr_mask_vnw.attr,
731ed367e6cSBorislav Petkov 	&format_attr_mask0.attr,
732ed367e6cSBorislav Petkov 	&format_attr_mask1.attr,
733ed367e6cSBorislav Petkov 	NULL,
734ed367e6cSBorislav Petkov };
735ed367e6cSBorislav Petkov 
736ed367e6cSBorislav Petkov static struct uncore_event_desc snbep_uncore_imc_events[] = {
737ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(clockticks,      "event=0xff,umask=0x00"),
738ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_read,  "event=0x04,umask=0x03"),
739ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_read.scale, "6.103515625e-5"),
740ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_read.unit, "MiB"),
741ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"),
742ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_write.scale, "6.103515625e-5"),
743ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_write.unit, "MiB"),
744ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ },
745ed367e6cSBorislav Petkov };
746ed367e6cSBorislav Petkov 
747ed367e6cSBorislav Petkov static struct uncore_event_desc snbep_uncore_qpi_events[] = {
748ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(clockticks,       "event=0x14"),
749ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(txl_flits_active, "event=0x00,umask=0x06"),
750ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(drs_data,         "event=0x102,umask=0x08"),
751ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(ncb_data,         "event=0x103,umask=0x04"),
752ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ },
753ed367e6cSBorislav Petkov };
754ed367e6cSBorislav Petkov 
75545bd07adSArvind Yadav static const struct attribute_group snbep_uncore_format_group = {
756ed367e6cSBorislav Petkov 	.name = "format",
757ed367e6cSBorislav Petkov 	.attrs = snbep_uncore_formats_attr,
758ed367e6cSBorislav Petkov };
759ed367e6cSBorislav Petkov 
76045bd07adSArvind Yadav static const struct attribute_group snbep_uncore_ubox_format_group = {
761ed367e6cSBorislav Petkov 	.name = "format",
762ed367e6cSBorislav Petkov 	.attrs = snbep_uncore_ubox_formats_attr,
763ed367e6cSBorislav Petkov };
764ed367e6cSBorislav Petkov 
76545bd07adSArvind Yadav static const struct attribute_group snbep_uncore_cbox_format_group = {
766ed367e6cSBorislav Petkov 	.name = "format",
767ed367e6cSBorislav Petkov 	.attrs = snbep_uncore_cbox_formats_attr,
768ed367e6cSBorislav Petkov };
769ed367e6cSBorislav Petkov 
77045bd07adSArvind Yadav static const struct attribute_group snbep_uncore_pcu_format_group = {
771ed367e6cSBorislav Petkov 	.name = "format",
772ed367e6cSBorislav Petkov 	.attrs = snbep_uncore_pcu_formats_attr,
773ed367e6cSBorislav Petkov };
774ed367e6cSBorislav Petkov 
77545bd07adSArvind Yadav static const struct attribute_group snbep_uncore_qpi_format_group = {
776ed367e6cSBorislav Petkov 	.name = "format",
777ed367e6cSBorislav Petkov 	.attrs = snbep_uncore_qpi_formats_attr,
778ed367e6cSBorislav Petkov };
779ed367e6cSBorislav Petkov 
780ed367e6cSBorislav Petkov #define __SNBEP_UNCORE_MSR_OPS_COMMON_INIT()			\
781ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_msr_disable_box,		\
782ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_msr_enable_box,		\
783ed367e6cSBorislav Petkov 	.disable_event	= snbep_uncore_msr_disable_event,	\
784ed367e6cSBorislav Petkov 	.enable_event	= snbep_uncore_msr_enable_event,	\
785ed367e6cSBorislav Petkov 	.read_counter	= uncore_msr_read_counter
786ed367e6cSBorislav Petkov 
787ed367e6cSBorislav Petkov #define SNBEP_UNCORE_MSR_OPS_COMMON_INIT()			\
788ed367e6cSBorislav Petkov 	__SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),			\
789ed367e6cSBorislav Petkov 	.init_box	= snbep_uncore_msr_init_box		\
790ed367e6cSBorislav Petkov 
791ed367e6cSBorislav Petkov static struct intel_uncore_ops snbep_uncore_msr_ops = {
792ed367e6cSBorislav Petkov 	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
793ed367e6cSBorislav Petkov };
794ed367e6cSBorislav Petkov 
795ed367e6cSBorislav Petkov #define SNBEP_UNCORE_PCI_OPS_COMMON_INIT()			\
796ed367e6cSBorislav Petkov 	.init_box	= snbep_uncore_pci_init_box,		\
797ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_pci_disable_box,		\
798ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_pci_enable_box,		\
799ed367e6cSBorislav Petkov 	.disable_event	= snbep_uncore_pci_disable_event,	\
800ed367e6cSBorislav Petkov 	.read_counter	= snbep_uncore_pci_read_counter
801ed367e6cSBorislav Petkov 
802ed367e6cSBorislav Petkov static struct intel_uncore_ops snbep_uncore_pci_ops = {
803ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_OPS_COMMON_INIT(),
804ed367e6cSBorislav Petkov 	.enable_event	= snbep_uncore_pci_enable_event,	\
805ed367e6cSBorislav Petkov };
806ed367e6cSBorislav Petkov 
807ed367e6cSBorislav Petkov static struct event_constraint snbep_uncore_cbox_constraints[] = {
808ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x01, 0x1),
809ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x02, 0x3),
810ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x04, 0x3),
811ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x05, 0x3),
812ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x07, 0x3),
813ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x09, 0x3),
814ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
815ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
816ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x13, 0x3),
817ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1b, 0xc),
818ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1c, 0xc),
819ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1d, 0xc),
820ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1e, 0xc),
8211134c2b5SPeter Zijlstra 	UNCORE_EVENT_CONSTRAINT(0x1f, 0xe),
822ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
823ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
824ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
825ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
826ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
827ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
828ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
829ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
830ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
831ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
832ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
833ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x3b, 0x1),
834ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
835ed367e6cSBorislav Petkov };
836ed367e6cSBorislav Petkov 
837ed367e6cSBorislav Petkov static struct event_constraint snbep_uncore_r2pcie_constraints[] = {
838ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
839ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
840ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x12, 0x1),
841ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
842ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
843ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
844ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
845ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
846ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
847ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
848ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
849ed367e6cSBorislav Petkov };
850ed367e6cSBorislav Petkov 
851ed367e6cSBorislav Petkov static struct event_constraint snbep_uncore_r3qpi_constraints[] = {
852ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
853ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
854ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
855ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
856ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
857ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
858ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
859ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
860ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
861ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
862ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
863ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
864ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
865ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2a, 0x3),
866ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2b, 0x3),
867ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
868ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
869ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
870ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
871ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x30, 0x3),
872ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
873ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
874ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
875ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
876ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
877ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
878ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
879ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
880ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
881ed367e6cSBorislav Petkov };
882ed367e6cSBorislav Petkov 
883ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_ubox = {
884ed367e6cSBorislav Petkov 	.name		= "ubox",
885ed367e6cSBorislav Petkov 	.num_counters   = 2,
886ed367e6cSBorislav Petkov 	.num_boxes	= 1,
887ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
888ed367e6cSBorislav Petkov 	.fixed_ctr_bits	= 48,
889ed367e6cSBorislav Petkov 	.perf_ctr	= SNBEP_U_MSR_PMON_CTR0,
890ed367e6cSBorislav Petkov 	.event_ctl	= SNBEP_U_MSR_PMON_CTL0,
891ed367e6cSBorislav Petkov 	.event_mask	= SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
892ed367e6cSBorislav Petkov 	.fixed_ctr	= SNBEP_U_MSR_PMON_UCLK_FIXED_CTR,
893ed367e6cSBorislav Petkov 	.fixed_ctl	= SNBEP_U_MSR_PMON_UCLK_FIXED_CTL,
894ed367e6cSBorislav Petkov 	.ops		= &snbep_uncore_msr_ops,
895ed367e6cSBorislav Petkov 	.format_group	= &snbep_uncore_ubox_format_group,
896ed367e6cSBorislav Petkov };
897ed367e6cSBorislav Petkov 
898ed367e6cSBorislav Petkov static struct extra_reg snbep_uncore_cbox_extra_regs[] = {
899ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
900ed367e6cSBorislav Petkov 				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
901ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
902ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0x6),
903ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
904ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0x6),
905ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
906ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0x6),
907ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x6),
908ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x8),
909ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x8),
910ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0xa),
911ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0xa),
912ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x2),
913ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x2),
914ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x2),
915ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x2),
916ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x8),
917ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x8),
918ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0xa),
919ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0xa),
920ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x2),
921ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x2),
922ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x2),
923ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x2),
924ed367e6cSBorislav Petkov 	EVENT_EXTRA_END
925ed367e6cSBorislav Petkov };
926ed367e6cSBorislav Petkov 
927ed367e6cSBorislav Petkov static void snbep_cbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
928ed367e6cSBorislav Petkov {
929ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
930ed367e6cSBorislav Petkov 	struct intel_uncore_extra_reg *er = &box->shared_regs[0];
931ed367e6cSBorislav Petkov 	int i;
932ed367e6cSBorislav Petkov 
933ed367e6cSBorislav Petkov 	if (uncore_box_is_fake(box))
934ed367e6cSBorislav Petkov 		return;
935ed367e6cSBorislav Petkov 
936ed367e6cSBorislav Petkov 	for (i = 0; i < 5; i++) {
937ed367e6cSBorislav Petkov 		if (reg1->alloc & (0x1 << i))
938ed367e6cSBorislav Petkov 			atomic_sub(1 << (i * 6), &er->ref);
939ed367e6cSBorislav Petkov 	}
940ed367e6cSBorislav Petkov 	reg1->alloc = 0;
941ed367e6cSBorislav Petkov }
942ed367e6cSBorislav Petkov 
943ed367e6cSBorislav Petkov static struct event_constraint *
944ed367e6cSBorislav Petkov __snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event,
945ed367e6cSBorislav Petkov 			    u64 (*cbox_filter_mask)(int fields))
946ed367e6cSBorislav Petkov {
947ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
948ed367e6cSBorislav Petkov 	struct intel_uncore_extra_reg *er = &box->shared_regs[0];
949ed367e6cSBorislav Petkov 	int i, alloc = 0;
950ed367e6cSBorislav Petkov 	unsigned long flags;
951ed367e6cSBorislav Petkov 	u64 mask;
952ed367e6cSBorislav Petkov 
953ed367e6cSBorislav Petkov 	if (reg1->idx == EXTRA_REG_NONE)
954ed367e6cSBorislav Petkov 		return NULL;
955ed367e6cSBorislav Petkov 
956ed367e6cSBorislav Petkov 	raw_spin_lock_irqsave(&er->lock, flags);
957ed367e6cSBorislav Petkov 	for (i = 0; i < 5; i++) {
958ed367e6cSBorislav Petkov 		if (!(reg1->idx & (0x1 << i)))
959ed367e6cSBorislav Petkov 			continue;
960ed367e6cSBorislav Petkov 		if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i)))
961ed367e6cSBorislav Petkov 			continue;
962ed367e6cSBorislav Petkov 
963ed367e6cSBorislav Petkov 		mask = cbox_filter_mask(0x1 << i);
964ed367e6cSBorislav Petkov 		if (!__BITS_VALUE(atomic_read(&er->ref), i, 6) ||
965ed367e6cSBorislav Petkov 		    !((reg1->config ^ er->config) & mask)) {
966ed367e6cSBorislav Petkov 			atomic_add(1 << (i * 6), &er->ref);
967ed367e6cSBorislav Petkov 			er->config &= ~mask;
968ed367e6cSBorislav Petkov 			er->config |= reg1->config & mask;
969ed367e6cSBorislav Petkov 			alloc |= (0x1 << i);
970ed367e6cSBorislav Petkov 		} else {
971ed367e6cSBorislav Petkov 			break;
972ed367e6cSBorislav Petkov 		}
973ed367e6cSBorislav Petkov 	}
974ed367e6cSBorislav Petkov 	raw_spin_unlock_irqrestore(&er->lock, flags);
975ed367e6cSBorislav Petkov 	if (i < 5)
976ed367e6cSBorislav Petkov 		goto fail;
977ed367e6cSBorislav Petkov 
978ed367e6cSBorislav Petkov 	if (!uncore_box_is_fake(box))
979ed367e6cSBorislav Petkov 		reg1->alloc |= alloc;
980ed367e6cSBorislav Petkov 
981ed367e6cSBorislav Petkov 	return NULL;
982ed367e6cSBorislav Petkov fail:
983ed367e6cSBorislav Petkov 	for (; i >= 0; i--) {
984ed367e6cSBorislav Petkov 		if (alloc & (0x1 << i))
985ed367e6cSBorislav Petkov 			atomic_sub(1 << (i * 6), &er->ref);
986ed367e6cSBorislav Petkov 	}
987ed367e6cSBorislav Petkov 	return &uncore_constraint_empty;
988ed367e6cSBorislav Petkov }
989ed367e6cSBorislav Petkov 
990ed367e6cSBorislav Petkov static u64 snbep_cbox_filter_mask(int fields)
991ed367e6cSBorislav Petkov {
992ed367e6cSBorislav Petkov 	u64 mask = 0;
993ed367e6cSBorislav Petkov 
994ed367e6cSBorislav Petkov 	if (fields & 0x1)
995ed367e6cSBorislav Petkov 		mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_TID;
996ed367e6cSBorislav Petkov 	if (fields & 0x2)
997ed367e6cSBorislav Petkov 		mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_NID;
998ed367e6cSBorislav Petkov 	if (fields & 0x4)
999ed367e6cSBorislav Petkov 		mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_STATE;
1000ed367e6cSBorislav Petkov 	if (fields & 0x8)
1001ed367e6cSBorislav Petkov 		mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_OPC;
1002ed367e6cSBorislav Petkov 
1003ed367e6cSBorislav Petkov 	return mask;
1004ed367e6cSBorislav Petkov }
1005ed367e6cSBorislav Petkov 
1006ed367e6cSBorislav Petkov static struct event_constraint *
1007ed367e6cSBorislav Petkov snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
1008ed367e6cSBorislav Petkov {
1009ed367e6cSBorislav Petkov 	return __snbep_cbox_get_constraint(box, event, snbep_cbox_filter_mask);
1010ed367e6cSBorislav Petkov }
1011ed367e6cSBorislav Petkov 
1012ed367e6cSBorislav Petkov static int snbep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
1013ed367e6cSBorislav Petkov {
1014ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
1015ed367e6cSBorislav Petkov 	struct extra_reg *er;
1016ed367e6cSBorislav Petkov 	int idx = 0;
1017ed367e6cSBorislav Petkov 
1018ed367e6cSBorislav Petkov 	for (er = snbep_uncore_cbox_extra_regs; er->msr; er++) {
1019ed367e6cSBorislav Petkov 		if (er->event != (event->hw.config & er->config_mask))
1020ed367e6cSBorislav Petkov 			continue;
1021ed367e6cSBorislav Petkov 		idx |= er->idx;
1022ed367e6cSBorislav Petkov 	}
1023ed367e6cSBorislav Petkov 
1024ed367e6cSBorislav Petkov 	if (idx) {
1025ed367e6cSBorislav Petkov 		reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER +
1026ed367e6cSBorislav Petkov 			SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
1027ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1 & snbep_cbox_filter_mask(idx);
1028ed367e6cSBorislav Petkov 		reg1->idx = idx;
1029ed367e6cSBorislav Petkov 	}
1030ed367e6cSBorislav Petkov 	return 0;
1031ed367e6cSBorislav Petkov }
1032ed367e6cSBorislav Petkov 
1033ed367e6cSBorislav Petkov static struct intel_uncore_ops snbep_uncore_cbox_ops = {
1034ed367e6cSBorislav Petkov 	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
1035ed367e6cSBorislav Petkov 	.hw_config		= snbep_cbox_hw_config,
1036ed367e6cSBorislav Petkov 	.get_constraint		= snbep_cbox_get_constraint,
1037ed367e6cSBorislav Petkov 	.put_constraint		= snbep_cbox_put_constraint,
1038ed367e6cSBorislav Petkov };
1039ed367e6cSBorislav Petkov 
1040ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_cbox = {
1041ed367e6cSBorislav Petkov 	.name			= "cbox",
1042ed367e6cSBorislav Petkov 	.num_counters		= 4,
1043ed367e6cSBorislav Petkov 	.num_boxes		= 8,
1044ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 44,
1045ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_C0_MSR_PMON_CTL0,
1046ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_C0_MSR_PMON_CTR0,
1047ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
1048ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_C0_MSR_PMON_BOX_CTL,
1049ed367e6cSBorislav Petkov 	.msr_offset		= SNBEP_CBO_MSR_OFFSET,
1050ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
1051ed367e6cSBorislav Petkov 	.constraints		= snbep_uncore_cbox_constraints,
1052ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_cbox_ops,
1053ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_cbox_format_group,
1054ed367e6cSBorislav Petkov };
1055ed367e6cSBorislav Petkov 
1056ed367e6cSBorislav Petkov static u64 snbep_pcu_alter_er(struct perf_event *event, int new_idx, bool modify)
1057ed367e6cSBorislav Petkov {
1058ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1059ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
1060ed367e6cSBorislav Petkov 	u64 config = reg1->config;
1061ed367e6cSBorislav Petkov 
1062ed367e6cSBorislav Petkov 	if (new_idx > reg1->idx)
1063ed367e6cSBorislav Petkov 		config <<= 8 * (new_idx - reg1->idx);
1064ed367e6cSBorislav Petkov 	else
1065ed367e6cSBorislav Petkov 		config >>= 8 * (reg1->idx - new_idx);
1066ed367e6cSBorislav Petkov 
1067ed367e6cSBorislav Petkov 	if (modify) {
1068ed367e6cSBorislav Petkov 		hwc->config += new_idx - reg1->idx;
1069ed367e6cSBorislav Petkov 		reg1->config = config;
1070ed367e6cSBorislav Petkov 		reg1->idx = new_idx;
1071ed367e6cSBorislav Petkov 	}
1072ed367e6cSBorislav Petkov 	return config;
1073ed367e6cSBorislav Petkov }
1074ed367e6cSBorislav Petkov 
1075ed367e6cSBorislav Petkov static struct event_constraint *
1076ed367e6cSBorislav Petkov snbep_pcu_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
1077ed367e6cSBorislav Petkov {
1078ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
1079ed367e6cSBorislav Petkov 	struct intel_uncore_extra_reg *er = &box->shared_regs[0];
1080ed367e6cSBorislav Petkov 	unsigned long flags;
1081ed367e6cSBorislav Petkov 	int idx = reg1->idx;
1082ed367e6cSBorislav Petkov 	u64 mask, config1 = reg1->config;
1083ed367e6cSBorislav Petkov 	bool ok = false;
1084ed367e6cSBorislav Petkov 
1085ed367e6cSBorislav Petkov 	if (reg1->idx == EXTRA_REG_NONE ||
1086ed367e6cSBorislav Petkov 	    (!uncore_box_is_fake(box) && reg1->alloc))
1087ed367e6cSBorislav Petkov 		return NULL;
1088ed367e6cSBorislav Petkov again:
1089ed367e6cSBorislav Petkov 	mask = 0xffULL << (idx * 8);
1090ed367e6cSBorislav Petkov 	raw_spin_lock_irqsave(&er->lock, flags);
1091ed367e6cSBorislav Petkov 	if (!__BITS_VALUE(atomic_read(&er->ref), idx, 8) ||
1092ed367e6cSBorislav Petkov 	    !((config1 ^ er->config) & mask)) {
1093ed367e6cSBorislav Petkov 		atomic_add(1 << (idx * 8), &er->ref);
1094ed367e6cSBorislav Petkov 		er->config &= ~mask;
1095ed367e6cSBorislav Petkov 		er->config |= config1 & mask;
1096ed367e6cSBorislav Petkov 		ok = true;
1097ed367e6cSBorislav Petkov 	}
1098ed367e6cSBorislav Petkov 	raw_spin_unlock_irqrestore(&er->lock, flags);
1099ed367e6cSBorislav Petkov 
1100ed367e6cSBorislav Petkov 	if (!ok) {
1101ed367e6cSBorislav Petkov 		idx = (idx + 1) % 4;
1102ed367e6cSBorislav Petkov 		if (idx != reg1->idx) {
1103ed367e6cSBorislav Petkov 			config1 = snbep_pcu_alter_er(event, idx, false);
1104ed367e6cSBorislav Petkov 			goto again;
1105ed367e6cSBorislav Petkov 		}
1106ed367e6cSBorislav Petkov 		return &uncore_constraint_empty;
1107ed367e6cSBorislav Petkov 	}
1108ed367e6cSBorislav Petkov 
1109ed367e6cSBorislav Petkov 	if (!uncore_box_is_fake(box)) {
1110ed367e6cSBorislav Petkov 		if (idx != reg1->idx)
1111ed367e6cSBorislav Petkov 			snbep_pcu_alter_er(event, idx, true);
1112ed367e6cSBorislav Petkov 		reg1->alloc = 1;
1113ed367e6cSBorislav Petkov 	}
1114ed367e6cSBorislav Petkov 	return NULL;
1115ed367e6cSBorislav Petkov }
1116ed367e6cSBorislav Petkov 
1117ed367e6cSBorislav Petkov static void snbep_pcu_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
1118ed367e6cSBorislav Petkov {
1119ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
1120ed367e6cSBorislav Petkov 	struct intel_uncore_extra_reg *er = &box->shared_regs[0];
1121ed367e6cSBorislav Petkov 
1122ed367e6cSBorislav Petkov 	if (uncore_box_is_fake(box) || !reg1->alloc)
1123ed367e6cSBorislav Petkov 		return;
1124ed367e6cSBorislav Petkov 
1125ed367e6cSBorislav Petkov 	atomic_sub(1 << (reg1->idx * 8), &er->ref);
1126ed367e6cSBorislav Petkov 	reg1->alloc = 0;
1127ed367e6cSBorislav Petkov }
1128ed367e6cSBorislav Petkov 
1129ed367e6cSBorislav Petkov static int snbep_pcu_hw_config(struct intel_uncore_box *box, struct perf_event *event)
1130ed367e6cSBorislav Petkov {
1131ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1132ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
1133ed367e6cSBorislav Petkov 	int ev_sel = hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK;
1134ed367e6cSBorislav Petkov 
1135ed367e6cSBorislav Petkov 	if (ev_sel >= 0xb && ev_sel <= 0xe) {
1136ed367e6cSBorislav Petkov 		reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER;
1137ed367e6cSBorislav Petkov 		reg1->idx = ev_sel - 0xb;
1138ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1 & (0xff << (reg1->idx * 8));
1139ed367e6cSBorislav Petkov 	}
1140ed367e6cSBorislav Petkov 	return 0;
1141ed367e6cSBorislav Petkov }
1142ed367e6cSBorislav Petkov 
1143ed367e6cSBorislav Petkov static struct intel_uncore_ops snbep_uncore_pcu_ops = {
1144ed367e6cSBorislav Petkov 	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
1145ed367e6cSBorislav Petkov 	.hw_config		= snbep_pcu_hw_config,
1146ed367e6cSBorislav Petkov 	.get_constraint		= snbep_pcu_get_constraint,
1147ed367e6cSBorislav Petkov 	.put_constraint		= snbep_pcu_put_constraint,
1148ed367e6cSBorislav Petkov };
1149ed367e6cSBorislav Petkov 
1150ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_pcu = {
1151ed367e6cSBorislav Petkov 	.name			= "pcu",
1152ed367e6cSBorislav Petkov 	.num_counters		= 4,
1153ed367e6cSBorislav Petkov 	.num_boxes		= 1,
1154ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
1155ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCU_MSR_PMON_CTR0,
1156ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCU_MSR_PMON_CTL0,
1157ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
1158ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCU_MSR_PMON_BOX_CTL,
1159ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
1160ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_pcu_ops,
1161ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_pcu_format_group,
1162ed367e6cSBorislav Petkov };
1163ed367e6cSBorislav Petkov 
1164ed367e6cSBorislav Petkov static struct intel_uncore_type *snbep_msr_uncores[] = {
1165ed367e6cSBorislav Petkov 	&snbep_uncore_ubox,
1166ed367e6cSBorislav Petkov 	&snbep_uncore_cbox,
1167ed367e6cSBorislav Petkov 	&snbep_uncore_pcu,
1168ed367e6cSBorislav Petkov 	NULL,
1169ed367e6cSBorislav Petkov };
1170ed367e6cSBorislav Petkov 
1171ed367e6cSBorislav Petkov void snbep_uncore_cpu_init(void)
1172ed367e6cSBorislav Petkov {
1173ed367e6cSBorislav Petkov 	if (snbep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
1174ed367e6cSBorislav Petkov 		snbep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
1175ed367e6cSBorislav Petkov 	uncore_msr_uncores = snbep_msr_uncores;
1176ed367e6cSBorislav Petkov }
1177ed367e6cSBorislav Petkov 
1178ed367e6cSBorislav Petkov enum {
1179ed367e6cSBorislav Petkov 	SNBEP_PCI_QPI_PORT0_FILTER,
1180ed367e6cSBorislav Petkov 	SNBEP_PCI_QPI_PORT1_FILTER,
1181156c8b58SKan Liang 	BDX_PCI_QPI_PORT2_FILTER,
1182ed367e6cSBorislav Petkov };
1183ed367e6cSBorislav Petkov 
1184ed367e6cSBorislav Petkov static int snbep_qpi_hw_config(struct intel_uncore_box *box, struct perf_event *event)
1185ed367e6cSBorislav Petkov {
1186ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1187ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
1188ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
1189ed367e6cSBorislav Petkov 
1190ed367e6cSBorislav Petkov 	if ((hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK) == 0x38) {
1191ed367e6cSBorislav Petkov 		reg1->idx = 0;
1192ed367e6cSBorislav Petkov 		reg1->reg = SNBEP_Q_Py_PCI_PMON_PKT_MATCH0;
1193ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1;
1194ed367e6cSBorislav Petkov 		reg2->reg = SNBEP_Q_Py_PCI_PMON_PKT_MASK0;
1195ed367e6cSBorislav Petkov 		reg2->config = event->attr.config2;
1196ed367e6cSBorislav Petkov 	}
1197ed367e6cSBorislav Petkov 	return 0;
1198ed367e6cSBorislav Petkov }
1199ed367e6cSBorislav Petkov 
1200ed367e6cSBorislav Petkov static void snbep_qpi_enable_event(struct intel_uncore_box *box, struct perf_event *event)
1201ed367e6cSBorislav Petkov {
1202ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
1203ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1204ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
1205ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
1206ed367e6cSBorislav Petkov 
1207ed367e6cSBorislav Petkov 	if (reg1->idx != EXTRA_REG_NONE) {
1208ed367e6cSBorislav Petkov 		int idx = box->pmu->pmu_idx + SNBEP_PCI_QPI_PORT0_FILTER;
1209b0529b9cSKan Liang 		int die = box->dieid;
1210b0529b9cSKan Liang 		struct pci_dev *filter_pdev = uncore_extra_pci_dev[die].dev[idx];
1211cf6d445fSThomas Gleixner 
1212ed367e6cSBorislav Petkov 		if (filter_pdev) {
1213ed367e6cSBorislav Petkov 			pci_write_config_dword(filter_pdev, reg1->reg,
1214ed367e6cSBorislav Petkov 						(u32)reg1->config);
1215ed367e6cSBorislav Petkov 			pci_write_config_dword(filter_pdev, reg1->reg + 4,
1216ed367e6cSBorislav Petkov 						(u32)(reg1->config >> 32));
1217ed367e6cSBorislav Petkov 			pci_write_config_dword(filter_pdev, reg2->reg,
1218ed367e6cSBorislav Petkov 						(u32)reg2->config);
1219ed367e6cSBorislav Petkov 			pci_write_config_dword(filter_pdev, reg2->reg + 4,
1220ed367e6cSBorislav Petkov 						(u32)(reg2->config >> 32));
1221ed367e6cSBorislav Petkov 		}
1222ed367e6cSBorislav Petkov 	}
1223ed367e6cSBorislav Petkov 
1224ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
1225ed367e6cSBorislav Petkov }
1226ed367e6cSBorislav Petkov 
1227ed367e6cSBorislav Petkov static struct intel_uncore_ops snbep_uncore_qpi_ops = {
1228ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_OPS_COMMON_INIT(),
1229ed367e6cSBorislav Petkov 	.enable_event		= snbep_qpi_enable_event,
1230ed367e6cSBorislav Petkov 	.hw_config		= snbep_qpi_hw_config,
1231ed367e6cSBorislav Petkov 	.get_constraint		= uncore_get_constraint,
1232ed367e6cSBorislav Petkov 	.put_constraint		= uncore_put_constraint,
1233ed367e6cSBorislav Petkov };
1234ed367e6cSBorislav Petkov 
1235ed367e6cSBorislav Petkov #define SNBEP_UNCORE_PCI_COMMON_INIT()				\
1236ed367e6cSBorislav Petkov 	.perf_ctr	= SNBEP_PCI_PMON_CTR0,			\
1237ed367e6cSBorislav Petkov 	.event_ctl	= SNBEP_PCI_PMON_CTL0,			\
1238ed367e6cSBorislav Petkov 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,		\
1239ed367e6cSBorislav Petkov 	.box_ctl	= SNBEP_PCI_PMON_BOX_CTL,		\
1240ed367e6cSBorislav Petkov 	.ops		= &snbep_uncore_pci_ops,		\
1241ed367e6cSBorislav Petkov 	.format_group	= &snbep_uncore_format_group
1242ed367e6cSBorislav Petkov 
1243ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_ha = {
1244ed367e6cSBorislav Petkov 	.name		= "ha",
1245ed367e6cSBorislav Petkov 	.num_counters   = 4,
1246ed367e6cSBorislav Petkov 	.num_boxes	= 1,
1247ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
1248ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
1249ed367e6cSBorislav Petkov };
1250ed367e6cSBorislav Petkov 
1251ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_imc = {
1252ed367e6cSBorislav Petkov 	.name		= "imc",
1253ed367e6cSBorislav Petkov 	.num_counters   = 4,
1254ed367e6cSBorislav Petkov 	.num_boxes	= 4,
1255ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
1256ed367e6cSBorislav Petkov 	.fixed_ctr_bits	= 48,
1257ed367e6cSBorislav Petkov 	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
1258ed367e6cSBorislav Petkov 	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
1259ed367e6cSBorislav Petkov 	.event_descs	= snbep_uncore_imc_events,
1260ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
1261ed367e6cSBorislav Petkov };
1262ed367e6cSBorislav Petkov 
1263ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_qpi = {
1264ed367e6cSBorislav Petkov 	.name			= "qpi",
1265ed367e6cSBorislav Petkov 	.num_counters		= 4,
1266ed367e6cSBorislav Petkov 	.num_boxes		= 2,
1267ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
1268ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
1269ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCI_PMON_CTL0,
1270ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
1271ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
1272ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
1273ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_qpi_ops,
1274ed367e6cSBorislav Petkov 	.event_descs		= snbep_uncore_qpi_events,
1275ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_qpi_format_group,
1276ed367e6cSBorislav Petkov };
1277ed367e6cSBorislav Petkov 
1278ed367e6cSBorislav Petkov 
1279ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_r2pcie = {
1280ed367e6cSBorislav Petkov 	.name		= "r2pcie",
1281ed367e6cSBorislav Petkov 	.num_counters   = 4,
1282ed367e6cSBorislav Petkov 	.num_boxes	= 1,
1283ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
1284ed367e6cSBorislav Petkov 	.constraints	= snbep_uncore_r2pcie_constraints,
1285ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
1286ed367e6cSBorislav Petkov };
1287ed367e6cSBorislav Petkov 
1288ed367e6cSBorislav Petkov static struct intel_uncore_type snbep_uncore_r3qpi = {
1289ed367e6cSBorislav Petkov 	.name		= "r3qpi",
1290ed367e6cSBorislav Petkov 	.num_counters   = 3,
1291ed367e6cSBorislav Petkov 	.num_boxes	= 2,
1292ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
1293ed367e6cSBorislav Petkov 	.constraints	= snbep_uncore_r3qpi_constraints,
1294ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
1295ed367e6cSBorislav Petkov };
1296ed367e6cSBorislav Petkov 
1297ed367e6cSBorislav Petkov enum {
1298ed367e6cSBorislav Petkov 	SNBEP_PCI_UNCORE_HA,
1299ed367e6cSBorislav Petkov 	SNBEP_PCI_UNCORE_IMC,
1300ed367e6cSBorislav Petkov 	SNBEP_PCI_UNCORE_QPI,
1301ed367e6cSBorislav Petkov 	SNBEP_PCI_UNCORE_R2PCIE,
1302ed367e6cSBorislav Petkov 	SNBEP_PCI_UNCORE_R3QPI,
1303ed367e6cSBorislav Petkov };
1304ed367e6cSBorislav Petkov 
1305ed367e6cSBorislav Petkov static struct intel_uncore_type *snbep_pci_uncores[] = {
1306ed367e6cSBorislav Petkov 	[SNBEP_PCI_UNCORE_HA]		= &snbep_uncore_ha,
1307ed367e6cSBorislav Petkov 	[SNBEP_PCI_UNCORE_IMC]		= &snbep_uncore_imc,
1308ed367e6cSBorislav Petkov 	[SNBEP_PCI_UNCORE_QPI]		= &snbep_uncore_qpi,
1309ed367e6cSBorislav Petkov 	[SNBEP_PCI_UNCORE_R2PCIE]	= &snbep_uncore_r2pcie,
1310ed367e6cSBorislav Petkov 	[SNBEP_PCI_UNCORE_R3QPI]	= &snbep_uncore_r3qpi,
1311ed367e6cSBorislav Petkov 	NULL,
1312ed367e6cSBorislav Petkov };
1313ed367e6cSBorislav Petkov 
1314ed367e6cSBorislav Petkov static const struct pci_device_id snbep_uncore_pci_ids[] = {
1315ed367e6cSBorislav Petkov 	{ /* Home Agent */
1316ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA),
1317ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_HA, 0),
1318ed367e6cSBorislav Petkov 	},
1319ed367e6cSBorislav Petkov 	{ /* MC Channel 0 */
1320ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0),
1321ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 0),
1322ed367e6cSBorislav Petkov 	},
1323ed367e6cSBorislav Petkov 	{ /* MC Channel 1 */
1324ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1),
1325ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 1),
1326ed367e6cSBorislav Petkov 	},
1327ed367e6cSBorislav Petkov 	{ /* MC Channel 2 */
1328ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2),
1329ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 2),
1330ed367e6cSBorislav Petkov 	},
1331ed367e6cSBorislav Petkov 	{ /* MC Channel 3 */
1332ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3),
1333ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 3),
1334ed367e6cSBorislav Petkov 	},
1335ed367e6cSBorislav Petkov 	{ /* QPI Port 0 */
1336ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0),
1337ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 0),
1338ed367e6cSBorislav Petkov 	},
1339ed367e6cSBorislav Petkov 	{ /* QPI Port 1 */
1340ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1),
1341ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 1),
1342ed367e6cSBorislav Petkov 	},
1343ed367e6cSBorislav Petkov 	{ /* R2PCIe */
1344ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE),
1345ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R2PCIE, 0),
1346ed367e6cSBorislav Petkov 	},
1347ed367e6cSBorislav Petkov 	{ /* R3QPI Link 0 */
1348ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0),
1349ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 0),
1350ed367e6cSBorislav Petkov 	},
1351ed367e6cSBorislav Petkov 	{ /* R3QPI Link 1 */
1352ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1),
1353ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 1),
1354ed367e6cSBorislav Petkov 	},
1355ed367e6cSBorislav Petkov 	{ /* QPI Port 0 filter  */
1356ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c86),
1357ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
1358ed367e6cSBorislav Petkov 						   SNBEP_PCI_QPI_PORT0_FILTER),
1359ed367e6cSBorislav Petkov 	},
1360ed367e6cSBorislav Petkov 	{ /* QPI Port 0 filter  */
1361ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c96),
1362ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
1363ed367e6cSBorislav Petkov 						   SNBEP_PCI_QPI_PORT1_FILTER),
1364ed367e6cSBorislav Petkov 	},
1365ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ }
1366ed367e6cSBorislav Petkov };
1367ed367e6cSBorislav Petkov 
1368ed367e6cSBorislav Petkov static struct pci_driver snbep_uncore_pci_driver = {
1369ed367e6cSBorislav Petkov 	.name		= "snbep_uncore",
1370ed367e6cSBorislav Petkov 	.id_table	= snbep_uncore_pci_ids,
1371ed367e6cSBorislav Petkov };
1372ed367e6cSBorislav Petkov 
13739e63a789SKan Liang #define NODE_ID_MASK	0x7
13749e63a789SKan Liang 
1375ed367e6cSBorislav Petkov /*
1376ed367e6cSBorislav Petkov  * build pci bus to socket mapping
1377ed367e6cSBorislav Petkov  */
137868ce4a0dSKan Liang static int snbep_pci2phy_map_init(int devid, int nodeid_loc, int idmap_loc, bool reverse)
1379ed367e6cSBorislav Petkov {
1380ed367e6cSBorislav Petkov 	struct pci_dev *ubox_dev = NULL;
1381ba9506beSSteve Wahl 	int i, bus, nodeid, segment, die_id;
1382ed367e6cSBorislav Petkov 	struct pci2phy_map *map;
1383ed367e6cSBorislav Petkov 	int err = 0;
1384ed367e6cSBorislav Petkov 	u32 config = 0;
1385ed367e6cSBorislav Petkov 
1386ed367e6cSBorislav Petkov 	while (1) {
1387ed367e6cSBorislav Petkov 		/* find the UBOX device */
1388ed367e6cSBorislav Petkov 		ubox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, devid, ubox_dev);
1389ed367e6cSBorislav Petkov 		if (!ubox_dev)
1390ed367e6cSBorislav Petkov 			break;
1391ed367e6cSBorislav Petkov 		bus = ubox_dev->bus->number;
13929a7832ceSSteve Wahl 		/*
13939a7832ceSSteve Wahl 		 * The nodeid and idmap registers only contain enough
13949a7832ceSSteve Wahl 		 * information to handle 8 nodes.  On systems with more
13959a7832ceSSteve Wahl 		 * than 8 nodes, we need to rely on NUMA information,
13969a7832ceSSteve Wahl 		 * filled in from BIOS supplied information, to determine
13979a7832ceSSteve Wahl 		 * the topology.
13989a7832ceSSteve Wahl 		 */
13999a7832ceSSteve Wahl 		if (nr_node_ids <= 8) {
1400ed367e6cSBorislav Petkov 			/* get the Node ID of the local register */
140168ce4a0dSKan Liang 			err = pci_read_config_dword(ubox_dev, nodeid_loc, &config);
1402ed367e6cSBorislav Petkov 			if (err)
1403ed367e6cSBorislav Petkov 				break;
14049e63a789SKan Liang 			nodeid = config & NODE_ID_MASK;
1405ed367e6cSBorislav Petkov 			/* get the Node ID mapping */
140668ce4a0dSKan Liang 			err = pci_read_config_dword(ubox_dev, idmap_loc, &config);
1407ed367e6cSBorislav Petkov 			if (err)
1408ed367e6cSBorislav Petkov 				break;
1409ed367e6cSBorislav Petkov 
1410ed367e6cSBorislav Petkov 			segment = pci_domain_nr(ubox_dev->bus);
1411ed367e6cSBorislav Petkov 			raw_spin_lock(&pci2phy_map_lock);
1412ed367e6cSBorislav Petkov 			map = __find_pci2phy_map(segment);
1413ed367e6cSBorislav Petkov 			if (!map) {
1414ed367e6cSBorislav Petkov 				raw_spin_unlock(&pci2phy_map_lock);
1415ed367e6cSBorislav Petkov 				err = -ENOMEM;
1416ed367e6cSBorislav Petkov 				break;
1417ed367e6cSBorislav Petkov 			}
1418ed367e6cSBorislav Petkov 
1419ed367e6cSBorislav Petkov 			/*
1420ed367e6cSBorislav Petkov 			 * every three bits in the Node ID mapping register maps
1421ed367e6cSBorislav Petkov 			 * to a particular node.
1422ed367e6cSBorislav Petkov 			 */
1423ed367e6cSBorislav Petkov 			for (i = 0; i < 8; i++) {
1424ed367e6cSBorislav Petkov 				if (nodeid == ((config >> (3 * i)) & 0x7)) {
1425ba9506beSSteve Wahl 					if (topology_max_die_per_package() > 1)
1426ba9506beSSteve Wahl 						die_id = i;
1427ba9506beSSteve Wahl 					else
1428ba9506beSSteve Wahl 						die_id = topology_phys_to_logical_pkg(i);
14294a0e3ff3SKan Liang 					if (die_id < 0)
14304a0e3ff3SKan Liang 						die_id = -ENODEV;
1431ba9506beSSteve Wahl 					map->pbus_to_dieid[bus] = die_id;
1432ed367e6cSBorislav Petkov 					break;
1433ed367e6cSBorislav Petkov 				}
1434ed367e6cSBorislav Petkov 			}
1435ed367e6cSBorislav Petkov 			raw_spin_unlock(&pci2phy_map_lock);
14369a7832ceSSteve Wahl 		} else {
14379a7832ceSSteve Wahl 			int node = pcibus_to_node(ubox_dev->bus);
14389a7832ceSSteve Wahl 			int cpu;
14399a7832ceSSteve Wahl 
14409a7832ceSSteve Wahl 			segment = pci_domain_nr(ubox_dev->bus);
14419a7832ceSSteve Wahl 			raw_spin_lock(&pci2phy_map_lock);
14429a7832ceSSteve Wahl 			map = __find_pci2phy_map(segment);
14439a7832ceSSteve Wahl 			if (!map) {
14449a7832ceSSteve Wahl 				raw_spin_unlock(&pci2phy_map_lock);
14459a7832ceSSteve Wahl 				err = -ENOMEM;
14469a7832ceSSteve Wahl 				break;
14479a7832ceSSteve Wahl 			}
14489a7832ceSSteve Wahl 
14499a7832ceSSteve Wahl 			die_id = -1;
14509a7832ceSSteve Wahl 			for_each_cpu(cpu, cpumask_of_pcibus(ubox_dev->bus)) {
14519a7832ceSSteve Wahl 				struct cpuinfo_x86 *c = &cpu_data(cpu);
14529a7832ceSSteve Wahl 
14539a7832ceSSteve Wahl 				if (c->initialized && cpu_to_node(cpu) == node) {
14549a7832ceSSteve Wahl 					map->pbus_to_dieid[bus] = die_id = c->logical_die_id;
14559a7832ceSSteve Wahl 					break;
14569a7832ceSSteve Wahl 				}
14579a7832ceSSteve Wahl 			}
14589a7832ceSSteve Wahl 			raw_spin_unlock(&pci2phy_map_lock);
14599a7832ceSSteve Wahl 
14609a7832ceSSteve Wahl 			if (WARN_ON_ONCE(die_id == -1)) {
14619a7832ceSSteve Wahl 				err = -EINVAL;
14629a7832ceSSteve Wahl 				break;
14639a7832ceSSteve Wahl 			}
14649a7832ceSSteve Wahl 		}
1465ed367e6cSBorislav Petkov 	}
1466ed367e6cSBorislav Petkov 
1467ed367e6cSBorislav Petkov 	if (!err) {
1468ed367e6cSBorislav Petkov 		/*
1469ed367e6cSBorislav Petkov 		 * For PCI bus with no UBOX device, find the next bus
1470ed367e6cSBorislav Petkov 		 * that has UBOX device and use its mapping.
1471ed367e6cSBorislav Petkov 		 */
1472ed367e6cSBorislav Petkov 		raw_spin_lock(&pci2phy_map_lock);
1473ed367e6cSBorislav Petkov 		list_for_each_entry(map, &pci2phy_map_head, list) {
1474ed367e6cSBorislav Petkov 			i = -1;
147568ce4a0dSKan Liang 			if (reverse) {
1476ed367e6cSBorislav Petkov 				for (bus = 255; bus >= 0; bus--) {
14774a0e3ff3SKan Liang 					if (map->pbus_to_dieid[bus] != -1)
1478ba9506beSSteve Wahl 						i = map->pbus_to_dieid[bus];
1479ed367e6cSBorislav Petkov 					else
1480ba9506beSSteve Wahl 						map->pbus_to_dieid[bus] = i;
1481ed367e6cSBorislav Petkov 				}
148268ce4a0dSKan Liang 			} else {
148368ce4a0dSKan Liang 				for (bus = 0; bus <= 255; bus++) {
14844a0e3ff3SKan Liang 					if (map->pbus_to_dieid[bus] != -1)
1485ba9506beSSteve Wahl 						i = map->pbus_to_dieid[bus];
148668ce4a0dSKan Liang 					else
1487ba9506beSSteve Wahl 						map->pbus_to_dieid[bus] = i;
148868ce4a0dSKan Liang 				}
148968ce4a0dSKan Liang 			}
1490ed367e6cSBorislav Petkov 		}
1491ed367e6cSBorislav Petkov 		raw_spin_unlock(&pci2phy_map_lock);
1492ed367e6cSBorislav Petkov 	}
1493ed367e6cSBorislav Petkov 
1494ed367e6cSBorislav Petkov 	pci_dev_put(ubox_dev);
1495ed367e6cSBorislav Petkov 
1496ed367e6cSBorislav Petkov 	return err ? pcibios_err_to_errno(err) : 0;
1497ed367e6cSBorislav Petkov }
1498ed367e6cSBorislav Petkov 
1499ed367e6cSBorislav Petkov int snbep_uncore_pci_init(void)
1500ed367e6cSBorislav Petkov {
150168ce4a0dSKan Liang 	int ret = snbep_pci2phy_map_init(0x3ce0, SNBEP_CPUNODEID, SNBEP_GIDNIDMAP, true);
1502ed367e6cSBorislav Petkov 	if (ret)
1503ed367e6cSBorislav Petkov 		return ret;
1504ed367e6cSBorislav Petkov 	uncore_pci_uncores = snbep_pci_uncores;
1505ed367e6cSBorislav Petkov 	uncore_pci_driver = &snbep_uncore_pci_driver;
1506ed367e6cSBorislav Petkov 	return 0;
1507ed367e6cSBorislav Petkov }
1508ed367e6cSBorislav Petkov /* end of Sandy Bridge-EP uncore support */
1509ed367e6cSBorislav Petkov 
1510ed367e6cSBorislav Petkov /* IvyTown uncore support */
1511ed367e6cSBorislav Petkov static void ivbep_uncore_msr_init_box(struct intel_uncore_box *box)
1512ed367e6cSBorislav Petkov {
1513ed367e6cSBorislav Petkov 	unsigned msr = uncore_msr_box_ctl(box);
1514ed367e6cSBorislav Petkov 	if (msr)
1515ed367e6cSBorislav Petkov 		wrmsrl(msr, IVBEP_PMON_BOX_CTL_INT);
1516ed367e6cSBorislav Petkov }
1517ed367e6cSBorislav Petkov 
1518ed367e6cSBorislav Petkov static void ivbep_uncore_pci_init_box(struct intel_uncore_box *box)
1519ed367e6cSBorislav Petkov {
1520ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
1521ed367e6cSBorislav Petkov 
1522ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, IVBEP_PMON_BOX_CTL_INT);
1523ed367e6cSBorislav Petkov }
1524ed367e6cSBorislav Petkov 
1525ed367e6cSBorislav Petkov #define IVBEP_UNCORE_MSR_OPS_COMMON_INIT()			\
1526ed367e6cSBorislav Petkov 	.init_box	= ivbep_uncore_msr_init_box,		\
1527ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_msr_disable_box,		\
1528ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_msr_enable_box,		\
1529ed367e6cSBorislav Petkov 	.disable_event	= snbep_uncore_msr_disable_event,	\
1530ed367e6cSBorislav Petkov 	.enable_event	= snbep_uncore_msr_enable_event,	\
1531ed367e6cSBorislav Petkov 	.read_counter	= uncore_msr_read_counter
1532ed367e6cSBorislav Petkov 
1533ed367e6cSBorislav Petkov static struct intel_uncore_ops ivbep_uncore_msr_ops = {
1534ed367e6cSBorislav Petkov 	IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
1535ed367e6cSBorislav Petkov };
1536ed367e6cSBorislav Petkov 
1537ed367e6cSBorislav Petkov static struct intel_uncore_ops ivbep_uncore_pci_ops = {
1538ed367e6cSBorislav Petkov 	.init_box	= ivbep_uncore_pci_init_box,
1539ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_pci_disable_box,
1540ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_pci_enable_box,
1541ed367e6cSBorislav Petkov 	.disable_event	= snbep_uncore_pci_disable_event,
1542ed367e6cSBorislav Petkov 	.enable_event	= snbep_uncore_pci_enable_event,
1543ed367e6cSBorislav Petkov 	.read_counter	= snbep_uncore_pci_read_counter,
1544ed367e6cSBorislav Petkov };
1545ed367e6cSBorislav Petkov 
1546ed367e6cSBorislav Petkov #define IVBEP_UNCORE_PCI_COMMON_INIT()				\
1547ed367e6cSBorislav Petkov 	.perf_ctr	= SNBEP_PCI_PMON_CTR0,			\
1548ed367e6cSBorislav Petkov 	.event_ctl	= SNBEP_PCI_PMON_CTL0,			\
1549ed367e6cSBorislav Petkov 	.event_mask	= IVBEP_PMON_RAW_EVENT_MASK,		\
1550ed367e6cSBorislav Petkov 	.box_ctl	= SNBEP_PCI_PMON_BOX_CTL,		\
1551ed367e6cSBorislav Petkov 	.ops		= &ivbep_uncore_pci_ops,			\
1552ed367e6cSBorislav Petkov 	.format_group	= &ivbep_uncore_format_group
1553ed367e6cSBorislav Petkov 
1554ed367e6cSBorislav Petkov static struct attribute *ivbep_uncore_formats_attr[] = {
1555ed367e6cSBorislav Petkov 	&format_attr_event.attr,
1556ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
1557ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
1558ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
1559ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
1560ed367e6cSBorislav Petkov 	NULL,
1561ed367e6cSBorislav Petkov };
1562ed367e6cSBorislav Petkov 
1563ed367e6cSBorislav Petkov static struct attribute *ivbep_uncore_ubox_formats_attr[] = {
1564ed367e6cSBorislav Petkov 	&format_attr_event.attr,
1565ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
1566ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
1567ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
1568ed367e6cSBorislav Petkov 	&format_attr_thresh5.attr,
1569ed367e6cSBorislav Petkov 	NULL,
1570ed367e6cSBorislav Petkov };
1571ed367e6cSBorislav Petkov 
1572ed367e6cSBorislav Petkov static struct attribute *ivbep_uncore_cbox_formats_attr[] = {
1573ed367e6cSBorislav Petkov 	&format_attr_event.attr,
1574ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
1575ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
1576ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
1577ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
1578ed367e6cSBorislav Petkov 	&format_attr_filter_tid.attr,
1579ed367e6cSBorislav Petkov 	&format_attr_filter_link.attr,
1580ed367e6cSBorislav Petkov 	&format_attr_filter_state2.attr,
1581ed367e6cSBorislav Petkov 	&format_attr_filter_nid2.attr,
1582ed367e6cSBorislav Petkov 	&format_attr_filter_opc2.attr,
1583ed367e6cSBorislav Petkov 	&format_attr_filter_nc.attr,
1584ed367e6cSBorislav Petkov 	&format_attr_filter_c6.attr,
1585ed367e6cSBorislav Petkov 	&format_attr_filter_isoc.attr,
1586ed367e6cSBorislav Petkov 	NULL,
1587ed367e6cSBorislav Petkov };
1588ed367e6cSBorislav Petkov 
1589ed367e6cSBorislav Petkov static struct attribute *ivbep_uncore_pcu_formats_attr[] = {
1590cb225252SKan Liang 	&format_attr_event.attr,
1591ed367e6cSBorislav Petkov 	&format_attr_occ_sel.attr,
1592ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
1593ed367e6cSBorislav Petkov 	&format_attr_thresh5.attr,
1594ed367e6cSBorislav Petkov 	&format_attr_occ_invert.attr,
1595ed367e6cSBorislav Petkov 	&format_attr_occ_edge.attr,
1596ed367e6cSBorislav Petkov 	&format_attr_filter_band0.attr,
1597ed367e6cSBorislav Petkov 	&format_attr_filter_band1.attr,
1598ed367e6cSBorislav Petkov 	&format_attr_filter_band2.attr,
1599ed367e6cSBorislav Petkov 	&format_attr_filter_band3.attr,
1600ed367e6cSBorislav Petkov 	NULL,
1601ed367e6cSBorislav Petkov };
1602ed367e6cSBorislav Petkov 
1603ed367e6cSBorislav Petkov static struct attribute *ivbep_uncore_qpi_formats_attr[] = {
1604ed367e6cSBorislav Petkov 	&format_attr_event_ext.attr,
1605ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
1606ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
1607ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
1608ed367e6cSBorislav Petkov 	&format_attr_match_rds.attr,
1609ed367e6cSBorislav Petkov 	&format_attr_match_rnid30.attr,
1610ed367e6cSBorislav Petkov 	&format_attr_match_rnid4.attr,
1611ed367e6cSBorislav Petkov 	&format_attr_match_dnid.attr,
1612ed367e6cSBorislav Petkov 	&format_attr_match_mc.attr,
1613ed367e6cSBorislav Petkov 	&format_attr_match_opc.attr,
1614ed367e6cSBorislav Petkov 	&format_attr_match_vnw.attr,
1615ed367e6cSBorislav Petkov 	&format_attr_match0.attr,
1616ed367e6cSBorislav Petkov 	&format_attr_match1.attr,
1617ed367e6cSBorislav Petkov 	&format_attr_mask_rds.attr,
1618ed367e6cSBorislav Petkov 	&format_attr_mask_rnid30.attr,
1619ed367e6cSBorislav Petkov 	&format_attr_mask_rnid4.attr,
1620ed367e6cSBorislav Petkov 	&format_attr_mask_dnid.attr,
1621ed367e6cSBorislav Petkov 	&format_attr_mask_mc.attr,
1622ed367e6cSBorislav Petkov 	&format_attr_mask_opc.attr,
1623ed367e6cSBorislav Petkov 	&format_attr_mask_vnw.attr,
1624ed367e6cSBorislav Petkov 	&format_attr_mask0.attr,
1625ed367e6cSBorislav Petkov 	&format_attr_mask1.attr,
1626ed367e6cSBorislav Petkov 	NULL,
1627ed367e6cSBorislav Petkov };
1628ed367e6cSBorislav Petkov 
162945bd07adSArvind Yadav static const struct attribute_group ivbep_uncore_format_group = {
1630ed367e6cSBorislav Petkov 	.name = "format",
1631ed367e6cSBorislav Petkov 	.attrs = ivbep_uncore_formats_attr,
1632ed367e6cSBorislav Petkov };
1633ed367e6cSBorislav Petkov 
163445bd07adSArvind Yadav static const struct attribute_group ivbep_uncore_ubox_format_group = {
1635ed367e6cSBorislav Petkov 	.name = "format",
1636ed367e6cSBorislav Petkov 	.attrs = ivbep_uncore_ubox_formats_attr,
1637ed367e6cSBorislav Petkov };
1638ed367e6cSBorislav Petkov 
163945bd07adSArvind Yadav static const struct attribute_group ivbep_uncore_cbox_format_group = {
1640ed367e6cSBorislav Petkov 	.name = "format",
1641ed367e6cSBorislav Petkov 	.attrs = ivbep_uncore_cbox_formats_attr,
1642ed367e6cSBorislav Petkov };
1643ed367e6cSBorislav Petkov 
164445bd07adSArvind Yadav static const struct attribute_group ivbep_uncore_pcu_format_group = {
1645ed367e6cSBorislav Petkov 	.name = "format",
1646ed367e6cSBorislav Petkov 	.attrs = ivbep_uncore_pcu_formats_attr,
1647ed367e6cSBorislav Petkov };
1648ed367e6cSBorislav Petkov 
164945bd07adSArvind Yadav static const struct attribute_group ivbep_uncore_qpi_format_group = {
1650ed367e6cSBorislav Petkov 	.name = "format",
1651ed367e6cSBorislav Petkov 	.attrs = ivbep_uncore_qpi_formats_attr,
1652ed367e6cSBorislav Petkov };
1653ed367e6cSBorislav Petkov 
1654ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_ubox = {
1655ed367e6cSBorislav Petkov 	.name		= "ubox",
1656ed367e6cSBorislav Petkov 	.num_counters   = 2,
1657ed367e6cSBorislav Petkov 	.num_boxes	= 1,
1658ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
1659ed367e6cSBorislav Petkov 	.fixed_ctr_bits	= 48,
1660ed367e6cSBorislav Petkov 	.perf_ctr	= SNBEP_U_MSR_PMON_CTR0,
1661ed367e6cSBorislav Petkov 	.event_ctl	= SNBEP_U_MSR_PMON_CTL0,
1662ed367e6cSBorislav Petkov 	.event_mask	= IVBEP_U_MSR_PMON_RAW_EVENT_MASK,
1663ed367e6cSBorislav Petkov 	.fixed_ctr	= SNBEP_U_MSR_PMON_UCLK_FIXED_CTR,
1664ed367e6cSBorislav Petkov 	.fixed_ctl	= SNBEP_U_MSR_PMON_UCLK_FIXED_CTL,
1665ed367e6cSBorislav Petkov 	.ops		= &ivbep_uncore_msr_ops,
1666ed367e6cSBorislav Petkov 	.format_group	= &ivbep_uncore_ubox_format_group,
1667ed367e6cSBorislav Petkov };
1668ed367e6cSBorislav Petkov 
1669ed367e6cSBorislav Petkov static struct extra_reg ivbep_uncore_cbox_extra_regs[] = {
1670ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
1671ed367e6cSBorislav Petkov 				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
1672ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x1031, 0x10ff, 0x2),
1673ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4),
1674ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0xc),
1675ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x5134, 0xffff, 0xc),
1676ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
1677ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0xc),
1678ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
1679ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0xc),
1680ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
1681ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0xc),
1682ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x10),
1683ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10),
1684ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10),
1685ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2335, 0xffff, 0x10),
1686ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0x18),
1687ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0x18),
1688ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x8),
1689ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x8),
1690ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x8),
1691ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x8),
1692ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8135, 0xffff, 0x10),
1693ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8335, 0xffff, 0x10),
1694ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x10),
1695ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x10),
1696ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2136, 0xffff, 0x10),
1697ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2336, 0xffff, 0x10),
1698ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0x18),
1699ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0x18),
1700ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x8),
1701ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x8),
1702ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x8),
1703ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x5036, 0xffff, 0x8),
1704ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8136, 0xffff, 0x10),
1705ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8336, 0xffff, 0x10),
1706ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x8),
1707ed367e6cSBorislav Petkov 	EVENT_EXTRA_END
1708ed367e6cSBorislav Petkov };
1709ed367e6cSBorislav Petkov 
1710ed367e6cSBorislav Petkov static u64 ivbep_cbox_filter_mask(int fields)
1711ed367e6cSBorislav Petkov {
1712ed367e6cSBorislav Petkov 	u64 mask = 0;
1713ed367e6cSBorislav Petkov 
1714ed367e6cSBorislav Petkov 	if (fields & 0x1)
1715ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_TID;
1716ed367e6cSBorislav Petkov 	if (fields & 0x2)
1717ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_LINK;
1718ed367e6cSBorislav Petkov 	if (fields & 0x4)
1719ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_STATE;
1720ed367e6cSBorislav Petkov 	if (fields & 0x8)
1721ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_NID;
1722ed367e6cSBorislav Petkov 	if (fields & 0x10) {
1723ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_OPC;
1724ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_NC;
1725ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_C6;
1726ed367e6cSBorislav Petkov 		mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_ISOC;
1727ed367e6cSBorislav Petkov 	}
1728ed367e6cSBorislav Petkov 
1729ed367e6cSBorislav Petkov 	return mask;
1730ed367e6cSBorislav Petkov }
1731ed367e6cSBorislav Petkov 
1732ed367e6cSBorislav Petkov static struct event_constraint *
1733ed367e6cSBorislav Petkov ivbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
1734ed367e6cSBorislav Petkov {
1735ed367e6cSBorislav Petkov 	return __snbep_cbox_get_constraint(box, event, ivbep_cbox_filter_mask);
1736ed367e6cSBorislav Petkov }
1737ed367e6cSBorislav Petkov 
1738ed367e6cSBorislav Petkov static int ivbep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
1739ed367e6cSBorislav Petkov {
1740ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
1741ed367e6cSBorislav Petkov 	struct extra_reg *er;
1742ed367e6cSBorislav Petkov 	int idx = 0;
1743ed367e6cSBorislav Petkov 
1744ed367e6cSBorislav Petkov 	for (er = ivbep_uncore_cbox_extra_regs; er->msr; er++) {
1745ed367e6cSBorislav Petkov 		if (er->event != (event->hw.config & er->config_mask))
1746ed367e6cSBorislav Petkov 			continue;
1747ed367e6cSBorislav Petkov 		idx |= er->idx;
1748ed367e6cSBorislav Petkov 	}
1749ed367e6cSBorislav Petkov 
1750ed367e6cSBorislav Petkov 	if (idx) {
1751ed367e6cSBorislav Petkov 		reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER +
1752ed367e6cSBorislav Petkov 			SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
1753ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1 & ivbep_cbox_filter_mask(idx);
1754ed367e6cSBorislav Petkov 		reg1->idx = idx;
1755ed367e6cSBorislav Petkov 	}
1756ed367e6cSBorislav Petkov 	return 0;
1757ed367e6cSBorislav Petkov }
1758ed367e6cSBorislav Petkov 
1759ed367e6cSBorislav Petkov static void ivbep_cbox_enable_event(struct intel_uncore_box *box, struct perf_event *event)
1760ed367e6cSBorislav Petkov {
1761ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1762ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
1763ed367e6cSBorislav Petkov 
1764ed367e6cSBorislav Petkov 	if (reg1->idx != EXTRA_REG_NONE) {
1765ed367e6cSBorislav Petkov 		u64 filter = uncore_shared_reg_config(box, 0);
1766ed367e6cSBorislav Petkov 		wrmsrl(reg1->reg, filter & 0xffffffff);
1767ed367e6cSBorislav Petkov 		wrmsrl(reg1->reg + 6, filter >> 32);
1768ed367e6cSBorislav Petkov 	}
1769ed367e6cSBorislav Petkov 
1770ed367e6cSBorislav Petkov 	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
1771ed367e6cSBorislav Petkov }
1772ed367e6cSBorislav Petkov 
1773ed367e6cSBorislav Petkov static struct intel_uncore_ops ivbep_uncore_cbox_ops = {
1774ed367e6cSBorislav Petkov 	.init_box		= ivbep_uncore_msr_init_box,
1775ed367e6cSBorislav Petkov 	.disable_box		= snbep_uncore_msr_disable_box,
1776ed367e6cSBorislav Petkov 	.enable_box		= snbep_uncore_msr_enable_box,
1777ed367e6cSBorislav Petkov 	.disable_event		= snbep_uncore_msr_disable_event,
1778ed367e6cSBorislav Petkov 	.enable_event		= ivbep_cbox_enable_event,
1779ed367e6cSBorislav Petkov 	.read_counter		= uncore_msr_read_counter,
1780ed367e6cSBorislav Petkov 	.hw_config		= ivbep_cbox_hw_config,
1781ed367e6cSBorislav Petkov 	.get_constraint		= ivbep_cbox_get_constraint,
1782ed367e6cSBorislav Petkov 	.put_constraint		= snbep_cbox_put_constraint,
1783ed367e6cSBorislav Petkov };
1784ed367e6cSBorislav Petkov 
1785ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_cbox = {
1786ed367e6cSBorislav Petkov 	.name			= "cbox",
1787ed367e6cSBorislav Petkov 	.num_counters		= 4,
1788ed367e6cSBorislav Petkov 	.num_boxes		= 15,
1789ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 44,
1790ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_C0_MSR_PMON_CTL0,
1791ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_C0_MSR_PMON_CTR0,
1792ed367e6cSBorislav Petkov 	.event_mask		= IVBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
1793ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_C0_MSR_PMON_BOX_CTL,
1794ed367e6cSBorislav Petkov 	.msr_offset		= SNBEP_CBO_MSR_OFFSET,
1795ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
1796ed367e6cSBorislav Petkov 	.constraints		= snbep_uncore_cbox_constraints,
1797ed367e6cSBorislav Petkov 	.ops			= &ivbep_uncore_cbox_ops,
1798ed367e6cSBorislav Petkov 	.format_group		= &ivbep_uncore_cbox_format_group,
1799ed367e6cSBorislav Petkov };
1800ed367e6cSBorislav Petkov 
1801ed367e6cSBorislav Petkov static struct intel_uncore_ops ivbep_uncore_pcu_ops = {
1802ed367e6cSBorislav Petkov 	IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
1803ed367e6cSBorislav Petkov 	.hw_config		= snbep_pcu_hw_config,
1804ed367e6cSBorislav Petkov 	.get_constraint		= snbep_pcu_get_constraint,
1805ed367e6cSBorislav Petkov 	.put_constraint		= snbep_pcu_put_constraint,
1806ed367e6cSBorislav Petkov };
1807ed367e6cSBorislav Petkov 
1808ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_pcu = {
1809ed367e6cSBorislav Petkov 	.name			= "pcu",
1810ed367e6cSBorislav Petkov 	.num_counters		= 4,
1811ed367e6cSBorislav Petkov 	.num_boxes		= 1,
1812ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
1813ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCU_MSR_PMON_CTR0,
1814ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCU_MSR_PMON_CTL0,
1815ed367e6cSBorislav Petkov 	.event_mask		= IVBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
1816ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCU_MSR_PMON_BOX_CTL,
1817ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
1818ed367e6cSBorislav Petkov 	.ops			= &ivbep_uncore_pcu_ops,
1819ed367e6cSBorislav Petkov 	.format_group		= &ivbep_uncore_pcu_format_group,
1820ed367e6cSBorislav Petkov };
1821ed367e6cSBorislav Petkov 
1822ed367e6cSBorislav Petkov static struct intel_uncore_type *ivbep_msr_uncores[] = {
1823ed367e6cSBorislav Petkov 	&ivbep_uncore_ubox,
1824ed367e6cSBorislav Petkov 	&ivbep_uncore_cbox,
1825ed367e6cSBorislav Petkov 	&ivbep_uncore_pcu,
1826ed367e6cSBorislav Petkov 	NULL,
1827ed367e6cSBorislav Petkov };
1828ed367e6cSBorislav Petkov 
1829ed367e6cSBorislav Petkov void ivbep_uncore_cpu_init(void)
1830ed367e6cSBorislav Petkov {
1831ed367e6cSBorislav Petkov 	if (ivbep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
1832ed367e6cSBorislav Petkov 		ivbep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
1833ed367e6cSBorislav Petkov 	uncore_msr_uncores = ivbep_msr_uncores;
1834ed367e6cSBorislav Petkov }
1835ed367e6cSBorislav Petkov 
1836ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_ha = {
1837ed367e6cSBorislav Petkov 	.name		= "ha",
1838ed367e6cSBorislav Petkov 	.num_counters   = 4,
1839ed367e6cSBorislav Petkov 	.num_boxes	= 2,
1840ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
1841ed367e6cSBorislav Petkov 	IVBEP_UNCORE_PCI_COMMON_INIT(),
1842ed367e6cSBorislav Petkov };
1843ed367e6cSBorislav Petkov 
1844ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_imc = {
1845ed367e6cSBorislav Petkov 	.name		= "imc",
1846ed367e6cSBorislav Petkov 	.num_counters   = 4,
1847ed367e6cSBorislav Petkov 	.num_boxes	= 8,
1848ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
1849ed367e6cSBorislav Petkov 	.fixed_ctr_bits	= 48,
1850ed367e6cSBorislav Petkov 	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
1851ed367e6cSBorislav Petkov 	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
1852ed367e6cSBorislav Petkov 	.event_descs	= snbep_uncore_imc_events,
1853ed367e6cSBorislav Petkov 	IVBEP_UNCORE_PCI_COMMON_INIT(),
1854ed367e6cSBorislav Petkov };
1855ed367e6cSBorislav Petkov 
1856ed367e6cSBorislav Petkov /* registers in IRP boxes are not properly aligned */
1857ed367e6cSBorislav Petkov static unsigned ivbep_uncore_irp_ctls[] = {0xd8, 0xdc, 0xe0, 0xe4};
1858ed367e6cSBorislav Petkov static unsigned ivbep_uncore_irp_ctrs[] = {0xa0, 0xb0, 0xb8, 0xc0};
1859ed367e6cSBorislav Petkov 
1860ed367e6cSBorislav Petkov static void ivbep_uncore_irp_enable_event(struct intel_uncore_box *box, struct perf_event *event)
1861ed367e6cSBorislav Petkov {
1862ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
1863ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1864ed367e6cSBorislav Petkov 
1865ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, ivbep_uncore_irp_ctls[hwc->idx],
1866ed367e6cSBorislav Petkov 			       hwc->config | SNBEP_PMON_CTL_EN);
1867ed367e6cSBorislav Petkov }
1868ed367e6cSBorislav Petkov 
1869ed367e6cSBorislav Petkov static void ivbep_uncore_irp_disable_event(struct intel_uncore_box *box, struct perf_event *event)
1870ed367e6cSBorislav Petkov {
1871ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
1872ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1873ed367e6cSBorislav Petkov 
1874ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, ivbep_uncore_irp_ctls[hwc->idx], hwc->config);
1875ed367e6cSBorislav Petkov }
1876ed367e6cSBorislav Petkov 
1877ed367e6cSBorislav Petkov static u64 ivbep_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event)
1878ed367e6cSBorislav Petkov {
1879ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
1880ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
1881ed367e6cSBorislav Petkov 	u64 count = 0;
1882ed367e6cSBorislav Petkov 
1883ed367e6cSBorislav Petkov 	pci_read_config_dword(pdev, ivbep_uncore_irp_ctrs[hwc->idx], (u32 *)&count);
1884ed367e6cSBorislav Petkov 	pci_read_config_dword(pdev, ivbep_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1);
1885ed367e6cSBorislav Petkov 
1886ed367e6cSBorislav Petkov 	return count;
1887ed367e6cSBorislav Petkov }
1888ed367e6cSBorislav Petkov 
1889ed367e6cSBorislav Petkov static struct intel_uncore_ops ivbep_uncore_irp_ops = {
1890ed367e6cSBorislav Petkov 	.init_box	= ivbep_uncore_pci_init_box,
1891ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_pci_disable_box,
1892ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_pci_enable_box,
1893ed367e6cSBorislav Petkov 	.disable_event	= ivbep_uncore_irp_disable_event,
1894ed367e6cSBorislav Petkov 	.enable_event	= ivbep_uncore_irp_enable_event,
1895ed367e6cSBorislav Petkov 	.read_counter	= ivbep_uncore_irp_read_counter,
1896ed367e6cSBorislav Petkov };
1897ed367e6cSBorislav Petkov 
1898ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_irp = {
1899ed367e6cSBorislav Petkov 	.name			= "irp",
1900ed367e6cSBorislav Petkov 	.num_counters		= 4,
1901ed367e6cSBorislav Petkov 	.num_boxes		= 1,
1902ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
1903ed367e6cSBorislav Petkov 	.event_mask		= IVBEP_PMON_RAW_EVENT_MASK,
1904ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
1905ed367e6cSBorislav Petkov 	.ops			= &ivbep_uncore_irp_ops,
1906ed367e6cSBorislav Petkov 	.format_group		= &ivbep_uncore_format_group,
1907ed367e6cSBorislav Petkov };
1908ed367e6cSBorislav Petkov 
1909ed367e6cSBorislav Petkov static struct intel_uncore_ops ivbep_uncore_qpi_ops = {
1910ed367e6cSBorislav Petkov 	.init_box	= ivbep_uncore_pci_init_box,
1911ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_pci_disable_box,
1912ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_pci_enable_box,
1913ed367e6cSBorislav Petkov 	.disable_event	= snbep_uncore_pci_disable_event,
1914ed367e6cSBorislav Petkov 	.enable_event	= snbep_qpi_enable_event,
1915ed367e6cSBorislav Petkov 	.read_counter	= snbep_uncore_pci_read_counter,
1916ed367e6cSBorislav Petkov 	.hw_config	= snbep_qpi_hw_config,
1917ed367e6cSBorislav Petkov 	.get_constraint	= uncore_get_constraint,
1918ed367e6cSBorislav Petkov 	.put_constraint	= uncore_put_constraint,
1919ed367e6cSBorislav Petkov };
1920ed367e6cSBorislav Petkov 
1921ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_qpi = {
1922ed367e6cSBorislav Petkov 	.name			= "qpi",
1923ed367e6cSBorislav Petkov 	.num_counters		= 4,
1924ed367e6cSBorislav Petkov 	.num_boxes		= 3,
1925ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
1926ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
1927ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCI_PMON_CTL0,
1928ed367e6cSBorislav Petkov 	.event_mask		= IVBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
1929ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
1930ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
1931ed367e6cSBorislav Petkov 	.ops			= &ivbep_uncore_qpi_ops,
1932ed367e6cSBorislav Petkov 	.format_group		= &ivbep_uncore_qpi_format_group,
1933ed367e6cSBorislav Petkov };
1934ed367e6cSBorislav Petkov 
1935ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_r2pcie = {
1936ed367e6cSBorislav Petkov 	.name		= "r2pcie",
1937ed367e6cSBorislav Petkov 	.num_counters   = 4,
1938ed367e6cSBorislav Petkov 	.num_boxes	= 1,
1939ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
1940ed367e6cSBorislav Petkov 	.constraints	= snbep_uncore_r2pcie_constraints,
1941ed367e6cSBorislav Petkov 	IVBEP_UNCORE_PCI_COMMON_INIT(),
1942ed367e6cSBorislav Petkov };
1943ed367e6cSBorislav Petkov 
1944ed367e6cSBorislav Petkov static struct intel_uncore_type ivbep_uncore_r3qpi = {
1945ed367e6cSBorislav Petkov 	.name		= "r3qpi",
1946ed367e6cSBorislav Petkov 	.num_counters   = 3,
1947ed367e6cSBorislav Petkov 	.num_boxes	= 2,
1948ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
1949ed367e6cSBorislav Petkov 	.constraints	= snbep_uncore_r3qpi_constraints,
1950ed367e6cSBorislav Petkov 	IVBEP_UNCORE_PCI_COMMON_INIT(),
1951ed367e6cSBorislav Petkov };
1952ed367e6cSBorislav Petkov 
1953ed367e6cSBorislav Petkov enum {
1954ed367e6cSBorislav Petkov 	IVBEP_PCI_UNCORE_HA,
1955ed367e6cSBorislav Petkov 	IVBEP_PCI_UNCORE_IMC,
1956ed367e6cSBorislav Petkov 	IVBEP_PCI_UNCORE_IRP,
1957ed367e6cSBorislav Petkov 	IVBEP_PCI_UNCORE_QPI,
1958ed367e6cSBorislav Petkov 	IVBEP_PCI_UNCORE_R2PCIE,
1959ed367e6cSBorislav Petkov 	IVBEP_PCI_UNCORE_R3QPI,
1960ed367e6cSBorislav Petkov };
1961ed367e6cSBorislav Petkov 
1962ed367e6cSBorislav Petkov static struct intel_uncore_type *ivbep_pci_uncores[] = {
1963ed367e6cSBorislav Petkov 	[IVBEP_PCI_UNCORE_HA]	= &ivbep_uncore_ha,
1964ed367e6cSBorislav Petkov 	[IVBEP_PCI_UNCORE_IMC]	= &ivbep_uncore_imc,
1965ed367e6cSBorislav Petkov 	[IVBEP_PCI_UNCORE_IRP]	= &ivbep_uncore_irp,
1966ed367e6cSBorislav Petkov 	[IVBEP_PCI_UNCORE_QPI]	= &ivbep_uncore_qpi,
1967ed367e6cSBorislav Petkov 	[IVBEP_PCI_UNCORE_R2PCIE]	= &ivbep_uncore_r2pcie,
1968ed367e6cSBorislav Petkov 	[IVBEP_PCI_UNCORE_R3QPI]	= &ivbep_uncore_r3qpi,
1969ed367e6cSBorislav Petkov 	NULL,
1970ed367e6cSBorislav Petkov };
1971ed367e6cSBorislav Petkov 
1972ed367e6cSBorislav Petkov static const struct pci_device_id ivbep_uncore_pci_ids[] = {
1973ed367e6cSBorislav Petkov 	{ /* Home Agent 0 */
1974ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe30),
1975ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_HA, 0),
1976ed367e6cSBorislav Petkov 	},
1977ed367e6cSBorislav Petkov 	{ /* Home Agent 1 */
1978ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe38),
1979ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_HA, 1),
1980ed367e6cSBorislav Petkov 	},
1981ed367e6cSBorislav Petkov 	{ /* MC0 Channel 0 */
1982ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb4),
1983ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 0),
1984ed367e6cSBorislav Petkov 	},
1985ed367e6cSBorislav Petkov 	{ /* MC0 Channel 1 */
1986ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb5),
1987ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 1),
1988ed367e6cSBorislav Petkov 	},
1989ed367e6cSBorislav Petkov 	{ /* MC0 Channel 3 */
1990ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb0),
1991ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 2),
1992ed367e6cSBorislav Petkov 	},
1993ed367e6cSBorislav Petkov 	{ /* MC0 Channel 4 */
1994ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb1),
1995ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 3),
1996ed367e6cSBorislav Petkov 	},
1997ed367e6cSBorislav Petkov 	{ /* MC1 Channel 0 */
1998ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef4),
1999ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 4),
2000ed367e6cSBorislav Petkov 	},
2001ed367e6cSBorislav Petkov 	{ /* MC1 Channel 1 */
2002ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef5),
2003ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 5),
2004ed367e6cSBorislav Petkov 	},
2005ed367e6cSBorislav Petkov 	{ /* MC1 Channel 3 */
2006ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef0),
2007ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 6),
2008ed367e6cSBorislav Petkov 	},
2009ed367e6cSBorislav Petkov 	{ /* MC1 Channel 4 */
2010ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1),
2011ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 7),
2012ed367e6cSBorislav Petkov 	},
2013ed367e6cSBorislav Petkov 	{ /* IRP */
2014ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe39),
2015ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IRP, 0),
2016ed367e6cSBorislav Petkov 	},
2017ed367e6cSBorislav Petkov 	{ /* QPI0 Port 0 */
2018ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32),
2019ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 0),
2020ed367e6cSBorislav Petkov 	},
2021ed367e6cSBorislav Petkov 	{ /* QPI0 Port 1 */
2022ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe33),
2023ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 1),
2024ed367e6cSBorislav Petkov 	},
2025ed367e6cSBorislav Petkov 	{ /* QPI1 Port 2 */
2026ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3a),
2027ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 2),
2028ed367e6cSBorislav Petkov 	},
2029ed367e6cSBorislav Petkov 	{ /* R2PCIe */
2030ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe34),
2031ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R2PCIE, 0),
2032ed367e6cSBorislav Petkov 	},
2033ed367e6cSBorislav Petkov 	{ /* R3QPI0 Link 0 */
2034ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe36),
2035ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 0),
2036ed367e6cSBorislav Petkov 	},
2037ed367e6cSBorislav Petkov 	{ /* R3QPI0 Link 1 */
2038ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe37),
2039ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 1),
2040ed367e6cSBorislav Petkov 	},
2041ed367e6cSBorislav Petkov 	{ /* R3QPI1 Link 2 */
2042ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3e),
2043ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 2),
2044ed367e6cSBorislav Petkov 	},
2045ed367e6cSBorislav Petkov 	{ /* QPI Port 0 filter  */
2046ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe86),
2047ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
2048ed367e6cSBorislav Petkov 						   SNBEP_PCI_QPI_PORT0_FILTER),
2049ed367e6cSBorislav Petkov 	},
2050ed367e6cSBorislav Petkov 	{ /* QPI Port 0 filter  */
2051ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe96),
2052ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
2053ed367e6cSBorislav Petkov 						   SNBEP_PCI_QPI_PORT1_FILTER),
2054ed367e6cSBorislav Petkov 	},
2055ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ }
2056ed367e6cSBorislav Petkov };
2057ed367e6cSBorislav Petkov 
2058ed367e6cSBorislav Petkov static struct pci_driver ivbep_uncore_pci_driver = {
2059ed367e6cSBorislav Petkov 	.name		= "ivbep_uncore",
2060ed367e6cSBorislav Petkov 	.id_table	= ivbep_uncore_pci_ids,
2061ed367e6cSBorislav Petkov };
2062ed367e6cSBorislav Petkov 
2063ed367e6cSBorislav Petkov int ivbep_uncore_pci_init(void)
2064ed367e6cSBorislav Petkov {
206568ce4a0dSKan Liang 	int ret = snbep_pci2phy_map_init(0x0e1e, SNBEP_CPUNODEID, SNBEP_GIDNIDMAP, true);
2066ed367e6cSBorislav Petkov 	if (ret)
2067ed367e6cSBorislav Petkov 		return ret;
2068ed367e6cSBorislav Petkov 	uncore_pci_uncores = ivbep_pci_uncores;
2069ed367e6cSBorislav Petkov 	uncore_pci_driver = &ivbep_uncore_pci_driver;
2070ed367e6cSBorislav Petkov 	return 0;
2071ed367e6cSBorislav Petkov }
2072ed367e6cSBorislav Petkov /* end of IvyTown uncore support */
2073ed367e6cSBorislav Petkov 
2074ed367e6cSBorislav Petkov /* KNL uncore support */
2075ed367e6cSBorislav Petkov static struct attribute *knl_uncore_ubox_formats_attr[] = {
2076ed367e6cSBorislav Petkov 	&format_attr_event.attr,
2077ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
2078ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2079ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
2080ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
2081ed367e6cSBorislav Petkov 	&format_attr_thresh5.attr,
2082ed367e6cSBorislav Petkov 	NULL,
2083ed367e6cSBorislav Petkov };
2084ed367e6cSBorislav Petkov 
208545bd07adSArvind Yadav static const struct attribute_group knl_uncore_ubox_format_group = {
2086ed367e6cSBorislav Petkov 	.name = "format",
2087ed367e6cSBorislav Petkov 	.attrs = knl_uncore_ubox_formats_attr,
2088ed367e6cSBorislav Petkov };
2089ed367e6cSBorislav Petkov 
2090ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_ubox = {
2091ed367e6cSBorislav Petkov 	.name			= "ubox",
2092ed367e6cSBorislav Petkov 	.num_counters		= 2,
2093ed367e6cSBorislav Petkov 	.num_boxes		= 1,
2094ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2095ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
2096ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_U_MSR_PMON_CTR0,
2097ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_U_MSR_PMON_CTL0,
2098ed367e6cSBorislav Petkov 	.event_mask		= KNL_U_MSR_PMON_RAW_EVENT_MASK,
2099ed367e6cSBorislav Petkov 	.fixed_ctr		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
2100ed367e6cSBorislav Petkov 	.fixed_ctl		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
2101ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_msr_ops,
2102ed367e6cSBorislav Petkov 	.format_group		= &knl_uncore_ubox_format_group,
2103ed367e6cSBorislav Petkov };
2104ed367e6cSBorislav Petkov 
2105ed367e6cSBorislav Petkov static struct attribute *knl_uncore_cha_formats_attr[] = {
2106ed367e6cSBorislav Petkov 	&format_attr_event.attr,
2107ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
2108ed367e6cSBorislav Petkov 	&format_attr_qor.attr,
2109ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2110ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
2111ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
2112ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
2113ed367e6cSBorislav Petkov 	&format_attr_filter_tid4.attr,
2114ed367e6cSBorislav Petkov 	&format_attr_filter_link3.attr,
2115ed367e6cSBorislav Petkov 	&format_attr_filter_state4.attr,
2116ed367e6cSBorislav Petkov 	&format_attr_filter_local.attr,
2117ed367e6cSBorislav Petkov 	&format_attr_filter_all_op.attr,
2118ed367e6cSBorislav Petkov 	&format_attr_filter_nnm.attr,
2119ed367e6cSBorislav Petkov 	&format_attr_filter_opc3.attr,
2120ed367e6cSBorislav Petkov 	&format_attr_filter_nc.attr,
2121ed367e6cSBorislav Petkov 	&format_attr_filter_isoc.attr,
2122ed367e6cSBorislav Petkov 	NULL,
2123ed367e6cSBorislav Petkov };
2124ed367e6cSBorislav Petkov 
212545bd07adSArvind Yadav static const struct attribute_group knl_uncore_cha_format_group = {
2126ed367e6cSBorislav Petkov 	.name = "format",
2127ed367e6cSBorislav Petkov 	.attrs = knl_uncore_cha_formats_attr,
2128ed367e6cSBorislav Petkov };
2129ed367e6cSBorislav Petkov 
2130ed367e6cSBorislav Petkov static struct event_constraint knl_uncore_cha_constraints[] = {
2131ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
2132ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1f, 0x1),
2133ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
2134ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
2135ed367e6cSBorislav Petkov };
2136ed367e6cSBorislav Petkov 
2137ed367e6cSBorislav Petkov static struct extra_reg knl_uncore_cha_extra_regs[] = {
2138ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
2139ed367e6cSBorislav Petkov 				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
2140ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x3d, 0xff, 0x2),
2141ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x35, 0xff, 0x4),
2142ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x36, 0xff, 0x4),
2143ed367e6cSBorislav Petkov 	EVENT_EXTRA_END
2144ed367e6cSBorislav Petkov };
2145ed367e6cSBorislav Petkov 
2146ed367e6cSBorislav Petkov static u64 knl_cha_filter_mask(int fields)
2147ed367e6cSBorislav Petkov {
2148ed367e6cSBorislav Petkov 	u64 mask = 0;
2149ed367e6cSBorislav Petkov 
2150ed367e6cSBorislav Petkov 	if (fields & 0x1)
2151ed367e6cSBorislav Petkov 		mask |= KNL_CHA_MSR_PMON_BOX_FILTER_TID;
2152ed367e6cSBorislav Petkov 	if (fields & 0x2)
2153ed367e6cSBorislav Petkov 		mask |= KNL_CHA_MSR_PMON_BOX_FILTER_STATE;
2154ed367e6cSBorislav Petkov 	if (fields & 0x4)
2155ed367e6cSBorislav Petkov 		mask |= KNL_CHA_MSR_PMON_BOX_FILTER_OP;
2156ed367e6cSBorislav Petkov 	return mask;
2157ed367e6cSBorislav Petkov }
2158ed367e6cSBorislav Petkov 
2159ed367e6cSBorislav Petkov static struct event_constraint *
2160ed367e6cSBorislav Petkov knl_cha_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
2161ed367e6cSBorislav Petkov {
2162ed367e6cSBorislav Petkov 	return __snbep_cbox_get_constraint(box, event, knl_cha_filter_mask);
2163ed367e6cSBorislav Petkov }
2164ed367e6cSBorislav Petkov 
2165ed367e6cSBorislav Petkov static int knl_cha_hw_config(struct intel_uncore_box *box,
2166ed367e6cSBorislav Petkov 			     struct perf_event *event)
2167ed367e6cSBorislav Petkov {
2168ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
2169ed367e6cSBorislav Petkov 	struct extra_reg *er;
2170ed367e6cSBorislav Petkov 	int idx = 0;
2171ed367e6cSBorislav Petkov 
2172ed367e6cSBorislav Petkov 	for (er = knl_uncore_cha_extra_regs; er->msr; er++) {
2173ed367e6cSBorislav Petkov 		if (er->event != (event->hw.config & er->config_mask))
2174ed367e6cSBorislav Petkov 			continue;
2175ed367e6cSBorislav Petkov 		idx |= er->idx;
2176ed367e6cSBorislav Petkov 	}
2177ed367e6cSBorislav Petkov 
2178ed367e6cSBorislav Petkov 	if (idx) {
2179ed367e6cSBorislav Petkov 		reg1->reg = HSWEP_C0_MSR_PMON_BOX_FILTER0 +
2180ed367e6cSBorislav Petkov 			    KNL_CHA_MSR_OFFSET * box->pmu->pmu_idx;
2181ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1 & knl_cha_filter_mask(idx);
2182ec336c87Shchrzani 
2183ec336c87Shchrzani 		reg1->config |= KNL_CHA_MSR_PMON_BOX_FILTER_REMOTE_NODE;
2184ec336c87Shchrzani 		reg1->config |= KNL_CHA_MSR_PMON_BOX_FILTER_LOCAL_NODE;
2185ec336c87Shchrzani 		reg1->config |= KNL_CHA_MSR_PMON_BOX_FILTER_NNC;
2186ed367e6cSBorislav Petkov 		reg1->idx = idx;
2187ed367e6cSBorislav Petkov 	}
2188ed367e6cSBorislav Petkov 	return 0;
2189ed367e6cSBorislav Petkov }
2190ed367e6cSBorislav Petkov 
2191ed367e6cSBorislav Petkov static void hswep_cbox_enable_event(struct intel_uncore_box *box,
2192ed367e6cSBorislav Petkov 				    struct perf_event *event);
2193ed367e6cSBorislav Petkov 
2194ed367e6cSBorislav Petkov static struct intel_uncore_ops knl_uncore_cha_ops = {
2195ed367e6cSBorislav Petkov 	.init_box		= snbep_uncore_msr_init_box,
2196ed367e6cSBorislav Petkov 	.disable_box		= snbep_uncore_msr_disable_box,
2197ed367e6cSBorislav Petkov 	.enable_box		= snbep_uncore_msr_enable_box,
2198ed367e6cSBorislav Petkov 	.disable_event		= snbep_uncore_msr_disable_event,
2199ed367e6cSBorislav Petkov 	.enable_event		= hswep_cbox_enable_event,
2200ed367e6cSBorislav Petkov 	.read_counter		= uncore_msr_read_counter,
2201ed367e6cSBorislav Petkov 	.hw_config		= knl_cha_hw_config,
2202ed367e6cSBorislav Petkov 	.get_constraint		= knl_cha_get_constraint,
2203ed367e6cSBorislav Petkov 	.put_constraint		= snbep_cbox_put_constraint,
2204ed367e6cSBorislav Petkov };
2205ed367e6cSBorislav Petkov 
2206ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_cha = {
2207ed367e6cSBorislav Petkov 	.name			= "cha",
2208ed367e6cSBorislav Petkov 	.num_counters		= 4,
2209ed367e6cSBorislav Petkov 	.num_boxes		= 38,
2210ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2211ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_C0_MSR_PMON_CTL0,
2212ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_C0_MSR_PMON_CTR0,
2213ed367e6cSBorislav Petkov 	.event_mask		= KNL_CHA_MSR_PMON_RAW_EVENT_MASK,
2214ed367e6cSBorislav Petkov 	.box_ctl		= HSWEP_C0_MSR_PMON_BOX_CTL,
2215ed367e6cSBorislav Petkov 	.msr_offset		= KNL_CHA_MSR_OFFSET,
2216ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
2217ed367e6cSBorislav Petkov 	.constraints		= knl_uncore_cha_constraints,
2218ed367e6cSBorislav Petkov 	.ops			= &knl_uncore_cha_ops,
2219ed367e6cSBorislav Petkov 	.format_group		= &knl_uncore_cha_format_group,
2220ed367e6cSBorislav Petkov };
2221ed367e6cSBorislav Petkov 
2222ed367e6cSBorislav Petkov static struct attribute *knl_uncore_pcu_formats_attr[] = {
2223ed367e6cSBorislav Petkov 	&format_attr_event2.attr,
2224ed367e6cSBorislav Petkov 	&format_attr_use_occ_ctr.attr,
2225ed367e6cSBorislav Petkov 	&format_attr_occ_sel.attr,
2226ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2227ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
2228ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
2229ed367e6cSBorislav Petkov 	&format_attr_thresh6.attr,
2230ed367e6cSBorislav Petkov 	&format_attr_occ_invert.attr,
2231ed367e6cSBorislav Petkov 	&format_attr_occ_edge_det.attr,
2232ed367e6cSBorislav Petkov 	NULL,
2233ed367e6cSBorislav Petkov };
2234ed367e6cSBorislav Petkov 
223545bd07adSArvind Yadav static const struct attribute_group knl_uncore_pcu_format_group = {
2236ed367e6cSBorislav Petkov 	.name = "format",
2237ed367e6cSBorislav Petkov 	.attrs = knl_uncore_pcu_formats_attr,
2238ed367e6cSBorislav Petkov };
2239ed367e6cSBorislav Petkov 
2240ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_pcu = {
2241ed367e6cSBorislav Petkov 	.name			= "pcu",
2242ed367e6cSBorislav Petkov 	.num_counters		= 4,
2243ed367e6cSBorislav Petkov 	.num_boxes		= 1,
2244ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2245ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_PCU_MSR_PMON_CTR0,
2246ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_PCU_MSR_PMON_CTL0,
2247ed367e6cSBorislav Petkov 	.event_mask		= KNL_PCU_MSR_PMON_RAW_EVENT_MASK,
2248ed367e6cSBorislav Petkov 	.box_ctl		= HSWEP_PCU_MSR_PMON_BOX_CTL,
2249ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_msr_ops,
2250ed367e6cSBorislav Petkov 	.format_group		= &knl_uncore_pcu_format_group,
2251ed367e6cSBorislav Petkov };
2252ed367e6cSBorislav Petkov 
2253ed367e6cSBorislav Petkov static struct intel_uncore_type *knl_msr_uncores[] = {
2254ed367e6cSBorislav Petkov 	&knl_uncore_ubox,
2255ed367e6cSBorislav Petkov 	&knl_uncore_cha,
2256ed367e6cSBorislav Petkov 	&knl_uncore_pcu,
2257ed367e6cSBorislav Petkov 	NULL,
2258ed367e6cSBorislav Petkov };
2259ed367e6cSBorislav Petkov 
2260ed367e6cSBorislav Petkov void knl_uncore_cpu_init(void)
2261ed367e6cSBorislav Petkov {
2262ed367e6cSBorislav Petkov 	uncore_msr_uncores = knl_msr_uncores;
2263ed367e6cSBorislav Petkov }
2264ed367e6cSBorislav Petkov 
2265ed367e6cSBorislav Petkov static void knl_uncore_imc_enable_box(struct intel_uncore_box *box)
2266ed367e6cSBorislav Petkov {
2267ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
2268ed367e6cSBorislav Petkov 	int box_ctl = uncore_pci_box_ctl(box);
2269ed367e6cSBorislav Petkov 
2270ed367e6cSBorislav Petkov 	pci_write_config_dword(pdev, box_ctl, 0);
2271ed367e6cSBorislav Petkov }
2272ed367e6cSBorislav Petkov 
2273ed367e6cSBorislav Petkov static void knl_uncore_imc_enable_event(struct intel_uncore_box *box,
2274ed367e6cSBorislav Petkov 					struct perf_event *event)
2275ed367e6cSBorislav Petkov {
2276ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
2277ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
2278ed367e6cSBorislav Petkov 
2279ed367e6cSBorislav Petkov 	if ((event->attr.config & SNBEP_PMON_CTL_EV_SEL_MASK)
2280ed367e6cSBorislav Petkov 							== UNCORE_FIXED_EVENT)
2281ed367e6cSBorislav Petkov 		pci_write_config_dword(pdev, hwc->config_base,
2282ed367e6cSBorislav Petkov 				       hwc->config | KNL_PMON_FIXED_CTL_EN);
2283ed367e6cSBorislav Petkov 	else
2284ed367e6cSBorislav Petkov 		pci_write_config_dword(pdev, hwc->config_base,
2285ed367e6cSBorislav Petkov 				       hwc->config | SNBEP_PMON_CTL_EN);
2286ed367e6cSBorislav Petkov }
2287ed367e6cSBorislav Petkov 
2288ed367e6cSBorislav Petkov static struct intel_uncore_ops knl_uncore_imc_ops = {
2289ed367e6cSBorislav Petkov 	.init_box	= snbep_uncore_pci_init_box,
2290ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_pci_disable_box,
2291ed367e6cSBorislav Petkov 	.enable_box	= knl_uncore_imc_enable_box,
2292ed367e6cSBorislav Petkov 	.read_counter	= snbep_uncore_pci_read_counter,
2293ed367e6cSBorislav Petkov 	.enable_event	= knl_uncore_imc_enable_event,
2294ed367e6cSBorislav Petkov 	.disable_event	= snbep_uncore_pci_disable_event,
2295ed367e6cSBorislav Petkov };
2296ed367e6cSBorislav Petkov 
2297ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_imc_uclk = {
2298ed367e6cSBorislav Petkov 	.name			= "imc_uclk",
2299ed367e6cSBorislav Petkov 	.num_counters		= 4,
2300ed367e6cSBorislav Petkov 	.num_boxes		= 2,
2301ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2302ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
2303ed367e6cSBorislav Petkov 	.perf_ctr		= KNL_UCLK_MSR_PMON_CTR0_LOW,
2304ed367e6cSBorislav Petkov 	.event_ctl		= KNL_UCLK_MSR_PMON_CTL0,
2305ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
2306ed367e6cSBorislav Petkov 	.fixed_ctr		= KNL_UCLK_MSR_PMON_UCLK_FIXED_LOW,
2307ed367e6cSBorislav Petkov 	.fixed_ctl		= KNL_UCLK_MSR_PMON_UCLK_FIXED_CTL,
2308ed367e6cSBorislav Petkov 	.box_ctl		= KNL_UCLK_MSR_PMON_BOX_CTL,
2309ed367e6cSBorislav Petkov 	.ops			= &knl_uncore_imc_ops,
2310ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_format_group,
2311ed367e6cSBorislav Petkov };
2312ed367e6cSBorislav Petkov 
2313ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_imc_dclk = {
2314ed367e6cSBorislav Petkov 	.name			= "imc",
2315ed367e6cSBorislav Petkov 	.num_counters		= 4,
2316ed367e6cSBorislav Petkov 	.num_boxes		= 6,
2317ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2318ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
2319ed367e6cSBorislav Petkov 	.perf_ctr		= KNL_MC0_CH0_MSR_PMON_CTR0_LOW,
2320ed367e6cSBorislav Petkov 	.event_ctl		= KNL_MC0_CH0_MSR_PMON_CTL0,
2321ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
2322ed367e6cSBorislav Petkov 	.fixed_ctr		= KNL_MC0_CH0_MSR_PMON_FIXED_LOW,
2323ed367e6cSBorislav Petkov 	.fixed_ctl		= KNL_MC0_CH0_MSR_PMON_FIXED_CTL,
2324ed367e6cSBorislav Petkov 	.box_ctl		= KNL_MC0_CH0_MSR_PMON_BOX_CTL,
2325ed367e6cSBorislav Petkov 	.ops			= &knl_uncore_imc_ops,
2326ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_format_group,
2327ed367e6cSBorislav Petkov };
2328ed367e6cSBorislav Petkov 
2329ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_edc_uclk = {
2330ed367e6cSBorislav Petkov 	.name			= "edc_uclk",
2331ed367e6cSBorislav Petkov 	.num_counters		= 4,
2332ed367e6cSBorislav Petkov 	.num_boxes		= 8,
2333ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2334ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
2335ed367e6cSBorislav Petkov 	.perf_ctr		= KNL_UCLK_MSR_PMON_CTR0_LOW,
2336ed367e6cSBorislav Petkov 	.event_ctl		= KNL_UCLK_MSR_PMON_CTL0,
2337ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
2338ed367e6cSBorislav Petkov 	.fixed_ctr		= KNL_UCLK_MSR_PMON_UCLK_FIXED_LOW,
2339ed367e6cSBorislav Petkov 	.fixed_ctl		= KNL_UCLK_MSR_PMON_UCLK_FIXED_CTL,
2340ed367e6cSBorislav Petkov 	.box_ctl		= KNL_UCLK_MSR_PMON_BOX_CTL,
2341ed367e6cSBorislav Petkov 	.ops			= &knl_uncore_imc_ops,
2342ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_format_group,
2343ed367e6cSBorislav Petkov };
2344ed367e6cSBorislav Petkov 
2345ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_edc_eclk = {
2346ed367e6cSBorislav Petkov 	.name			= "edc_eclk",
2347ed367e6cSBorislav Petkov 	.num_counters		= 4,
2348ed367e6cSBorislav Petkov 	.num_boxes		= 8,
2349ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2350ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
2351ed367e6cSBorislav Petkov 	.perf_ctr		= KNL_EDC0_ECLK_MSR_PMON_CTR0_LOW,
2352ed367e6cSBorislav Petkov 	.event_ctl		= KNL_EDC0_ECLK_MSR_PMON_CTL0,
2353ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
2354ed367e6cSBorislav Petkov 	.fixed_ctr		= KNL_EDC0_ECLK_MSR_PMON_ECLK_FIXED_LOW,
2355ed367e6cSBorislav Petkov 	.fixed_ctl		= KNL_EDC0_ECLK_MSR_PMON_ECLK_FIXED_CTL,
2356ed367e6cSBorislav Petkov 	.box_ctl		= KNL_EDC0_ECLK_MSR_PMON_BOX_CTL,
2357ed367e6cSBorislav Petkov 	.ops			= &knl_uncore_imc_ops,
2358ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_format_group,
2359ed367e6cSBorislav Petkov };
2360ed367e6cSBorislav Petkov 
2361ed367e6cSBorislav Petkov static struct event_constraint knl_uncore_m2pcie_constraints[] = {
2362ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
2363ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
2364ed367e6cSBorislav Petkov };
2365ed367e6cSBorislav Petkov 
2366ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_m2pcie = {
2367ed367e6cSBorislav Petkov 	.name		= "m2pcie",
2368ed367e6cSBorislav Petkov 	.num_counters   = 4,
2369ed367e6cSBorislav Petkov 	.num_boxes	= 1,
2370ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
2371ed367e6cSBorislav Petkov 	.constraints	= knl_uncore_m2pcie_constraints,
2372ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
2373ed367e6cSBorislav Petkov };
2374ed367e6cSBorislav Petkov 
2375ed367e6cSBorislav Petkov static struct attribute *knl_uncore_irp_formats_attr[] = {
2376ed367e6cSBorislav Petkov 	&format_attr_event.attr,
2377ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
2378ed367e6cSBorislav Petkov 	&format_attr_qor.attr,
2379ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2380ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
2381ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
2382ed367e6cSBorislav Petkov 	NULL,
2383ed367e6cSBorislav Petkov };
2384ed367e6cSBorislav Petkov 
238545bd07adSArvind Yadav static const struct attribute_group knl_uncore_irp_format_group = {
2386ed367e6cSBorislav Petkov 	.name = "format",
2387ed367e6cSBorislav Petkov 	.attrs = knl_uncore_irp_formats_attr,
2388ed367e6cSBorislav Petkov };
2389ed367e6cSBorislav Petkov 
2390ed367e6cSBorislav Petkov static struct intel_uncore_type knl_uncore_irp = {
2391ed367e6cSBorislav Petkov 	.name			= "irp",
2392ed367e6cSBorislav Petkov 	.num_counters		= 2,
2393ed367e6cSBorislav Petkov 	.num_boxes		= 1,
2394ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2395ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
2396ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCI_PMON_CTL0,
2397ed367e6cSBorislav Petkov 	.event_mask		= KNL_IRP_PCI_PMON_RAW_EVENT_MASK,
2398ed367e6cSBorislav Petkov 	.box_ctl		= KNL_IRP_PCI_PMON_BOX_CTL,
2399ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_pci_ops,
2400ed367e6cSBorislav Petkov 	.format_group		= &knl_uncore_irp_format_group,
2401ed367e6cSBorislav Petkov };
2402ed367e6cSBorislav Petkov 
2403ed367e6cSBorislav Petkov enum {
2404ed367e6cSBorislav Petkov 	KNL_PCI_UNCORE_MC_UCLK,
2405ed367e6cSBorislav Petkov 	KNL_PCI_UNCORE_MC_DCLK,
2406ed367e6cSBorislav Petkov 	KNL_PCI_UNCORE_EDC_UCLK,
2407ed367e6cSBorislav Petkov 	KNL_PCI_UNCORE_EDC_ECLK,
2408ed367e6cSBorislav Petkov 	KNL_PCI_UNCORE_M2PCIE,
2409ed367e6cSBorislav Petkov 	KNL_PCI_UNCORE_IRP,
2410ed367e6cSBorislav Petkov };
2411ed367e6cSBorislav Petkov 
2412ed367e6cSBorislav Petkov static struct intel_uncore_type *knl_pci_uncores[] = {
2413ed367e6cSBorislav Petkov 	[KNL_PCI_UNCORE_MC_UCLK]	= &knl_uncore_imc_uclk,
2414ed367e6cSBorislav Petkov 	[KNL_PCI_UNCORE_MC_DCLK]	= &knl_uncore_imc_dclk,
2415ed367e6cSBorislav Petkov 	[KNL_PCI_UNCORE_EDC_UCLK]	= &knl_uncore_edc_uclk,
2416ed367e6cSBorislav Petkov 	[KNL_PCI_UNCORE_EDC_ECLK]	= &knl_uncore_edc_eclk,
2417ed367e6cSBorislav Petkov 	[KNL_PCI_UNCORE_M2PCIE]		= &knl_uncore_m2pcie,
2418ed367e6cSBorislav Petkov 	[KNL_PCI_UNCORE_IRP]		= &knl_uncore_irp,
2419ed367e6cSBorislav Petkov 	NULL,
2420ed367e6cSBorislav Petkov };
2421ed367e6cSBorislav Petkov 
2422ed367e6cSBorislav Petkov /*
2423ed367e6cSBorislav Petkov  * KNL uses a common PCI device ID for multiple instances of an Uncore PMU
2424ed367e6cSBorislav Petkov  * device type. prior to KNL, each instance of a PMU device type had a unique
2425ed367e6cSBorislav Petkov  * device ID.
2426ed367e6cSBorislav Petkov  *
2427ed367e6cSBorislav Petkov  *	PCI Device ID	Uncore PMU Devices
2428ed367e6cSBorislav Petkov  *	----------------------------------
2429ed367e6cSBorislav Petkov  *	0x7841		MC0 UClk, MC1 UClk
2430ed367e6cSBorislav Petkov  *	0x7843		MC0 DClk CH 0, MC0 DClk CH 1, MC0 DClk CH 2,
2431ed367e6cSBorislav Petkov  *			MC1 DClk CH 0, MC1 DClk CH 1, MC1 DClk CH 2
2432ed367e6cSBorislav Petkov  *	0x7833		EDC0 UClk, EDC1 UClk, EDC2 UClk, EDC3 UClk,
2433ed367e6cSBorislav Petkov  *			EDC4 UClk, EDC5 UClk, EDC6 UClk, EDC7 UClk
2434ed367e6cSBorislav Petkov  *	0x7835		EDC0 EClk, EDC1 EClk, EDC2 EClk, EDC3 EClk,
2435ed367e6cSBorislav Petkov  *			EDC4 EClk, EDC5 EClk, EDC6 EClk, EDC7 EClk
2436ed367e6cSBorislav Petkov  *	0x7817		M2PCIe
2437ed367e6cSBorislav Petkov  *	0x7814		IRP
2438ed367e6cSBorislav Petkov */
2439ed367e6cSBorislav Petkov 
2440ed367e6cSBorislav Petkov static const struct pci_device_id knl_uncore_pci_ids[] = {
2441a54fa079SKan Liang 	{ /* MC0 UClk */
2442ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7841),
2443a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(10, 0, KNL_PCI_UNCORE_MC_UCLK, 0),
2444ed367e6cSBorislav Petkov 	},
2445a54fa079SKan Liang 	{ /* MC1 UClk */
2446a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7841),
2447a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(11, 0, KNL_PCI_UNCORE_MC_UCLK, 1),
2448a54fa079SKan Liang 	},
2449a54fa079SKan Liang 	{ /* MC0 DClk CH 0 */
2450ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7843),
2451a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(8, 2, KNL_PCI_UNCORE_MC_DCLK, 0),
2452ed367e6cSBorislav Petkov 	},
2453a54fa079SKan Liang 	{ /* MC0 DClk CH 1 */
2454a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7843),
2455a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(8, 3, KNL_PCI_UNCORE_MC_DCLK, 1),
2456a54fa079SKan Liang 	},
2457a54fa079SKan Liang 	{ /* MC0 DClk CH 2 */
2458a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7843),
2459a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(8, 4, KNL_PCI_UNCORE_MC_DCLK, 2),
2460a54fa079SKan Liang 	},
2461a54fa079SKan Liang 	{ /* MC1 DClk CH 0 */
2462a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7843),
2463a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(9, 2, KNL_PCI_UNCORE_MC_DCLK, 3),
2464a54fa079SKan Liang 	},
2465a54fa079SKan Liang 	{ /* MC1 DClk CH 1 */
2466a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7843),
2467a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(9, 3, KNL_PCI_UNCORE_MC_DCLK, 4),
2468a54fa079SKan Liang 	},
2469a54fa079SKan Liang 	{ /* MC1 DClk CH 2 */
2470a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7843),
2471a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(9, 4, KNL_PCI_UNCORE_MC_DCLK, 5),
2472a54fa079SKan Liang 	},
2473a54fa079SKan Liang 	{ /* EDC0 UClk */
2474ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2475a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(15, 0, KNL_PCI_UNCORE_EDC_UCLK, 0),
2476ed367e6cSBorislav Petkov 	},
2477a54fa079SKan Liang 	{ /* EDC1 UClk */
2478a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2479a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(16, 0, KNL_PCI_UNCORE_EDC_UCLK, 1),
2480a54fa079SKan Liang 	},
2481a54fa079SKan Liang 	{ /* EDC2 UClk */
2482a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2483a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(17, 0, KNL_PCI_UNCORE_EDC_UCLK, 2),
2484a54fa079SKan Liang 	},
2485a54fa079SKan Liang 	{ /* EDC3 UClk */
2486a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2487a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(18, 0, KNL_PCI_UNCORE_EDC_UCLK, 3),
2488a54fa079SKan Liang 	},
2489a54fa079SKan Liang 	{ /* EDC4 UClk */
2490a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2491a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(19, 0, KNL_PCI_UNCORE_EDC_UCLK, 4),
2492a54fa079SKan Liang 	},
2493a54fa079SKan Liang 	{ /* EDC5 UClk */
2494a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2495a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(20, 0, KNL_PCI_UNCORE_EDC_UCLK, 5),
2496a54fa079SKan Liang 	},
2497a54fa079SKan Liang 	{ /* EDC6 UClk */
2498a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2499a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(21, 0, KNL_PCI_UNCORE_EDC_UCLK, 6),
2500a54fa079SKan Liang 	},
2501a54fa079SKan Liang 	{ /* EDC7 UClk */
2502a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7833),
2503a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(22, 0, KNL_PCI_UNCORE_EDC_UCLK, 7),
2504a54fa079SKan Liang 	},
2505a54fa079SKan Liang 	{ /* EDC0 EClk */
2506ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2507a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(24, 2, KNL_PCI_UNCORE_EDC_ECLK, 0),
2508a54fa079SKan Liang 	},
2509a54fa079SKan Liang 	{ /* EDC1 EClk */
2510a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2511a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(25, 2, KNL_PCI_UNCORE_EDC_ECLK, 1),
2512a54fa079SKan Liang 	},
2513a54fa079SKan Liang 	{ /* EDC2 EClk */
2514a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2515a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(26, 2, KNL_PCI_UNCORE_EDC_ECLK, 2),
2516a54fa079SKan Liang 	},
2517a54fa079SKan Liang 	{ /* EDC3 EClk */
2518a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2519a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(27, 2, KNL_PCI_UNCORE_EDC_ECLK, 3),
2520a54fa079SKan Liang 	},
2521a54fa079SKan Liang 	{ /* EDC4 EClk */
2522a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2523a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(28, 2, KNL_PCI_UNCORE_EDC_ECLK, 4),
2524a54fa079SKan Liang 	},
2525a54fa079SKan Liang 	{ /* EDC5 EClk */
2526a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2527a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(29, 2, KNL_PCI_UNCORE_EDC_ECLK, 5),
2528a54fa079SKan Liang 	},
2529a54fa079SKan Liang 	{ /* EDC6 EClk */
2530a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2531a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(30, 2, KNL_PCI_UNCORE_EDC_ECLK, 6),
2532a54fa079SKan Liang 	},
2533a54fa079SKan Liang 	{ /* EDC7 EClk */
2534a54fa079SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7835),
2535a54fa079SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(31, 2, KNL_PCI_UNCORE_EDC_ECLK, 7),
2536ed367e6cSBorislav Petkov 	},
2537ed367e6cSBorislav Petkov 	{ /* M2PCIe */
2538ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7817),
2539ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(KNL_PCI_UNCORE_M2PCIE, 0),
2540ed367e6cSBorislav Petkov 	},
2541ed367e6cSBorislav Petkov 	{ /* IRP */
2542ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7814),
2543ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(KNL_PCI_UNCORE_IRP, 0),
2544ed367e6cSBorislav Petkov 	},
2545ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ }
2546ed367e6cSBorislav Petkov };
2547ed367e6cSBorislav Petkov 
2548ed367e6cSBorislav Petkov static struct pci_driver knl_uncore_pci_driver = {
2549ed367e6cSBorislav Petkov 	.name		= "knl_uncore",
2550ed367e6cSBorislav Petkov 	.id_table	= knl_uncore_pci_ids,
2551ed367e6cSBorislav Petkov };
2552ed367e6cSBorislav Petkov 
2553ed367e6cSBorislav Petkov int knl_uncore_pci_init(void)
2554ed367e6cSBorislav Petkov {
2555ed367e6cSBorislav Petkov 	int ret;
2556ed367e6cSBorislav Petkov 
2557ed367e6cSBorislav Petkov 	/* All KNL PCI based PMON units are on the same PCI bus except IRP */
2558ed367e6cSBorislav Petkov 	ret = snb_pci2phy_map_init(0x7814); /* IRP */
2559ed367e6cSBorislav Petkov 	if (ret)
2560ed367e6cSBorislav Petkov 		return ret;
2561ed367e6cSBorislav Petkov 	ret = snb_pci2phy_map_init(0x7817); /* M2PCIe */
2562ed367e6cSBorislav Petkov 	if (ret)
2563ed367e6cSBorislav Petkov 		return ret;
2564ed367e6cSBorislav Petkov 	uncore_pci_uncores = knl_pci_uncores;
2565ed367e6cSBorislav Petkov 	uncore_pci_driver = &knl_uncore_pci_driver;
2566ed367e6cSBorislav Petkov 	return 0;
2567ed367e6cSBorislav Petkov }
2568ed367e6cSBorislav Petkov 
2569ed367e6cSBorislav Petkov /* end of KNL uncore support */
2570ed367e6cSBorislav Petkov 
2571ed367e6cSBorislav Petkov /* Haswell-EP uncore support */
2572ed367e6cSBorislav Petkov static struct attribute *hswep_uncore_ubox_formats_attr[] = {
2573ed367e6cSBorislav Petkov 	&format_attr_event.attr,
2574ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
2575ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2576ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
2577ed367e6cSBorislav Petkov 	&format_attr_thresh5.attr,
2578ed367e6cSBorislav Petkov 	&format_attr_filter_tid2.attr,
2579ed367e6cSBorislav Petkov 	&format_attr_filter_cid.attr,
2580ed367e6cSBorislav Petkov 	NULL,
2581ed367e6cSBorislav Petkov };
2582ed367e6cSBorislav Petkov 
258345bd07adSArvind Yadav static const struct attribute_group hswep_uncore_ubox_format_group = {
2584ed367e6cSBorislav Petkov 	.name = "format",
2585ed367e6cSBorislav Petkov 	.attrs = hswep_uncore_ubox_formats_attr,
2586ed367e6cSBorislav Petkov };
2587ed367e6cSBorislav Petkov 
2588ed367e6cSBorislav Petkov static int hswep_ubox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
2589ed367e6cSBorislav Petkov {
2590ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
2591ed367e6cSBorislav Petkov 	reg1->reg = HSWEP_U_MSR_PMON_FILTER;
2592ed367e6cSBorislav Petkov 	reg1->config = event->attr.config1 & HSWEP_U_MSR_PMON_BOX_FILTER_MASK;
2593ed367e6cSBorislav Petkov 	reg1->idx = 0;
2594ed367e6cSBorislav Petkov 	return 0;
2595ed367e6cSBorislav Petkov }
2596ed367e6cSBorislav Petkov 
2597ed367e6cSBorislav Petkov static struct intel_uncore_ops hswep_uncore_ubox_ops = {
2598ed367e6cSBorislav Petkov 	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
2599ed367e6cSBorislav Petkov 	.hw_config		= hswep_ubox_hw_config,
2600ed367e6cSBorislav Petkov 	.get_constraint		= uncore_get_constraint,
2601ed367e6cSBorislav Petkov 	.put_constraint		= uncore_put_constraint,
2602ed367e6cSBorislav Petkov };
2603ed367e6cSBorislav Petkov 
2604ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_ubox = {
2605ed367e6cSBorislav Petkov 	.name			= "ubox",
2606ed367e6cSBorislav Petkov 	.num_counters		= 2,
2607ed367e6cSBorislav Petkov 	.num_boxes		= 1,
2608ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 44,
2609ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
2610ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_U_MSR_PMON_CTR0,
2611ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_U_MSR_PMON_CTL0,
2612ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
2613ed367e6cSBorislav Petkov 	.fixed_ctr		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
2614ed367e6cSBorislav Petkov 	.fixed_ctl		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
2615ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
2616ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_ubox_ops,
2617ed367e6cSBorislav Petkov 	.format_group		= &hswep_uncore_ubox_format_group,
2618ed367e6cSBorislav Petkov };
2619ed367e6cSBorislav Petkov 
2620ed367e6cSBorislav Petkov static struct attribute *hswep_uncore_cbox_formats_attr[] = {
2621ed367e6cSBorislav Petkov 	&format_attr_event.attr,
2622ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
2623ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2624ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
2625ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
2626ed367e6cSBorislav Petkov 	&format_attr_filter_tid3.attr,
2627ed367e6cSBorislav Petkov 	&format_attr_filter_link2.attr,
2628ed367e6cSBorislav Petkov 	&format_attr_filter_state3.attr,
2629ed367e6cSBorislav Petkov 	&format_attr_filter_nid2.attr,
2630ed367e6cSBorislav Petkov 	&format_attr_filter_opc2.attr,
2631ed367e6cSBorislav Petkov 	&format_attr_filter_nc.attr,
2632ed367e6cSBorislav Petkov 	&format_attr_filter_c6.attr,
2633ed367e6cSBorislav Petkov 	&format_attr_filter_isoc.attr,
2634ed367e6cSBorislav Petkov 	NULL,
2635ed367e6cSBorislav Petkov };
2636ed367e6cSBorislav Petkov 
263745bd07adSArvind Yadav static const struct attribute_group hswep_uncore_cbox_format_group = {
2638ed367e6cSBorislav Petkov 	.name = "format",
2639ed367e6cSBorislav Petkov 	.attrs = hswep_uncore_cbox_formats_attr,
2640ed367e6cSBorislav Petkov };
2641ed367e6cSBorislav Petkov 
2642ed367e6cSBorislav Petkov static struct event_constraint hswep_uncore_cbox_constraints[] = {
2643ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x01, 0x1),
2644ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x09, 0x1),
2645ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
2646ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
2647ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
2648ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x3b, 0x1),
2649ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x3e, 0x1),
2650ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
2651ed367e6cSBorislav Petkov };
2652ed367e6cSBorislav Petkov 
2653ed367e6cSBorislav Petkov static struct extra_reg hswep_uncore_cbox_extra_regs[] = {
2654ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
2655ed367e6cSBorislav Petkov 				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
2656ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
2657ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
2658ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
2659ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4),
2660ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2134, 0xffff, 0x4),
2661ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x4),
2662ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x8),
2663ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4028, 0x40ff, 0x8),
2664ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4032, 0x40ff, 0x8),
2665ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4029, 0x40ff, 0x8),
2666ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4033, 0x40ff, 0x8),
2667ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x402A, 0x40ff, 0x8),
2668ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x12),
2669ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10),
2670ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0x18),
2671ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x8),
2672ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x8),
2673ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x8),
2674ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0x18),
2675ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x8),
2676ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2335, 0xffff, 0x10),
2677ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8335, 0xffff, 0x10),
2678ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10),
2679ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8135, 0xffff, 0x10),
2680ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x10),
2681ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x10),
2682ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0x18),
2683ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x8),
2684ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x8),
2685ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0x18),
2686ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x8),
2687ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2336, 0xffff, 0x10),
2688ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8336, 0xffff, 0x10),
2689ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x2136, 0xffff, 0x10),
2690ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x8136, 0xffff, 0x10),
2691ed367e6cSBorislav Petkov 	SNBEP_CBO_EVENT_EXTRA_REG(0x5036, 0xffff, 0x8),
2692ed367e6cSBorislav Petkov 	EVENT_EXTRA_END
2693ed367e6cSBorislav Petkov };
2694ed367e6cSBorislav Petkov 
2695ed367e6cSBorislav Petkov static u64 hswep_cbox_filter_mask(int fields)
2696ed367e6cSBorislav Petkov {
2697ed367e6cSBorislav Petkov 	u64 mask = 0;
2698ed367e6cSBorislav Petkov 	if (fields & 0x1)
2699ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_TID;
2700ed367e6cSBorislav Petkov 	if (fields & 0x2)
2701ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_LINK;
2702ed367e6cSBorislav Petkov 	if (fields & 0x4)
2703ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_STATE;
2704ed367e6cSBorislav Petkov 	if (fields & 0x8)
2705ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_NID;
2706ed367e6cSBorislav Petkov 	if (fields & 0x10) {
2707ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_OPC;
2708ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_NC;
2709ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_C6;
2710ed367e6cSBorislav Petkov 		mask |= HSWEP_CB0_MSR_PMON_BOX_FILTER_ISOC;
2711ed367e6cSBorislav Petkov 	}
2712ed367e6cSBorislav Petkov 	return mask;
2713ed367e6cSBorislav Petkov }
2714ed367e6cSBorislav Petkov 
2715ed367e6cSBorislav Petkov static struct event_constraint *
2716ed367e6cSBorislav Petkov hswep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
2717ed367e6cSBorislav Petkov {
2718ed367e6cSBorislav Petkov 	return __snbep_cbox_get_constraint(box, event, hswep_cbox_filter_mask);
2719ed367e6cSBorislav Petkov }
2720ed367e6cSBorislav Petkov 
2721ed367e6cSBorislav Petkov static int hswep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
2722ed367e6cSBorislav Petkov {
2723ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
2724ed367e6cSBorislav Petkov 	struct extra_reg *er;
2725ed367e6cSBorislav Petkov 	int idx = 0;
2726ed367e6cSBorislav Petkov 
2727ed367e6cSBorislav Petkov 	for (er = hswep_uncore_cbox_extra_regs; er->msr; er++) {
2728ed367e6cSBorislav Petkov 		if (er->event != (event->hw.config & er->config_mask))
2729ed367e6cSBorislav Petkov 			continue;
2730ed367e6cSBorislav Petkov 		idx |= er->idx;
2731ed367e6cSBorislav Petkov 	}
2732ed367e6cSBorislav Petkov 
2733ed367e6cSBorislav Petkov 	if (idx) {
2734ed367e6cSBorislav Petkov 		reg1->reg = HSWEP_C0_MSR_PMON_BOX_FILTER0 +
2735ed367e6cSBorislav Petkov 			    HSWEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
2736ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1 & hswep_cbox_filter_mask(idx);
2737ed367e6cSBorislav Petkov 		reg1->idx = idx;
2738ed367e6cSBorislav Petkov 	}
2739ed367e6cSBorislav Petkov 	return 0;
2740ed367e6cSBorislav Petkov }
2741ed367e6cSBorislav Petkov 
2742ed367e6cSBorislav Petkov static void hswep_cbox_enable_event(struct intel_uncore_box *box,
2743ed367e6cSBorislav Petkov 				  struct perf_event *event)
2744ed367e6cSBorislav Petkov {
2745ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
2746ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
2747ed367e6cSBorislav Petkov 
2748ed367e6cSBorislav Petkov 	if (reg1->idx != EXTRA_REG_NONE) {
2749ed367e6cSBorislav Petkov 		u64 filter = uncore_shared_reg_config(box, 0);
2750ed367e6cSBorislav Petkov 		wrmsrl(reg1->reg, filter & 0xffffffff);
2751ed367e6cSBorislav Petkov 		wrmsrl(reg1->reg + 1, filter >> 32);
2752ed367e6cSBorislav Petkov 	}
2753ed367e6cSBorislav Petkov 
2754ed367e6cSBorislav Petkov 	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
2755ed367e6cSBorislav Petkov }
2756ed367e6cSBorislav Petkov 
2757ed367e6cSBorislav Petkov static struct intel_uncore_ops hswep_uncore_cbox_ops = {
2758ed367e6cSBorislav Petkov 	.init_box		= snbep_uncore_msr_init_box,
2759ed367e6cSBorislav Petkov 	.disable_box		= snbep_uncore_msr_disable_box,
2760ed367e6cSBorislav Petkov 	.enable_box		= snbep_uncore_msr_enable_box,
2761ed367e6cSBorislav Petkov 	.disable_event		= snbep_uncore_msr_disable_event,
2762ed367e6cSBorislav Petkov 	.enable_event		= hswep_cbox_enable_event,
2763ed367e6cSBorislav Petkov 	.read_counter		= uncore_msr_read_counter,
2764ed367e6cSBorislav Petkov 	.hw_config		= hswep_cbox_hw_config,
2765ed367e6cSBorislav Petkov 	.get_constraint		= hswep_cbox_get_constraint,
2766ed367e6cSBorislav Petkov 	.put_constraint		= snbep_cbox_put_constraint,
2767ed367e6cSBorislav Petkov };
2768ed367e6cSBorislav Petkov 
2769ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_cbox = {
2770ed367e6cSBorislav Petkov 	.name			= "cbox",
2771ed367e6cSBorislav Petkov 	.num_counters		= 4,
2772ed367e6cSBorislav Petkov 	.num_boxes		= 18,
2773ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2774ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_C0_MSR_PMON_CTL0,
2775ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_C0_MSR_PMON_CTR0,
2776ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
2777ed367e6cSBorislav Petkov 	.box_ctl		= HSWEP_C0_MSR_PMON_BOX_CTL,
2778ed367e6cSBorislav Petkov 	.msr_offset		= HSWEP_CBO_MSR_OFFSET,
2779ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
2780ed367e6cSBorislav Petkov 	.constraints		= hswep_uncore_cbox_constraints,
2781ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_cbox_ops,
2782ed367e6cSBorislav Petkov 	.format_group		= &hswep_uncore_cbox_format_group,
2783ed367e6cSBorislav Petkov };
2784ed367e6cSBorislav Petkov 
2785ed367e6cSBorislav Petkov /*
2786ed367e6cSBorislav Petkov  * Write SBOX Initialization register bit by bit to avoid spurious #GPs
2787ed367e6cSBorislav Petkov  */
2788ed367e6cSBorislav Petkov static void hswep_uncore_sbox_msr_init_box(struct intel_uncore_box *box)
2789ed367e6cSBorislav Petkov {
2790ed367e6cSBorislav Petkov 	unsigned msr = uncore_msr_box_ctl(box);
2791ed367e6cSBorislav Petkov 
2792ed367e6cSBorislav Petkov 	if (msr) {
2793ed367e6cSBorislav Petkov 		u64 init = SNBEP_PMON_BOX_CTL_INT;
2794ed367e6cSBorislav Petkov 		u64 flags = 0;
2795ed367e6cSBorislav Petkov 		int i;
2796ed367e6cSBorislav Petkov 
2797ed367e6cSBorislav Petkov 		for_each_set_bit(i, (unsigned long *)&init, 64) {
2798ed367e6cSBorislav Petkov 			flags |= (1ULL << i);
2799ed367e6cSBorislav Petkov 			wrmsrl(msr, flags);
2800ed367e6cSBorislav Petkov 		}
2801ed367e6cSBorislav Petkov 	}
2802ed367e6cSBorislav Petkov }
2803ed367e6cSBorislav Petkov 
2804ed367e6cSBorislav Petkov static struct intel_uncore_ops hswep_uncore_sbox_msr_ops = {
2805ed367e6cSBorislav Petkov 	__SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
2806ed367e6cSBorislav Petkov 	.init_box		= hswep_uncore_sbox_msr_init_box
2807ed367e6cSBorislav Petkov };
2808ed367e6cSBorislav Petkov 
2809ed367e6cSBorislav Petkov static struct attribute *hswep_uncore_sbox_formats_attr[] = {
2810ed367e6cSBorislav Petkov 	&format_attr_event.attr,
2811ed367e6cSBorislav Petkov 	&format_attr_umask.attr,
2812ed367e6cSBorislav Petkov 	&format_attr_edge.attr,
2813ed367e6cSBorislav Petkov 	&format_attr_tid_en.attr,
2814ed367e6cSBorislav Petkov 	&format_attr_inv.attr,
2815ed367e6cSBorislav Petkov 	&format_attr_thresh8.attr,
2816ed367e6cSBorislav Petkov 	NULL,
2817ed367e6cSBorislav Petkov };
2818ed367e6cSBorislav Petkov 
281945bd07adSArvind Yadav static const struct attribute_group hswep_uncore_sbox_format_group = {
2820ed367e6cSBorislav Petkov 	.name = "format",
2821ed367e6cSBorislav Petkov 	.attrs = hswep_uncore_sbox_formats_attr,
2822ed367e6cSBorislav Petkov };
2823ed367e6cSBorislav Petkov 
2824ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_sbox = {
2825ed367e6cSBorislav Petkov 	.name			= "sbox",
2826ed367e6cSBorislav Petkov 	.num_counters		= 4,
2827ed367e6cSBorislav Petkov 	.num_boxes		= 4,
2828ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 44,
2829ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_S0_MSR_PMON_CTL0,
2830ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_S0_MSR_PMON_CTR0,
2831ed367e6cSBorislav Petkov 	.event_mask		= HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
2832ed367e6cSBorislav Petkov 	.box_ctl		= HSWEP_S0_MSR_PMON_BOX_CTL,
2833ed367e6cSBorislav Petkov 	.msr_offset		= HSWEP_SBOX_MSR_OFFSET,
2834ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_sbox_msr_ops,
2835ed367e6cSBorislav Petkov 	.format_group		= &hswep_uncore_sbox_format_group,
2836ed367e6cSBorislav Petkov };
2837ed367e6cSBorislav Petkov 
2838ed367e6cSBorislav Petkov static int hswep_pcu_hw_config(struct intel_uncore_box *box, struct perf_event *event)
2839ed367e6cSBorislav Petkov {
2840ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
2841ed367e6cSBorislav Petkov 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
2842ed367e6cSBorislav Petkov 	int ev_sel = hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK;
2843ed367e6cSBorislav Petkov 
2844ed367e6cSBorislav Petkov 	if (ev_sel >= 0xb && ev_sel <= 0xe) {
2845ed367e6cSBorislav Petkov 		reg1->reg = HSWEP_PCU_MSR_PMON_BOX_FILTER;
2846ed367e6cSBorislav Petkov 		reg1->idx = ev_sel - 0xb;
2847ed367e6cSBorislav Petkov 		reg1->config = event->attr.config1 & (0xff << reg1->idx);
2848ed367e6cSBorislav Petkov 	}
2849ed367e6cSBorislav Petkov 	return 0;
2850ed367e6cSBorislav Petkov }
2851ed367e6cSBorislav Petkov 
2852ed367e6cSBorislav Petkov static struct intel_uncore_ops hswep_uncore_pcu_ops = {
2853ed367e6cSBorislav Petkov 	SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
2854ed367e6cSBorislav Petkov 	.hw_config		= hswep_pcu_hw_config,
2855ed367e6cSBorislav Petkov 	.get_constraint		= snbep_pcu_get_constraint,
2856ed367e6cSBorislav Petkov 	.put_constraint		= snbep_pcu_put_constraint,
2857ed367e6cSBorislav Petkov };
2858ed367e6cSBorislav Petkov 
2859ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_pcu = {
2860ed367e6cSBorislav Petkov 	.name			= "pcu",
2861ed367e6cSBorislav Petkov 	.num_counters		= 4,
2862ed367e6cSBorislav Petkov 	.num_boxes		= 1,
2863ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2864ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_PCU_MSR_PMON_CTR0,
2865ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_PCU_MSR_PMON_CTL0,
2866ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
2867ed367e6cSBorislav Petkov 	.box_ctl		= HSWEP_PCU_MSR_PMON_BOX_CTL,
2868ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
2869ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_pcu_ops,
2870ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_pcu_format_group,
2871ed367e6cSBorislav Petkov };
2872ed367e6cSBorislav Petkov 
2873ed367e6cSBorislav Petkov static struct intel_uncore_type *hswep_msr_uncores[] = {
2874ed367e6cSBorislav Petkov 	&hswep_uncore_ubox,
2875ed367e6cSBorislav Petkov 	&hswep_uncore_cbox,
2876ed367e6cSBorislav Petkov 	&hswep_uncore_sbox,
2877ed367e6cSBorislav Petkov 	&hswep_uncore_pcu,
2878ed367e6cSBorislav Petkov 	NULL,
2879ed367e6cSBorislav Petkov };
2880ed367e6cSBorislav Petkov 
28819d480158SKan Liang #define HSWEP_PCU_DID			0x2fc0
28829d480158SKan Liang #define HSWEP_PCU_CAPID4_OFFET		0x94
28839d480158SKan Liang #define hswep_get_chop(_cap)		(((_cap) >> 6) & 0x3)
28849d480158SKan Liang 
28859d480158SKan Liang static bool hswep_has_limit_sbox(unsigned int device)
28869d480158SKan Liang {
28879d480158SKan Liang 	struct pci_dev *dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
28889d480158SKan Liang 	u32 capid4;
28899d480158SKan Liang 
28909d480158SKan Liang 	if (!dev)
28919d480158SKan Liang 		return false;
28929d480158SKan Liang 
28939d480158SKan Liang 	pci_read_config_dword(dev, HSWEP_PCU_CAPID4_OFFET, &capid4);
28949d480158SKan Liang 	if (!hswep_get_chop(capid4))
28959d480158SKan Liang 		return true;
28969d480158SKan Liang 
28979d480158SKan Liang 	return false;
28989d480158SKan Liang }
28999d480158SKan Liang 
2900ed367e6cSBorislav Petkov void hswep_uncore_cpu_init(void)
2901ed367e6cSBorislav Petkov {
2902ed367e6cSBorislav Petkov 	if (hswep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
2903ed367e6cSBorislav Petkov 		hswep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
2904ed367e6cSBorislav Petkov 
2905ed367e6cSBorislav Petkov 	/* Detect 6-8 core systems with only two SBOXes */
29069d480158SKan Liang 	if (hswep_has_limit_sbox(HSWEP_PCU_DID))
2907ed367e6cSBorislav Petkov 		hswep_uncore_sbox.num_boxes = 2;
2908ed367e6cSBorislav Petkov 
2909ed367e6cSBorislav Petkov 	uncore_msr_uncores = hswep_msr_uncores;
2910ed367e6cSBorislav Petkov }
2911ed367e6cSBorislav Petkov 
2912ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_ha = {
2913ed367e6cSBorislav Petkov 	.name		= "ha",
291410e9e7bdSKan Liang 	.num_counters   = 4,
2915ed367e6cSBorislav Petkov 	.num_boxes	= 2,
2916ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
2917ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
2918ed367e6cSBorislav Petkov };
2919ed367e6cSBorislav Petkov 
2920ed367e6cSBorislav Petkov static struct uncore_event_desc hswep_uncore_imc_events[] = {
2921ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(clockticks,      "event=0x00,umask=0x00"),
2922ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_read,  "event=0x04,umask=0x03"),
2923ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_read.scale, "6.103515625e-5"),
2924ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_read.unit, "MiB"),
2925ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"),
2926ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_write.scale, "6.103515625e-5"),
2927ed367e6cSBorislav Petkov 	INTEL_UNCORE_EVENT_DESC(cas_count_write.unit, "MiB"),
2928ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ },
2929ed367e6cSBorislav Petkov };
2930ed367e6cSBorislav Petkov 
2931ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_imc = {
2932ed367e6cSBorislav Petkov 	.name		= "imc",
293310e9e7bdSKan Liang 	.num_counters   = 4,
2934ed367e6cSBorislav Petkov 	.num_boxes	= 8,
2935ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
2936ed367e6cSBorislav Petkov 	.fixed_ctr_bits	= 48,
2937ed367e6cSBorislav Petkov 	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
2938ed367e6cSBorislav Petkov 	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
2939ed367e6cSBorislav Petkov 	.event_descs	= hswep_uncore_imc_events,
2940ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
2941ed367e6cSBorislav Petkov };
2942ed367e6cSBorislav Petkov 
2943ed367e6cSBorislav Petkov static unsigned hswep_uncore_irp_ctrs[] = {0xa0, 0xa8, 0xb0, 0xb8};
2944ed367e6cSBorislav Petkov 
2945ed367e6cSBorislav Petkov static u64 hswep_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event)
2946ed367e6cSBorislav Petkov {
2947ed367e6cSBorislav Petkov 	struct pci_dev *pdev = box->pci_dev;
2948ed367e6cSBorislav Petkov 	struct hw_perf_event *hwc = &event->hw;
2949ed367e6cSBorislav Petkov 	u64 count = 0;
2950ed367e6cSBorislav Petkov 
2951ed367e6cSBorislav Petkov 	pci_read_config_dword(pdev, hswep_uncore_irp_ctrs[hwc->idx], (u32 *)&count);
2952ed367e6cSBorislav Petkov 	pci_read_config_dword(pdev, hswep_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1);
2953ed367e6cSBorislav Petkov 
2954ed367e6cSBorislav Petkov 	return count;
2955ed367e6cSBorislav Petkov }
2956ed367e6cSBorislav Petkov 
2957ed367e6cSBorislav Petkov static struct intel_uncore_ops hswep_uncore_irp_ops = {
2958ed367e6cSBorislav Petkov 	.init_box	= snbep_uncore_pci_init_box,
2959ed367e6cSBorislav Petkov 	.disable_box	= snbep_uncore_pci_disable_box,
2960ed367e6cSBorislav Petkov 	.enable_box	= snbep_uncore_pci_enable_box,
2961ed367e6cSBorislav Petkov 	.disable_event	= ivbep_uncore_irp_disable_event,
2962ed367e6cSBorislav Petkov 	.enable_event	= ivbep_uncore_irp_enable_event,
2963ed367e6cSBorislav Petkov 	.read_counter	= hswep_uncore_irp_read_counter,
2964ed367e6cSBorislav Petkov };
2965ed367e6cSBorislav Petkov 
2966ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_irp = {
2967ed367e6cSBorislav Petkov 	.name			= "irp",
2968ed367e6cSBorislav Petkov 	.num_counters		= 4,
2969ed367e6cSBorislav Petkov 	.num_boxes		= 1,
2970ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2971ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
2972ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
2973ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_irp_ops,
2974ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_format_group,
2975ed367e6cSBorislav Petkov };
2976ed367e6cSBorislav Petkov 
2977ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_qpi = {
2978ed367e6cSBorislav Petkov 	.name			= "qpi",
297910e9e7bdSKan Liang 	.num_counters		= 4,
2980ed367e6cSBorislav Petkov 	.num_boxes		= 3,
2981ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
2982ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
2983ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCI_PMON_CTL0,
2984ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
2985ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
2986ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
2987ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_qpi_ops,
2988ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_qpi_format_group,
2989ed367e6cSBorislav Petkov };
2990ed367e6cSBorislav Petkov 
2991ed367e6cSBorislav Petkov static struct event_constraint hswep_uncore_r2pcie_constraints[] = {
2992ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
2993ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
2994ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
2995ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x1),
2996ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x24, 0x1),
2997ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
2998ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
2999ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x27, 0x1),
3000ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
3001ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
3002ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2a, 0x1),
3003ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2b, 0x3),
3004ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
3005ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
3006ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
3007ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
3008ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
3009ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
3010ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
3011ed367e6cSBorislav Petkov };
3012ed367e6cSBorislav Petkov 
3013ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_r2pcie = {
3014ed367e6cSBorislav Petkov 	.name		= "r2pcie",
3015ed367e6cSBorislav Petkov 	.num_counters   = 4,
3016ed367e6cSBorislav Petkov 	.num_boxes	= 1,
3017ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
3018ed367e6cSBorislav Petkov 	.constraints	= hswep_uncore_r2pcie_constraints,
3019ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
3020ed367e6cSBorislav Petkov };
3021ed367e6cSBorislav Petkov 
3022ed367e6cSBorislav Petkov static struct event_constraint hswep_uncore_r3qpi_constraints[] = {
3023ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x01, 0x3),
3024ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x07, 0x7),
3025ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x08, 0x7),
3026ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x09, 0x7),
3027ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x0a, 0x7),
3028ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x0e, 0x7),
3029ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
3030ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
3031ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
3032ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
3033ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
3034ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x15, 0x3),
3035ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1f, 0x3),
3036ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
3037ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
3038ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
3039ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
3040ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
3041ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
3042ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
3043ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
3044ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
3045ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
3046ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
3047ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
3048ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
3049ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
3050ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
3051ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
3052ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
3053ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
3054ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
3055ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
3056ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
3057ed367e6cSBorislav Petkov };
3058ed367e6cSBorislav Petkov 
3059ed367e6cSBorislav Petkov static struct intel_uncore_type hswep_uncore_r3qpi = {
3060ed367e6cSBorislav Petkov 	.name		= "r3qpi",
306110e9e7bdSKan Liang 	.num_counters   = 3,
3062ed367e6cSBorislav Petkov 	.num_boxes	= 3,
3063ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 44,
3064ed367e6cSBorislav Petkov 	.constraints	= hswep_uncore_r3qpi_constraints,
3065ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
3066ed367e6cSBorislav Petkov };
3067ed367e6cSBorislav Petkov 
3068ed367e6cSBorislav Petkov enum {
3069ed367e6cSBorislav Petkov 	HSWEP_PCI_UNCORE_HA,
3070ed367e6cSBorislav Petkov 	HSWEP_PCI_UNCORE_IMC,
3071ed367e6cSBorislav Petkov 	HSWEP_PCI_UNCORE_IRP,
3072ed367e6cSBorislav Petkov 	HSWEP_PCI_UNCORE_QPI,
3073ed367e6cSBorislav Petkov 	HSWEP_PCI_UNCORE_R2PCIE,
3074ed367e6cSBorislav Petkov 	HSWEP_PCI_UNCORE_R3QPI,
3075ed367e6cSBorislav Petkov };
3076ed367e6cSBorislav Petkov 
3077ed367e6cSBorislav Petkov static struct intel_uncore_type *hswep_pci_uncores[] = {
3078ed367e6cSBorislav Petkov 	[HSWEP_PCI_UNCORE_HA]	= &hswep_uncore_ha,
3079ed367e6cSBorislav Petkov 	[HSWEP_PCI_UNCORE_IMC]	= &hswep_uncore_imc,
3080ed367e6cSBorislav Petkov 	[HSWEP_PCI_UNCORE_IRP]	= &hswep_uncore_irp,
3081ed367e6cSBorislav Petkov 	[HSWEP_PCI_UNCORE_QPI]	= &hswep_uncore_qpi,
3082ed367e6cSBorislav Petkov 	[HSWEP_PCI_UNCORE_R2PCIE]	= &hswep_uncore_r2pcie,
3083ed367e6cSBorislav Petkov 	[HSWEP_PCI_UNCORE_R3QPI]	= &hswep_uncore_r3qpi,
3084ed367e6cSBorislav Petkov 	NULL,
3085ed367e6cSBorislav Petkov };
3086ed367e6cSBorislav Petkov 
3087ed367e6cSBorislav Petkov static const struct pci_device_id hswep_uncore_pci_ids[] = {
3088ed367e6cSBorislav Petkov 	{ /* Home Agent 0 */
3089ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f30),
3090ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_HA, 0),
3091ed367e6cSBorislav Petkov 	},
3092ed367e6cSBorislav Petkov 	{ /* Home Agent 1 */
3093ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f38),
3094ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_HA, 1),
3095ed367e6cSBorislav Petkov 	},
3096ed367e6cSBorislav Petkov 	{ /* MC0 Channel 0 */
3097ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb0),
3098ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 0),
3099ed367e6cSBorislav Petkov 	},
3100ed367e6cSBorislav Petkov 	{ /* MC0 Channel 1 */
3101ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb1),
3102ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 1),
3103ed367e6cSBorislav Petkov 	},
3104ed367e6cSBorislav Petkov 	{ /* MC0 Channel 2 */
3105ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb4),
3106ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 2),
3107ed367e6cSBorislav Petkov 	},
3108ed367e6cSBorislav Petkov 	{ /* MC0 Channel 3 */
3109ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fb5),
3110ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 3),
3111ed367e6cSBorislav Petkov 	},
3112ed367e6cSBorislav Petkov 	{ /* MC1 Channel 0 */
3113ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd0),
3114ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 4),
3115ed367e6cSBorislav Petkov 	},
3116ed367e6cSBorislav Petkov 	{ /* MC1 Channel 1 */
3117ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd1),
3118ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 5),
3119ed367e6cSBorislav Petkov 	},
3120ed367e6cSBorislav Petkov 	{ /* MC1 Channel 2 */
3121ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd4),
3122ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 6),
3123ed367e6cSBorislav Petkov 	},
3124ed367e6cSBorislav Petkov 	{ /* MC1 Channel 3 */
3125ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fd5),
3126ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IMC, 7),
3127ed367e6cSBorislav Petkov 	},
3128ed367e6cSBorislav Petkov 	{ /* IRP */
3129ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f39),
3130ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_IRP, 0),
3131ed367e6cSBorislav Petkov 	},
3132ed367e6cSBorislav Petkov 	{ /* QPI0 Port 0 */
3133ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f32),
3134ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 0),
3135ed367e6cSBorislav Petkov 	},
3136ed367e6cSBorislav Petkov 	{ /* QPI0 Port 1 */
3137ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f33),
3138ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 1),
3139ed367e6cSBorislav Petkov 	},
3140ed367e6cSBorislav Petkov 	{ /* QPI1 Port 2 */
3141ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f3a),
3142ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_QPI, 2),
3143ed367e6cSBorislav Petkov 	},
3144ed367e6cSBorislav Petkov 	{ /* R2PCIe */
3145ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f34),
3146ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R2PCIE, 0),
3147ed367e6cSBorislav Petkov 	},
3148ed367e6cSBorislav Petkov 	{ /* R3QPI0 Link 0 */
3149ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f36),
3150ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 0),
3151ed367e6cSBorislav Petkov 	},
3152ed367e6cSBorislav Petkov 	{ /* R3QPI0 Link 1 */
3153ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f37),
3154ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 1),
3155ed367e6cSBorislav Petkov 	},
3156ed367e6cSBorislav Petkov 	{ /* R3QPI1 Link 2 */
3157ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f3e),
3158ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(HSWEP_PCI_UNCORE_R3QPI, 2),
3159ed367e6cSBorislav Petkov 	},
3160ed367e6cSBorislav Petkov 	{ /* QPI Port 0 filter  */
3161ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f86),
3162ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
3163ed367e6cSBorislav Petkov 						   SNBEP_PCI_QPI_PORT0_FILTER),
3164ed367e6cSBorislav Petkov 	},
3165ed367e6cSBorislav Petkov 	{ /* QPI Port 1 filter  */
3166ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2f96),
3167ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
3168ed367e6cSBorislav Petkov 						   SNBEP_PCI_QPI_PORT1_FILTER),
3169ed367e6cSBorislav Petkov 	},
3170ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ }
3171ed367e6cSBorislav Petkov };
3172ed367e6cSBorislav Petkov 
3173ed367e6cSBorislav Petkov static struct pci_driver hswep_uncore_pci_driver = {
3174ed367e6cSBorislav Petkov 	.name		= "hswep_uncore",
3175ed367e6cSBorislav Petkov 	.id_table	= hswep_uncore_pci_ids,
3176ed367e6cSBorislav Petkov };
3177ed367e6cSBorislav Petkov 
3178ed367e6cSBorislav Petkov int hswep_uncore_pci_init(void)
3179ed367e6cSBorislav Petkov {
318068ce4a0dSKan Liang 	int ret = snbep_pci2phy_map_init(0x2f1e, SNBEP_CPUNODEID, SNBEP_GIDNIDMAP, true);
3181ed367e6cSBorislav Petkov 	if (ret)
3182ed367e6cSBorislav Petkov 		return ret;
3183ed367e6cSBorislav Petkov 	uncore_pci_uncores = hswep_pci_uncores;
3184ed367e6cSBorislav Petkov 	uncore_pci_driver = &hswep_uncore_pci_driver;
3185ed367e6cSBorislav Petkov 	return 0;
3186ed367e6cSBorislav Petkov }
3187ed367e6cSBorislav Petkov /* end of Haswell-EP uncore support */
3188ed367e6cSBorislav Petkov 
3189ed367e6cSBorislav Petkov /* BDX uncore support */
3190ed367e6cSBorislav Petkov 
3191ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_ubox = {
3192ed367e6cSBorislav Petkov 	.name			= "ubox",
3193ed367e6cSBorislav Petkov 	.num_counters		= 2,
3194ed367e6cSBorislav Petkov 	.num_boxes		= 1,
3195ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
3196ed367e6cSBorislav Petkov 	.fixed_ctr_bits		= 48,
3197ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_U_MSR_PMON_CTR0,
3198ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_U_MSR_PMON_CTL0,
3199ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
3200ed367e6cSBorislav Petkov 	.fixed_ctr		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
3201ed367e6cSBorislav Petkov 	.fixed_ctl		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
3202ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
3203ed367e6cSBorislav Petkov 	.ops			= &ivbep_uncore_msr_ops,
3204ed367e6cSBorislav Petkov 	.format_group		= &ivbep_uncore_ubox_format_group,
3205ed367e6cSBorislav Petkov };
3206ed367e6cSBorislav Petkov 
3207ed367e6cSBorislav Petkov static struct event_constraint bdx_uncore_cbox_constraints[] = {
3208ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x09, 0x3),
3209ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
3210ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
3211ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x3e, 0x1),
3212ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
3213ed367e6cSBorislav Petkov };
3214ed367e6cSBorislav Petkov 
3215ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_cbox = {
3216ed367e6cSBorislav Petkov 	.name			= "cbox",
3217ed367e6cSBorislav Petkov 	.num_counters		= 4,
3218ed367e6cSBorislav Petkov 	.num_boxes		= 24,
3219ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
3220ed367e6cSBorislav Petkov 	.event_ctl		= HSWEP_C0_MSR_PMON_CTL0,
3221ed367e6cSBorislav Petkov 	.perf_ctr		= HSWEP_C0_MSR_PMON_CTR0,
3222ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
3223ed367e6cSBorislav Petkov 	.box_ctl		= HSWEP_C0_MSR_PMON_BOX_CTL,
3224ed367e6cSBorislav Petkov 	.msr_offset		= HSWEP_CBO_MSR_OFFSET,
3225ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
3226ed367e6cSBorislav Petkov 	.constraints		= bdx_uncore_cbox_constraints,
3227ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_cbox_ops,
3228ed367e6cSBorislav Petkov 	.format_group		= &hswep_uncore_cbox_format_group,
3229ed367e6cSBorislav Petkov };
3230ed367e6cSBorislav Petkov 
3231d7717587SStephane Eranian static struct intel_uncore_type bdx_uncore_sbox = {
3232d7717587SStephane Eranian 	.name			= "sbox",
3233d7717587SStephane Eranian 	.num_counters		= 4,
3234d7717587SStephane Eranian 	.num_boxes		= 4,
3235d7717587SStephane Eranian 	.perf_ctr_bits		= 48,
3236d7717587SStephane Eranian 	.event_ctl		= HSWEP_S0_MSR_PMON_CTL0,
3237d7717587SStephane Eranian 	.perf_ctr		= HSWEP_S0_MSR_PMON_CTR0,
3238d7717587SStephane Eranian 	.event_mask		= HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
3239d7717587SStephane Eranian 	.box_ctl		= HSWEP_S0_MSR_PMON_BOX_CTL,
3240d7717587SStephane Eranian 	.msr_offset		= HSWEP_SBOX_MSR_OFFSET,
3241d7717587SStephane Eranian 	.ops			= &hswep_uncore_sbox_msr_ops,
3242d7717587SStephane Eranian 	.format_group		= &hswep_uncore_sbox_format_group,
3243d7717587SStephane Eranian };
3244d7717587SStephane Eranian 
3245d7717587SStephane Eranian #define BDX_MSR_UNCORE_SBOX	3
3246d7717587SStephane Eranian 
3247ed367e6cSBorislav Petkov static struct intel_uncore_type *bdx_msr_uncores[] = {
3248ed367e6cSBorislav Petkov 	&bdx_uncore_ubox,
3249ed367e6cSBorislav Petkov 	&bdx_uncore_cbox,
3250ed367e6cSBorislav Petkov 	&hswep_uncore_pcu,
3251d7717587SStephane Eranian 	&bdx_uncore_sbox,
3252ed367e6cSBorislav Petkov 	NULL,
3253ed367e6cSBorislav Petkov };
3254ed367e6cSBorislav Petkov 
3255bb9fbe1bSKan Liang /* Bit 7 'Use Occupancy' is not available for counter 0 on BDX */
3256bb9fbe1bSKan Liang static struct event_constraint bdx_uncore_pcu_constraints[] = {
3257bb9fbe1bSKan Liang 	EVENT_CONSTRAINT(0x80, 0xe, 0x80),
3258bb9fbe1bSKan Liang 	EVENT_CONSTRAINT_END
3259bb9fbe1bSKan Liang };
3260bb9fbe1bSKan Liang 
32619d480158SKan Liang #define BDX_PCU_DID			0x6fc0
32629d480158SKan Liang 
3263ed367e6cSBorislav Petkov void bdx_uncore_cpu_init(void)
3264ed367e6cSBorislav Petkov {
3265ed367e6cSBorislav Petkov 	if (bdx_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
3266ed367e6cSBorislav Petkov 		bdx_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
3267ed367e6cSBorislav Petkov 	uncore_msr_uncores = bdx_msr_uncores;
3268bb9fbe1bSKan Liang 
326915a3e845SOskar Senft 	/* Detect systems with no SBOXes */
32709d480158SKan Liang 	if ((boot_cpu_data.x86_model == 86) || hswep_has_limit_sbox(BDX_PCU_DID))
32719d480158SKan Liang 		uncore_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL;
3272d7717587SStephane Eranian 
3273bb9fbe1bSKan Liang 	hswep_uncore_pcu.constraints = bdx_uncore_pcu_constraints;
3274ed367e6cSBorislav Petkov }
3275ed367e6cSBorislav Petkov 
3276ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_ha = {
3277ed367e6cSBorislav Petkov 	.name		= "ha",
3278ed367e6cSBorislav Petkov 	.num_counters   = 4,
3279ed367e6cSBorislav Petkov 	.num_boxes	= 2,
3280ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
3281ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
3282ed367e6cSBorislav Petkov };
3283ed367e6cSBorislav Petkov 
3284ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_imc = {
3285ed367e6cSBorislav Petkov 	.name		= "imc",
328610e9e7bdSKan Liang 	.num_counters   = 4,
3287ed367e6cSBorislav Petkov 	.num_boxes	= 8,
3288ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
3289ed367e6cSBorislav Petkov 	.fixed_ctr_bits	= 48,
3290ed367e6cSBorislav Petkov 	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
3291ed367e6cSBorislav Petkov 	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
3292ed367e6cSBorislav Petkov 	.event_descs	= hswep_uncore_imc_events,
3293ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
3294ed367e6cSBorislav Petkov };
3295ed367e6cSBorislav Petkov 
3296ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_irp = {
3297ed367e6cSBorislav Petkov 	.name			= "irp",
3298ed367e6cSBorislav Petkov 	.num_counters		= 4,
3299ed367e6cSBorislav Petkov 	.num_boxes		= 1,
3300ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
3301ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
3302ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
3303ed367e6cSBorislav Petkov 	.ops			= &hswep_uncore_irp_ops,
3304ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_format_group,
3305ed367e6cSBorislav Petkov };
3306ed367e6cSBorislav Petkov 
3307ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_qpi = {
3308ed367e6cSBorislav Petkov 	.name			= "qpi",
3309ed367e6cSBorislav Petkov 	.num_counters		= 4,
3310ed367e6cSBorislav Petkov 	.num_boxes		= 3,
3311ed367e6cSBorislav Petkov 	.perf_ctr_bits		= 48,
3312ed367e6cSBorislav Petkov 	.perf_ctr		= SNBEP_PCI_PMON_CTR0,
3313ed367e6cSBorislav Petkov 	.event_ctl		= SNBEP_PCI_PMON_CTL0,
3314ed367e6cSBorislav Petkov 	.event_mask		= SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
3315ed367e6cSBorislav Petkov 	.box_ctl		= SNBEP_PCI_PMON_BOX_CTL,
3316ed367e6cSBorislav Petkov 	.num_shared_regs	= 1,
3317ed367e6cSBorislav Petkov 	.ops			= &snbep_uncore_qpi_ops,
3318ed367e6cSBorislav Petkov 	.format_group		= &snbep_uncore_qpi_format_group,
3319ed367e6cSBorislav Petkov };
3320ed367e6cSBorislav Petkov 
3321ed367e6cSBorislav Petkov static struct event_constraint bdx_uncore_r2pcie_constraints[] = {
3322ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
3323ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
3324ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
3325ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x1),
3326ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
3327ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
3328ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
3329ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
3330ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
3331ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
3332ed367e6cSBorislav Petkov };
3333ed367e6cSBorislav Petkov 
3334ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_r2pcie = {
3335ed367e6cSBorislav Petkov 	.name		= "r2pcie",
3336ed367e6cSBorislav Petkov 	.num_counters   = 4,
3337ed367e6cSBorislav Petkov 	.num_boxes	= 1,
3338ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
3339ed367e6cSBorislav Petkov 	.constraints	= bdx_uncore_r2pcie_constraints,
3340ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
3341ed367e6cSBorislav Petkov };
3342ed367e6cSBorislav Petkov 
3343ed367e6cSBorislav Petkov static struct event_constraint bdx_uncore_r3qpi_constraints[] = {
3344ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x01, 0x7),
3345ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x07, 0x7),
3346ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x08, 0x7),
3347ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x09, 0x7),
3348ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x0a, 0x7),
3349ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x0e, 0x7),
3350ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
3351ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
3352ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
3353ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
3354ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x15, 0x3),
3355ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x1f, 0x3),
3356ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
3357ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
3358ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
3359ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
3360ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
3361ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
3362ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
3363ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
3364ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
3365ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
3366ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
3367ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
3368ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
3369ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
3370ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
3371ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
3372ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
3373ed367e6cSBorislav Petkov 	UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
3374ed367e6cSBorislav Petkov 	EVENT_CONSTRAINT_END
3375ed367e6cSBorislav Petkov };
3376ed367e6cSBorislav Petkov 
3377ed367e6cSBorislav Petkov static struct intel_uncore_type bdx_uncore_r3qpi = {
3378ed367e6cSBorislav Petkov 	.name		= "r3qpi",
3379ed367e6cSBorislav Petkov 	.num_counters   = 3,
3380ed367e6cSBorislav Petkov 	.num_boxes	= 3,
3381ed367e6cSBorislav Petkov 	.perf_ctr_bits	= 48,
3382ed367e6cSBorislav Petkov 	.constraints	= bdx_uncore_r3qpi_constraints,
3383ed367e6cSBorislav Petkov 	SNBEP_UNCORE_PCI_COMMON_INIT(),
3384ed367e6cSBorislav Petkov };
3385ed367e6cSBorislav Petkov 
3386ed367e6cSBorislav Petkov enum {
3387ed367e6cSBorislav Petkov 	BDX_PCI_UNCORE_HA,
3388ed367e6cSBorislav Petkov 	BDX_PCI_UNCORE_IMC,
3389ed367e6cSBorislav Petkov 	BDX_PCI_UNCORE_IRP,
3390ed367e6cSBorislav Petkov 	BDX_PCI_UNCORE_QPI,
3391ed367e6cSBorislav Petkov 	BDX_PCI_UNCORE_R2PCIE,
3392ed367e6cSBorislav Petkov 	BDX_PCI_UNCORE_R3QPI,
3393ed367e6cSBorislav Petkov };
3394ed367e6cSBorislav Petkov 
3395ed367e6cSBorislav Petkov static struct intel_uncore_type *bdx_pci_uncores[] = {
3396ed367e6cSBorislav Petkov 	[BDX_PCI_UNCORE_HA]	= &bdx_uncore_ha,
3397ed367e6cSBorislav Petkov 	[BDX_PCI_UNCORE_IMC]	= &bdx_uncore_imc,
3398ed367e6cSBorislav Petkov 	[BDX_PCI_UNCORE_IRP]	= &bdx_uncore_irp,
3399ed367e6cSBorislav Petkov 	[BDX_PCI_UNCORE_QPI]	= &bdx_uncore_qpi,
3400ed367e6cSBorislav Petkov 	[BDX_PCI_UNCORE_R2PCIE]	= &bdx_uncore_r2pcie,
3401ed367e6cSBorislav Petkov 	[BDX_PCI_UNCORE_R3QPI]	= &bdx_uncore_r3qpi,
3402ed367e6cSBorislav Petkov 	NULL,
3403ed367e6cSBorislav Petkov };
3404ed367e6cSBorislav Petkov 
3405ed367e6cSBorislav Petkov static const struct pci_device_id bdx_uncore_pci_ids[] = {
3406ed367e6cSBorislav Petkov 	{ /* Home Agent 0 */
3407ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f30),
3408ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_HA, 0),
3409ed367e6cSBorislav Petkov 	},
3410ed367e6cSBorislav Petkov 	{ /* Home Agent 1 */
3411ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f38),
3412ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_HA, 1),
3413ed367e6cSBorislav Petkov 	},
3414ed367e6cSBorislav Petkov 	{ /* MC0 Channel 0 */
3415ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb0),
3416ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 0),
3417ed367e6cSBorislav Petkov 	},
3418ed367e6cSBorislav Petkov 	{ /* MC0 Channel 1 */
3419ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb1),
3420ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 1),
3421ed367e6cSBorislav Petkov 	},
3422ed367e6cSBorislav Petkov 	{ /* MC0 Channel 2 */
3423ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb4),
3424ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 2),
3425ed367e6cSBorislav Petkov 	},
3426ed367e6cSBorislav Petkov 	{ /* MC0 Channel 3 */
3427ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fb5),
3428ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 3),
3429ed367e6cSBorislav Petkov 	},
3430ed367e6cSBorislav Petkov 	{ /* MC1 Channel 0 */
3431ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fd0),
3432ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 4),
3433ed367e6cSBorislav Petkov 	},
3434ed367e6cSBorislav Petkov 	{ /* MC1 Channel 1 */
3435ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fd1),
3436ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 5),
3437ed367e6cSBorislav Petkov 	},
3438ed367e6cSBorislav Petkov 	{ /* MC1 Channel 2 */
3439ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fd4),
3440ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 6),
3441ed367e6cSBorislav Petkov 	},
3442ed367e6cSBorislav Petkov 	{ /* MC1 Channel 3 */
3443ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fd5),
3444ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IMC, 7),
3445ed367e6cSBorislav Petkov 	},
3446ed367e6cSBorislav Petkov 	{ /* IRP */
3447ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f39),
3448ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_IRP, 0),
3449ed367e6cSBorislav Petkov 	},
3450ed367e6cSBorislav Petkov 	{ /* QPI0 Port 0 */
3451ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f32),
3452ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_QPI, 0),
3453ed367e6cSBorislav Petkov 	},
3454ed367e6cSBorislav Petkov 	{ /* QPI0 Port 1 */
3455ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f33),
3456ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_QPI, 1),
3457ed367e6cSBorislav Petkov 	},
3458ed367e6cSBorislav Petkov 	{ /* QPI1 Port 2 */
3459ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f3a),
3460ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_QPI, 2),
3461ed367e6cSBorislav Petkov 	},
3462ed367e6cSBorislav Petkov 	{ /* R2PCIe */
3463ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f34),
3464ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R2PCIE, 0),
3465ed367e6cSBorislav Petkov 	},
3466ed367e6cSBorislav Petkov 	{ /* R3QPI0 Link 0 */
3467ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f36),
3468ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R3QPI, 0),
3469ed367e6cSBorislav Petkov 	},
3470ed367e6cSBorislav Petkov 	{ /* R3QPI0 Link 1 */
3471ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f37),
3472ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R3QPI, 1),
3473ed367e6cSBorislav Petkov 	},
3474ed367e6cSBorislav Petkov 	{ /* R3QPI1 Link 2 */
3475ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f3e),
3476ed367e6cSBorislav Petkov 		.driver_data = UNCORE_PCI_DEV_DATA(BDX_PCI_UNCORE_R3QPI, 2),
3477ed367e6cSBorislav Petkov 	},
3478ed367e6cSBorislav Petkov 	{ /* QPI Port 0 filter  */
3479ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f86),
3480156c8b58SKan Liang 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
3481156c8b58SKan Liang 						   SNBEP_PCI_QPI_PORT0_FILTER),
3482ed367e6cSBorislav Petkov 	},
3483ed367e6cSBorislav Petkov 	{ /* QPI Port 1 filter  */
3484ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f96),
3485156c8b58SKan Liang 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
3486156c8b58SKan Liang 						   SNBEP_PCI_QPI_PORT1_FILTER),
3487ed367e6cSBorislav Petkov 	},
3488ed367e6cSBorislav Petkov 	{ /* QPI Port 2 filter  */
3489ed367e6cSBorislav Petkov 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f46),
3490156c8b58SKan Liang 		.driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
3491156c8b58SKan Liang 						   BDX_PCI_QPI_PORT2_FILTER),
3492ed367e6cSBorislav Petkov 	},
3493ed367e6cSBorislav Petkov 	{ /* end: all zeroes */ }
3494ed367e6cSBorislav Petkov };
3495ed367e6cSBorislav Petkov 
3496ed367e6cSBorislav Petkov static struct pci_driver bdx_uncore_pci_driver = {
3497ed367e6cSBorislav Petkov 	.name		= "bdx_uncore",
3498ed367e6cSBorislav Petkov 	.id_table	= bdx_uncore_pci_ids,
3499ed367e6cSBorislav Petkov };
3500ed367e6cSBorislav Petkov 
3501ed367e6cSBorislav Petkov int bdx_uncore_pci_init(void)
3502ed367e6cSBorislav Petkov {
350368ce4a0dSKan Liang 	int ret = snbep_pci2phy_map_init(0x6f1e, SNBEP_CPUNODEID, SNBEP_GIDNIDMAP, true);
3504ed367e6cSBorislav Petkov 
3505ed367e6cSBorislav Petkov 	if (ret)
3506ed367e6cSBorislav Petkov 		return ret;
3507ed367e6cSBorislav Petkov 	uncore_pci_uncores = bdx_pci_uncores;
3508ed367e6cSBorislav Petkov 	uncore_pci_driver = &bdx_uncore_pci_driver;
3509ed367e6cSBorislav Petkov 	return 0;
3510ed367e6cSBorislav Petkov }
3511ed367e6cSBorislav Petkov 
3512ed367e6cSBorislav Petkov /* end of BDX uncore support */
3513cd34cd97SKan Liang 
3514cd34cd97SKan Liang /* SKX uncore support */
3515cd34cd97SKan Liang 
3516cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_ubox = {
3517cd34cd97SKan Liang 	.name			= "ubox",
3518cd34cd97SKan Liang 	.num_counters		= 2,
3519cd34cd97SKan Liang 	.num_boxes		= 1,
3520cd34cd97SKan Liang 	.perf_ctr_bits		= 48,
3521cd34cd97SKan Liang 	.fixed_ctr_bits		= 48,
3522cd34cd97SKan Liang 	.perf_ctr		= HSWEP_U_MSR_PMON_CTR0,
3523cd34cd97SKan Liang 	.event_ctl		= HSWEP_U_MSR_PMON_CTL0,
3524cd34cd97SKan Liang 	.event_mask		= SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
3525cd34cd97SKan Liang 	.fixed_ctr		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTR,
3526cd34cd97SKan Liang 	.fixed_ctl		= HSWEP_U_MSR_PMON_UCLK_FIXED_CTL,
3527cd34cd97SKan Liang 	.ops			= &ivbep_uncore_msr_ops,
3528cd34cd97SKan Liang 	.format_group		= &ivbep_uncore_ubox_format_group,
3529cd34cd97SKan Liang };
3530cd34cd97SKan Liang 
3531cd34cd97SKan Liang static struct attribute *skx_uncore_cha_formats_attr[] = {
3532cd34cd97SKan Liang 	&format_attr_event.attr,
3533cd34cd97SKan Liang 	&format_attr_umask.attr,
3534cd34cd97SKan Liang 	&format_attr_edge.attr,
3535cd34cd97SKan Liang 	&format_attr_tid_en.attr,
3536cd34cd97SKan Liang 	&format_attr_inv.attr,
3537cd34cd97SKan Liang 	&format_attr_thresh8.attr,
3538cd34cd97SKan Liang 	&format_attr_filter_tid4.attr,
3539cd34cd97SKan Liang 	&format_attr_filter_state5.attr,
3540cd34cd97SKan Liang 	&format_attr_filter_rem.attr,
3541cd34cd97SKan Liang 	&format_attr_filter_loc.attr,
3542cd34cd97SKan Liang 	&format_attr_filter_nm.attr,
3543cd34cd97SKan Liang 	&format_attr_filter_all_op.attr,
3544cd34cd97SKan Liang 	&format_attr_filter_not_nm.attr,
3545cd34cd97SKan Liang 	&format_attr_filter_opc_0.attr,
3546cd34cd97SKan Liang 	&format_attr_filter_opc_1.attr,
3547cd34cd97SKan Liang 	&format_attr_filter_nc.attr,
3548cd34cd97SKan Liang 	&format_attr_filter_isoc.attr,
3549cd34cd97SKan Liang 	NULL,
3550cd34cd97SKan Liang };
3551cd34cd97SKan Liang 
355245bd07adSArvind Yadav static const struct attribute_group skx_uncore_chabox_format_group = {
3553cd34cd97SKan Liang 	.name = "format",
3554cd34cd97SKan Liang 	.attrs = skx_uncore_cha_formats_attr,
3555cd34cd97SKan Liang };
3556cd34cd97SKan Liang 
3557cd34cd97SKan Liang static struct event_constraint skx_uncore_chabox_constraints[] = {
3558cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
3559cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
3560cd34cd97SKan Liang 	EVENT_CONSTRAINT_END
3561cd34cd97SKan Liang };
3562cd34cd97SKan Liang 
3563cd34cd97SKan Liang static struct extra_reg skx_uncore_cha_extra_regs[] = {
3564cd34cd97SKan Liang 	SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4),
3565cd34cd97SKan Liang 	SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
3566cd34cd97SKan Liang 	SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
3567cd34cd97SKan Liang 	SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4),
3568c3f02682SKan Liang 	SNBEP_CBO_EVENT_EXTRA_REG(0x3134, 0xffff, 0x4),
3569c3f02682SKan Liang 	SNBEP_CBO_EVENT_EXTRA_REG(0x9134, 0xffff, 0x4),
35708aa7b7b4SStephane Eranian 	SNBEP_CBO_EVENT_EXTRA_REG(0x35, 0xff, 0x8),
35718aa7b7b4SStephane Eranian 	SNBEP_CBO_EVENT_EXTRA_REG(0x36, 0xff, 0x8),
3572e340895cSStephane Eranian 	SNBEP_CBO_EVENT_EXTRA_REG(0x38, 0xff, 0x3),
3573ba883b4aSStephane Eranian 	EVENT_EXTRA_END
3574cd34cd97SKan Liang };
3575cd34cd97SKan Liang 
3576cd34cd97SKan Liang static u64 skx_cha_filter_mask(int fields)
3577cd34cd97SKan Liang {
3578cd34cd97SKan Liang 	u64 mask = 0;
3579cd34cd97SKan Liang 
3580cd34cd97SKan Liang 	if (fields & 0x1)
3581cd34cd97SKan Liang 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_TID;
3582cd34cd97SKan Liang 	if (fields & 0x2)
3583cd34cd97SKan Liang 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_LINK;
3584cd34cd97SKan Liang 	if (fields & 0x4)
3585cd34cd97SKan Liang 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_STATE;
35868aa7b7b4SStephane Eranian 	if (fields & 0x8) {
35878aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_REM;
35888aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_LOC;
35898aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_ALL_OPC;
35908aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_NM;
35918aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_NOT_NM;
35928aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_OPC0;
35938aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_OPC1;
35948aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_NC;
35958aa7b7b4SStephane Eranian 		mask |= SKX_CHA_MSR_PMON_BOX_FILTER_ISOC;
35968aa7b7b4SStephane Eranian 	}
3597cd34cd97SKan Liang 	return mask;
3598cd34cd97SKan Liang }
3599cd34cd97SKan Liang 
3600cd34cd97SKan Liang static struct event_constraint *
3601cd34cd97SKan Liang skx_cha_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
3602cd34cd97SKan Liang {
3603cd34cd97SKan Liang 	return __snbep_cbox_get_constraint(box, event, skx_cha_filter_mask);
3604cd34cd97SKan Liang }
3605cd34cd97SKan Liang 
3606cd34cd97SKan Liang static int skx_cha_hw_config(struct intel_uncore_box *box, struct perf_event *event)
3607cd34cd97SKan Liang {
3608cd34cd97SKan Liang 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
3609cd34cd97SKan Liang 	struct extra_reg *er;
3610cd34cd97SKan Liang 	int idx = 0;
3611cd34cd97SKan Liang 
3612cd34cd97SKan Liang 	for (er = skx_uncore_cha_extra_regs; er->msr; er++) {
3613cd34cd97SKan Liang 		if (er->event != (event->hw.config & er->config_mask))
3614cd34cd97SKan Liang 			continue;
3615cd34cd97SKan Liang 		idx |= er->idx;
3616cd34cd97SKan Liang 	}
3617cd34cd97SKan Liang 
3618cd34cd97SKan Liang 	if (idx) {
3619cd34cd97SKan Liang 		reg1->reg = HSWEP_C0_MSR_PMON_BOX_FILTER0 +
3620cd34cd97SKan Liang 			    HSWEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
3621cd34cd97SKan Liang 		reg1->config = event->attr.config1 & skx_cha_filter_mask(idx);
3622cd34cd97SKan Liang 		reg1->idx = idx;
3623cd34cd97SKan Liang 	}
3624cd34cd97SKan Liang 	return 0;
3625cd34cd97SKan Liang }
3626cd34cd97SKan Liang 
3627cd34cd97SKan Liang static struct intel_uncore_ops skx_uncore_chabox_ops = {
3628cd34cd97SKan Liang 	/* There is no frz_en for chabox ctl */
3629cd34cd97SKan Liang 	.init_box		= ivbep_uncore_msr_init_box,
3630cd34cd97SKan Liang 	.disable_box		= snbep_uncore_msr_disable_box,
3631cd34cd97SKan Liang 	.enable_box		= snbep_uncore_msr_enable_box,
3632cd34cd97SKan Liang 	.disable_event		= snbep_uncore_msr_disable_event,
3633cd34cd97SKan Liang 	.enable_event		= hswep_cbox_enable_event,
3634cd34cd97SKan Liang 	.read_counter		= uncore_msr_read_counter,
3635cd34cd97SKan Liang 	.hw_config		= skx_cha_hw_config,
3636cd34cd97SKan Liang 	.get_constraint		= skx_cha_get_constraint,
3637cd34cd97SKan Liang 	.put_constraint		= snbep_cbox_put_constraint,
3638cd34cd97SKan Liang };
3639cd34cd97SKan Liang 
3640cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_chabox = {
3641cd34cd97SKan Liang 	.name			= "cha",
3642cd34cd97SKan Liang 	.num_counters		= 4,
3643cd34cd97SKan Liang 	.perf_ctr_bits		= 48,
3644cd34cd97SKan Liang 	.event_ctl		= HSWEP_C0_MSR_PMON_CTL0,
3645cd34cd97SKan Liang 	.perf_ctr		= HSWEP_C0_MSR_PMON_CTR0,
3646cd34cd97SKan Liang 	.event_mask		= HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
3647cd34cd97SKan Liang 	.box_ctl		= HSWEP_C0_MSR_PMON_BOX_CTL,
3648cd34cd97SKan Liang 	.msr_offset		= HSWEP_CBO_MSR_OFFSET,
3649cd34cd97SKan Liang 	.num_shared_regs	= 1,
3650cd34cd97SKan Liang 	.constraints		= skx_uncore_chabox_constraints,
3651cd34cd97SKan Liang 	.ops			= &skx_uncore_chabox_ops,
3652cd34cd97SKan Liang 	.format_group		= &skx_uncore_chabox_format_group,
3653cd34cd97SKan Liang };
3654cd34cd97SKan Liang 
3655cd34cd97SKan Liang static struct attribute *skx_uncore_iio_formats_attr[] = {
3656cd34cd97SKan Liang 	&format_attr_event.attr,
3657cd34cd97SKan Liang 	&format_attr_umask.attr,
3658cd34cd97SKan Liang 	&format_attr_edge.attr,
3659cd34cd97SKan Liang 	&format_attr_inv.attr,
3660cd34cd97SKan Liang 	&format_attr_thresh9.attr,
3661cd34cd97SKan Liang 	&format_attr_ch_mask.attr,
3662cd34cd97SKan Liang 	&format_attr_fc_mask.attr,
3663cd34cd97SKan Liang 	NULL,
3664cd34cd97SKan Liang };
3665cd34cd97SKan Liang 
366645bd07adSArvind Yadav static const struct attribute_group skx_uncore_iio_format_group = {
3667cd34cd97SKan Liang 	.name = "format",
3668cd34cd97SKan Liang 	.attrs = skx_uncore_iio_formats_attr,
3669cd34cd97SKan Liang };
3670cd34cd97SKan Liang 
3671cd34cd97SKan Liang static struct event_constraint skx_uncore_iio_constraints[] = {
3672cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x83, 0x3),
3673cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x88, 0xc),
3674cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x95, 0xc),
3675cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0xc0, 0xc),
3676cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0xc5, 0xc),
3677cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0xd4, 0xc),
3678cd34cd97SKan Liang 	EVENT_CONSTRAINT_END
3679cd34cd97SKan Liang };
3680cd34cd97SKan Liang 
3681cd34cd97SKan Liang static void skx_iio_enable_event(struct intel_uncore_box *box,
3682cd34cd97SKan Liang 				 struct perf_event *event)
3683cd34cd97SKan Liang {
3684cd34cd97SKan Liang 	struct hw_perf_event *hwc = &event->hw;
3685cd34cd97SKan Liang 
3686cd34cd97SKan Liang 	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
3687cd34cd97SKan Liang }
3688cd34cd97SKan Liang 
3689cd34cd97SKan Liang static struct intel_uncore_ops skx_uncore_iio_ops = {
3690cd34cd97SKan Liang 	.init_box		= ivbep_uncore_msr_init_box,
3691cd34cd97SKan Liang 	.disable_box		= snbep_uncore_msr_disable_box,
3692cd34cd97SKan Liang 	.enable_box		= snbep_uncore_msr_enable_box,
3693cd34cd97SKan Liang 	.disable_event		= snbep_uncore_msr_disable_event,
3694cd34cd97SKan Liang 	.enable_event		= skx_iio_enable_event,
3695cd34cd97SKan Liang 	.read_counter		= uncore_msr_read_counter,
3696cd34cd97SKan Liang };
3697cd34cd97SKan Liang 
3698bb42b3d3SRoman Sudarikov static inline u8 skx_iio_stack(struct intel_uncore_pmu *pmu, int die)
3699bb42b3d3SRoman Sudarikov {
3700cface032SAlexander Antonov 	return pmu->type->topology[die].configuration >>
3701cface032SAlexander Antonov 	       (pmu->pmu_idx * BUS_NUM_STRIDE);
3702bb42b3d3SRoman Sudarikov }
3703bb42b3d3SRoman Sudarikov 
3704bb42b3d3SRoman Sudarikov static umode_t
3705f471fac7SAlexander Antonov pmu_iio_mapping_visible(struct kobject *kobj, struct attribute *attr,
3706f471fac7SAlexander Antonov 			 int die, int zero_bus_pmu)
3707bb42b3d3SRoman Sudarikov {
3708bb42b3d3SRoman Sudarikov 	struct intel_uncore_pmu *pmu = dev_to_uncore_pmu(kobj_to_dev(kobj));
3709bb42b3d3SRoman Sudarikov 
3710f471fac7SAlexander Antonov 	return (!skx_iio_stack(pmu, die) && pmu->pmu_idx != zero_bus_pmu) ? 0 : attr->mode;
3711f471fac7SAlexander Antonov }
3712f471fac7SAlexander Antonov 
3713f471fac7SAlexander Antonov static umode_t
3714f471fac7SAlexander Antonov skx_iio_mapping_visible(struct kobject *kobj, struct attribute *attr, int die)
3715f471fac7SAlexander Antonov {
3716f471fac7SAlexander Antonov 	/* Root bus 0x00 is valid only for pmu_idx = 0. */
3717f471fac7SAlexander Antonov 	return pmu_iio_mapping_visible(kobj, attr, die, 0);
3718bb42b3d3SRoman Sudarikov }
3719bb42b3d3SRoman Sudarikov 
3720bb42b3d3SRoman Sudarikov static ssize_t skx_iio_mapping_show(struct device *dev,
3721bb42b3d3SRoman Sudarikov 				    struct device_attribute *attr, char *buf)
3722bb42b3d3SRoman Sudarikov {
3723cface032SAlexander Antonov 	struct intel_uncore_pmu *pmu = dev_to_uncore_pmu(dev);
3724bb42b3d3SRoman Sudarikov 	struct dev_ext_attribute *ea = to_dev_ext_attribute(attr);
3725bb42b3d3SRoman Sudarikov 	long die = (long)ea->var;
3726bb42b3d3SRoman Sudarikov 
3727cface032SAlexander Antonov 	return sprintf(buf, "%04x:%02x\n", pmu->type->topology[die].segment,
3728cface032SAlexander Antonov 					   skx_iio_stack(pmu, die));
3729bb42b3d3SRoman Sudarikov }
3730bb42b3d3SRoman Sudarikov 
3731bb42b3d3SRoman Sudarikov static int skx_msr_cpu_bus_read(int cpu, u64 *topology)
3732bb42b3d3SRoman Sudarikov {
3733bb42b3d3SRoman Sudarikov 	u64 msr_value;
3734bb42b3d3SRoman Sudarikov 
3735bb42b3d3SRoman Sudarikov 	if (rdmsrl_on_cpu(cpu, SKX_MSR_CPU_BUS_NUMBER, &msr_value) ||
3736bb42b3d3SRoman Sudarikov 			!(msr_value & SKX_MSR_CPU_BUS_VALID_BIT))
3737bb42b3d3SRoman Sudarikov 		return -ENXIO;
3738bb42b3d3SRoman Sudarikov 
3739bb42b3d3SRoman Sudarikov 	*topology = msr_value;
3740bb42b3d3SRoman Sudarikov 
3741bb42b3d3SRoman Sudarikov 	return 0;
3742bb42b3d3SRoman Sudarikov }
3743bb42b3d3SRoman Sudarikov 
3744bb42b3d3SRoman Sudarikov static int die_to_cpu(int die)
3745bb42b3d3SRoman Sudarikov {
3746bb42b3d3SRoman Sudarikov 	int res = 0, cpu, current_die;
3747bb42b3d3SRoman Sudarikov 	/*
3748bb42b3d3SRoman Sudarikov 	 * Using cpus_read_lock() to ensure cpu is not going down between
3749bb42b3d3SRoman Sudarikov 	 * looking at cpu_online_mask.
3750bb42b3d3SRoman Sudarikov 	 */
3751bb42b3d3SRoman Sudarikov 	cpus_read_lock();
3752bb42b3d3SRoman Sudarikov 	for_each_online_cpu(cpu) {
3753bb42b3d3SRoman Sudarikov 		current_die = topology_logical_die_id(cpu);
3754bb42b3d3SRoman Sudarikov 		if (current_die == die) {
3755bb42b3d3SRoman Sudarikov 			res = cpu;
3756bb42b3d3SRoman Sudarikov 			break;
3757bb42b3d3SRoman Sudarikov 		}
3758bb42b3d3SRoman Sudarikov 	}
3759bb42b3d3SRoman Sudarikov 	cpus_read_unlock();
3760bb42b3d3SRoman Sudarikov 	return res;
3761bb42b3d3SRoman Sudarikov }
3762bb42b3d3SRoman Sudarikov 
3763bb42b3d3SRoman Sudarikov static int skx_iio_get_topology(struct intel_uncore_type *type)
3764bb42b3d3SRoman Sudarikov {
3765cface032SAlexander Antonov 	int die, ret = -EPERM;
3766bb42b3d3SRoman Sudarikov 
3767cface032SAlexander Antonov 	type->topology = kcalloc(uncore_max_dies(), sizeof(*type->topology),
3768cface032SAlexander Antonov 				 GFP_KERNEL);
3769bb42b3d3SRoman Sudarikov 	if (!type->topology)
3770bb42b3d3SRoman Sudarikov 		return -ENOMEM;
3771bb42b3d3SRoman Sudarikov 
3772cface032SAlexander Antonov 	for (die = 0; die < uncore_max_dies(); die++) {
3773cface032SAlexander Antonov 		ret = skx_msr_cpu_bus_read(die_to_cpu(die),
3774cface032SAlexander Antonov 					   &type->topology[die].configuration);
3775cface032SAlexander Antonov 		if (ret)
3776cface032SAlexander Antonov 			break;
3777cface032SAlexander Antonov 
3778cface032SAlexander Antonov 		ret = uncore_die_to_segment(die);
3779cface032SAlexander Antonov 		if (ret < 0)
3780cface032SAlexander Antonov 			break;
3781cface032SAlexander Antonov 
3782cface032SAlexander Antonov 		type->topology[die].segment = ret;
3783bb42b3d3SRoman Sudarikov 	}
3784bb42b3d3SRoman Sudarikov 
3785cface032SAlexander Antonov 	if (ret < 0) {
3786cface032SAlexander Antonov 		kfree(type->topology);
3787cface032SAlexander Antonov 		type->topology = NULL;
3788cface032SAlexander Antonov 	}
3789cface032SAlexander Antonov 
3790cface032SAlexander Antonov 	return ret;
3791bb42b3d3SRoman Sudarikov }
3792bb42b3d3SRoman Sudarikov 
3793bb42b3d3SRoman Sudarikov static struct attribute_group skx_iio_mapping_group = {
3794bb42b3d3SRoman Sudarikov 	.is_visible	= skx_iio_mapping_visible,
3795bb42b3d3SRoman Sudarikov };
3796bb42b3d3SRoman Sudarikov 
3797bb42b3d3SRoman Sudarikov static const struct attribute_group *skx_iio_attr_update[] = {
3798bb42b3d3SRoman Sudarikov 	&skx_iio_mapping_group,
3799bb42b3d3SRoman Sudarikov 	NULL,
3800bb42b3d3SRoman Sudarikov };
3801bb42b3d3SRoman Sudarikov 
3802f471fac7SAlexander Antonov static int
3803f471fac7SAlexander Antonov pmu_iio_set_mapping(struct intel_uncore_type *type, struct attribute_group *ag)
3804bb42b3d3SRoman Sudarikov {
3805bb42b3d3SRoman Sudarikov 	char buf[64];
3806bb42b3d3SRoman Sudarikov 	int ret;
3807bb42b3d3SRoman Sudarikov 	long die = -1;
3808bb42b3d3SRoman Sudarikov 	struct attribute **attrs = NULL;
3809bb42b3d3SRoman Sudarikov 	struct dev_ext_attribute *eas = NULL;
3810bb42b3d3SRoman Sudarikov 
3811f471fac7SAlexander Antonov 	ret = type->get_topology(type);
3812cface032SAlexander Antonov 	if (ret < 0)
3813f797f05dSAlexander Antonov 		goto clear_attr_update;
3814f797f05dSAlexander Antonov 
3815f797f05dSAlexander Antonov 	ret = -ENOMEM;
3816bb42b3d3SRoman Sudarikov 
3817bb42b3d3SRoman Sudarikov 	/* One more for NULL. */
3818bb42b3d3SRoman Sudarikov 	attrs = kcalloc((uncore_max_dies() + 1), sizeof(*attrs), GFP_KERNEL);
3819bb42b3d3SRoman Sudarikov 	if (!attrs)
3820d4ba0b06SKan Liang 		goto clear_topology;
3821bb42b3d3SRoman Sudarikov 
3822bb42b3d3SRoman Sudarikov 	eas = kcalloc(uncore_max_dies(), sizeof(*eas), GFP_KERNEL);
3823bb42b3d3SRoman Sudarikov 	if (!eas)
3824d4ba0b06SKan Liang 		goto clear_attrs;
3825bb42b3d3SRoman Sudarikov 
3826bb42b3d3SRoman Sudarikov 	for (die = 0; die < uncore_max_dies(); die++) {
3827bb42b3d3SRoman Sudarikov 		sprintf(buf, "die%ld", die);
3828bb42b3d3SRoman Sudarikov 		sysfs_attr_init(&eas[die].attr.attr);
3829bb42b3d3SRoman Sudarikov 		eas[die].attr.attr.name = kstrdup(buf, GFP_KERNEL);
3830bb42b3d3SRoman Sudarikov 		if (!eas[die].attr.attr.name)
3831bb42b3d3SRoman Sudarikov 			goto err;
3832bb42b3d3SRoman Sudarikov 		eas[die].attr.attr.mode = 0444;
3833bb42b3d3SRoman Sudarikov 		eas[die].attr.show = skx_iio_mapping_show;
3834bb42b3d3SRoman Sudarikov 		eas[die].attr.store = NULL;
3835bb42b3d3SRoman Sudarikov 		eas[die].var = (void *)die;
3836bb42b3d3SRoman Sudarikov 		attrs[die] = &eas[die].attr.attr;
3837bb42b3d3SRoman Sudarikov 	}
3838f471fac7SAlexander Antonov 	ag->attrs = attrs;
3839bb42b3d3SRoman Sudarikov 
3840bb42b3d3SRoman Sudarikov 	return 0;
3841bb42b3d3SRoman Sudarikov err:
3842bb42b3d3SRoman Sudarikov 	for (; die >= 0; die--)
3843bb42b3d3SRoman Sudarikov 		kfree(eas[die].attr.attr.name);
3844bb42b3d3SRoman Sudarikov 	kfree(eas);
3845d4ba0b06SKan Liang clear_attrs:
3846bb42b3d3SRoman Sudarikov 	kfree(attrs);
3847d4ba0b06SKan Liang clear_topology:
3848bb42b3d3SRoman Sudarikov 	kfree(type->topology);
3849f797f05dSAlexander Antonov clear_attr_update:
3850bb42b3d3SRoman Sudarikov 	type->attr_update = NULL;
3851f797f05dSAlexander Antonov 	return ret;
3852bb42b3d3SRoman Sudarikov }
3853bb42b3d3SRoman Sudarikov 
38543f2cbe38SAlexander Antonov static void
38553f2cbe38SAlexander Antonov pmu_iio_cleanup_mapping(struct intel_uncore_type *type, struct attribute_group *ag)
38563f2cbe38SAlexander Antonov {
38573f2cbe38SAlexander Antonov 	struct attribute **attr = ag->attrs;
38583f2cbe38SAlexander Antonov 
38593f2cbe38SAlexander Antonov 	if (!attr)
38603f2cbe38SAlexander Antonov 		return;
38613f2cbe38SAlexander Antonov 
38623f2cbe38SAlexander Antonov 	for (; *attr; attr++)
38633f2cbe38SAlexander Antonov 		kfree((*attr)->name);
38643f2cbe38SAlexander Antonov 	kfree(attr_to_ext_attr(*ag->attrs));
38653f2cbe38SAlexander Antonov 	kfree(ag->attrs);
38663f2cbe38SAlexander Antonov 	ag->attrs = NULL;
38673f2cbe38SAlexander Antonov 	kfree(type->topology);
38683f2cbe38SAlexander Antonov }
38693f2cbe38SAlexander Antonov 
3870f471fac7SAlexander Antonov static int skx_iio_set_mapping(struct intel_uncore_type *type)
3871f471fac7SAlexander Antonov {
3872f471fac7SAlexander Antonov 	return pmu_iio_set_mapping(type, &skx_iio_mapping_group);
3873f471fac7SAlexander Antonov }
3874f471fac7SAlexander Antonov 
3875bb42b3d3SRoman Sudarikov static void skx_iio_cleanup_mapping(struct intel_uncore_type *type)
3876bb42b3d3SRoman Sudarikov {
38773f2cbe38SAlexander Antonov 	pmu_iio_cleanup_mapping(type, &skx_iio_mapping_group);
3878bb42b3d3SRoman Sudarikov }
3879bb42b3d3SRoman Sudarikov 
3880cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_iio = {
3881cd34cd97SKan Liang 	.name			= "iio",
3882cd34cd97SKan Liang 	.num_counters		= 4,
388329b46dfbSKan Liang 	.num_boxes		= 6,
3884cd34cd97SKan Liang 	.perf_ctr_bits		= 48,
3885cd34cd97SKan Liang 	.event_ctl		= SKX_IIO0_MSR_PMON_CTL0,
3886cd34cd97SKan Liang 	.perf_ctr		= SKX_IIO0_MSR_PMON_CTR0,
3887cd34cd97SKan Liang 	.event_mask		= SKX_IIO_PMON_RAW_EVENT_MASK,
3888cd34cd97SKan Liang 	.event_mask_ext		= SKX_IIO_PMON_RAW_EVENT_MASK_EXT,
3889cd34cd97SKan Liang 	.box_ctl		= SKX_IIO0_MSR_PMON_BOX_CTL,
3890cd34cd97SKan Liang 	.msr_offset		= SKX_IIO_MSR_OFFSET,
3891cd34cd97SKan Liang 	.constraints		= skx_uncore_iio_constraints,
3892cd34cd97SKan Liang 	.ops			= &skx_uncore_iio_ops,
3893cd34cd97SKan Liang 	.format_group		= &skx_uncore_iio_format_group,
3894bb42b3d3SRoman Sudarikov 	.attr_update		= skx_iio_attr_update,
3895f471fac7SAlexander Antonov 	.get_topology		= skx_iio_get_topology,
3896bb42b3d3SRoman Sudarikov 	.set_mapping		= skx_iio_set_mapping,
3897bb42b3d3SRoman Sudarikov 	.cleanup_mapping	= skx_iio_cleanup_mapping,
3898cd34cd97SKan Liang };
3899cd34cd97SKan Liang 
39000f519f03SKan Liang enum perf_uncore_iio_freerunning_type_id {
39010f519f03SKan Liang 	SKX_IIO_MSR_IOCLK			= 0,
39020f519f03SKan Liang 	SKX_IIO_MSR_BW				= 1,
39030f519f03SKan Liang 	SKX_IIO_MSR_UTIL			= 2,
39040f519f03SKan Liang 
39050f519f03SKan Liang 	SKX_IIO_FREERUNNING_TYPE_MAX,
39060f519f03SKan Liang };
39070f519f03SKan Liang 
39080f519f03SKan Liang 
39090f519f03SKan Liang static struct freerunning_counters skx_iio_freerunning[] = {
39100f519f03SKan Liang 	[SKX_IIO_MSR_IOCLK]	= { 0xa45, 0x1, 0x20, 1, 36 },
39110f519f03SKan Liang 	[SKX_IIO_MSR_BW]	= { 0xb00, 0x1, 0x10, 8, 36 },
39120f519f03SKan Liang 	[SKX_IIO_MSR_UTIL]	= { 0xb08, 0x1, 0x10, 8, 36 },
39130f519f03SKan Liang };
39140f519f03SKan Liang 
39150f519f03SKan Liang static struct uncore_event_desc skx_uncore_iio_freerunning_events[] = {
39160f519f03SKan Liang 	/* Free-Running IO CLOCKS Counter */
39170f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(ioclk,			"event=0xff,umask=0x10"),
39180f519f03SKan Liang 	/* Free-Running IIO BANDWIDTH Counters */
39190f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0,		"event=0xff,umask=0x20"),
39200f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale,	"3.814697266e-6"),
39210f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit,	"MiB"),
39220f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1,		"event=0xff,umask=0x21"),
39230f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale,	"3.814697266e-6"),
39240f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit,	"MiB"),
39250f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2,		"event=0xff,umask=0x22"),
39260f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale,	"3.814697266e-6"),
39270f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit,	"MiB"),
39280f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3,		"event=0xff,umask=0x23"),
39290f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale,	"3.814697266e-6"),
39300f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit,	"MiB"),
39310f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port0,		"event=0xff,umask=0x24"),
39320f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port0.scale,	"3.814697266e-6"),
39330f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port0.unit,	"MiB"),
39340f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port1,		"event=0xff,umask=0x25"),
39350f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port1.scale,	"3.814697266e-6"),
39360f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port1.unit,	"MiB"),
39370f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port2,		"event=0xff,umask=0x26"),
39380f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port2.scale,	"3.814697266e-6"),
39390f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port2.unit,	"MiB"),
39400f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port3,		"event=0xff,umask=0x27"),
39410f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port3.scale,	"3.814697266e-6"),
39420f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port3.unit,	"MiB"),
39430f519f03SKan Liang 	/* Free-running IIO UTILIZATION Counters */
39440f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_in_port0,		"event=0xff,umask=0x30"),
39450f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_out_port0,		"event=0xff,umask=0x31"),
39460f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_in_port1,		"event=0xff,umask=0x32"),
39470f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_out_port1,		"event=0xff,umask=0x33"),
39480f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_in_port2,		"event=0xff,umask=0x34"),
39490f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_out_port2,		"event=0xff,umask=0x35"),
39500f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_in_port3,		"event=0xff,umask=0x36"),
39510f519f03SKan Liang 	INTEL_UNCORE_EVENT_DESC(util_out_port3,		"event=0xff,umask=0x37"),
39520f519f03SKan Liang 	{ /* end: all zeroes */ },
39530f519f03SKan Liang };
39540f519f03SKan Liang 
39550f519f03SKan Liang static struct intel_uncore_ops skx_uncore_iio_freerunning_ops = {
39560f519f03SKan Liang 	.read_counter		= uncore_msr_read_counter,
3957543ac280SKan Liang 	.hw_config		= uncore_freerunning_hw_config,
39580f519f03SKan Liang };
39590f519f03SKan Liang 
39600f519f03SKan Liang static struct attribute *skx_uncore_iio_freerunning_formats_attr[] = {
39610f519f03SKan Liang 	&format_attr_event.attr,
39620f519f03SKan Liang 	&format_attr_umask.attr,
39630f519f03SKan Liang 	NULL,
39640f519f03SKan Liang };
39650f519f03SKan Liang 
39660f519f03SKan Liang static const struct attribute_group skx_uncore_iio_freerunning_format_group = {
39670f519f03SKan Liang 	.name = "format",
39680f519f03SKan Liang 	.attrs = skx_uncore_iio_freerunning_formats_attr,
39690f519f03SKan Liang };
39700f519f03SKan Liang 
39710f519f03SKan Liang static struct intel_uncore_type skx_uncore_iio_free_running = {
39720f519f03SKan Liang 	.name			= "iio_free_running",
39730f519f03SKan Liang 	.num_counters		= 17,
39740f519f03SKan Liang 	.num_boxes		= 6,
39750f519f03SKan Liang 	.num_freerunning_types	= SKX_IIO_FREERUNNING_TYPE_MAX,
39760f519f03SKan Liang 	.freerunning		= skx_iio_freerunning,
39770f519f03SKan Liang 	.ops			= &skx_uncore_iio_freerunning_ops,
39780f519f03SKan Liang 	.event_descs		= skx_uncore_iio_freerunning_events,
39790f519f03SKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
39800f519f03SKan Liang };
39810f519f03SKan Liang 
3982cd34cd97SKan Liang static struct attribute *skx_uncore_formats_attr[] = {
3983cd34cd97SKan Liang 	&format_attr_event.attr,
3984cd34cd97SKan Liang 	&format_attr_umask.attr,
3985cd34cd97SKan Liang 	&format_attr_edge.attr,
3986cd34cd97SKan Liang 	&format_attr_inv.attr,
3987cd34cd97SKan Liang 	&format_attr_thresh8.attr,
3988cd34cd97SKan Liang 	NULL,
3989cd34cd97SKan Liang };
3990cd34cd97SKan Liang 
399145bd07adSArvind Yadav static const struct attribute_group skx_uncore_format_group = {
3992cd34cd97SKan Liang 	.name = "format",
3993cd34cd97SKan Liang 	.attrs = skx_uncore_formats_attr,
3994cd34cd97SKan Liang };
3995cd34cd97SKan Liang 
3996cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_irp = {
3997cd34cd97SKan Liang 	.name			= "irp",
3998cd34cd97SKan Liang 	.num_counters		= 2,
399929b46dfbSKan Liang 	.num_boxes		= 6,
4000cd34cd97SKan Liang 	.perf_ctr_bits		= 48,
4001cd34cd97SKan Liang 	.event_ctl		= SKX_IRP0_MSR_PMON_CTL0,
4002cd34cd97SKan Liang 	.perf_ctr		= SKX_IRP0_MSR_PMON_CTR0,
4003cd34cd97SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
4004cd34cd97SKan Liang 	.box_ctl		= SKX_IRP0_MSR_PMON_BOX_CTL,
4005cd34cd97SKan Liang 	.msr_offset		= SKX_IRP_MSR_OFFSET,
4006cd34cd97SKan Liang 	.ops			= &skx_uncore_iio_ops,
4007cd34cd97SKan Liang 	.format_group		= &skx_uncore_format_group,
4008cd34cd97SKan Liang };
4009cd34cd97SKan Liang 
4010bab4e569SKan Liang static struct attribute *skx_uncore_pcu_formats_attr[] = {
4011bab4e569SKan Liang 	&format_attr_event.attr,
4012bab4e569SKan Liang 	&format_attr_umask.attr,
4013bab4e569SKan Liang 	&format_attr_edge.attr,
4014bab4e569SKan Liang 	&format_attr_inv.attr,
4015bab4e569SKan Liang 	&format_attr_thresh8.attr,
4016bab4e569SKan Liang 	&format_attr_occ_invert.attr,
4017bab4e569SKan Liang 	&format_attr_occ_edge_det.attr,
4018bab4e569SKan Liang 	&format_attr_filter_band0.attr,
4019bab4e569SKan Liang 	&format_attr_filter_band1.attr,
4020bab4e569SKan Liang 	&format_attr_filter_band2.attr,
4021bab4e569SKan Liang 	&format_attr_filter_band3.attr,
4022bab4e569SKan Liang 	NULL,
4023bab4e569SKan Liang };
4024bab4e569SKan Liang 
4025bab4e569SKan Liang static struct attribute_group skx_uncore_pcu_format_group = {
4026bab4e569SKan Liang 	.name = "format",
4027bab4e569SKan Liang 	.attrs = skx_uncore_pcu_formats_attr,
4028bab4e569SKan Liang };
4029bab4e569SKan Liang 
4030cd34cd97SKan Liang static struct intel_uncore_ops skx_uncore_pcu_ops = {
4031cd34cd97SKan Liang 	IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
4032cd34cd97SKan Liang 	.hw_config		= hswep_pcu_hw_config,
4033cd34cd97SKan Liang 	.get_constraint		= snbep_pcu_get_constraint,
4034cd34cd97SKan Liang 	.put_constraint		= snbep_pcu_put_constraint,
4035cd34cd97SKan Liang };
4036cd34cd97SKan Liang 
4037cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_pcu = {
4038cd34cd97SKan Liang 	.name			= "pcu",
4039cd34cd97SKan Liang 	.num_counters		= 4,
4040cd34cd97SKan Liang 	.num_boxes		= 1,
4041cd34cd97SKan Liang 	.perf_ctr_bits		= 48,
4042cd34cd97SKan Liang 	.perf_ctr		= HSWEP_PCU_MSR_PMON_CTR0,
4043cd34cd97SKan Liang 	.event_ctl		= HSWEP_PCU_MSR_PMON_CTL0,
4044cd34cd97SKan Liang 	.event_mask		= SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
4045cd34cd97SKan Liang 	.box_ctl		= HSWEP_PCU_MSR_PMON_BOX_CTL,
4046cd34cd97SKan Liang 	.num_shared_regs	= 1,
4047cd34cd97SKan Liang 	.ops			= &skx_uncore_pcu_ops,
4048bab4e569SKan Liang 	.format_group		= &skx_uncore_pcu_format_group,
4049cd34cd97SKan Liang };
4050cd34cd97SKan Liang 
4051cd34cd97SKan Liang static struct intel_uncore_type *skx_msr_uncores[] = {
4052cd34cd97SKan Liang 	&skx_uncore_ubox,
4053cd34cd97SKan Liang 	&skx_uncore_chabox,
4054cd34cd97SKan Liang 	&skx_uncore_iio,
40550f519f03SKan Liang 	&skx_uncore_iio_free_running,
4056cd34cd97SKan Liang 	&skx_uncore_irp,
4057cd34cd97SKan Liang 	&skx_uncore_pcu,
4058cd34cd97SKan Liang 	NULL,
4059cd34cd97SKan Liang };
4060cd34cd97SKan Liang 
4061320b0651SKan Liang /*
4062320b0651SKan Liang  * To determine the number of CHAs, it should read bits 27:0 in the CAPID6
4063320b0651SKan Liang  * register which located at Device 30, Function 3, Offset 0x9C. PCI ID 0x2083.
4064320b0651SKan Liang  */
4065320b0651SKan Liang #define SKX_CAPID6		0x9c
4066320b0651SKan Liang #define SKX_CHA_BIT_MASK	GENMASK(27, 0)
4067320b0651SKan Liang 
4068cd34cd97SKan Liang static int skx_count_chabox(void)
4069cd34cd97SKan Liang {
4070320b0651SKan Liang 	struct pci_dev *dev = NULL;
4071320b0651SKan Liang 	u32 val = 0;
4072cd34cd97SKan Liang 
4073320b0651SKan Liang 	dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x2083, dev);
4074320b0651SKan Liang 	if (!dev)
4075320b0651SKan Liang 		goto out;
4076cd34cd97SKan Liang 
4077320b0651SKan Liang 	pci_read_config_dword(dev, SKX_CAPID6, &val);
4078320b0651SKan Liang 	val &= SKX_CHA_BIT_MASK;
4079320b0651SKan Liang out:
4080320b0651SKan Liang 	pci_dev_put(dev);
4081320b0651SKan Liang 	return hweight32(val);
4082cd34cd97SKan Liang }
4083cd34cd97SKan Liang 
4084cd34cd97SKan Liang void skx_uncore_cpu_init(void)
4085cd34cd97SKan Liang {
4086cd34cd97SKan Liang 	skx_uncore_chabox.num_boxes = skx_count_chabox();
4087cd34cd97SKan Liang 	uncore_msr_uncores = skx_msr_uncores;
4088cd34cd97SKan Liang }
4089cd34cd97SKan Liang 
4090cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_imc = {
4091cd34cd97SKan Liang 	.name		= "imc",
4092cd34cd97SKan Liang 	.num_counters   = 4,
4093cd34cd97SKan Liang 	.num_boxes	= 6,
4094cd34cd97SKan Liang 	.perf_ctr_bits	= 48,
4095cd34cd97SKan Liang 	.fixed_ctr_bits	= 48,
4096cd34cd97SKan Liang 	.fixed_ctr	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
4097cd34cd97SKan Liang 	.fixed_ctl	= SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
4098cd34cd97SKan Liang 	.event_descs	= hswep_uncore_imc_events,
4099cd34cd97SKan Liang 	.perf_ctr	= SNBEP_PCI_PMON_CTR0,
4100cd34cd97SKan Liang 	.event_ctl	= SNBEP_PCI_PMON_CTL0,
4101cd34cd97SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4102cd34cd97SKan Liang 	.box_ctl	= SNBEP_PCI_PMON_BOX_CTL,
4103cd34cd97SKan Liang 	.ops		= &ivbep_uncore_pci_ops,
4104cd34cd97SKan Liang 	.format_group	= &skx_uncore_format_group,
4105cd34cd97SKan Liang };
4106cd34cd97SKan Liang 
4107cd34cd97SKan Liang static struct attribute *skx_upi_uncore_formats_attr[] = {
410831766094SKan Liang 	&format_attr_event.attr,
4109cd34cd97SKan Liang 	&format_attr_umask_ext.attr,
4110cd34cd97SKan Liang 	&format_attr_edge.attr,
4111cd34cd97SKan Liang 	&format_attr_inv.attr,
4112cd34cd97SKan Liang 	&format_attr_thresh8.attr,
4113cd34cd97SKan Liang 	NULL,
4114cd34cd97SKan Liang };
4115cd34cd97SKan Liang 
411645bd07adSArvind Yadav static const struct attribute_group skx_upi_uncore_format_group = {
4117cd34cd97SKan Liang 	.name = "format",
4118cd34cd97SKan Liang 	.attrs = skx_upi_uncore_formats_attr,
4119cd34cd97SKan Liang };
4120cd34cd97SKan Liang 
4121cd34cd97SKan Liang static void skx_upi_uncore_pci_init_box(struct intel_uncore_box *box)
4122cd34cd97SKan Liang {
4123cd34cd97SKan Liang 	struct pci_dev *pdev = box->pci_dev;
4124cd34cd97SKan Liang 
4125cd34cd97SKan Liang 	__set_bit(UNCORE_BOX_FLAG_CTL_OFFS8, &box->flags);
4126cd34cd97SKan Liang 	pci_write_config_dword(pdev, SKX_UPI_PCI_PMON_BOX_CTL, IVBEP_PMON_BOX_CTL_INT);
4127cd34cd97SKan Liang }
4128cd34cd97SKan Liang 
4129cd34cd97SKan Liang static struct intel_uncore_ops skx_upi_uncore_pci_ops = {
4130cd34cd97SKan Liang 	.init_box	= skx_upi_uncore_pci_init_box,
4131cd34cd97SKan Liang 	.disable_box	= snbep_uncore_pci_disable_box,
4132cd34cd97SKan Liang 	.enable_box	= snbep_uncore_pci_enable_box,
4133cd34cd97SKan Liang 	.disable_event	= snbep_uncore_pci_disable_event,
4134cd34cd97SKan Liang 	.enable_event	= snbep_uncore_pci_enable_event,
4135cd34cd97SKan Liang 	.read_counter	= snbep_uncore_pci_read_counter,
4136cd34cd97SKan Liang };
4137cd34cd97SKan Liang 
4138cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_upi = {
4139cd34cd97SKan Liang 	.name		= "upi",
4140cd34cd97SKan Liang 	.num_counters   = 4,
4141cd34cd97SKan Liang 	.num_boxes	= 3,
4142cd34cd97SKan Liang 	.perf_ctr_bits	= 48,
4143cd34cd97SKan Liang 	.perf_ctr	= SKX_UPI_PCI_PMON_CTR0,
4144cd34cd97SKan Liang 	.event_ctl	= SKX_UPI_PCI_PMON_CTL0,
4145b3625980SStephane Eranian 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4146b3625980SStephane Eranian 	.event_mask_ext = SKX_UPI_CTL_UMASK_EXT,
4147cd34cd97SKan Liang 	.box_ctl	= SKX_UPI_PCI_PMON_BOX_CTL,
4148cd34cd97SKan Liang 	.ops		= &skx_upi_uncore_pci_ops,
4149cd34cd97SKan Liang 	.format_group	= &skx_upi_uncore_format_group,
4150cd34cd97SKan Liang };
4151cd34cd97SKan Liang 
4152cd34cd97SKan Liang static void skx_m2m_uncore_pci_init_box(struct intel_uncore_box *box)
4153cd34cd97SKan Liang {
4154cd34cd97SKan Liang 	struct pci_dev *pdev = box->pci_dev;
4155cd34cd97SKan Liang 
4156cd34cd97SKan Liang 	__set_bit(UNCORE_BOX_FLAG_CTL_OFFS8, &box->flags);
4157cd34cd97SKan Liang 	pci_write_config_dword(pdev, SKX_M2M_PCI_PMON_BOX_CTL, IVBEP_PMON_BOX_CTL_INT);
4158cd34cd97SKan Liang }
4159cd34cd97SKan Liang 
4160cd34cd97SKan Liang static struct intel_uncore_ops skx_m2m_uncore_pci_ops = {
4161cd34cd97SKan Liang 	.init_box	= skx_m2m_uncore_pci_init_box,
4162cd34cd97SKan Liang 	.disable_box	= snbep_uncore_pci_disable_box,
4163cd34cd97SKan Liang 	.enable_box	= snbep_uncore_pci_enable_box,
4164cd34cd97SKan Liang 	.disable_event	= snbep_uncore_pci_disable_event,
4165cd34cd97SKan Liang 	.enable_event	= snbep_uncore_pci_enable_event,
4166cd34cd97SKan Liang 	.read_counter	= snbep_uncore_pci_read_counter,
4167cd34cd97SKan Liang };
4168cd34cd97SKan Liang 
4169cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_m2m = {
4170cd34cd97SKan Liang 	.name		= "m2m",
4171cd34cd97SKan Liang 	.num_counters   = 4,
4172cd34cd97SKan Liang 	.num_boxes	= 2,
4173cd34cd97SKan Liang 	.perf_ctr_bits	= 48,
4174cd34cd97SKan Liang 	.perf_ctr	= SKX_M2M_PCI_PMON_CTR0,
4175cd34cd97SKan Liang 	.event_ctl	= SKX_M2M_PCI_PMON_CTL0,
4176cd34cd97SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4177cd34cd97SKan Liang 	.box_ctl	= SKX_M2M_PCI_PMON_BOX_CTL,
4178cd34cd97SKan Liang 	.ops		= &skx_m2m_uncore_pci_ops,
4179cd34cd97SKan Liang 	.format_group	= &skx_uncore_format_group,
4180cd34cd97SKan Liang };
4181cd34cd97SKan Liang 
4182cd34cd97SKan Liang static struct event_constraint skx_uncore_m2pcie_constraints[] = {
4183cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
4184cd34cd97SKan Liang 	EVENT_CONSTRAINT_END
4185cd34cd97SKan Liang };
4186cd34cd97SKan Liang 
4187cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_m2pcie = {
4188cd34cd97SKan Liang 	.name		= "m2pcie",
4189cd34cd97SKan Liang 	.num_counters   = 4,
4190cd34cd97SKan Liang 	.num_boxes	= 4,
4191cd34cd97SKan Liang 	.perf_ctr_bits	= 48,
4192cd34cd97SKan Liang 	.constraints	= skx_uncore_m2pcie_constraints,
4193cd34cd97SKan Liang 	.perf_ctr	= SNBEP_PCI_PMON_CTR0,
4194cd34cd97SKan Liang 	.event_ctl	= SNBEP_PCI_PMON_CTL0,
4195cd34cd97SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4196cd34cd97SKan Liang 	.box_ctl	= SNBEP_PCI_PMON_BOX_CTL,
4197cd34cd97SKan Liang 	.ops		= &ivbep_uncore_pci_ops,
4198cd34cd97SKan Liang 	.format_group	= &skx_uncore_format_group,
4199cd34cd97SKan Liang };
4200cd34cd97SKan Liang 
4201cd34cd97SKan Liang static struct event_constraint skx_uncore_m3upi_constraints[] = {
4202cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x1d, 0x1),
4203cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x1e, 0x1),
4204cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x40, 0x7),
4205cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x4e, 0x7),
4206cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x4f, 0x7),
4207cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x50, 0x7),
4208cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x51, 0x7),
4209cd34cd97SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x52, 0x7),
4210cd34cd97SKan Liang 	EVENT_CONSTRAINT_END
4211cd34cd97SKan Liang };
4212cd34cd97SKan Liang 
4213cd34cd97SKan Liang static struct intel_uncore_type skx_uncore_m3upi = {
4214cd34cd97SKan Liang 	.name		= "m3upi",
4215cd34cd97SKan Liang 	.num_counters   = 3,
4216cd34cd97SKan Liang 	.num_boxes	= 3,
4217cd34cd97SKan Liang 	.perf_ctr_bits	= 48,
4218cd34cd97SKan Liang 	.constraints	= skx_uncore_m3upi_constraints,
4219cd34cd97SKan Liang 	.perf_ctr	= SNBEP_PCI_PMON_CTR0,
4220cd34cd97SKan Liang 	.event_ctl	= SNBEP_PCI_PMON_CTL0,
4221cd34cd97SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4222cd34cd97SKan Liang 	.box_ctl	= SNBEP_PCI_PMON_BOX_CTL,
4223cd34cd97SKan Liang 	.ops		= &ivbep_uncore_pci_ops,
4224cd34cd97SKan Liang 	.format_group	= &skx_uncore_format_group,
4225cd34cd97SKan Liang };
4226cd34cd97SKan Liang 
4227cd34cd97SKan Liang enum {
4228cd34cd97SKan Liang 	SKX_PCI_UNCORE_IMC,
4229cd34cd97SKan Liang 	SKX_PCI_UNCORE_M2M,
4230cd34cd97SKan Liang 	SKX_PCI_UNCORE_UPI,
4231cd34cd97SKan Liang 	SKX_PCI_UNCORE_M2PCIE,
4232cd34cd97SKan Liang 	SKX_PCI_UNCORE_M3UPI,
4233cd34cd97SKan Liang };
4234cd34cd97SKan Liang 
4235cd34cd97SKan Liang static struct intel_uncore_type *skx_pci_uncores[] = {
4236cd34cd97SKan Liang 	[SKX_PCI_UNCORE_IMC]	= &skx_uncore_imc,
4237cd34cd97SKan Liang 	[SKX_PCI_UNCORE_M2M]	= &skx_uncore_m2m,
4238cd34cd97SKan Liang 	[SKX_PCI_UNCORE_UPI]	= &skx_uncore_upi,
4239cd34cd97SKan Liang 	[SKX_PCI_UNCORE_M2PCIE]	= &skx_uncore_m2pcie,
4240cd34cd97SKan Liang 	[SKX_PCI_UNCORE_M3UPI]	= &skx_uncore_m3upi,
4241cd34cd97SKan Liang 	NULL,
4242cd34cd97SKan Liang };
4243cd34cd97SKan Liang 
4244cd34cd97SKan Liang static const struct pci_device_id skx_uncore_pci_ids[] = {
4245cd34cd97SKan Liang 	{ /* MC0 Channel 0 */
4246cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2042),
4247cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(10, 2, SKX_PCI_UNCORE_IMC, 0),
4248cd34cd97SKan Liang 	},
4249cd34cd97SKan Liang 	{ /* MC0 Channel 1 */
4250cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2046),
4251cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(10, 6, SKX_PCI_UNCORE_IMC, 1),
4252cd34cd97SKan Liang 	},
4253cd34cd97SKan Liang 	{ /* MC0 Channel 2 */
4254cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204a),
4255cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(11, 2, SKX_PCI_UNCORE_IMC, 2),
4256cd34cd97SKan Liang 	},
4257cd34cd97SKan Liang 	{ /* MC1 Channel 0 */
4258cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2042),
4259cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(12, 2, SKX_PCI_UNCORE_IMC, 3),
4260cd34cd97SKan Liang 	},
4261cd34cd97SKan Liang 	{ /* MC1 Channel 1 */
4262cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2046),
4263cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(12, 6, SKX_PCI_UNCORE_IMC, 4),
4264cd34cd97SKan Liang 	},
4265cd34cd97SKan Liang 	{ /* MC1 Channel 2 */
4266cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204a),
4267cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(13, 2, SKX_PCI_UNCORE_IMC, 5),
4268cd34cd97SKan Liang 	},
4269cd34cd97SKan Liang 	{ /* M2M0 */
4270cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2066),
4271cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(8, 0, SKX_PCI_UNCORE_M2M, 0),
4272cd34cd97SKan Liang 	},
4273cd34cd97SKan Liang 	{ /* M2M1 */
4274cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2066),
4275cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(9, 0, SKX_PCI_UNCORE_M2M, 1),
4276cd34cd97SKan Liang 	},
4277cd34cd97SKan Liang 	{ /* UPI0 Link 0 */
4278cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2058),
4279cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(14, 0, SKX_PCI_UNCORE_UPI, 0),
4280cd34cd97SKan Liang 	},
4281cd34cd97SKan Liang 	{ /* UPI0 Link 1 */
4282cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2058),
4283cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(15, 0, SKX_PCI_UNCORE_UPI, 1),
4284cd34cd97SKan Liang 	},
4285cd34cd97SKan Liang 	{ /* UPI1 Link 2 */
4286cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2058),
4287cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(16, 0, SKX_PCI_UNCORE_UPI, 2),
4288cd34cd97SKan Liang 	},
4289cd34cd97SKan Liang 	{ /* M2PCIe 0 */
4290cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2088),
4291cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(21, 1, SKX_PCI_UNCORE_M2PCIE, 0),
4292cd34cd97SKan Liang 	},
4293cd34cd97SKan Liang 	{ /* M2PCIe 1 */
4294cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2088),
4295cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(22, 1, SKX_PCI_UNCORE_M2PCIE, 1),
4296cd34cd97SKan Liang 	},
4297cd34cd97SKan Liang 	{ /* M2PCIe 2 */
4298cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2088),
4299cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(23, 1, SKX_PCI_UNCORE_M2PCIE, 2),
4300cd34cd97SKan Liang 	},
4301cd34cd97SKan Liang 	{ /* M2PCIe 3 */
4302cd34cd97SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2088),
4303cd34cd97SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(21, 5, SKX_PCI_UNCORE_M2PCIE, 3),
4304cd34cd97SKan Liang 	},
4305cd34cd97SKan Liang 	{ /* M3UPI0 Link 0 */
43069d92cfeaSKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204D),
43079d92cfeaSKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(18, 1, SKX_PCI_UNCORE_M3UPI, 0),
4308cd34cd97SKan Liang 	},
4309cd34cd97SKan Liang 	{ /* M3UPI0 Link 1 */
43109d92cfeaSKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204E),
43119d92cfeaSKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(18, 2, SKX_PCI_UNCORE_M3UPI, 1),
4312cd34cd97SKan Liang 	},
4313cd34cd97SKan Liang 	{ /* M3UPI1 Link 2 */
43149d92cfeaSKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204D),
43159d92cfeaSKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(18, 5, SKX_PCI_UNCORE_M3UPI, 2),
4316cd34cd97SKan Liang 	},
4317cd34cd97SKan Liang 	{ /* end: all zeroes */ }
4318cd34cd97SKan Liang };
4319cd34cd97SKan Liang 
4320cd34cd97SKan Liang 
4321cd34cd97SKan Liang static struct pci_driver skx_uncore_pci_driver = {
4322cd34cd97SKan Liang 	.name		= "skx_uncore",
4323cd34cd97SKan Liang 	.id_table	= skx_uncore_pci_ids,
4324cd34cd97SKan Liang };
4325cd34cd97SKan Liang 
4326cd34cd97SKan Liang int skx_uncore_pci_init(void)
4327cd34cd97SKan Liang {
4328cd34cd97SKan Liang 	/* need to double check pci address */
4329cd34cd97SKan Liang 	int ret = snbep_pci2phy_map_init(0x2014, SKX_CPUNODEID, SKX_GIDNIDMAP, false);
4330cd34cd97SKan Liang 
4331cd34cd97SKan Liang 	if (ret)
4332cd34cd97SKan Liang 		return ret;
4333cd34cd97SKan Liang 
4334cd34cd97SKan Liang 	uncore_pci_uncores = skx_pci_uncores;
4335cd34cd97SKan Liang 	uncore_pci_driver = &skx_uncore_pci_driver;
4336cd34cd97SKan Liang 	return 0;
4337cd34cd97SKan Liang }
4338cd34cd97SKan Liang 
4339cd34cd97SKan Liang /* end of SKX uncore support */
4340210cc5f9SKan Liang 
4341210cc5f9SKan Liang /* SNR uncore support */
4342210cc5f9SKan Liang 
4343210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_ubox = {
4344210cc5f9SKan Liang 	.name			= "ubox",
4345210cc5f9SKan Liang 	.num_counters		= 2,
4346210cc5f9SKan Liang 	.num_boxes		= 1,
4347210cc5f9SKan Liang 	.perf_ctr_bits		= 48,
4348210cc5f9SKan Liang 	.fixed_ctr_bits		= 48,
4349210cc5f9SKan Liang 	.perf_ctr		= SNR_U_MSR_PMON_CTR0,
4350210cc5f9SKan Liang 	.event_ctl		= SNR_U_MSR_PMON_CTL0,
4351210cc5f9SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
4352210cc5f9SKan Liang 	.fixed_ctr		= SNR_U_MSR_PMON_UCLK_FIXED_CTR,
4353210cc5f9SKan Liang 	.fixed_ctl		= SNR_U_MSR_PMON_UCLK_FIXED_CTL,
4354210cc5f9SKan Liang 	.ops			= &ivbep_uncore_msr_ops,
4355210cc5f9SKan Liang 	.format_group		= &ivbep_uncore_format_group,
4356210cc5f9SKan Liang };
4357210cc5f9SKan Liang 
4358210cc5f9SKan Liang static struct attribute *snr_uncore_cha_formats_attr[] = {
4359210cc5f9SKan Liang 	&format_attr_event.attr,
4360210cc5f9SKan Liang 	&format_attr_umask_ext2.attr,
4361210cc5f9SKan Liang 	&format_attr_edge.attr,
4362210cc5f9SKan Liang 	&format_attr_tid_en.attr,
4363210cc5f9SKan Liang 	&format_attr_inv.attr,
4364210cc5f9SKan Liang 	&format_attr_thresh8.attr,
4365210cc5f9SKan Liang 	&format_attr_filter_tid5.attr,
4366210cc5f9SKan Liang 	NULL,
4367210cc5f9SKan Liang };
4368210cc5f9SKan Liang static const struct attribute_group snr_uncore_chabox_format_group = {
4369210cc5f9SKan Liang 	.name = "format",
4370210cc5f9SKan Liang 	.attrs = snr_uncore_cha_formats_attr,
4371210cc5f9SKan Liang };
4372210cc5f9SKan Liang 
4373210cc5f9SKan Liang static int snr_cha_hw_config(struct intel_uncore_box *box, struct perf_event *event)
4374210cc5f9SKan Liang {
4375210cc5f9SKan Liang 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
4376210cc5f9SKan Liang 
4377210cc5f9SKan Liang 	reg1->reg = SNR_C0_MSR_PMON_BOX_FILTER0 +
4378210cc5f9SKan Liang 		    box->pmu->type->msr_offset * box->pmu->pmu_idx;
4379210cc5f9SKan Liang 	reg1->config = event->attr.config1 & SKX_CHA_MSR_PMON_BOX_FILTER_TID;
4380210cc5f9SKan Liang 	reg1->idx = 0;
4381210cc5f9SKan Liang 
4382210cc5f9SKan Liang 	return 0;
4383210cc5f9SKan Liang }
4384210cc5f9SKan Liang 
4385210cc5f9SKan Liang static void snr_cha_enable_event(struct intel_uncore_box *box,
4386210cc5f9SKan Liang 				   struct perf_event *event)
4387210cc5f9SKan Liang {
4388210cc5f9SKan Liang 	struct hw_perf_event *hwc = &event->hw;
4389210cc5f9SKan Liang 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
4390210cc5f9SKan Liang 
4391210cc5f9SKan Liang 	if (reg1->idx != EXTRA_REG_NONE)
4392210cc5f9SKan Liang 		wrmsrl(reg1->reg, reg1->config);
4393210cc5f9SKan Liang 
4394210cc5f9SKan Liang 	wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
4395210cc5f9SKan Liang }
4396210cc5f9SKan Liang 
4397210cc5f9SKan Liang static struct intel_uncore_ops snr_uncore_chabox_ops = {
4398210cc5f9SKan Liang 	.init_box		= ivbep_uncore_msr_init_box,
4399210cc5f9SKan Liang 	.disable_box		= snbep_uncore_msr_disable_box,
4400210cc5f9SKan Liang 	.enable_box		= snbep_uncore_msr_enable_box,
4401210cc5f9SKan Liang 	.disable_event		= snbep_uncore_msr_disable_event,
4402210cc5f9SKan Liang 	.enable_event		= snr_cha_enable_event,
4403210cc5f9SKan Liang 	.read_counter		= uncore_msr_read_counter,
4404210cc5f9SKan Liang 	.hw_config		= snr_cha_hw_config,
4405210cc5f9SKan Liang };
4406210cc5f9SKan Liang 
4407210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_chabox = {
4408210cc5f9SKan Liang 	.name			= "cha",
4409210cc5f9SKan Liang 	.num_counters		= 4,
4410210cc5f9SKan Liang 	.num_boxes		= 6,
4411210cc5f9SKan Liang 	.perf_ctr_bits		= 48,
4412210cc5f9SKan Liang 	.event_ctl		= SNR_CHA_MSR_PMON_CTL0,
4413210cc5f9SKan Liang 	.perf_ctr		= SNR_CHA_MSR_PMON_CTR0,
4414210cc5f9SKan Liang 	.box_ctl		= SNR_CHA_MSR_PMON_BOX_CTL,
4415210cc5f9SKan Liang 	.msr_offset		= HSWEP_CBO_MSR_OFFSET,
4416210cc5f9SKan Liang 	.event_mask		= HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
4417210cc5f9SKan Liang 	.event_mask_ext		= SNR_CHA_RAW_EVENT_MASK_EXT,
4418210cc5f9SKan Liang 	.ops			= &snr_uncore_chabox_ops,
4419210cc5f9SKan Liang 	.format_group		= &snr_uncore_chabox_format_group,
4420210cc5f9SKan Liang };
4421210cc5f9SKan Liang 
4422210cc5f9SKan Liang static struct attribute *snr_uncore_iio_formats_attr[] = {
4423210cc5f9SKan Liang 	&format_attr_event.attr,
4424210cc5f9SKan Liang 	&format_attr_umask.attr,
4425210cc5f9SKan Liang 	&format_attr_edge.attr,
4426210cc5f9SKan Liang 	&format_attr_inv.attr,
4427210cc5f9SKan Liang 	&format_attr_thresh9.attr,
4428210cc5f9SKan Liang 	&format_attr_ch_mask2.attr,
4429210cc5f9SKan Liang 	&format_attr_fc_mask2.attr,
4430210cc5f9SKan Liang 	NULL,
4431210cc5f9SKan Liang };
4432210cc5f9SKan Liang 
4433210cc5f9SKan Liang static const struct attribute_group snr_uncore_iio_format_group = {
4434210cc5f9SKan Liang 	.name = "format",
4435210cc5f9SKan Liang 	.attrs = snr_uncore_iio_formats_attr,
4436210cc5f9SKan Liang };
4437210cc5f9SKan Liang 
4438c1777be3SAlexander Antonov static umode_t
4439c1777be3SAlexander Antonov snr_iio_mapping_visible(struct kobject *kobj, struct attribute *attr, int die)
4440c1777be3SAlexander Antonov {
4441c1777be3SAlexander Antonov 	/* Root bus 0x00 is valid only for pmu_idx = 1. */
4442c1777be3SAlexander Antonov 	return pmu_iio_mapping_visible(kobj, attr, die, 1);
4443c1777be3SAlexander Antonov }
4444c1777be3SAlexander Antonov 
4445c1777be3SAlexander Antonov static struct attribute_group snr_iio_mapping_group = {
4446c1777be3SAlexander Antonov 	.is_visible	= snr_iio_mapping_visible,
4447c1777be3SAlexander Antonov };
4448c1777be3SAlexander Antonov 
4449c1777be3SAlexander Antonov static const struct attribute_group *snr_iio_attr_update[] = {
4450c1777be3SAlexander Antonov 	&snr_iio_mapping_group,
4451c1777be3SAlexander Antonov 	NULL,
4452c1777be3SAlexander Antonov };
4453c1777be3SAlexander Antonov 
4454c1777be3SAlexander Antonov static int sad_cfg_iio_topology(struct intel_uncore_type *type, u8 *sad_pmon_mapping)
4455c1777be3SAlexander Antonov {
4456c1777be3SAlexander Antonov 	u32 sad_cfg;
4457c1777be3SAlexander Antonov 	int die, stack_id, ret = -EPERM;
4458c1777be3SAlexander Antonov 	struct pci_dev *dev = NULL;
4459c1777be3SAlexander Antonov 
4460c1777be3SAlexander Antonov 	type->topology = kcalloc(uncore_max_dies(), sizeof(*type->topology),
4461c1777be3SAlexander Antonov 				 GFP_KERNEL);
4462c1777be3SAlexander Antonov 	if (!type->topology)
4463c1777be3SAlexander Antonov 		return -ENOMEM;
4464c1777be3SAlexander Antonov 
4465c1777be3SAlexander Antonov 	while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL, SNR_ICX_MESH2IIO_MMAP_DID, dev))) {
4466c1777be3SAlexander Antonov 		ret = pci_read_config_dword(dev, SNR_ICX_SAD_CONTROL_CFG, &sad_cfg);
4467c1777be3SAlexander Antonov 		if (ret) {
4468c1777be3SAlexander Antonov 			ret = pcibios_err_to_errno(ret);
4469c1777be3SAlexander Antonov 			break;
4470c1777be3SAlexander Antonov 		}
4471c1777be3SAlexander Antonov 
4472c1777be3SAlexander Antonov 		die = uncore_pcibus_to_dieid(dev->bus);
4473c1777be3SAlexander Antonov 		stack_id = SAD_CONTROL_STACK_ID(sad_cfg);
4474c1777be3SAlexander Antonov 		if (die < 0 || stack_id >= type->num_boxes) {
4475c1777be3SAlexander Antonov 			ret = -EPERM;
4476c1777be3SAlexander Antonov 			break;
4477c1777be3SAlexander Antonov 		}
4478c1777be3SAlexander Antonov 
4479c1777be3SAlexander Antonov 		/* Convert stack id from SAD_CONTROL to PMON notation. */
4480c1777be3SAlexander Antonov 		stack_id = sad_pmon_mapping[stack_id];
4481c1777be3SAlexander Antonov 
4482c1777be3SAlexander Antonov 		((u8 *)&(type->topology[die].configuration))[stack_id] = dev->bus->number;
4483c1777be3SAlexander Antonov 		type->topology[die].segment = pci_domain_nr(dev->bus);
4484c1777be3SAlexander Antonov 	}
4485c1777be3SAlexander Antonov 
4486c1777be3SAlexander Antonov 	if (ret) {
4487c1777be3SAlexander Antonov 		kfree(type->topology);
4488c1777be3SAlexander Antonov 		type->topology = NULL;
4489c1777be3SAlexander Antonov 	}
4490c1777be3SAlexander Antonov 
4491c1777be3SAlexander Antonov 	return ret;
4492c1777be3SAlexander Antonov }
4493c1777be3SAlexander Antonov 
4494c1777be3SAlexander Antonov /*
4495c1777be3SAlexander Antonov  * SNR has a static mapping of stack IDs from SAD_CONTROL_CFG notation to PMON
4496c1777be3SAlexander Antonov  */
4497c1777be3SAlexander Antonov enum {
4498c1777be3SAlexander Antonov 	SNR_QAT_PMON_ID,
4499c1777be3SAlexander Antonov 	SNR_CBDMA_DMI_PMON_ID,
4500c1777be3SAlexander Antonov 	SNR_NIS_PMON_ID,
4501c1777be3SAlexander Antonov 	SNR_DLB_PMON_ID,
4502c1777be3SAlexander Antonov 	SNR_PCIE_GEN3_PMON_ID
4503c1777be3SAlexander Antonov };
4504c1777be3SAlexander Antonov 
4505c1777be3SAlexander Antonov static u8 snr_sad_pmon_mapping[] = {
4506c1777be3SAlexander Antonov 	SNR_CBDMA_DMI_PMON_ID,
4507c1777be3SAlexander Antonov 	SNR_PCIE_GEN3_PMON_ID,
4508c1777be3SAlexander Antonov 	SNR_DLB_PMON_ID,
4509c1777be3SAlexander Antonov 	SNR_NIS_PMON_ID,
4510c1777be3SAlexander Antonov 	SNR_QAT_PMON_ID
4511c1777be3SAlexander Antonov };
4512c1777be3SAlexander Antonov 
4513c1777be3SAlexander Antonov static int snr_iio_get_topology(struct intel_uncore_type *type)
4514c1777be3SAlexander Antonov {
4515c1777be3SAlexander Antonov 	return sad_cfg_iio_topology(type, snr_sad_pmon_mapping);
4516c1777be3SAlexander Antonov }
4517c1777be3SAlexander Antonov 
4518c1777be3SAlexander Antonov static int snr_iio_set_mapping(struct intel_uncore_type *type)
4519c1777be3SAlexander Antonov {
4520c1777be3SAlexander Antonov 	return pmu_iio_set_mapping(type, &snr_iio_mapping_group);
4521c1777be3SAlexander Antonov }
4522c1777be3SAlexander Antonov 
45233f2cbe38SAlexander Antonov static void snr_iio_cleanup_mapping(struct intel_uncore_type *type)
45243f2cbe38SAlexander Antonov {
45253f2cbe38SAlexander Antonov 	pmu_iio_cleanup_mapping(type, &snr_iio_mapping_group);
45263f2cbe38SAlexander Antonov }
45273f2cbe38SAlexander Antonov 
4528210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_iio = {
4529210cc5f9SKan Liang 	.name			= "iio",
4530210cc5f9SKan Liang 	.num_counters		= 4,
4531210cc5f9SKan Liang 	.num_boxes		= 5,
4532210cc5f9SKan Liang 	.perf_ctr_bits		= 48,
4533210cc5f9SKan Liang 	.event_ctl		= SNR_IIO_MSR_PMON_CTL0,
4534210cc5f9SKan Liang 	.perf_ctr		= SNR_IIO_MSR_PMON_CTR0,
4535210cc5f9SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
4536210cc5f9SKan Liang 	.event_mask_ext		= SNR_IIO_PMON_RAW_EVENT_MASK_EXT,
4537210cc5f9SKan Liang 	.box_ctl		= SNR_IIO_MSR_PMON_BOX_CTL,
4538210cc5f9SKan Liang 	.msr_offset		= SNR_IIO_MSR_OFFSET,
4539210cc5f9SKan Liang 	.ops			= &ivbep_uncore_msr_ops,
4540210cc5f9SKan Liang 	.format_group		= &snr_uncore_iio_format_group,
4541c1777be3SAlexander Antonov 	.attr_update		= snr_iio_attr_update,
4542c1777be3SAlexander Antonov 	.get_topology		= snr_iio_get_topology,
4543c1777be3SAlexander Antonov 	.set_mapping		= snr_iio_set_mapping,
45443f2cbe38SAlexander Antonov 	.cleanup_mapping	= snr_iio_cleanup_mapping,
4545210cc5f9SKan Liang };
4546210cc5f9SKan Liang 
4547210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_irp = {
4548210cc5f9SKan Liang 	.name			= "irp",
4549210cc5f9SKan Liang 	.num_counters		= 2,
4550210cc5f9SKan Liang 	.num_boxes		= 5,
4551210cc5f9SKan Liang 	.perf_ctr_bits		= 48,
4552210cc5f9SKan Liang 	.event_ctl		= SNR_IRP0_MSR_PMON_CTL0,
4553210cc5f9SKan Liang 	.perf_ctr		= SNR_IRP0_MSR_PMON_CTR0,
4554210cc5f9SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
4555210cc5f9SKan Liang 	.box_ctl		= SNR_IRP0_MSR_PMON_BOX_CTL,
4556210cc5f9SKan Liang 	.msr_offset		= SNR_IRP_MSR_OFFSET,
4557210cc5f9SKan Liang 	.ops			= &ivbep_uncore_msr_ops,
4558210cc5f9SKan Liang 	.format_group		= &ivbep_uncore_format_group,
4559210cc5f9SKan Liang };
4560210cc5f9SKan Liang 
4561210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_m2pcie = {
4562210cc5f9SKan Liang 	.name		= "m2pcie",
4563210cc5f9SKan Liang 	.num_counters	= 4,
4564210cc5f9SKan Liang 	.num_boxes	= 5,
4565210cc5f9SKan Liang 	.perf_ctr_bits	= 48,
4566210cc5f9SKan Liang 	.event_ctl	= SNR_M2PCIE_MSR_PMON_CTL0,
4567210cc5f9SKan Liang 	.perf_ctr	= SNR_M2PCIE_MSR_PMON_CTR0,
4568210cc5f9SKan Liang 	.box_ctl	= SNR_M2PCIE_MSR_PMON_BOX_CTL,
4569210cc5f9SKan Liang 	.msr_offset	= SNR_M2PCIE_MSR_OFFSET,
4570210cc5f9SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4571210cc5f9SKan Liang 	.ops		= &ivbep_uncore_msr_ops,
4572210cc5f9SKan Liang 	.format_group	= &ivbep_uncore_format_group,
4573210cc5f9SKan Liang };
4574210cc5f9SKan Liang 
4575210cc5f9SKan Liang static int snr_pcu_hw_config(struct intel_uncore_box *box, struct perf_event *event)
4576210cc5f9SKan Liang {
4577210cc5f9SKan Liang 	struct hw_perf_event *hwc = &event->hw;
4578210cc5f9SKan Liang 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
4579210cc5f9SKan Liang 	int ev_sel = hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK;
4580210cc5f9SKan Liang 
4581210cc5f9SKan Liang 	if (ev_sel >= 0xb && ev_sel <= 0xe) {
4582210cc5f9SKan Liang 		reg1->reg = SNR_PCU_MSR_PMON_BOX_FILTER;
4583210cc5f9SKan Liang 		reg1->idx = ev_sel - 0xb;
4584210cc5f9SKan Liang 		reg1->config = event->attr.config1 & (0xff << reg1->idx);
4585210cc5f9SKan Liang 	}
4586210cc5f9SKan Liang 	return 0;
4587210cc5f9SKan Liang }
4588210cc5f9SKan Liang 
4589210cc5f9SKan Liang static struct intel_uncore_ops snr_uncore_pcu_ops = {
4590210cc5f9SKan Liang 	IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
4591210cc5f9SKan Liang 	.hw_config		= snr_pcu_hw_config,
4592210cc5f9SKan Liang 	.get_constraint		= snbep_pcu_get_constraint,
4593210cc5f9SKan Liang 	.put_constraint		= snbep_pcu_put_constraint,
4594210cc5f9SKan Liang };
4595210cc5f9SKan Liang 
4596210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_pcu = {
4597210cc5f9SKan Liang 	.name			= "pcu",
4598210cc5f9SKan Liang 	.num_counters		= 4,
4599210cc5f9SKan Liang 	.num_boxes		= 1,
4600210cc5f9SKan Liang 	.perf_ctr_bits		= 48,
4601210cc5f9SKan Liang 	.perf_ctr		= SNR_PCU_MSR_PMON_CTR0,
4602210cc5f9SKan Liang 	.event_ctl		= SNR_PCU_MSR_PMON_CTL0,
4603210cc5f9SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
4604210cc5f9SKan Liang 	.box_ctl		= SNR_PCU_MSR_PMON_BOX_CTL,
4605210cc5f9SKan Liang 	.num_shared_regs	= 1,
4606210cc5f9SKan Liang 	.ops			= &snr_uncore_pcu_ops,
4607210cc5f9SKan Liang 	.format_group		= &skx_uncore_pcu_format_group,
4608210cc5f9SKan Liang };
4609210cc5f9SKan Liang 
4610210cc5f9SKan Liang enum perf_uncore_snr_iio_freerunning_type_id {
4611210cc5f9SKan Liang 	SNR_IIO_MSR_IOCLK,
4612210cc5f9SKan Liang 	SNR_IIO_MSR_BW_IN,
4613210cc5f9SKan Liang 
4614210cc5f9SKan Liang 	SNR_IIO_FREERUNNING_TYPE_MAX,
4615210cc5f9SKan Liang };
4616210cc5f9SKan Liang 
4617210cc5f9SKan Liang static struct freerunning_counters snr_iio_freerunning[] = {
4618210cc5f9SKan Liang 	[SNR_IIO_MSR_IOCLK]	= { 0x1eac, 0x1, 0x10, 1, 48 },
4619210cc5f9SKan Liang 	[SNR_IIO_MSR_BW_IN]	= { 0x1f00, 0x1, 0x10, 8, 48 },
4620210cc5f9SKan Liang };
4621210cc5f9SKan Liang 
4622210cc5f9SKan Liang static struct uncore_event_desc snr_uncore_iio_freerunning_events[] = {
4623210cc5f9SKan Liang 	/* Free-Running IIO CLOCKS Counter */
4624210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(ioclk,			"event=0xff,umask=0x10"),
4625210cc5f9SKan Liang 	/* Free-Running IIO BANDWIDTH IN Counters */
4626210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0,		"event=0xff,umask=0x20"),
4627210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale,	"3.814697266e-6"),
4628210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit,	"MiB"),
4629210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1,		"event=0xff,umask=0x21"),
4630210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale,	"3.814697266e-6"),
4631210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit,	"MiB"),
4632210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2,		"event=0xff,umask=0x22"),
4633210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale,	"3.814697266e-6"),
4634210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit,	"MiB"),
4635210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3,		"event=0xff,umask=0x23"),
4636210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale,	"3.814697266e-6"),
4637210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit,	"MiB"),
4638210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4,		"event=0xff,umask=0x24"),
4639210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4.scale,	"3.814697266e-6"),
4640210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4.unit,	"MiB"),
4641210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5,		"event=0xff,umask=0x25"),
4642210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5.scale,	"3.814697266e-6"),
4643210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5.unit,	"MiB"),
4644210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6,		"event=0xff,umask=0x26"),
4645210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6.scale,	"3.814697266e-6"),
4646210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6.unit,	"MiB"),
4647210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7,		"event=0xff,umask=0x27"),
4648210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7.scale,	"3.814697266e-6"),
4649210cc5f9SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7.unit,	"MiB"),
4650210cc5f9SKan Liang 	{ /* end: all zeroes */ },
4651210cc5f9SKan Liang };
4652210cc5f9SKan Liang 
4653210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_iio_free_running = {
4654210cc5f9SKan Liang 	.name			= "iio_free_running",
4655210cc5f9SKan Liang 	.num_counters		= 9,
4656210cc5f9SKan Liang 	.num_boxes		= 5,
4657210cc5f9SKan Liang 	.num_freerunning_types	= SNR_IIO_FREERUNNING_TYPE_MAX,
4658210cc5f9SKan Liang 	.freerunning		= snr_iio_freerunning,
4659210cc5f9SKan Liang 	.ops			= &skx_uncore_iio_freerunning_ops,
4660210cc5f9SKan Liang 	.event_descs		= snr_uncore_iio_freerunning_events,
4661210cc5f9SKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
4662210cc5f9SKan Liang };
4663210cc5f9SKan Liang 
4664210cc5f9SKan Liang static struct intel_uncore_type *snr_msr_uncores[] = {
4665210cc5f9SKan Liang 	&snr_uncore_ubox,
4666210cc5f9SKan Liang 	&snr_uncore_chabox,
4667210cc5f9SKan Liang 	&snr_uncore_iio,
4668210cc5f9SKan Liang 	&snr_uncore_irp,
4669210cc5f9SKan Liang 	&snr_uncore_m2pcie,
4670210cc5f9SKan Liang 	&snr_uncore_pcu,
4671210cc5f9SKan Liang 	&snr_uncore_iio_free_running,
4672210cc5f9SKan Liang 	NULL,
4673210cc5f9SKan Liang };
4674210cc5f9SKan Liang 
4675210cc5f9SKan Liang void snr_uncore_cpu_init(void)
4676210cc5f9SKan Liang {
4677210cc5f9SKan Liang 	uncore_msr_uncores = snr_msr_uncores;
4678210cc5f9SKan Liang }
4679210cc5f9SKan Liang 
4680210cc5f9SKan Liang static void snr_m2m_uncore_pci_init_box(struct intel_uncore_box *box)
4681210cc5f9SKan Liang {
4682210cc5f9SKan Liang 	struct pci_dev *pdev = box->pci_dev;
4683210cc5f9SKan Liang 	int box_ctl = uncore_pci_box_ctl(box);
4684210cc5f9SKan Liang 
4685210cc5f9SKan Liang 	__set_bit(UNCORE_BOX_FLAG_CTL_OFFS8, &box->flags);
4686210cc5f9SKan Liang 	pci_write_config_dword(pdev, box_ctl, IVBEP_PMON_BOX_CTL_INT);
4687210cc5f9SKan Liang }
4688210cc5f9SKan Liang 
4689210cc5f9SKan Liang static struct intel_uncore_ops snr_m2m_uncore_pci_ops = {
4690210cc5f9SKan Liang 	.init_box	= snr_m2m_uncore_pci_init_box,
4691210cc5f9SKan Liang 	.disable_box	= snbep_uncore_pci_disable_box,
4692210cc5f9SKan Liang 	.enable_box	= snbep_uncore_pci_enable_box,
4693210cc5f9SKan Liang 	.disable_event	= snbep_uncore_pci_disable_event,
4694210cc5f9SKan Liang 	.enable_event	= snbep_uncore_pci_enable_event,
4695210cc5f9SKan Liang 	.read_counter	= snbep_uncore_pci_read_counter,
4696210cc5f9SKan Liang };
4697210cc5f9SKan Liang 
4698210cc5f9SKan Liang static struct attribute *snr_m2m_uncore_formats_attr[] = {
4699210cc5f9SKan Liang 	&format_attr_event.attr,
4700210cc5f9SKan Liang 	&format_attr_umask_ext3.attr,
4701210cc5f9SKan Liang 	&format_attr_edge.attr,
4702210cc5f9SKan Liang 	&format_attr_inv.attr,
4703210cc5f9SKan Liang 	&format_attr_thresh8.attr,
4704210cc5f9SKan Liang 	NULL,
4705210cc5f9SKan Liang };
4706210cc5f9SKan Liang 
4707210cc5f9SKan Liang static const struct attribute_group snr_m2m_uncore_format_group = {
4708210cc5f9SKan Liang 	.name = "format",
4709210cc5f9SKan Liang 	.attrs = snr_m2m_uncore_formats_attr,
4710210cc5f9SKan Liang };
4711210cc5f9SKan Liang 
4712210cc5f9SKan Liang static struct intel_uncore_type snr_uncore_m2m = {
4713210cc5f9SKan Liang 	.name		= "m2m",
4714210cc5f9SKan Liang 	.num_counters   = 4,
4715210cc5f9SKan Liang 	.num_boxes	= 1,
4716210cc5f9SKan Liang 	.perf_ctr_bits	= 48,
4717210cc5f9SKan Liang 	.perf_ctr	= SNR_M2M_PCI_PMON_CTR0,
4718210cc5f9SKan Liang 	.event_ctl	= SNR_M2M_PCI_PMON_CTL0,
4719210cc5f9SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4720210cc5f9SKan Liang 	.event_mask_ext	= SNR_M2M_PCI_PMON_UMASK_EXT,
4721210cc5f9SKan Liang 	.box_ctl	= SNR_M2M_PCI_PMON_BOX_CTL,
4722210cc5f9SKan Liang 	.ops		= &snr_m2m_uncore_pci_ops,
4723210cc5f9SKan Liang 	.format_group	= &snr_m2m_uncore_format_group,
4724210cc5f9SKan Liang };
4725210cc5f9SKan Liang 
4726a3b1e845SKan Liang static void snr_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event)
4727a3b1e845SKan Liang {
4728a3b1e845SKan Liang 	struct pci_dev *pdev = box->pci_dev;
4729a3b1e845SKan Liang 	struct hw_perf_event *hwc = &event->hw;
4730a3b1e845SKan Liang 
4731a3b1e845SKan Liang 	pci_write_config_dword(pdev, hwc->config_base, (u32)(hwc->config | SNBEP_PMON_CTL_EN));
4732a3b1e845SKan Liang 	pci_write_config_dword(pdev, hwc->config_base + 4, (u32)(hwc->config >> 32));
4733a3b1e845SKan Liang }
4734a3b1e845SKan Liang 
4735a3b1e845SKan Liang static struct intel_uncore_ops snr_pcie3_uncore_pci_ops = {
4736a3b1e845SKan Liang 	.init_box	= snr_m2m_uncore_pci_init_box,
4737a3b1e845SKan Liang 	.disable_box	= snbep_uncore_pci_disable_box,
4738a3b1e845SKan Liang 	.enable_box	= snbep_uncore_pci_enable_box,
4739a3b1e845SKan Liang 	.disable_event	= snbep_uncore_pci_disable_event,
4740a3b1e845SKan Liang 	.enable_event	= snr_uncore_pci_enable_event,
4741a3b1e845SKan Liang 	.read_counter	= snbep_uncore_pci_read_counter,
4742a3b1e845SKan Liang };
4743a3b1e845SKan Liang 
4744a3b1e845SKan Liang static struct intel_uncore_type snr_uncore_pcie3 = {
4745a3b1e845SKan Liang 	.name		= "pcie3",
4746a3b1e845SKan Liang 	.num_counters	= 4,
4747a3b1e845SKan Liang 	.num_boxes	= 1,
4748a3b1e845SKan Liang 	.perf_ctr_bits	= 48,
4749a3b1e845SKan Liang 	.perf_ctr	= SNR_PCIE3_PCI_PMON_CTR0,
4750a3b1e845SKan Liang 	.event_ctl	= SNR_PCIE3_PCI_PMON_CTL0,
4751a3b1e845SKan Liang 	.event_mask	= SKX_IIO_PMON_RAW_EVENT_MASK,
4752a3b1e845SKan Liang 	.event_mask_ext	= SKX_IIO_PMON_RAW_EVENT_MASK_EXT,
4753a3b1e845SKan Liang 	.box_ctl	= SNR_PCIE3_PCI_PMON_BOX_CTL,
4754a3b1e845SKan Liang 	.ops		= &snr_pcie3_uncore_pci_ops,
4755a3b1e845SKan Liang 	.format_group	= &skx_uncore_iio_format_group,
4756a3b1e845SKan Liang };
4757a3b1e845SKan Liang 
4758210cc5f9SKan Liang enum {
4759210cc5f9SKan Liang 	SNR_PCI_UNCORE_M2M,
4760a3b1e845SKan Liang 	SNR_PCI_UNCORE_PCIE3,
4761210cc5f9SKan Liang };
4762210cc5f9SKan Liang 
4763210cc5f9SKan Liang static struct intel_uncore_type *snr_pci_uncores[] = {
4764210cc5f9SKan Liang 	[SNR_PCI_UNCORE_M2M]		= &snr_uncore_m2m,
4765a3b1e845SKan Liang 	[SNR_PCI_UNCORE_PCIE3]		= &snr_uncore_pcie3,
4766210cc5f9SKan Liang 	NULL,
4767210cc5f9SKan Liang };
4768210cc5f9SKan Liang 
4769210cc5f9SKan Liang static const struct pci_device_id snr_uncore_pci_ids[] = {
4770210cc5f9SKan Liang 	{ /* M2M */
4771210cc5f9SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a),
4772210cc5f9SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(12, 0, SNR_PCI_UNCORE_M2M, 0),
4773210cc5f9SKan Liang 	},
4774210cc5f9SKan Liang 	{ /* end: all zeroes */ }
4775210cc5f9SKan Liang };
4776210cc5f9SKan Liang 
4777210cc5f9SKan Liang static struct pci_driver snr_uncore_pci_driver = {
4778210cc5f9SKan Liang 	.name		= "snr_uncore",
4779210cc5f9SKan Liang 	.id_table	= snr_uncore_pci_ids,
4780210cc5f9SKan Liang };
4781210cc5f9SKan Liang 
4782a3b1e845SKan Liang static const struct pci_device_id snr_uncore_pci_sub_ids[] = {
4783a3b1e845SKan Liang 	{ /* PCIe3 RP */
4784a3b1e845SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x334a),
4785a3b1e845SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(4, 0, SNR_PCI_UNCORE_PCIE3, 0),
4786a3b1e845SKan Liang 	},
4787a3b1e845SKan Liang 	{ /* end: all zeroes */ }
4788a3b1e845SKan Liang };
4789a3b1e845SKan Liang 
4790a3b1e845SKan Liang static struct pci_driver snr_uncore_pci_sub_driver = {
4791a3b1e845SKan Liang 	.name		= "snr_uncore_sub",
4792a3b1e845SKan Liang 	.id_table	= snr_uncore_pci_sub_ids,
4793a3b1e845SKan Liang };
4794a3b1e845SKan Liang 
4795210cc5f9SKan Liang int snr_uncore_pci_init(void)
4796210cc5f9SKan Liang {
4797210cc5f9SKan Liang 	/* SNR UBOX DID */
4798210cc5f9SKan Liang 	int ret = snbep_pci2phy_map_init(0x3460, SKX_CPUNODEID,
4799210cc5f9SKan Liang 					 SKX_GIDNIDMAP, true);
4800210cc5f9SKan Liang 
4801210cc5f9SKan Liang 	if (ret)
4802210cc5f9SKan Liang 		return ret;
4803210cc5f9SKan Liang 
4804210cc5f9SKan Liang 	uncore_pci_uncores = snr_pci_uncores;
4805210cc5f9SKan Liang 	uncore_pci_driver = &snr_uncore_pci_driver;
4806a3b1e845SKan Liang 	uncore_pci_sub_driver = &snr_uncore_pci_sub_driver;
4807210cc5f9SKan Liang 	return 0;
4808210cc5f9SKan Liang }
4809210cc5f9SKan Liang 
48101583971bSKan Liang #define SNR_MC_DEVICE_ID	0x3451
48111583971bSKan Liang 
48121583971bSKan Liang static struct pci_dev *snr_uncore_get_mc_dev(unsigned int device, int id)
4813ee49532bSKan Liang {
4814ee49532bSKan Liang 	struct pci_dev *mc_dev = NULL;
4815ba9506beSSteve Wahl 	int pkg;
4816ee49532bSKan Liang 
4817ee49532bSKan Liang 	while (1) {
48181583971bSKan Liang 		mc_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, mc_dev);
4819ee49532bSKan Liang 		if (!mc_dev)
4820ee49532bSKan Liang 			break;
4821ba9506beSSteve Wahl 		pkg = uncore_pcibus_to_dieid(mc_dev->bus);
4822ba9506beSSteve Wahl 		if (pkg == id)
4823ee49532bSKan Liang 			break;
4824ee49532bSKan Liang 	}
4825ee49532bSKan Liang 	return mc_dev;
4826ee49532bSKan Liang }
4827ee49532bSKan Liang 
48281583971bSKan Liang static int snr_uncore_mmio_map(struct intel_uncore_box *box,
48291583971bSKan Liang 			       unsigned int box_ctl, int mem_offset,
48301583971bSKan Liang 			       unsigned int device)
4831ee49532bSKan Liang {
48321583971bSKan Liang 	struct pci_dev *pdev = snr_uncore_get_mc_dev(device, box->dieid);
48331b94d31dSKan Liang 	struct intel_uncore_type *type = box->pmu->type;
4834ee49532bSKan Liang 	resource_size_t addr;
4835ee49532bSKan Liang 	u32 pci_dword;
4836ee49532bSKan Liang 
4837ee49532bSKan Liang 	if (!pdev)
48381583971bSKan Liang 		return -ENODEV;
4839ee49532bSKan Liang 
4840ee49532bSKan Liang 	pci_read_config_dword(pdev, SNR_IMC_MMIO_BASE_OFFSET, &pci_dword);
48410b3a8738SColin Ian King 	addr = ((resource_size_t)pci_dword & SNR_IMC_MMIO_BASE_MASK) << 23;
4842ee49532bSKan Liang 
48433442a9ecSKan Liang 	pci_read_config_dword(pdev, mem_offset, &pci_dword);
4844ee49532bSKan Liang 	addr |= (pci_dword & SNR_IMC_MMIO_MEM0_MASK) << 12;
4845ee49532bSKan Liang 
4846ee49532bSKan Liang 	addr += box_ctl;
4847ee49532bSKan Liang 
48481b94d31dSKan Liang 	box->io_addr = ioremap(addr, type->mmio_map_size);
48491b94d31dSKan Liang 	if (!box->io_addr) {
48501b94d31dSKan Liang 		pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
48511583971bSKan Liang 		return -EINVAL;
48521b94d31dSKan Liang 	}
4853ee49532bSKan Liang 
48541583971bSKan Liang 	return 0;
48551583971bSKan Liang }
48561583971bSKan Liang 
48571583971bSKan Liang static void __snr_uncore_mmio_init_box(struct intel_uncore_box *box,
48581583971bSKan Liang 				       unsigned int box_ctl, int mem_offset,
48591583971bSKan Liang 				       unsigned int device)
48601583971bSKan Liang {
48611583971bSKan Liang 	if (!snr_uncore_mmio_map(box, box_ctl, mem_offset, device))
4862ee49532bSKan Liang 		writel(IVBEP_PMON_BOX_CTL_INT, box->io_addr);
4863ee49532bSKan Liang }
4864ee49532bSKan Liang 
48653442a9ecSKan Liang static void snr_uncore_mmio_init_box(struct intel_uncore_box *box)
48663442a9ecSKan Liang {
48673442a9ecSKan Liang 	__snr_uncore_mmio_init_box(box, uncore_mmio_box_ctl(box),
48681583971bSKan Liang 				   SNR_IMC_MMIO_MEM0_OFFSET,
48691583971bSKan Liang 				   SNR_MC_DEVICE_ID);
48703442a9ecSKan Liang }
48713442a9ecSKan Liang 
4872ee49532bSKan Liang static void snr_uncore_mmio_disable_box(struct intel_uncore_box *box)
4873ee49532bSKan Liang {
4874ee49532bSKan Liang 	u32 config;
4875ee49532bSKan Liang 
4876ee49532bSKan Liang 	if (!box->io_addr)
4877ee49532bSKan Liang 		return;
4878ee49532bSKan Liang 
4879ee49532bSKan Liang 	config = readl(box->io_addr);
4880ee49532bSKan Liang 	config |= SNBEP_PMON_BOX_CTL_FRZ;
4881ee49532bSKan Liang 	writel(config, box->io_addr);
4882ee49532bSKan Liang }
4883ee49532bSKan Liang 
4884ee49532bSKan Liang static void snr_uncore_mmio_enable_box(struct intel_uncore_box *box)
4885ee49532bSKan Liang {
4886ee49532bSKan Liang 	u32 config;
4887ee49532bSKan Liang 
4888ee49532bSKan Liang 	if (!box->io_addr)
4889ee49532bSKan Liang 		return;
4890ee49532bSKan Liang 
4891ee49532bSKan Liang 	config = readl(box->io_addr);
4892ee49532bSKan Liang 	config &= ~SNBEP_PMON_BOX_CTL_FRZ;
4893ee49532bSKan Liang 	writel(config, box->io_addr);
4894ee49532bSKan Liang }
4895ee49532bSKan Liang 
4896ee49532bSKan Liang static void snr_uncore_mmio_enable_event(struct intel_uncore_box *box,
4897ee49532bSKan Liang 					   struct perf_event *event)
4898ee49532bSKan Liang {
4899ee49532bSKan Liang 	struct hw_perf_event *hwc = &event->hw;
4900ee49532bSKan Liang 
4901ee49532bSKan Liang 	if (!box->io_addr)
4902ee49532bSKan Liang 		return;
4903ee49532bSKan Liang 
4904f0171973SKan Liang 	if (!uncore_mmio_is_valid_offset(box, hwc->config_base))
4905f0171973SKan Liang 		return;
4906f0171973SKan Liang 
4907ee49532bSKan Liang 	writel(hwc->config | SNBEP_PMON_CTL_EN,
4908ee49532bSKan Liang 	       box->io_addr + hwc->config_base);
4909ee49532bSKan Liang }
4910ee49532bSKan Liang 
4911ee49532bSKan Liang static void snr_uncore_mmio_disable_event(struct intel_uncore_box *box,
4912ee49532bSKan Liang 					    struct perf_event *event)
4913ee49532bSKan Liang {
4914ee49532bSKan Liang 	struct hw_perf_event *hwc = &event->hw;
4915ee49532bSKan Liang 
4916ee49532bSKan Liang 	if (!box->io_addr)
4917ee49532bSKan Liang 		return;
4918ee49532bSKan Liang 
4919f0171973SKan Liang 	if (!uncore_mmio_is_valid_offset(box, hwc->config_base))
4920f0171973SKan Liang 		return;
4921f0171973SKan Liang 
4922ee49532bSKan Liang 	writel(hwc->config, box->io_addr + hwc->config_base);
4923ee49532bSKan Liang }
4924ee49532bSKan Liang 
4925ee49532bSKan Liang static struct intel_uncore_ops snr_uncore_mmio_ops = {
4926ee49532bSKan Liang 	.init_box	= snr_uncore_mmio_init_box,
4927ee49532bSKan Liang 	.exit_box	= uncore_mmio_exit_box,
4928ee49532bSKan Liang 	.disable_box	= snr_uncore_mmio_disable_box,
4929ee49532bSKan Liang 	.enable_box	= snr_uncore_mmio_enable_box,
4930ee49532bSKan Liang 	.disable_event	= snr_uncore_mmio_disable_event,
4931ee49532bSKan Liang 	.enable_event	= snr_uncore_mmio_enable_event,
4932ee49532bSKan Liang 	.read_counter	= uncore_mmio_read_counter,
4933ee49532bSKan Liang };
4934ee49532bSKan Liang 
4935ee49532bSKan Liang static struct uncore_event_desc snr_uncore_imc_events[] = {
4936ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(clockticks,      "event=0x00,umask=0x00"),
4937ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(cas_count_read,  "event=0x04,umask=0x0f"),
4938ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(cas_count_read.scale, "6.103515625e-5"),
4939ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(cas_count_read.unit, "MiB"),
4940ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x30"),
4941ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(cas_count_write.scale, "6.103515625e-5"),
4942ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(cas_count_write.unit, "MiB"),
4943ee49532bSKan Liang 	{ /* end: all zeroes */ },
4944ee49532bSKan Liang };
4945ee49532bSKan Liang 
4946ee49532bSKan Liang static struct intel_uncore_type snr_uncore_imc = {
4947ee49532bSKan Liang 	.name		= "imc",
4948ee49532bSKan Liang 	.num_counters   = 4,
4949ee49532bSKan Liang 	.num_boxes	= 2,
4950ee49532bSKan Liang 	.perf_ctr_bits	= 48,
4951ee49532bSKan Liang 	.fixed_ctr_bits	= 48,
4952ee49532bSKan Liang 	.fixed_ctr	= SNR_IMC_MMIO_PMON_FIXED_CTR,
4953ee49532bSKan Liang 	.fixed_ctl	= SNR_IMC_MMIO_PMON_FIXED_CTL,
4954ee49532bSKan Liang 	.event_descs	= snr_uncore_imc_events,
4955ee49532bSKan Liang 	.perf_ctr	= SNR_IMC_MMIO_PMON_CTR0,
4956ee49532bSKan Liang 	.event_ctl	= SNR_IMC_MMIO_PMON_CTL0,
4957ee49532bSKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
4958ee49532bSKan Liang 	.box_ctl	= SNR_IMC_MMIO_PMON_BOX_CTL,
4959ee49532bSKan Liang 	.mmio_offset	= SNR_IMC_MMIO_OFFSET,
49601b94d31dSKan Liang 	.mmio_map_size	= SNR_IMC_MMIO_SIZE,
4961ee49532bSKan Liang 	.ops		= &snr_uncore_mmio_ops,
4962ee49532bSKan Liang 	.format_group	= &skx_uncore_format_group,
4963ee49532bSKan Liang };
4964ee49532bSKan Liang 
4965ee49532bSKan Liang enum perf_uncore_snr_imc_freerunning_type_id {
4966ee49532bSKan Liang 	SNR_IMC_DCLK,
4967ee49532bSKan Liang 	SNR_IMC_DDR,
4968ee49532bSKan Liang 
4969ee49532bSKan Liang 	SNR_IMC_FREERUNNING_TYPE_MAX,
4970ee49532bSKan Liang };
4971ee49532bSKan Liang 
4972ee49532bSKan Liang static struct freerunning_counters snr_imc_freerunning[] = {
4973ee49532bSKan Liang 	[SNR_IMC_DCLK]	= { 0x22b0, 0x0, 0, 1, 48 },
4974ee49532bSKan Liang 	[SNR_IMC_DDR]	= { 0x2290, 0x8, 0, 2, 48 },
4975ee49532bSKan Liang };
4976ee49532bSKan Liang 
4977ee49532bSKan Liang static struct uncore_event_desc snr_uncore_imc_freerunning_events[] = {
4978ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(dclk,		"event=0xff,umask=0x10"),
4979ee49532bSKan Liang 
4980ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(read,		"event=0xff,umask=0x20"),
49818191016aSKan Liang 	INTEL_UNCORE_EVENT_DESC(read.scale,	"6.103515625e-5"),
4982ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(read.unit,	"MiB"),
4983ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(write,		"event=0xff,umask=0x21"),
49848191016aSKan Liang 	INTEL_UNCORE_EVENT_DESC(write.scale,	"6.103515625e-5"),
4985ee49532bSKan Liang 	INTEL_UNCORE_EVENT_DESC(write.unit,	"MiB"),
4986fa694ae5SKan Liang 	{ /* end: all zeroes */ },
4987ee49532bSKan Liang };
4988ee49532bSKan Liang 
4989ee49532bSKan Liang static struct intel_uncore_ops snr_uncore_imc_freerunning_ops = {
4990ee49532bSKan Liang 	.init_box	= snr_uncore_mmio_init_box,
4991ee49532bSKan Liang 	.exit_box	= uncore_mmio_exit_box,
4992ee49532bSKan Liang 	.read_counter	= uncore_mmio_read_counter,
4993ee49532bSKan Liang 	.hw_config	= uncore_freerunning_hw_config,
4994ee49532bSKan Liang };
4995ee49532bSKan Liang 
4996ee49532bSKan Liang static struct intel_uncore_type snr_uncore_imc_free_running = {
4997ee49532bSKan Liang 	.name			= "imc_free_running",
4998ee49532bSKan Liang 	.num_counters		= 3,
4999ee49532bSKan Liang 	.num_boxes		= 1,
5000ee49532bSKan Liang 	.num_freerunning_types	= SNR_IMC_FREERUNNING_TYPE_MAX,
50011b94d31dSKan Liang 	.mmio_map_size		= SNR_IMC_MMIO_SIZE,
5002ee49532bSKan Liang 	.freerunning		= snr_imc_freerunning,
5003ee49532bSKan Liang 	.ops			= &snr_uncore_imc_freerunning_ops,
5004ee49532bSKan Liang 	.event_descs		= snr_uncore_imc_freerunning_events,
5005ee49532bSKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
5006ee49532bSKan Liang };
5007ee49532bSKan Liang 
5008ee49532bSKan Liang static struct intel_uncore_type *snr_mmio_uncores[] = {
5009ee49532bSKan Liang 	&snr_uncore_imc,
5010ee49532bSKan Liang 	&snr_uncore_imc_free_running,
5011ee49532bSKan Liang 	NULL,
5012ee49532bSKan Liang };
5013ee49532bSKan Liang 
5014ee49532bSKan Liang void snr_uncore_mmio_init(void)
5015ee49532bSKan Liang {
5016ee49532bSKan Liang 	uncore_mmio_uncores = snr_mmio_uncores;
5017ee49532bSKan Liang }
5018ee49532bSKan Liang 
5019210cc5f9SKan Liang /* end of SNR uncore support */
50202b3b76b5SKan Liang 
50212b3b76b5SKan Liang /* ICX uncore support */
50222b3b76b5SKan Liang 
50232b3b76b5SKan Liang static unsigned icx_cha_msr_offsets[] = {
50242b3b76b5SKan Liang 	0x2a0, 0x2ae, 0x2bc, 0x2ca, 0x2d8, 0x2e6, 0x2f4, 0x302, 0x310,
50252b3b76b5SKan Liang 	0x31e, 0x32c, 0x33a, 0x348, 0x356, 0x364, 0x372, 0x380, 0x38e,
50262b3b76b5SKan Liang 	0x3aa, 0x3b8, 0x3c6, 0x3d4, 0x3e2, 0x3f0, 0x3fe, 0x40c, 0x41a,
50272b3b76b5SKan Liang 	0x428, 0x436, 0x444, 0x452, 0x460, 0x46e, 0x47c, 0x0,   0xe,
50282b3b76b5SKan Liang 	0x1c,  0x2a,  0x38,  0x46,
50292b3b76b5SKan Liang };
50302b3b76b5SKan Liang 
50312b3b76b5SKan Liang static int icx_cha_hw_config(struct intel_uncore_box *box, struct perf_event *event)
50322b3b76b5SKan Liang {
50332b3b76b5SKan Liang 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
50342b3b76b5SKan Liang 	bool tie_en = !!(event->hw.config & SNBEP_CBO_PMON_CTL_TID_EN);
50352b3b76b5SKan Liang 
50362b3b76b5SKan Liang 	if (tie_en) {
50372b3b76b5SKan Liang 		reg1->reg = ICX_C34_MSR_PMON_BOX_FILTER0 +
50382b3b76b5SKan Liang 			    icx_cha_msr_offsets[box->pmu->pmu_idx];
50392b3b76b5SKan Liang 		reg1->config = event->attr.config1 & SKX_CHA_MSR_PMON_BOX_FILTER_TID;
50402b3b76b5SKan Liang 		reg1->idx = 0;
50412b3b76b5SKan Liang 	}
50422b3b76b5SKan Liang 
50432b3b76b5SKan Liang 	return 0;
50442b3b76b5SKan Liang }
50452b3b76b5SKan Liang 
50462b3b76b5SKan Liang static struct intel_uncore_ops icx_uncore_chabox_ops = {
50472b3b76b5SKan Liang 	.init_box		= ivbep_uncore_msr_init_box,
50482b3b76b5SKan Liang 	.disable_box		= snbep_uncore_msr_disable_box,
50492b3b76b5SKan Liang 	.enable_box		= snbep_uncore_msr_enable_box,
50502b3b76b5SKan Liang 	.disable_event		= snbep_uncore_msr_disable_event,
50512b3b76b5SKan Liang 	.enable_event		= snr_cha_enable_event,
50522b3b76b5SKan Liang 	.read_counter		= uncore_msr_read_counter,
50532b3b76b5SKan Liang 	.hw_config		= icx_cha_hw_config,
50542b3b76b5SKan Liang };
50552b3b76b5SKan Liang 
50562b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_chabox = {
50572b3b76b5SKan Liang 	.name			= "cha",
50582b3b76b5SKan Liang 	.num_counters		= 4,
50592b3b76b5SKan Liang 	.perf_ctr_bits		= 48,
50602b3b76b5SKan Liang 	.event_ctl		= ICX_C34_MSR_PMON_CTL0,
50612b3b76b5SKan Liang 	.perf_ctr		= ICX_C34_MSR_PMON_CTR0,
50622b3b76b5SKan Liang 	.box_ctl		= ICX_C34_MSR_PMON_BOX_CTL,
50632b3b76b5SKan Liang 	.msr_offsets		= icx_cha_msr_offsets,
50642b3b76b5SKan Liang 	.event_mask		= HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
50652b3b76b5SKan Liang 	.event_mask_ext		= SNR_CHA_RAW_EVENT_MASK_EXT,
50662b3b76b5SKan Liang 	.constraints		= skx_uncore_chabox_constraints,
50672b3b76b5SKan Liang 	.ops			= &icx_uncore_chabox_ops,
50682b3b76b5SKan Liang 	.format_group		= &snr_uncore_chabox_format_group,
50692b3b76b5SKan Liang };
50702b3b76b5SKan Liang 
50712b3b76b5SKan Liang static unsigned icx_msr_offsets[] = {
50722b3b76b5SKan Liang 	0x0, 0x20, 0x40, 0x90, 0xb0, 0xd0,
50732b3b76b5SKan Liang };
50742b3b76b5SKan Liang 
50752b3b76b5SKan Liang static struct event_constraint icx_uncore_iio_constraints[] = {
50762b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x02, 0x3),
50772b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x03, 0x3),
50782b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x83, 0x3),
5079*f42e8a60SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x88, 0xc),
50802b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0xc0, 0xc),
50812b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0xc5, 0xc),
5082*f42e8a60SKan Liang 	UNCORE_EVENT_CONSTRAINT(0xd5, 0xc),
50832b3b76b5SKan Liang 	EVENT_CONSTRAINT_END
50842b3b76b5SKan Liang };
50852b3b76b5SKan Liang 
508610337e95SAlexander Antonov static umode_t
508710337e95SAlexander Antonov icx_iio_mapping_visible(struct kobject *kobj, struct attribute *attr, int die)
508810337e95SAlexander Antonov {
508910337e95SAlexander Antonov 	/* Root bus 0x00 is valid only for pmu_idx = 5. */
509010337e95SAlexander Antonov 	return pmu_iio_mapping_visible(kobj, attr, die, 5);
509110337e95SAlexander Antonov }
509210337e95SAlexander Antonov 
509310337e95SAlexander Antonov static struct attribute_group icx_iio_mapping_group = {
509410337e95SAlexander Antonov 	.is_visible	= icx_iio_mapping_visible,
509510337e95SAlexander Antonov };
509610337e95SAlexander Antonov 
509710337e95SAlexander Antonov static const struct attribute_group *icx_iio_attr_update[] = {
509810337e95SAlexander Antonov 	&icx_iio_mapping_group,
509910337e95SAlexander Antonov 	NULL,
510010337e95SAlexander Antonov };
510110337e95SAlexander Antonov 
510210337e95SAlexander Antonov /*
510310337e95SAlexander Antonov  * ICX has a static mapping of stack IDs from SAD_CONTROL_CFG notation to PMON
510410337e95SAlexander Antonov  */
510510337e95SAlexander Antonov enum {
510610337e95SAlexander Antonov 	ICX_PCIE1_PMON_ID,
510710337e95SAlexander Antonov 	ICX_PCIE2_PMON_ID,
510810337e95SAlexander Antonov 	ICX_PCIE3_PMON_ID,
510910337e95SAlexander Antonov 	ICX_PCIE4_PMON_ID,
511010337e95SAlexander Antonov 	ICX_PCIE5_PMON_ID,
511110337e95SAlexander Antonov 	ICX_CBDMA_DMI_PMON_ID
511210337e95SAlexander Antonov };
511310337e95SAlexander Antonov 
511410337e95SAlexander Antonov static u8 icx_sad_pmon_mapping[] = {
511510337e95SAlexander Antonov 	ICX_CBDMA_DMI_PMON_ID,
511610337e95SAlexander Antonov 	ICX_PCIE1_PMON_ID,
511710337e95SAlexander Antonov 	ICX_PCIE2_PMON_ID,
511810337e95SAlexander Antonov 	ICX_PCIE3_PMON_ID,
511910337e95SAlexander Antonov 	ICX_PCIE4_PMON_ID,
512010337e95SAlexander Antonov 	ICX_PCIE5_PMON_ID,
512110337e95SAlexander Antonov };
512210337e95SAlexander Antonov 
512310337e95SAlexander Antonov static int icx_iio_get_topology(struct intel_uncore_type *type)
512410337e95SAlexander Antonov {
512510337e95SAlexander Antonov 	return sad_cfg_iio_topology(type, icx_sad_pmon_mapping);
512610337e95SAlexander Antonov }
512710337e95SAlexander Antonov 
512810337e95SAlexander Antonov static int icx_iio_set_mapping(struct intel_uncore_type *type)
512910337e95SAlexander Antonov {
513010337e95SAlexander Antonov 	return pmu_iio_set_mapping(type, &icx_iio_mapping_group);
513110337e95SAlexander Antonov }
513210337e95SAlexander Antonov 
51333f2cbe38SAlexander Antonov static void icx_iio_cleanup_mapping(struct intel_uncore_type *type)
51343f2cbe38SAlexander Antonov {
51353f2cbe38SAlexander Antonov 	pmu_iio_cleanup_mapping(type, &icx_iio_mapping_group);
51363f2cbe38SAlexander Antonov }
51373f2cbe38SAlexander Antonov 
51382b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_iio = {
51392b3b76b5SKan Liang 	.name			= "iio",
51402b3b76b5SKan Liang 	.num_counters		= 4,
51412b3b76b5SKan Liang 	.num_boxes		= 6,
51422b3b76b5SKan Liang 	.perf_ctr_bits		= 48,
51432b3b76b5SKan Liang 	.event_ctl		= ICX_IIO_MSR_PMON_CTL0,
51442b3b76b5SKan Liang 	.perf_ctr		= ICX_IIO_MSR_PMON_CTR0,
51452b3b76b5SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
51462b3b76b5SKan Liang 	.event_mask_ext		= SNR_IIO_PMON_RAW_EVENT_MASK_EXT,
51472b3b76b5SKan Liang 	.box_ctl		= ICX_IIO_MSR_PMON_BOX_CTL,
51482b3b76b5SKan Liang 	.msr_offsets		= icx_msr_offsets,
51492b3b76b5SKan Liang 	.constraints		= icx_uncore_iio_constraints,
51502b3b76b5SKan Liang 	.ops			= &skx_uncore_iio_ops,
51512b3b76b5SKan Liang 	.format_group		= &snr_uncore_iio_format_group,
515210337e95SAlexander Antonov 	.attr_update		= icx_iio_attr_update,
515310337e95SAlexander Antonov 	.get_topology		= icx_iio_get_topology,
515410337e95SAlexander Antonov 	.set_mapping		= icx_iio_set_mapping,
51553f2cbe38SAlexander Antonov 	.cleanup_mapping	= icx_iio_cleanup_mapping,
51562b3b76b5SKan Liang };
51572b3b76b5SKan Liang 
51582b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_irp = {
51592b3b76b5SKan Liang 	.name			= "irp",
51602b3b76b5SKan Liang 	.num_counters		= 2,
51612b3b76b5SKan Liang 	.num_boxes		= 6,
51622b3b76b5SKan Liang 	.perf_ctr_bits		= 48,
51632b3b76b5SKan Liang 	.event_ctl		= ICX_IRP0_MSR_PMON_CTL0,
51642b3b76b5SKan Liang 	.perf_ctr		= ICX_IRP0_MSR_PMON_CTR0,
51652b3b76b5SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
51662b3b76b5SKan Liang 	.box_ctl		= ICX_IRP0_MSR_PMON_BOX_CTL,
51672b3b76b5SKan Liang 	.msr_offsets		= icx_msr_offsets,
51682b3b76b5SKan Liang 	.ops			= &ivbep_uncore_msr_ops,
51692b3b76b5SKan Liang 	.format_group		= &ivbep_uncore_format_group,
51702b3b76b5SKan Liang };
51712b3b76b5SKan Liang 
51722b3b76b5SKan Liang static struct event_constraint icx_uncore_m2pcie_constraints[] = {
51732b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
51742b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
51752b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
51762b3b76b5SKan Liang 	EVENT_CONSTRAINT_END
51772b3b76b5SKan Liang };
51782b3b76b5SKan Liang 
51792b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_m2pcie = {
51802b3b76b5SKan Liang 	.name		= "m2pcie",
51812b3b76b5SKan Liang 	.num_counters	= 4,
51822b3b76b5SKan Liang 	.num_boxes	= 6,
51832b3b76b5SKan Liang 	.perf_ctr_bits	= 48,
51842b3b76b5SKan Liang 	.event_ctl	= ICX_M2PCIE_MSR_PMON_CTL0,
51852b3b76b5SKan Liang 	.perf_ctr	= ICX_M2PCIE_MSR_PMON_CTR0,
51862b3b76b5SKan Liang 	.box_ctl	= ICX_M2PCIE_MSR_PMON_BOX_CTL,
51872b3b76b5SKan Liang 	.msr_offsets	= icx_msr_offsets,
51882b3b76b5SKan Liang 	.constraints	= icx_uncore_m2pcie_constraints,
51892b3b76b5SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
51902b3b76b5SKan Liang 	.ops		= &ivbep_uncore_msr_ops,
51912b3b76b5SKan Liang 	.format_group	= &ivbep_uncore_format_group,
51922b3b76b5SKan Liang };
51932b3b76b5SKan Liang 
51942b3b76b5SKan Liang enum perf_uncore_icx_iio_freerunning_type_id {
51952b3b76b5SKan Liang 	ICX_IIO_MSR_IOCLK,
51962b3b76b5SKan Liang 	ICX_IIO_MSR_BW_IN,
51972b3b76b5SKan Liang 
51982b3b76b5SKan Liang 	ICX_IIO_FREERUNNING_TYPE_MAX,
51992b3b76b5SKan Liang };
52002b3b76b5SKan Liang 
52012b3b76b5SKan Liang static unsigned icx_iio_clk_freerunning_box_offsets[] = {
52022b3b76b5SKan Liang 	0x0, 0x20, 0x40, 0x90, 0xb0, 0xd0,
52032b3b76b5SKan Liang };
52042b3b76b5SKan Liang 
52052b3b76b5SKan Liang static unsigned icx_iio_bw_freerunning_box_offsets[] = {
52062b3b76b5SKan Liang 	0x0, 0x10, 0x20, 0x90, 0xa0, 0xb0,
52072b3b76b5SKan Liang };
52082b3b76b5SKan Liang 
52092b3b76b5SKan Liang static struct freerunning_counters icx_iio_freerunning[] = {
52102b3b76b5SKan Liang 	[ICX_IIO_MSR_IOCLK]	= { 0xa55, 0x1, 0x20, 1, 48, icx_iio_clk_freerunning_box_offsets },
52112b3b76b5SKan Liang 	[ICX_IIO_MSR_BW_IN]	= { 0xaa0, 0x1, 0x10, 8, 48, icx_iio_bw_freerunning_box_offsets },
52122b3b76b5SKan Liang };
52132b3b76b5SKan Liang 
52142b3b76b5SKan Liang static struct uncore_event_desc icx_uncore_iio_freerunning_events[] = {
52152b3b76b5SKan Liang 	/* Free-Running IIO CLOCKS Counter */
52162b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(ioclk,			"event=0xff,umask=0x10"),
52172b3b76b5SKan Liang 	/* Free-Running IIO BANDWIDTH IN Counters */
52182b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0,		"event=0xff,umask=0x20"),
52192b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale,	"3.814697266e-6"),
52202b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit,	"MiB"),
52212b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1,		"event=0xff,umask=0x21"),
52222b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale,	"3.814697266e-6"),
52232b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit,	"MiB"),
52242b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2,		"event=0xff,umask=0x22"),
52252b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale,	"3.814697266e-6"),
52262b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit,	"MiB"),
52272b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3,		"event=0xff,umask=0x23"),
52282b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale,	"3.814697266e-6"),
52292b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit,	"MiB"),
52302b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4,		"event=0xff,umask=0x24"),
52312b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4.scale,	"3.814697266e-6"),
52322b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4.unit,	"MiB"),
52332b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5,		"event=0xff,umask=0x25"),
52342b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5.scale,	"3.814697266e-6"),
52352b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5.unit,	"MiB"),
52362b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6,		"event=0xff,umask=0x26"),
52372b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6.scale,	"3.814697266e-6"),
52382b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6.unit,	"MiB"),
52392b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7,		"event=0xff,umask=0x27"),
52402b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7.scale,	"3.814697266e-6"),
52412b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7.unit,	"MiB"),
52422b3b76b5SKan Liang 	{ /* end: all zeroes */ },
52432b3b76b5SKan Liang };
52442b3b76b5SKan Liang 
52452b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_iio_free_running = {
52462b3b76b5SKan Liang 	.name			= "iio_free_running",
52472b3b76b5SKan Liang 	.num_counters		= 9,
52482b3b76b5SKan Liang 	.num_boxes		= 6,
52492b3b76b5SKan Liang 	.num_freerunning_types	= ICX_IIO_FREERUNNING_TYPE_MAX,
52502b3b76b5SKan Liang 	.freerunning		= icx_iio_freerunning,
52512b3b76b5SKan Liang 	.ops			= &skx_uncore_iio_freerunning_ops,
52522b3b76b5SKan Liang 	.event_descs		= icx_uncore_iio_freerunning_events,
52532b3b76b5SKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
52542b3b76b5SKan Liang };
52552b3b76b5SKan Liang 
52562b3b76b5SKan Liang static struct intel_uncore_type *icx_msr_uncores[] = {
52572b3b76b5SKan Liang 	&skx_uncore_ubox,
52582b3b76b5SKan Liang 	&icx_uncore_chabox,
52592b3b76b5SKan Liang 	&icx_uncore_iio,
52602b3b76b5SKan Liang 	&icx_uncore_irp,
52612b3b76b5SKan Liang 	&icx_uncore_m2pcie,
52622b3b76b5SKan Liang 	&skx_uncore_pcu,
52632b3b76b5SKan Liang 	&icx_uncore_iio_free_running,
52642b3b76b5SKan Liang 	NULL,
52652b3b76b5SKan Liang };
52662b3b76b5SKan Liang 
52672b3b76b5SKan Liang /*
52682b3b76b5SKan Liang  * To determine the number of CHAs, it should read CAPID6(Low) and CAPID7 (High)
52692b3b76b5SKan Liang  * registers which located at Device 30, Function 3
52702b3b76b5SKan Liang  */
52712b3b76b5SKan Liang #define ICX_CAPID6		0x9c
52722b3b76b5SKan Liang #define ICX_CAPID7		0xa0
52732b3b76b5SKan Liang 
52742b3b76b5SKan Liang static u64 icx_count_chabox(void)
52752b3b76b5SKan Liang {
52762b3b76b5SKan Liang 	struct pci_dev *dev = NULL;
52772b3b76b5SKan Liang 	u64 caps = 0;
52782b3b76b5SKan Liang 
52792b3b76b5SKan Liang 	dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x345b, dev);
52802b3b76b5SKan Liang 	if (!dev)
52812b3b76b5SKan Liang 		goto out;
52822b3b76b5SKan Liang 
52832b3b76b5SKan Liang 	pci_read_config_dword(dev, ICX_CAPID6, (u32 *)&caps);
52842b3b76b5SKan Liang 	pci_read_config_dword(dev, ICX_CAPID7, (u32 *)&caps + 1);
52852b3b76b5SKan Liang out:
52862b3b76b5SKan Liang 	pci_dev_put(dev);
52872b3b76b5SKan Liang 	return hweight64(caps);
52882b3b76b5SKan Liang }
52892b3b76b5SKan Liang 
52902b3b76b5SKan Liang void icx_uncore_cpu_init(void)
52912b3b76b5SKan Liang {
52922b3b76b5SKan Liang 	u64 num_boxes = icx_count_chabox();
52932b3b76b5SKan Liang 
52942b3b76b5SKan Liang 	if (WARN_ON(num_boxes > ARRAY_SIZE(icx_cha_msr_offsets)))
52952b3b76b5SKan Liang 		return;
52962b3b76b5SKan Liang 	icx_uncore_chabox.num_boxes = num_boxes;
52972b3b76b5SKan Liang 	uncore_msr_uncores = icx_msr_uncores;
52982b3b76b5SKan Liang }
52992b3b76b5SKan Liang 
53002b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_m2m = {
53012b3b76b5SKan Liang 	.name		= "m2m",
53022b3b76b5SKan Liang 	.num_counters   = 4,
53032b3b76b5SKan Liang 	.num_boxes	= 4,
53042b3b76b5SKan Liang 	.perf_ctr_bits	= 48,
53052b3b76b5SKan Liang 	.perf_ctr	= SNR_M2M_PCI_PMON_CTR0,
53062b3b76b5SKan Liang 	.event_ctl	= SNR_M2M_PCI_PMON_CTL0,
53072b3b76b5SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
5308848ff376SKan Liang 	.event_mask_ext	= SNR_M2M_PCI_PMON_UMASK_EXT,
53092b3b76b5SKan Liang 	.box_ctl	= SNR_M2M_PCI_PMON_BOX_CTL,
53102b3b76b5SKan Liang 	.ops		= &snr_m2m_uncore_pci_ops,
5311848ff376SKan Liang 	.format_group	= &snr_m2m_uncore_format_group,
53122b3b76b5SKan Liang };
53132b3b76b5SKan Liang 
53142b3b76b5SKan Liang static struct attribute *icx_upi_uncore_formats_attr[] = {
53152b3b76b5SKan Liang 	&format_attr_event.attr,
53162b3b76b5SKan Liang 	&format_attr_umask_ext4.attr,
53172b3b76b5SKan Liang 	&format_attr_edge.attr,
53182b3b76b5SKan Liang 	&format_attr_inv.attr,
53192b3b76b5SKan Liang 	&format_attr_thresh8.attr,
53202b3b76b5SKan Liang 	NULL,
53212b3b76b5SKan Liang };
53222b3b76b5SKan Liang 
53232b3b76b5SKan Liang static const struct attribute_group icx_upi_uncore_format_group = {
53242b3b76b5SKan Liang 	.name = "format",
53252b3b76b5SKan Liang 	.attrs = icx_upi_uncore_formats_attr,
53262b3b76b5SKan Liang };
53272b3b76b5SKan Liang 
53282b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_upi = {
53292b3b76b5SKan Liang 	.name		= "upi",
53302b3b76b5SKan Liang 	.num_counters   = 4,
53312b3b76b5SKan Liang 	.num_boxes	= 3,
53322b3b76b5SKan Liang 	.perf_ctr_bits	= 48,
53332b3b76b5SKan Liang 	.perf_ctr	= ICX_UPI_PCI_PMON_CTR0,
53342b3b76b5SKan Liang 	.event_ctl	= ICX_UPI_PCI_PMON_CTL0,
53352b3b76b5SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
53362b3b76b5SKan Liang 	.event_mask_ext = ICX_UPI_CTL_UMASK_EXT,
53372b3b76b5SKan Liang 	.box_ctl	= ICX_UPI_PCI_PMON_BOX_CTL,
53382b3b76b5SKan Liang 	.ops		= &skx_upi_uncore_pci_ops,
53392b3b76b5SKan Liang 	.format_group	= &icx_upi_uncore_format_group,
53402b3b76b5SKan Liang };
53412b3b76b5SKan Liang 
53422b3b76b5SKan Liang static struct event_constraint icx_uncore_m3upi_constraints[] = {
53432b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x1c, 0x1),
53442b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x1d, 0x1),
53452b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x1e, 0x1),
53462b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x1f, 0x1),
53472b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x40, 0x7),
53482b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x4e, 0x7),
53492b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x4f, 0x7),
53502b3b76b5SKan Liang 	UNCORE_EVENT_CONSTRAINT(0x50, 0x7),
53512b3b76b5SKan Liang 	EVENT_CONSTRAINT_END
53522b3b76b5SKan Liang };
53532b3b76b5SKan Liang 
53542b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_m3upi = {
53552b3b76b5SKan Liang 	.name		= "m3upi",
53562b3b76b5SKan Liang 	.num_counters   = 4,
53572b3b76b5SKan Liang 	.num_boxes	= 3,
53582b3b76b5SKan Liang 	.perf_ctr_bits	= 48,
53592b3b76b5SKan Liang 	.perf_ctr	= ICX_M3UPI_PCI_PMON_CTR0,
53602b3b76b5SKan Liang 	.event_ctl	= ICX_M3UPI_PCI_PMON_CTL0,
53612b3b76b5SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
53622b3b76b5SKan Liang 	.box_ctl	= ICX_M3UPI_PCI_PMON_BOX_CTL,
53632b3b76b5SKan Liang 	.constraints	= icx_uncore_m3upi_constraints,
53642b3b76b5SKan Liang 	.ops		= &ivbep_uncore_pci_ops,
53652b3b76b5SKan Liang 	.format_group	= &skx_uncore_format_group,
53662b3b76b5SKan Liang };
53672b3b76b5SKan Liang 
53682b3b76b5SKan Liang enum {
53692b3b76b5SKan Liang 	ICX_PCI_UNCORE_M2M,
53702b3b76b5SKan Liang 	ICX_PCI_UNCORE_UPI,
53712b3b76b5SKan Liang 	ICX_PCI_UNCORE_M3UPI,
53722b3b76b5SKan Liang };
53732b3b76b5SKan Liang 
53742b3b76b5SKan Liang static struct intel_uncore_type *icx_pci_uncores[] = {
53752b3b76b5SKan Liang 	[ICX_PCI_UNCORE_M2M]		= &icx_uncore_m2m,
53762b3b76b5SKan Liang 	[ICX_PCI_UNCORE_UPI]		= &icx_uncore_upi,
53772b3b76b5SKan Liang 	[ICX_PCI_UNCORE_M3UPI]		= &icx_uncore_m3upi,
53782b3b76b5SKan Liang 	NULL,
53792b3b76b5SKan Liang };
53802b3b76b5SKan Liang 
53812b3b76b5SKan Liang static const struct pci_device_id icx_uncore_pci_ids[] = {
53822b3b76b5SKan Liang 	{ /* M2M 0 */
53832b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a),
53842b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(12, 0, ICX_PCI_UNCORE_M2M, 0),
53852b3b76b5SKan Liang 	},
53862b3b76b5SKan Liang 	{ /* M2M 1 */
53872b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a),
53882b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(13, 0, ICX_PCI_UNCORE_M2M, 1),
53892b3b76b5SKan Liang 	},
53902b3b76b5SKan Liang 	{ /* M2M 2 */
53912b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a),
53922b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(14, 0, ICX_PCI_UNCORE_M2M, 2),
53932b3b76b5SKan Liang 	},
53942b3b76b5SKan Liang 	{ /* M2M 3 */
53952b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a),
53962b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(15, 0, ICX_PCI_UNCORE_M2M, 3),
53972b3b76b5SKan Liang 	},
53982b3b76b5SKan Liang 	{ /* UPI Link 0 */
53992b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3441),
54002b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(2, 1, ICX_PCI_UNCORE_UPI, 0),
54012b3b76b5SKan Liang 	},
54022b3b76b5SKan Liang 	{ /* UPI Link 1 */
54032b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3441),
54042b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(3, 1, ICX_PCI_UNCORE_UPI, 1),
54052b3b76b5SKan Liang 	},
54062b3b76b5SKan Liang 	{ /* UPI Link 2 */
54072b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3441),
54082b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(4, 1, ICX_PCI_UNCORE_UPI, 2),
54092b3b76b5SKan Liang 	},
54102b3b76b5SKan Liang 	{ /* M3UPI Link 0 */
54112b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3446),
54122b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(5, 1, ICX_PCI_UNCORE_M3UPI, 0),
54132b3b76b5SKan Liang 	},
54142b3b76b5SKan Liang 	{ /* M3UPI Link 1 */
54152b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3446),
54162b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(6, 1, ICX_PCI_UNCORE_M3UPI, 1),
54172b3b76b5SKan Liang 	},
54182b3b76b5SKan Liang 	{ /* M3UPI Link 2 */
54192b3b76b5SKan Liang 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3446),
54202b3b76b5SKan Liang 		.driver_data = UNCORE_PCI_DEV_FULL_DATA(7, 1, ICX_PCI_UNCORE_M3UPI, 2),
54212b3b76b5SKan Liang 	},
54222b3b76b5SKan Liang 	{ /* end: all zeroes */ }
54232b3b76b5SKan Liang };
54242b3b76b5SKan Liang 
54252b3b76b5SKan Liang static struct pci_driver icx_uncore_pci_driver = {
54262b3b76b5SKan Liang 	.name		= "icx_uncore",
54272b3b76b5SKan Liang 	.id_table	= icx_uncore_pci_ids,
54282b3b76b5SKan Liang };
54292b3b76b5SKan Liang 
54302b3b76b5SKan Liang int icx_uncore_pci_init(void)
54312b3b76b5SKan Liang {
54322b3b76b5SKan Liang 	/* ICX UBOX DID */
54332b3b76b5SKan Liang 	int ret = snbep_pci2phy_map_init(0x3450, SKX_CPUNODEID,
54342b3b76b5SKan Liang 					 SKX_GIDNIDMAP, true);
54352b3b76b5SKan Liang 
54362b3b76b5SKan Liang 	if (ret)
54372b3b76b5SKan Liang 		return ret;
54382b3b76b5SKan Liang 
54392b3b76b5SKan Liang 	uncore_pci_uncores = icx_pci_uncores;
54402b3b76b5SKan Liang 	uncore_pci_driver = &icx_uncore_pci_driver;
54412b3b76b5SKan Liang 	return 0;
54422b3b76b5SKan Liang }
54432b3b76b5SKan Liang 
54442b3b76b5SKan Liang static void icx_uncore_imc_init_box(struct intel_uncore_box *box)
54452b3b76b5SKan Liang {
54462b3b76b5SKan Liang 	unsigned int box_ctl = box->pmu->type->box_ctl +
54472b3b76b5SKan Liang 			       box->pmu->type->mmio_offset * (box->pmu->pmu_idx % ICX_NUMBER_IMC_CHN);
54482b3b76b5SKan Liang 	int mem_offset = (box->pmu->pmu_idx / ICX_NUMBER_IMC_CHN) * ICX_IMC_MEM_STRIDE +
54492b3b76b5SKan Liang 			 SNR_IMC_MMIO_MEM0_OFFSET;
54502b3b76b5SKan Liang 
54511583971bSKan Liang 	__snr_uncore_mmio_init_box(box, box_ctl, mem_offset,
54521583971bSKan Liang 				   SNR_MC_DEVICE_ID);
54532b3b76b5SKan Liang }
54542b3b76b5SKan Liang 
54552b3b76b5SKan Liang static struct intel_uncore_ops icx_uncore_mmio_ops = {
54562b3b76b5SKan Liang 	.init_box	= icx_uncore_imc_init_box,
54572b3b76b5SKan Liang 	.exit_box	= uncore_mmio_exit_box,
54582b3b76b5SKan Liang 	.disable_box	= snr_uncore_mmio_disable_box,
54592b3b76b5SKan Liang 	.enable_box	= snr_uncore_mmio_enable_box,
54602b3b76b5SKan Liang 	.disable_event	= snr_uncore_mmio_disable_event,
54612b3b76b5SKan Liang 	.enable_event	= snr_uncore_mmio_enable_event,
54622b3b76b5SKan Liang 	.read_counter	= uncore_mmio_read_counter,
54632b3b76b5SKan Liang };
54642b3b76b5SKan Liang 
54652b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_imc = {
54662b3b76b5SKan Liang 	.name		= "imc",
54672b3b76b5SKan Liang 	.num_counters   = 4,
5468496a18f0SKan Liang 	.num_boxes	= 12,
54692b3b76b5SKan Liang 	.perf_ctr_bits	= 48,
54702b3b76b5SKan Liang 	.fixed_ctr_bits	= 48,
54712b3b76b5SKan Liang 	.fixed_ctr	= SNR_IMC_MMIO_PMON_FIXED_CTR,
54722b3b76b5SKan Liang 	.fixed_ctl	= SNR_IMC_MMIO_PMON_FIXED_CTL,
54732b3b76b5SKan Liang 	.event_descs	= hswep_uncore_imc_events,
54742b3b76b5SKan Liang 	.perf_ctr	= SNR_IMC_MMIO_PMON_CTR0,
54752b3b76b5SKan Liang 	.event_ctl	= SNR_IMC_MMIO_PMON_CTL0,
54762b3b76b5SKan Liang 	.event_mask	= SNBEP_PMON_RAW_EVENT_MASK,
54772b3b76b5SKan Liang 	.box_ctl	= SNR_IMC_MMIO_PMON_BOX_CTL,
54782b3b76b5SKan Liang 	.mmio_offset	= SNR_IMC_MMIO_OFFSET,
54791b94d31dSKan Liang 	.mmio_map_size	= SNR_IMC_MMIO_SIZE,
54802b3b76b5SKan Liang 	.ops		= &icx_uncore_mmio_ops,
54812b3b76b5SKan Liang 	.format_group	= &skx_uncore_format_group,
54822b3b76b5SKan Liang };
54832b3b76b5SKan Liang 
54842b3b76b5SKan Liang enum perf_uncore_icx_imc_freerunning_type_id {
54852b3b76b5SKan Liang 	ICX_IMC_DCLK,
54862b3b76b5SKan Liang 	ICX_IMC_DDR,
54872b3b76b5SKan Liang 	ICX_IMC_DDRT,
54882b3b76b5SKan Liang 
54892b3b76b5SKan Liang 	ICX_IMC_FREERUNNING_TYPE_MAX,
54902b3b76b5SKan Liang };
54912b3b76b5SKan Liang 
54922b3b76b5SKan Liang static struct freerunning_counters icx_imc_freerunning[] = {
54932b3b76b5SKan Liang 	[ICX_IMC_DCLK]	= { 0x22b0, 0x0, 0, 1, 48 },
54942b3b76b5SKan Liang 	[ICX_IMC_DDR]	= { 0x2290, 0x8, 0, 2, 48 },
54952b3b76b5SKan Liang 	[ICX_IMC_DDRT]	= { 0x22a0, 0x8, 0, 2, 48 },
54962b3b76b5SKan Liang };
54972b3b76b5SKan Liang 
54982b3b76b5SKan Liang static struct uncore_event_desc icx_uncore_imc_freerunning_events[] = {
54992b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(dclk,			"event=0xff,umask=0x10"),
55002b3b76b5SKan Liang 
55012b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(read,			"event=0xff,umask=0x20"),
55028191016aSKan Liang 	INTEL_UNCORE_EVENT_DESC(read.scale,		"6.103515625e-5"),
55032b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(read.unit,		"MiB"),
55042b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(write,			"event=0xff,umask=0x21"),
55058191016aSKan Liang 	INTEL_UNCORE_EVENT_DESC(write.scale,		"6.103515625e-5"),
55062b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(write.unit,		"MiB"),
55072b3b76b5SKan Liang 
55082b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(ddrt_read,		"event=0xff,umask=0x30"),
55098191016aSKan Liang 	INTEL_UNCORE_EVENT_DESC(ddrt_read.scale,	"6.103515625e-5"),
55102b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(ddrt_read.unit,		"MiB"),
55112b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(ddrt_write,		"event=0xff,umask=0x31"),
55128191016aSKan Liang 	INTEL_UNCORE_EVENT_DESC(ddrt_write.scale,	"6.103515625e-5"),
55132b3b76b5SKan Liang 	INTEL_UNCORE_EVENT_DESC(ddrt_write.unit,	"MiB"),
55142b3b76b5SKan Liang 	{ /* end: all zeroes */ },
55152b3b76b5SKan Liang };
55162b3b76b5SKan Liang 
55172b3b76b5SKan Liang static void icx_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
55182b3b76b5SKan Liang {
55192b3b76b5SKan Liang 	int mem_offset = box->pmu->pmu_idx * ICX_IMC_MEM_STRIDE +
55202b3b76b5SKan Liang 			 SNR_IMC_MMIO_MEM0_OFFSET;
55212b3b76b5SKan Liang 
55221583971bSKan Liang 	snr_uncore_mmio_map(box, uncore_mmio_box_ctl(box),
55231583971bSKan Liang 			    mem_offset, SNR_MC_DEVICE_ID);
55242b3b76b5SKan Liang }
55252b3b76b5SKan Liang 
55262b3b76b5SKan Liang static struct intel_uncore_ops icx_uncore_imc_freerunning_ops = {
55272b3b76b5SKan Liang 	.init_box	= icx_uncore_imc_freerunning_init_box,
55282b3b76b5SKan Liang 	.exit_box	= uncore_mmio_exit_box,
55292b3b76b5SKan Liang 	.read_counter	= uncore_mmio_read_counter,
55302b3b76b5SKan Liang 	.hw_config	= uncore_freerunning_hw_config,
55312b3b76b5SKan Liang };
55322b3b76b5SKan Liang 
55332b3b76b5SKan Liang static struct intel_uncore_type icx_uncore_imc_free_running = {
55342b3b76b5SKan Liang 	.name			= "imc_free_running",
55352b3b76b5SKan Liang 	.num_counters		= 5,
55362b3b76b5SKan Liang 	.num_boxes		= 4,
55372b3b76b5SKan Liang 	.num_freerunning_types	= ICX_IMC_FREERUNNING_TYPE_MAX,
55381b94d31dSKan Liang 	.mmio_map_size		= SNR_IMC_MMIO_SIZE,
55392b3b76b5SKan Liang 	.freerunning		= icx_imc_freerunning,
55402b3b76b5SKan Liang 	.ops			= &icx_uncore_imc_freerunning_ops,
55412b3b76b5SKan Liang 	.event_descs		= icx_uncore_imc_freerunning_events,
55422b3b76b5SKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
55432b3b76b5SKan Liang };
55442b3b76b5SKan Liang 
55452b3b76b5SKan Liang static struct intel_uncore_type *icx_mmio_uncores[] = {
55462b3b76b5SKan Liang 	&icx_uncore_imc,
55472b3b76b5SKan Liang 	&icx_uncore_imc_free_running,
55482b3b76b5SKan Liang 	NULL,
55492b3b76b5SKan Liang };
55502b3b76b5SKan Liang 
55512b3b76b5SKan Liang void icx_uncore_mmio_init(void)
55522b3b76b5SKan Liang {
55532b3b76b5SKan Liang 	uncore_mmio_uncores = icx_mmio_uncores;
55542b3b76b5SKan Liang }
55552b3b76b5SKan Liang 
55562b3b76b5SKan Liang /* end of ICX uncore support */
5557c54c53d9SKan Liang 
5558c54c53d9SKan Liang /* SPR uncore support */
5559c54c53d9SKan Liang 
5560949b1138SKan Liang static void spr_uncore_msr_enable_event(struct intel_uncore_box *box,
5561949b1138SKan Liang 					struct perf_event *event)
5562949b1138SKan Liang {
5563949b1138SKan Liang 	struct hw_perf_event *hwc = &event->hw;
5564949b1138SKan Liang 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
5565949b1138SKan Liang 
5566949b1138SKan Liang 	if (reg1->idx != EXTRA_REG_NONE)
5567949b1138SKan Liang 		wrmsrl(reg1->reg, reg1->config);
5568949b1138SKan Liang 
5569949b1138SKan Liang 	wrmsrl(hwc->config_base, hwc->config);
5570949b1138SKan Liang }
5571949b1138SKan Liang 
5572949b1138SKan Liang static void spr_uncore_msr_disable_event(struct intel_uncore_box *box,
5573949b1138SKan Liang 					 struct perf_event *event)
5574949b1138SKan Liang {
5575949b1138SKan Liang 	struct hw_perf_event *hwc = &event->hw;
5576949b1138SKan Liang 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
5577949b1138SKan Liang 
5578949b1138SKan Liang 	if (reg1->idx != EXTRA_REG_NONE)
5579949b1138SKan Liang 		wrmsrl(reg1->reg, 0);
5580949b1138SKan Liang 
5581949b1138SKan Liang 	wrmsrl(hwc->config_base, 0);
5582949b1138SKan Liang }
5583949b1138SKan Liang 
5584949b1138SKan Liang static int spr_cha_hw_config(struct intel_uncore_box *box, struct perf_event *event)
5585949b1138SKan Liang {
5586949b1138SKan Liang 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
5587949b1138SKan Liang 	bool tie_en = !!(event->hw.config & SPR_CHA_PMON_CTL_TID_EN);
5588949b1138SKan Liang 	struct intel_uncore_type *type = box->pmu->type;
5589949b1138SKan Liang 
5590949b1138SKan Liang 	if (tie_en) {
5591949b1138SKan Liang 		reg1->reg = SPR_C0_MSR_PMON_BOX_FILTER0 +
5592949b1138SKan Liang 			    HSWEP_CBO_MSR_OFFSET * type->box_ids[box->pmu->pmu_idx];
5593949b1138SKan Liang 		reg1->config = event->attr.config1 & SPR_CHA_PMON_BOX_FILTER_TID;
5594949b1138SKan Liang 		reg1->idx = 0;
5595949b1138SKan Liang 	}
5596949b1138SKan Liang 
5597949b1138SKan Liang 	return 0;
5598949b1138SKan Liang }
5599949b1138SKan Liang 
5600949b1138SKan Liang static struct intel_uncore_ops spr_uncore_chabox_ops = {
5601949b1138SKan Liang 	.init_box		= intel_generic_uncore_msr_init_box,
5602949b1138SKan Liang 	.disable_box		= intel_generic_uncore_msr_disable_box,
5603949b1138SKan Liang 	.enable_box		= intel_generic_uncore_msr_enable_box,
5604949b1138SKan Liang 	.disable_event		= spr_uncore_msr_disable_event,
5605949b1138SKan Liang 	.enable_event		= spr_uncore_msr_enable_event,
5606949b1138SKan Liang 	.read_counter		= uncore_msr_read_counter,
5607949b1138SKan Liang 	.hw_config		= spr_cha_hw_config,
5608949b1138SKan Liang 	.get_constraint		= uncore_get_constraint,
5609949b1138SKan Liang 	.put_constraint		= uncore_put_constraint,
5610949b1138SKan Liang };
5611949b1138SKan Liang 
5612949b1138SKan Liang static struct attribute *spr_uncore_cha_formats_attr[] = {
5613949b1138SKan Liang 	&format_attr_event.attr,
5614949b1138SKan Liang 	&format_attr_umask_ext4.attr,
5615949b1138SKan Liang 	&format_attr_tid_en2.attr,
5616949b1138SKan Liang 	&format_attr_edge.attr,
5617949b1138SKan Liang 	&format_attr_inv.attr,
5618949b1138SKan Liang 	&format_attr_thresh8.attr,
5619949b1138SKan Liang 	&format_attr_filter_tid5.attr,
5620949b1138SKan Liang 	NULL,
5621949b1138SKan Liang };
5622949b1138SKan Liang static const struct attribute_group spr_uncore_chabox_format_group = {
5623949b1138SKan Liang 	.name = "format",
5624949b1138SKan Liang 	.attrs = spr_uncore_cha_formats_attr,
5625949b1138SKan Liang };
5626949b1138SKan Liang 
56278053f2d7SKan Liang static ssize_t alias_show(struct device *dev,
56288053f2d7SKan Liang 			  struct device_attribute *attr,
56298053f2d7SKan Liang 			  char *buf)
56308053f2d7SKan Liang {
56318053f2d7SKan Liang 	struct intel_uncore_pmu *pmu = dev_to_uncore_pmu(dev);
56328053f2d7SKan Liang 	char pmu_name[UNCORE_PMU_NAME_LEN];
56338053f2d7SKan Liang 
56348053f2d7SKan Liang 	uncore_get_alias_name(pmu_name, pmu);
56358053f2d7SKan Liang 	return sysfs_emit(buf, "%s\n", pmu_name);
56368053f2d7SKan Liang }
56378053f2d7SKan Liang 
56388053f2d7SKan Liang static DEVICE_ATTR_RO(alias);
56398053f2d7SKan Liang 
56408053f2d7SKan Liang static struct attribute *uncore_alias_attrs[] = {
56418053f2d7SKan Liang 	&dev_attr_alias.attr,
56428053f2d7SKan Liang 	NULL
56438053f2d7SKan Liang };
56448053f2d7SKan Liang 
56458053f2d7SKan Liang ATTRIBUTE_GROUPS(uncore_alias);
56468053f2d7SKan Liang 
5647949b1138SKan Liang static struct intel_uncore_type spr_uncore_chabox = {
5648949b1138SKan Liang 	.name			= "cha",
5649949b1138SKan Liang 	.event_mask		= SPR_CHA_PMON_EVENT_MASK,
5650949b1138SKan Liang 	.event_mask_ext		= SPR_RAW_EVENT_MASK_EXT,
5651949b1138SKan Liang 	.num_shared_regs	= 1,
5652949b1138SKan Liang 	.ops			= &spr_uncore_chabox_ops,
5653949b1138SKan Liang 	.format_group		= &spr_uncore_chabox_format_group,
56548053f2d7SKan Liang 	.attr_update		= uncore_alias_groups,
5655949b1138SKan Liang };
5656949b1138SKan Liang 
56573ba7095bSKan Liang static struct intel_uncore_type spr_uncore_iio = {
56583ba7095bSKan Liang 	.name			= "iio",
56593ba7095bSKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
56603ba7095bSKan Liang 	.event_mask_ext		= SNR_IIO_PMON_RAW_EVENT_MASK_EXT,
56613ba7095bSKan Liang 	.format_group		= &snr_uncore_iio_format_group,
56628053f2d7SKan Liang 	.attr_update		= uncore_alias_groups,
56633ba7095bSKan Liang };
56643ba7095bSKan Liang 
5665e199eb51SKan Liang static struct attribute *spr_uncore_raw_formats_attr[] = {
5666e199eb51SKan Liang 	&format_attr_event.attr,
5667e199eb51SKan Liang 	&format_attr_umask_ext4.attr,
5668e199eb51SKan Liang 	&format_attr_edge.attr,
5669e199eb51SKan Liang 	&format_attr_inv.attr,
5670e199eb51SKan Liang 	&format_attr_thresh8.attr,
5671e199eb51SKan Liang 	NULL,
5672e199eb51SKan Liang };
5673e199eb51SKan Liang 
5674e199eb51SKan Liang static const struct attribute_group spr_uncore_raw_format_group = {
5675e199eb51SKan Liang 	.name			= "format",
5676e199eb51SKan Liang 	.attrs			= spr_uncore_raw_formats_attr,
5677e199eb51SKan Liang };
5678e199eb51SKan Liang 
5679e199eb51SKan Liang #define SPR_UNCORE_COMMON_FORMAT()				\
5680e199eb51SKan Liang 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,	\
5681e199eb51SKan Liang 	.event_mask_ext		= SPR_RAW_EVENT_MASK_EXT,	\
56828053f2d7SKan Liang 	.format_group		= &spr_uncore_raw_format_group,	\
56838053f2d7SKan Liang 	.attr_update		= uncore_alias_groups
5684e199eb51SKan Liang 
5685e199eb51SKan Liang static struct intel_uncore_type spr_uncore_irp = {
5686e199eb51SKan Liang 	SPR_UNCORE_COMMON_FORMAT(),
5687e199eb51SKan Liang 	.name			= "irp",
5688e199eb51SKan Liang 
5689e199eb51SKan Liang };
5690e199eb51SKan Liang 
5691f85ef898SKan Liang static struct intel_uncore_type spr_uncore_m2pcie = {
5692f85ef898SKan Liang 	SPR_UNCORE_COMMON_FORMAT(),
5693f85ef898SKan Liang 	.name			= "m2pcie",
5694f85ef898SKan Liang };
5695f85ef898SKan Liang 
56960654dfdcSKan Liang static struct intel_uncore_type spr_uncore_pcu = {
56970654dfdcSKan Liang 	.name			= "pcu",
56988053f2d7SKan Liang 	.attr_update		= uncore_alias_groups,
56990654dfdcSKan Liang };
57000654dfdcSKan Liang 
570185f2e30fSKan Liang static void spr_uncore_mmio_enable_event(struct intel_uncore_box *box,
570285f2e30fSKan Liang 					 struct perf_event *event)
570385f2e30fSKan Liang {
570485f2e30fSKan Liang 	struct hw_perf_event *hwc = &event->hw;
570585f2e30fSKan Liang 
570685f2e30fSKan Liang 	if (!box->io_addr)
570785f2e30fSKan Liang 		return;
570885f2e30fSKan Liang 
570985f2e30fSKan Liang 	if (uncore_pmc_fixed(hwc->idx))
571085f2e30fSKan Liang 		writel(SNBEP_PMON_CTL_EN, box->io_addr + hwc->config_base);
571185f2e30fSKan Liang 	else
571285f2e30fSKan Liang 		writel(hwc->config, box->io_addr + hwc->config_base);
571385f2e30fSKan Liang }
571485f2e30fSKan Liang 
571585f2e30fSKan Liang static struct intel_uncore_ops spr_uncore_mmio_ops = {
571685f2e30fSKan Liang 	.init_box		= intel_generic_uncore_mmio_init_box,
571785f2e30fSKan Liang 	.exit_box		= uncore_mmio_exit_box,
571885f2e30fSKan Liang 	.disable_box		= intel_generic_uncore_mmio_disable_box,
571985f2e30fSKan Liang 	.enable_box		= intel_generic_uncore_mmio_enable_box,
572085f2e30fSKan Liang 	.disable_event		= intel_generic_uncore_mmio_disable_event,
572185f2e30fSKan Liang 	.enable_event		= spr_uncore_mmio_enable_event,
572285f2e30fSKan Liang 	.read_counter		= uncore_mmio_read_counter,
572385f2e30fSKan Liang };
572485f2e30fSKan Liang 
572585f2e30fSKan Liang static struct intel_uncore_type spr_uncore_imc = {
572685f2e30fSKan Liang 	SPR_UNCORE_COMMON_FORMAT(),
572785f2e30fSKan Liang 	.name			= "imc",
572885f2e30fSKan Liang 	.fixed_ctr_bits		= 48,
572985f2e30fSKan Liang 	.fixed_ctr		= SNR_IMC_MMIO_PMON_FIXED_CTR,
573085f2e30fSKan Liang 	.fixed_ctl		= SNR_IMC_MMIO_PMON_FIXED_CTL,
573185f2e30fSKan Liang 	.ops			= &spr_uncore_mmio_ops,
573285f2e30fSKan Liang };
573385f2e30fSKan Liang 
5734f57191edSKan Liang static void spr_uncore_pci_enable_event(struct intel_uncore_box *box,
5735f57191edSKan Liang 					struct perf_event *event)
5736f57191edSKan Liang {
5737f57191edSKan Liang 	struct pci_dev *pdev = box->pci_dev;
5738f57191edSKan Liang 	struct hw_perf_event *hwc = &event->hw;
5739f57191edSKan Liang 
5740f57191edSKan Liang 	pci_write_config_dword(pdev, hwc->config_base + 4, (u32)(hwc->config >> 32));
5741f57191edSKan Liang 	pci_write_config_dword(pdev, hwc->config_base, (u32)hwc->config);
5742f57191edSKan Liang }
5743f57191edSKan Liang 
5744f57191edSKan Liang static struct intel_uncore_ops spr_uncore_pci_ops = {
5745f57191edSKan Liang 	.init_box		= intel_generic_uncore_pci_init_box,
5746f57191edSKan Liang 	.disable_box		= intel_generic_uncore_pci_disable_box,
5747f57191edSKan Liang 	.enable_box		= intel_generic_uncore_pci_enable_box,
5748f57191edSKan Liang 	.disable_event		= intel_generic_uncore_pci_disable_event,
5749f57191edSKan Liang 	.enable_event		= spr_uncore_pci_enable_event,
5750f57191edSKan Liang 	.read_counter		= intel_generic_uncore_pci_read_counter,
5751f57191edSKan Liang };
5752f57191edSKan Liang 
5753f57191edSKan Liang #define SPR_UNCORE_PCI_COMMON_FORMAT()			\
5754f57191edSKan Liang 	SPR_UNCORE_COMMON_FORMAT(),			\
5755f57191edSKan Liang 	.ops			= &spr_uncore_pci_ops
5756f57191edSKan Liang 
5757f57191edSKan Liang static struct intel_uncore_type spr_uncore_m2m = {
5758f57191edSKan Liang 	SPR_UNCORE_PCI_COMMON_FORMAT(),
5759f57191edSKan Liang 	.name			= "m2m",
5760f57191edSKan Liang };
5761f57191edSKan Liang 
5762da5a9156SKan Liang static struct intel_uncore_type spr_uncore_upi = {
5763da5a9156SKan Liang 	SPR_UNCORE_PCI_COMMON_FORMAT(),
5764da5a9156SKan Liang 	.name			= "upi",
5765da5a9156SKan Liang };
5766da5a9156SKan Liang 
57672a8e51eaSKan Liang static struct intel_uncore_type spr_uncore_m3upi = {
57682a8e51eaSKan Liang 	SPR_UNCORE_PCI_COMMON_FORMAT(),
57692a8e51eaSKan Liang 	.name			= "m3upi",
57702a8e51eaSKan Liang };
57712a8e51eaSKan Liang 
57720d771cafSKan Liang static struct intel_uncore_type spr_uncore_mdf = {
57730d771cafSKan Liang 	SPR_UNCORE_COMMON_FORMAT(),
57740d771cafSKan Liang 	.name			= "mdf",
57750d771cafSKan Liang };
57760d771cafSKan Liang 
5777c54c53d9SKan Liang #define UNCORE_SPR_NUM_UNCORE_TYPES		12
57780378c93aSKan Liang #define UNCORE_SPR_IIO				1
5779c76826a6SKan Liang #define UNCORE_SPR_IMC				6
5780c54c53d9SKan Liang 
5781c54c53d9SKan Liang static struct intel_uncore_type *spr_uncores[UNCORE_SPR_NUM_UNCORE_TYPES] = {
5782949b1138SKan Liang 	&spr_uncore_chabox,
57833ba7095bSKan Liang 	&spr_uncore_iio,
5784e199eb51SKan Liang 	&spr_uncore_irp,
5785f85ef898SKan Liang 	&spr_uncore_m2pcie,
57860654dfdcSKan Liang 	&spr_uncore_pcu,
5787c54c53d9SKan Liang 	NULL,
578885f2e30fSKan Liang 	&spr_uncore_imc,
5789f57191edSKan Liang 	&spr_uncore_m2m,
5790da5a9156SKan Liang 	&spr_uncore_upi,
57912a8e51eaSKan Liang 	&spr_uncore_m3upi,
5792c54c53d9SKan Liang 	NULL,
57930d771cafSKan Liang 	&spr_uncore_mdf,
5794c54c53d9SKan Liang };
5795c54c53d9SKan Liang 
57960378c93aSKan Liang enum perf_uncore_spr_iio_freerunning_type_id {
57970378c93aSKan Liang 	SPR_IIO_MSR_IOCLK,
57980378c93aSKan Liang 	SPR_IIO_MSR_BW_IN,
57990378c93aSKan Liang 	SPR_IIO_MSR_BW_OUT,
58000378c93aSKan Liang 
58010378c93aSKan Liang 	SPR_IIO_FREERUNNING_TYPE_MAX,
58020378c93aSKan Liang };
58030378c93aSKan Liang 
58040378c93aSKan Liang static struct freerunning_counters spr_iio_freerunning[] = {
58050378c93aSKan Liang 	[SPR_IIO_MSR_IOCLK]	= { 0x340e, 0x1, 0x10, 1, 48 },
58060378c93aSKan Liang 	[SPR_IIO_MSR_BW_IN]	= { 0x3800, 0x1, 0x10, 8, 48 },
58070378c93aSKan Liang 	[SPR_IIO_MSR_BW_OUT]	= { 0x3808, 0x1, 0x10, 8, 48 },
58080378c93aSKan Liang };
58090378c93aSKan Liang 
58100378c93aSKan Liang static struct uncore_event_desc spr_uncore_iio_freerunning_events[] = {
58110378c93aSKan Liang 	/* Free-Running IIO CLOCKS Counter */
58120378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(ioclk,			"event=0xff,umask=0x10"),
58130378c93aSKan Liang 	/* Free-Running IIO BANDWIDTH IN Counters */
58140378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0,		"event=0xff,umask=0x20"),
58150378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale,	"3.814697266e-6"),
58160378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit,	"MiB"),
58170378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1,		"event=0xff,umask=0x21"),
58180378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale,	"3.814697266e-6"),
58190378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit,	"MiB"),
58200378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2,		"event=0xff,umask=0x22"),
58210378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale,	"3.814697266e-6"),
58220378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit,	"MiB"),
58230378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3,		"event=0xff,umask=0x23"),
58240378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale,	"3.814697266e-6"),
58250378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit,	"MiB"),
58260378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4,		"event=0xff,umask=0x24"),
58270378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4.scale,	"3.814697266e-6"),
58280378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port4.unit,	"MiB"),
58290378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5,		"event=0xff,umask=0x25"),
58300378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5.scale,	"3.814697266e-6"),
58310378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port5.unit,	"MiB"),
58320378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6,		"event=0xff,umask=0x26"),
58330378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6.scale,	"3.814697266e-6"),
58340378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port6.unit,	"MiB"),
58350378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7,		"event=0xff,umask=0x27"),
58360378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7.scale,	"3.814697266e-6"),
58370378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_in_port7.unit,	"MiB"),
58380378c93aSKan Liang 	/* Free-Running IIO BANDWIDTH OUT Counters */
58390378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port0,		"event=0xff,umask=0x30"),
58400378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port0.scale,	"3.814697266e-6"),
58410378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port0.unit,	"MiB"),
58420378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port1,		"event=0xff,umask=0x31"),
58430378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port1.scale,	"3.814697266e-6"),
58440378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port1.unit,	"MiB"),
58450378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port2,		"event=0xff,umask=0x32"),
58460378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port2.scale,	"3.814697266e-6"),
58470378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port2.unit,	"MiB"),
58480378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port3,		"event=0xff,umask=0x33"),
58490378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port3.scale,	"3.814697266e-6"),
58500378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port3.unit,	"MiB"),
58510378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port4,		"event=0xff,umask=0x34"),
58520378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port4.scale,	"3.814697266e-6"),
58530378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port4.unit,	"MiB"),
58540378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port5,		"event=0xff,umask=0x35"),
58550378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port5.scale,	"3.814697266e-6"),
58560378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port5.unit,	"MiB"),
58570378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port6,		"event=0xff,umask=0x36"),
58580378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port6.scale,	"3.814697266e-6"),
58590378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port6.unit,	"MiB"),
58600378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port7,		"event=0xff,umask=0x37"),
58610378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port7.scale,	"3.814697266e-6"),
58620378c93aSKan Liang 	INTEL_UNCORE_EVENT_DESC(bw_out_port7.unit,	"MiB"),
58630378c93aSKan Liang 	{ /* end: all zeroes */ },
58640378c93aSKan Liang };
58650378c93aSKan Liang 
58660378c93aSKan Liang static struct intel_uncore_type spr_uncore_iio_free_running = {
58670378c93aSKan Liang 	.name			= "iio_free_running",
58680378c93aSKan Liang 	.num_counters		= 17,
58690378c93aSKan Liang 	.num_freerunning_types	= SPR_IIO_FREERUNNING_TYPE_MAX,
58700378c93aSKan Liang 	.freerunning		= spr_iio_freerunning,
58710378c93aSKan Liang 	.ops			= &skx_uncore_iio_freerunning_ops,
58720378c93aSKan Liang 	.event_descs		= spr_uncore_iio_freerunning_events,
58730378c93aSKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
58740378c93aSKan Liang };
58750378c93aSKan Liang 
5876c76826a6SKan Liang enum perf_uncore_spr_imc_freerunning_type_id {
5877c76826a6SKan Liang 	SPR_IMC_DCLK,
5878c76826a6SKan Liang 	SPR_IMC_PQ_CYCLES,
5879c76826a6SKan Liang 
5880c76826a6SKan Liang 	SPR_IMC_FREERUNNING_TYPE_MAX,
5881c76826a6SKan Liang };
5882c76826a6SKan Liang 
5883c76826a6SKan Liang static struct freerunning_counters spr_imc_freerunning[] = {
5884c76826a6SKan Liang 	[SPR_IMC_DCLK]		= { 0x22b0, 0x0, 0, 1, 48 },
5885c76826a6SKan Liang 	[SPR_IMC_PQ_CYCLES]	= { 0x2318, 0x8, 0, 2, 48 },
5886c76826a6SKan Liang };
5887c76826a6SKan Liang 
5888c76826a6SKan Liang static struct uncore_event_desc spr_uncore_imc_freerunning_events[] = {
5889c76826a6SKan Liang 	INTEL_UNCORE_EVENT_DESC(dclk,			"event=0xff,umask=0x10"),
5890c76826a6SKan Liang 
5891c76826a6SKan Liang 	INTEL_UNCORE_EVENT_DESC(rpq_cycles,		"event=0xff,umask=0x20"),
5892c76826a6SKan Liang 	INTEL_UNCORE_EVENT_DESC(wpq_cycles,		"event=0xff,umask=0x21"),
5893c76826a6SKan Liang 	{ /* end: all zeroes */ },
5894c76826a6SKan Liang };
5895c76826a6SKan Liang 
5896c76826a6SKan Liang #define SPR_MC_DEVICE_ID	0x3251
5897c76826a6SKan Liang 
5898c76826a6SKan Liang static void spr_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
5899c76826a6SKan Liang {
5900c76826a6SKan Liang 	int mem_offset = box->pmu->pmu_idx * ICX_IMC_MEM_STRIDE + SNR_IMC_MMIO_MEM0_OFFSET;
5901c76826a6SKan Liang 
5902c76826a6SKan Liang 	snr_uncore_mmio_map(box, uncore_mmio_box_ctl(box),
5903c76826a6SKan Liang 			    mem_offset, SPR_MC_DEVICE_ID);
5904c76826a6SKan Liang }
5905c76826a6SKan Liang 
5906c76826a6SKan Liang static struct intel_uncore_ops spr_uncore_imc_freerunning_ops = {
5907c76826a6SKan Liang 	.init_box	= spr_uncore_imc_freerunning_init_box,
5908c76826a6SKan Liang 	.exit_box	= uncore_mmio_exit_box,
5909c76826a6SKan Liang 	.read_counter	= uncore_mmio_read_counter,
5910c76826a6SKan Liang 	.hw_config	= uncore_freerunning_hw_config,
5911c76826a6SKan Liang };
5912c76826a6SKan Liang 
5913c76826a6SKan Liang static struct intel_uncore_type spr_uncore_imc_free_running = {
5914c76826a6SKan Liang 	.name			= "imc_free_running",
5915c76826a6SKan Liang 	.num_counters		= 3,
5916c76826a6SKan Liang 	.mmio_map_size		= SNR_IMC_MMIO_SIZE,
5917c76826a6SKan Liang 	.num_freerunning_types	= SPR_IMC_FREERUNNING_TYPE_MAX,
5918c76826a6SKan Liang 	.freerunning		= spr_imc_freerunning,
5919c76826a6SKan Liang 	.ops			= &spr_uncore_imc_freerunning_ops,
5920c76826a6SKan Liang 	.event_descs		= spr_uncore_imc_freerunning_events,
5921c76826a6SKan Liang 	.format_group		= &skx_uncore_iio_freerunning_format_group,
5922c76826a6SKan Liang };
5923c76826a6SKan Liang 
59240378c93aSKan Liang #define UNCORE_SPR_MSR_EXTRA_UNCORES		1
5925c76826a6SKan Liang #define UNCORE_SPR_MMIO_EXTRA_UNCORES		1
59260378c93aSKan Liang 
59270378c93aSKan Liang static struct intel_uncore_type *spr_msr_uncores[UNCORE_SPR_MSR_EXTRA_UNCORES] = {
59280378c93aSKan Liang 	&spr_uncore_iio_free_running,
59290378c93aSKan Liang };
59300378c93aSKan Liang 
5931c76826a6SKan Liang static struct intel_uncore_type *spr_mmio_uncores[UNCORE_SPR_MMIO_EXTRA_UNCORES] = {
5932c76826a6SKan Liang 	&spr_uncore_imc_free_running,
5933c76826a6SKan Liang };
5934c76826a6SKan Liang 
5935c54c53d9SKan Liang static void uncore_type_customized_copy(struct intel_uncore_type *to_type,
5936c54c53d9SKan Liang 					struct intel_uncore_type *from_type)
5937c54c53d9SKan Liang {
5938c54c53d9SKan Liang 	if (!to_type || !from_type)
5939c54c53d9SKan Liang 		return;
5940c54c53d9SKan Liang 
5941c54c53d9SKan Liang 	if (from_type->name)
5942c54c53d9SKan Liang 		to_type->name = from_type->name;
5943c54c53d9SKan Liang 	if (from_type->fixed_ctr_bits)
5944c54c53d9SKan Liang 		to_type->fixed_ctr_bits = from_type->fixed_ctr_bits;
5945c54c53d9SKan Liang 	if (from_type->event_mask)
5946c54c53d9SKan Liang 		to_type->event_mask = from_type->event_mask;
5947c54c53d9SKan Liang 	if (from_type->event_mask_ext)
5948c54c53d9SKan Liang 		to_type->event_mask_ext = from_type->event_mask_ext;
5949c54c53d9SKan Liang 	if (from_type->fixed_ctr)
5950c54c53d9SKan Liang 		to_type->fixed_ctr = from_type->fixed_ctr;
5951c54c53d9SKan Liang 	if (from_type->fixed_ctl)
5952c54c53d9SKan Liang 		to_type->fixed_ctl = from_type->fixed_ctl;
5953c54c53d9SKan Liang 	if (from_type->fixed_ctr_bits)
5954c54c53d9SKan Liang 		to_type->fixed_ctr_bits = from_type->fixed_ctr_bits;
5955c54c53d9SKan Liang 	if (from_type->num_shared_regs)
5956c54c53d9SKan Liang 		to_type->num_shared_regs = from_type->num_shared_regs;
5957c54c53d9SKan Liang 	if (from_type->constraints)
5958c54c53d9SKan Liang 		to_type->constraints = from_type->constraints;
5959c54c53d9SKan Liang 	if (from_type->ops)
5960c54c53d9SKan Liang 		to_type->ops = from_type->ops;
5961c54c53d9SKan Liang 	if (from_type->event_descs)
5962c54c53d9SKan Liang 		to_type->event_descs = from_type->event_descs;
5963c54c53d9SKan Liang 	if (from_type->format_group)
5964c54c53d9SKan Liang 		to_type->format_group = from_type->format_group;
59658053f2d7SKan Liang 	if (from_type->attr_update)
59668053f2d7SKan Liang 		to_type->attr_update = from_type->attr_update;
5967c54c53d9SKan Liang }
5968c54c53d9SKan Liang 
5969c54c53d9SKan Liang static struct intel_uncore_type **
59700378c93aSKan Liang uncore_get_uncores(enum uncore_access_type type_id, int num_extra,
59710378c93aSKan Liang 		    struct intel_uncore_type **extra)
5972c54c53d9SKan Liang {
5973c54c53d9SKan Liang 	struct intel_uncore_type **types, **start_types;
59740378c93aSKan Liang 	int i;
5975c54c53d9SKan Liang 
59760378c93aSKan Liang 	start_types = types = intel_uncore_generic_init_uncores(type_id, num_extra);
5977c54c53d9SKan Liang 
5978c54c53d9SKan Liang 	/* Only copy the customized features */
5979c54c53d9SKan Liang 	for (; *types; types++) {
5980c54c53d9SKan Liang 		if ((*types)->type_id >= UNCORE_SPR_NUM_UNCORE_TYPES)
5981c54c53d9SKan Liang 			continue;
5982c54c53d9SKan Liang 		uncore_type_customized_copy(*types, spr_uncores[(*types)->type_id]);
5983c54c53d9SKan Liang 	}
5984c54c53d9SKan Liang 
59850378c93aSKan Liang 	for (i = 0; i < num_extra; i++, types++)
59860378c93aSKan Liang 		*types = extra[i];
59870378c93aSKan Liang 
5988c54c53d9SKan Liang 	return start_types;
5989c54c53d9SKan Liang }
5990c54c53d9SKan Liang 
59910378c93aSKan Liang static struct intel_uncore_type *
59920378c93aSKan Liang uncore_find_type_by_id(struct intel_uncore_type **types, int type_id)
59930378c93aSKan Liang {
59940378c93aSKan Liang 	for (; *types; types++) {
59950378c93aSKan Liang 		if (type_id == (*types)->type_id)
59960378c93aSKan Liang 			return *types;
59970378c93aSKan Liang 	}
59980378c93aSKan Liang 
59990378c93aSKan Liang 	return NULL;
60000378c93aSKan Liang }
60010378c93aSKan Liang 
60020378c93aSKan Liang static int uncore_type_max_boxes(struct intel_uncore_type **types,
60030378c93aSKan Liang 				 int type_id)
60040378c93aSKan Liang {
60050378c93aSKan Liang 	struct intel_uncore_type *type;
60060378c93aSKan Liang 	int i, max = 0;
60070378c93aSKan Liang 
60080378c93aSKan Liang 	type = uncore_find_type_by_id(types, type_id);
60090378c93aSKan Liang 	if (!type)
60100378c93aSKan Liang 		return 0;
60110378c93aSKan Liang 
60120378c93aSKan Liang 	for (i = 0; i < type->num_boxes; i++) {
60130378c93aSKan Liang 		if (type->box_ids[i] > max)
60140378c93aSKan Liang 			max = type->box_ids[i];
60150378c93aSKan Liang 	}
60160378c93aSKan Liang 
60170378c93aSKan Liang 	return max + 1;
60180378c93aSKan Liang }
60190378c93aSKan Liang 
6020c54c53d9SKan Liang void spr_uncore_cpu_init(void)
6021c54c53d9SKan Liang {
60220378c93aSKan Liang 	uncore_msr_uncores = uncore_get_uncores(UNCORE_ACCESS_MSR,
60230378c93aSKan Liang 						UNCORE_SPR_MSR_EXTRA_UNCORES,
60240378c93aSKan Liang 						spr_msr_uncores);
60250378c93aSKan Liang 
60260378c93aSKan Liang 	spr_uncore_iio_free_running.num_boxes = uncore_type_max_boxes(uncore_msr_uncores, UNCORE_SPR_IIO);
6027c54c53d9SKan Liang }
6028c54c53d9SKan Liang 
6029c54c53d9SKan Liang int spr_uncore_pci_init(void)
6030c54c53d9SKan Liang {
60310378c93aSKan Liang 	uncore_pci_uncores = uncore_get_uncores(UNCORE_ACCESS_PCI, 0, NULL);
6032c54c53d9SKan Liang 	return 0;
6033c54c53d9SKan Liang }
6034c54c53d9SKan Liang 
6035c54c53d9SKan Liang void spr_uncore_mmio_init(void)
6036c54c53d9SKan Liang {
6037c76826a6SKan Liang 	int ret = snbep_pci2phy_map_init(0x3250, SKX_CPUNODEID, SKX_GIDNIDMAP, true);
6038c76826a6SKan Liang 
6039c76826a6SKan Liang 	if (ret)
60400378c93aSKan Liang 		uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO, 0, NULL);
6041c76826a6SKan Liang 	else {
6042c76826a6SKan Liang 		uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO,
6043c76826a6SKan Liang 							 UNCORE_SPR_MMIO_EXTRA_UNCORES,
6044c76826a6SKan Liang 							 spr_mmio_uncores);
6045c76826a6SKan Liang 
6046c76826a6SKan Liang 		spr_uncore_imc_free_running.num_boxes = uncore_type_max_boxes(uncore_mmio_uncores, UNCORE_SPR_IMC) / 2;
6047c76826a6SKan Liang 	}
6048c54c53d9SKan Liang }
6049c54c53d9SKan Liang 
6050c54c53d9SKan Liang /* end of SPR uncore support */
6051